What is the correct way to add new tokens (rewrite) to create AST nodes that are not on the input pair

I have a fairly simple mathematical expression grammar for ANTLR, and an interest in handling the implied operator *between parentheses, for example. (2-3)(4+5)(6*7)should be (2-3)*(4+5)*(6*7).

Given the input (2-3)(4+5)(6*7), I try to add the missing operator *to the AST tree when parsing, in the following grammar, I think I managed to achieve this, but I wonder the correct, most elegant way?

grammar G; 

options {
    language = Java;
    output=AST;
ASTLabelType=CommonTree;
}

tokens {
  ADD = '+' ;
  SUB = '-' ;
  MUL = '*' ;
  DIV = '/' ;
  OPARN = '(' ;
  CPARN = ')' ;
}

start
    : expression EOF!
    ;

expression
    : mult (( ADD^ | SUB^ ) mult)*
    ;

mult
   : atom (( MUL^ | DIV^) atom)*    
   ;

atom
   : INTEGER
   | (
       OPARN  expression CPARN -> expression
     )

     (
       OPARN  expression CPARN -> ^(MUL expression)+
     )*  
   ;


INTEGER : ('0'..'9')+ ;
WS  : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};

This grammar appears to display the correct AST tree in ANTLRworks:

AST Output

I'm just starting to understand parsing and ANTLR, I don't have much experience, so the reviews are really appreciated!

Thanks in advance! Charles

+3
1

, , ANTLR.

language=Java ASTLabelType=CommonTree, . :

options {
  output=AST;
}

, node . :

(ADD^ | SUB^)

:

(ADD | SUB)^

. , , (>=, <=, > <) .

, AST: , , : , , , . , atom:

atom
   : INTEGER
   | (
       OPARN  expression CPARN -> expression
     )
     (
       OPARN  e=expression CPARN -> ^(MUL $atom $e)
     )*  
   ;

AST "(2-3)(4+5)(6*7)":

enter image description here

(, : graphviz-dev.appspot.com)

DOT :

import org.antlr.runtime.*;
import org.antlr.runtime.tree.*;
import org.antlr.stringtemplate.*;

public class Main {
  public static void main(String[] args) throws Exception {
    GLexer lexer = new GLexer(new ANTLRStringStream("(2-3)(4+5)(6*7)"));
    GParser parser = new GParser(new CommonTokenStream(lexer));
    CommonTree tree = (CommonTree)parser.start().getTree();
    DOTTreeGenerator gen = new DOTTreeGenerator();
    StringTemplate st = gen.toDOT(tree);
    System.out.println(st);
  }
}
+3

All Articles