2

Below is a the test question for a practice LPIC-1 exam I took. The correct answer is A. I'm really dazzled at how this is the case. If it's not too much trouble can someone walk me through how A is the correct answer?

int double(int n)
    { /* int arg, int return */
       return n*2;
    }
    char hello(int n)
    { /* int arg, char return */
       printf("hello %i\n", n);
    }
    int five()
    { /* no args, int return */
       return 5;
    }
    int        triple(int n, int other, char nonsense)
    { /* int arg, int return */
       return n*3;
    }

Correctly parsing a C source file requires a full-fledged parser (such as that built into a C compiler). Nonetheless, regular expressions can be used to provide a pretty good approximate descriptions of many program constructs. Which of the following searches will locate at least most of the C functions that accept an int as a first argument, and return an int (and will not produce false positives very often). The exhibit contains a fragment of C code with several annotated matching and non-matching functions (for non-C programmers).

  • A. grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" *.c
  • B. grep -E "^int\w+[A-Za-z_]+\w*\(\w*int" *.c
  • C. grep -E "int.+\([ \t]+int.*\) " *.c
  • D. grep -E "int[ \t]+[A-Za-z_][ \t]+\(int" *.c

Reference: http://gnosis.cx/publish/programming/exam101.html - specifically this question - 1.3/7/1.

  • 1
    I advise reading the core appontments for the corresponding LPIC levels and trying to understang it. You might be in for a disappointment if you thing doing mock exams does cut it. Some of the LPI tests are a bit unusual, my LPI 201 focused a lot in Linux network knowledge. – Rui F Ribeiro Aug 7 '18 at 23:54
  • 1
    gnosis.cx/publish/programming/exam101.html - it's this Q - 1.3/7/1. – slm Aug 8 '18 at 2:25
  • 1
    always use a tool or build your own graph of the regexp: regexper.com – Kiwy Aug 8 '18 at 7:48
  • 1
    Bonus points could be given to those pointing out that you shouldn't use double as the name of a function as that's one of the builtin C types. Or that [ \t] matches on space, backslash and t instead of the intended TAB. – Stéphane Chazelas Aug 8 '18 at 12:10
2

So "A." is the answer simply because it's the only one that returns the 2 functions defined in the sample code:

$ grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" sample.c
int double(int n)
    int        triple(int n, int other, char nonsense)

The other 3 return nothing, if you were to try them. This one works because it's able to deal with both situations that present in these lines:

int double(int n)
    int        triple(int n, int other, char nonsense)

The grep:

  • int[ \t]+ - matches lines that begin with int followed by at least 1 space or tab (\t)
  • \w+ - this matches one or more characters in a word (double & triple)
  • [ \t]* - zero or more spaces or tabs
  • \([ \t]*int - a open paren (() followed by zero or more spaces or tabs followed by the string int

NOTE: the question assumes GNU grep since it's utilizing \w. Other implementations of grep do not support this notation with their regex (-E), for these, using [[:alnum:]] is the better choice. Also a wiser choice would've been [[:blank:]] instead of [ \t] since technically this matches spaces, backslashes, and t as POSIX requires.

Rewriting the "A." answer this is a much more compliant solution:

$ grep -E "int[[:blank:]]+[[:alpha:]_][[:alnum:]_]+[[:blank:]]*\([[:blank:]]*int" sample.c

Here you can see in red what the above grep actually matched:

ss2

  • A C function name may match [[:alpha:]_][[:alnum:]_]+ in the C locale. – Kusalananda Aug 8 '18 at 9:20
  • @Kusalananda - you're turning into Stephane 8-) - so this? grep -E "int[[:blank:]]+[[:alpha:]_][[:alnum:]_]+[[:blank:]]*\([[:blank:]]*int" sample.c. – slm Aug 8 '18 at 9:54
  • 1
    Oh, I hope not. I don't know what Stéphane would have said, but it looks ok to me... – Kusalananda Aug 8 '18 at 10:05
  • Why does "[ \t]* - zero or more spaces or tabs" have an astrix at the end, isn't that a wildcard? – user284179 Aug 10 '18 at 21:54
  • 1
    @user284179 no it's a count against the set of characters in the square brackets, means zero or more of the things inside the set. Also per POSIX the set is actually space, backslash, or t which is technically incorrect per our conversations. – slm Aug 10 '18 at 22:02
3

Assuming that when you take the test, you can't actually run the grep commands against the input data, then you will have to look at the expressions and do some guessing.

Looking at them in reverse order:

  • D. grep -E "int[ \t]+[A-Za-z_][ \t]+\(int" *.c

    This does not allow for function names longer than a single character ([A-Za-z_]) and assumes that there must be at least a space, backslash or t between the function name and the argument list.

    Matches int a (int or int at(int but not int foo(int.

  • C. grep -E "int.+\([ \t]+int.*\) " *.c

    This assumes that the argument list starts with at least one space, backslash or t.

    Matches int foo( int or int foo(tint but not int foo(int.

  • B. grep -E "^int\w+[A-Za-z_]+\w*\(\w*int" *.c

    This does not allow for any space between the int return type and the function name, and it assumes that the function definition starts at the start of the line (the example code contains some indented function definitions).

    Matches intfoo(int but not int foo(int.

  • A. grep -E "int[ \t]+\w+[ \t]*\([ \t]*int" *.c

    This is the only one that allows a match on int foo(int, but it also matches invalid function names such as int 000(int. It is however the best regular expression out of the four given ones.

Note too that this question assumes GNU grep for matching \w. With a standard grep implementation [[:alnum:]_] would have been better for \w and [[:blank:]] should have been used in place of for matching space or tab ([ \t] matches space, backslash or t).

  • Note that it's fine to match on int \w+ since int 000 would not occur in C code (other than in things like char *p = "int 000(int)" but that's the kind of thing that would fool int [a-zA-Z_]\w* as well). – Stéphane Chazelas Aug 8 '18 at 8:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.