Fortran comment confuses with C preprocessor

36 views
Skip to first unread message

Li Dong

unread,
Dec 16, 2013, 8:34:12 PM12/16/13
to antlr-di...@googlegroups.com

Dear all,

I am revisiting my Fortran parser written in ANTLR4, and found a bug. The 'COMMENT' token confuses with negative condition rule in C preprocessor directives.

conditionDirective

   : conditionDirective ( CPP_AND | CPP_OR ) conditionDirective

   | definedCondition

   | LEFT_PAREN conditionDirective RIGHT_PAREN

   | EXCAL conditionDirective

   ;

// ...
COMMENT
: EXCAL .*? NEW_LINE+ -> skip;

EXCAL: '!';


So the following code is not parsed correctly:
#if defined A && ! defined B

I would ask what is the best practice to solve this problem? Thank you!

Terence Parr

unread,
Dec 16, 2013, 8:40:07 PM12/16/13
to antlr-di...@googlegroups.com
does ! for a comment have to start in a specific column? I.e., what is the context or difference between a comment and ! op in preprocessor macro?

Ter
--
You received this message because you are subscribed to the Google Groups "antlr-discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to antlr-discussi...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Terence Parr

unread,
Dec 16, 2013, 8:41:08 PM12/16/13
to antlr-di...@googlegroups.com
PS: then of course use a semantic predicate to check the context like

NOT : {am i in a C preprocessor command}? '!'

COMMENT : {am i not in a C preprocessor command)? … ;

Ter
On Dec 16, 2013, at 5:34 PM, Li Dong wrote:

Li Dong

unread,
Dec 16, 2013, 8:48:14 PM12/16/13
to antlr-di...@googlegroups.com
Hi Ter,

does ! for a comment have to start in a specific column?
 
The Fortran codes are in free form, so '!' can be in any column.

PS: then of course use a semantic predicate to check the context like

I will check semantic predicate. Thanks for advice!

Li

Li Dong

unread,
Dec 16, 2013, 9:55:11 PM12/16/13
to antlr-di...@googlegroups.com
Hi Ter,

I have checked semantic predicate, but I am not sure how to implement '{am i not in a C preprocessor command)?'. The rule that I am thinking is:

  1. When '#' is encountered, set some flag to true to indicate that C preprocessor command starts;
  2. When NEW_LINE is encountered, reset the flag to false?
  3. We also need to consider the break line in command by '\\'.

DIRECTIVE_START: {flag = true} '#';

// ...

COMMENT: {$flag == false}? EXCAL .*? NEW_LINE+ -> skip;

// ...

fragment NEW_LINE: {if (!cpp_break) { flag = false; cpp_break = false; }} '\r'? '\n';

NEW_LINES: NEW_LINE+ -> skip;

BREAK_LINE: ( '&' | '\\' {cpp_break = true} ) WS? ( NEW_LINES | COMMENT ) -> skip;


Could you correct the above lexer rules? Thank you again!

Li

Jim Idle

unread,
Dec 17, 2013, 2:28:25 AM12/17/13
to antlr-di...@googlegroups.com
Probably lexer modes. 

If the first non-space character on a line is '#', then you are in CPP mode and can return different tokens until you see a new line, at which point you drop out of CPP mode. However, you might just want to use m4 or the actual C pre-processor to pre-process before hitting your parser. You will generally find that try to perform pre-processing functions and parse the code at the same time does not really work. If you are just parsing for formatting, then it won't be so bad. C# defines pre-processing directives as being part of the lexer for instance and they are very limited.

Jim


董理

unread,
Dec 17, 2013, 2:44:08 AM12/17/13
to antlr-di...@googlegroups.com
Dear Jim,

I am developing an automatic building tools for Fortran (maybe C++). The parser will find out what the dependencies among codes (use statements in Fortran and #include in C++), and these dependencies may be affected by a CPP directive. So I need to parse CPP directives.

This function has been achieved and works fine, except for the little bug.

How could I specify CPP mode in detail? Use type() or channel()?

Thanks for help!

Li

You received this message because you are subscribed to a topic in the Google Groups "antlr-discussion" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/antlr-discussion/83V-zAlmtYE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to antlr-discussi...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages