How to avoid building intermediates and useless AST nodes with ANTLR3?

后端 未结 1 631
北荒
北荒 2021-01-14 20:20

I wrote an ANTLR3 grammar subdivided into smaller rules to increase readability. For example:

messageSequenceChart:
  \'msc\' mscHead bmsc \'endmsc\' end
;

         


        
相关标签:
1条回答
  • 2021-01-14 20:39

    You can solve this by letting your sub-rule(s) return multiple values and accessing only those you're interested in.

    The following demo shows how to do it. Although it is not in C, I am confident that you'll be able to adjust it so that it fits your needs:

    grammar Test;
    
    parse
      :  sub EOF {System.out.printf("second=\%s\n", $sub.second);}
      ;
    
    sub returns [String first, String second, String third]
      :  a=INT b=INT c=INT
         {
           $first = $a.text;
           $second = $b.text;
           $third = $c.text;
         }
      ;
    
    INT
      :  '0'..'9'+
      ;
    
    SPACE
      :  ' ' {$channel=HIDDEN;}
      ;
    

    And if your parse the input "12 34 56" with the generated parser, second=34 is printed to the console, as you can see after running:

    import org.antlr.runtime.*;
    
    public class Main {
      public static void main(String[] args) throws Exception {
        TestLexer lex = new TestLexer(new ANTLRStringStream("12 34 56"));
        TokenStream tokens = new TokenRewriteStream(lex);
        TestParser parser = new TestParser(tokens);
        parser.parse();
      }
    }
    

    So, a shortcut from the parse rule like $sub.INT, or $sub.$a to access one of the three INT tokens, in not possible, unfortunately.

    0 讨论(0)
提交回复
热议问题