My goal is to parse defines in Objective-C code:#define wowFont [UIFont fontWithName:(DEV)?@one:@two size:(DEV? 10: 12)]#define wowColor [UIColor colorWithRed:(DEV?240/255.0f:255.0f) green:((DEV)? 230.0f / 255.0f) blue: 10.0f]I try to write grammar for it:grammar Defines::Grammar {    token TOP {        \s*<define_expression>\n    }    token define_expression {        ^^ #define $<keyword>=\w+ \s+ $<value> = <general_expression>    }    token general_expression{        # here, determine parenthes        <simple_expression>|[(]<general_expression>[)]|<value_expression>    }    token simple_expression{        # here, determine ?: behaviour        \s*<general_expression>\s*[?]\s*<general_expression>\s*[:]\s*<general_expression>\s*    }    token value_expression {        # stop here, need to determine ?: operator here        <numeric_expression>|<string_expression>|<function_invocation_expression>|<bareword_expression>    }    token function_invocation_expression {        [\[] (<class>|<bareword_expression>) \s+ <function_body>\s* [\]]    }    token function_body {        <bareword_expression>|<bareword_expression> \s* [:] <general_expression>    }    token bareword_expression {        [\w_]+    }    token string_expression {        \@[][^][]    }    token numeric_expression {        # we could +-*/ numeric expressions, also we can put lead sigil [-]. put parentheses and it could be a <number>        <numeric_expression> [*/+-] <numeric_expression> | [-+]<numberic_expression> | [(] <numeric_expression> [)] | <number>    }    token number {          # number expression here, ok        # not needed legal sign here, numeric_expression already have it        \d+ [\.] \d+    }}Could anybody help to improve it?P.S: As a part of answer (I hope that somebody will find this documents helpful) I place here a link to Perl 6 book (I found out that Grammars section is good enough for beginning). Perl 6 Book
Perl 6: Grammar issues (simple defines)
parsing;perl;grammar
It doesn't look like this code is currently working.AFAIK Objective-C uses the normal C preprocessor. The preprocessor works on a token level, and does not know about stuff like method calls. It is entirely irrelevant that [ starts a method call or an array subscript, for the preprocessor it's just some token. So as a rough sketch:token TOP {    ^^ \s* '#define' \s* $<name>=<bareword> \s* $<value>=(<token>+) $$}Notice that my # is inside a string and is thus not interpreted as a comment!There are however some special cases to consider:Arguments to the macros:#define MIN(a, b) (((a) < (b)) ? a : b)Here, the a and b tokens have special meaning to the preprocessor.Line continuations:#define MIN(a, b)         \    (((a) < (b)) ? a : b)Token concatenation with ##:// MANGLE(foo, bar)  foobar#define MANGLE(prefix, name) prefix##nameThe next problem is that \s is any Unicode whitespace, including newlines. It would be recommendable to restrict that to horizontal whitespace. It would make sense to override the ws rule:token ws {    <!ww> \h*}With support for line continuations:token ws {    <!ww> [ \h | \\\n ]*}We can now use sigspace (significant whitespace) to simplify our tokens as rules, e.g:rule TOP {    ^^ '#define' $<name>=<bareword> $<value>=(<token>+) $$}What is a token? Identifier, number, character, symbol, or string. You attempt to match a string with \@[][^][], but this fails for various reasons:In Perl 6, the [] denotes a non-capturing group, but not a character class. These now look like <[]>. Especially, a negated character class looks like <-[]>.If that were a Perl 5 regex, you'd only be allowing a single letter inside the string, because the [^] charclass is not being repeated.If we also want to handle escapes inside the string, a string token might be matched bytoken string {    \@\ [ <-[\\\]> | \\. ]* \}Similar errors also occur in other tokens.