[antlr-interest] C and #define
Andy Tripp
antlr at jazillian.com
Mon May 21 06:42:19 PDT 2007
Here's what I've got for handling C/C++ preprocessor directives:
protected RestOfPP :
(
'\\'! Newline! // note the "!"s to delete escaped newlines
| Comment
| CharLiteral
//avoid matching '"' as StringLiteral
| StringLiteral
// without this, "//" inside string gets processed
| {LA(2) != '*' && LA(2) != '/'}? '/'
| '#' // "stringification"
| ~('\r' | '\n' | '/')
)+
;
// note: I have one pass that removes any spaces after "#" (e.g.
converts "# define" to "#define").
// That pass looks for PPspace tokens and removes the space. Then all
other passes
// use the other PP rules below
PPspace : "#" (Whitespace)+ RestOfPP
;
PPdefine : "#define" (Whitespace)+ RestOfPP
;
PPif : "#if" (Whitespace)+ RestOfPP
;
PPelse : "#else"
;
PPelif : "#elif" (Whitespace)+ RestOfPP
;
PPendif : "#endif"
;
// Note the "*" instead of "+" here, to handle "#include<whatever.h>"
PPinclude : "#include" (Whitespace)* RestOfPP
;
PPifdef : "#ifdef" (Whitespace)+ RestOfPP
;
PPifndef : "#ifndef" (Whitespace)+ RestOfPP
;
PPundef : "#undef" (Whitespace)+ RestOfPP
;
PPpragma : "#pragma" RestOfPP
;
PPerror : "#error" (RestOfPP)?
;
PPline : "#line" RestOfPP
;
Paul Keir wrote:
> Hi,
>
> I'm building on the C grammar from the examples, and would like to
> modify the lexer rule which ignores lines starting with #; I'd like
> not to ignore #define, but ignore the rest. Currently the rule is:
>
> // ignore #line info for now
> LINE_COMMAND
> : '#' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
> ;
>
> Remembering that the # can be separated from the define, I've tried a
> few things like this:
>
> // ignore #line info for now
> LINE_COMMAND
> : ~( '#' 'define' | '#define' ) ~('\n'|'\r')* '\r'? '\n'
> {$channel=HIDDEN;}
> ;
>
> but I can't get it to work as intended. Can anyone offer a suggestion?
>
> Best regards,
> Paul
>
>
More information about the antlr-interest
mailing list