0
votes

How to create a parser rule that accept whatever the previous rules doesn't accept?

What I am doing is that I try to rewrite c++ src files with ANTLR. My grammar only need to understand a subset of C++ and ignore the rest. By ignoring the rest, I mean I must still output the input line as it is. I cannot simply drop the input. For example, I may need to locate #if, #ifdef, #ifndef, #else, #elif, #endif but send any other valid C++ syntax back the to the output as it is.

Part of my solution looks like:

inputLines :  ( preprocessorLineSet  |  oneNormalInputLine ) ;
preprocessorLineSet  : ....;// pattern to match #if #else etc
oneNormalInputLine : (any_token_except_crlf)* CRLF {System.out.println($text)}; 
// a catch-all rule for anything including #if #else #endif, it must send any unrecognised input back to the ouput

I am assuming the parser would try the alternatives in the order listed in the grammar. So my preprocessorLineSet rule is listed before oneNormalInputLine in the inputLines rule. But, it seems like ANTLR still prefer oneNormalInputLine even if the input is of the #if pattern which I assume should be matched by the previous rule.

Is my assumption correct? Is it a correct way to implement this kind of ignore-the-rest logic?

1

1 Answers

1
votes

JavaMan wrote:

I am assuming the parser would try the alternatives in the order listed in the grammar. So my preprocessorLineSet rule is listed before oneNormalInputLine in the inputLines rule.

Correct, the rules are tried from left to right (preprocessorLineSet before oneNormalInputLine).

JavaMan wrote:

But, it seems like ANTLR still prefer oneNormalInputLine even if the input is of the #if pattern which I assume should be matched by the previous rule.

Wouldn't you need to exclude stuff like #if and #elif from any_token_except_crlf? Could you post a working example including a driver class that shows the unexpected behavior?