[antlr-interest] newbie help with treewalker

jmcclain jmcclain1 at surewest.net
Wed Dec 29 20:28:25 PST 2004


I am parsing expressions of the form:

left(f1("a", "b", "c"+f2(f3()), ""), 5) + mid(f1("a", "b", "c"+f2(f3()), ""), 
5,5)

I have built the lexer and parser grammar. The parser grammar is setup to 
build an AST where each node is the function name, logical operator or logical 
comparator, and each child is a parameter of said node. What I want to do is 
associate an action with each node that calls the associated function or 
operator. I.E., each node will execute its action that will execute a function 
passing in the child nodes as parameters. The result of the function should 
overwrite the node. What I want is to treewalk the ast, overwriting the ast 
nodes, until you get to the root, which will hold the final value of the 
expression.

There are no examples of how to do this that I can see. 

Can someone out there show me how (pseudo code or treeparser grammar would be 
appreciated), or point me in the right direction? here is my grammar:



class P extends Parser;
options {buildAST=true;}

prog: expression EOF;


procedureCallStatement
  : IDENT^ (actualParameters)?
  ;

// either proc call or variable
actualParameters
  : LPAREN! (expression (COMMA! expression)*)? RPAREN!
  ;

constantValue
  : INTLIT
  | STRING_LITERAL
  ;
  
    
  primitiveElement
  : 
  constantValue
  | LPAREN! expression RPAREN!
  | procedureCallStatement
  ;


booleanNegationExpression
  : ("not"^)* primitiveElement
  ;

signExpression
  : ((PLUS^|MINUS^))* booleanNegationExpression   ;


multiplyingExpression
  : signExpression ((TIMES^|DIV^|"mod"^) signExpression)* 
  ;

addingExpression
  : multiplyingExpression ((PLUS^|MINUS^) multiplyingExpression)* 
  ;

relationalExpression
  : addingExpression ((EQUALS^|NOT_EQUALS^|GT^|GTE^|LT^|LTE^) addingExpression)
* 
  ;

expression
  : relationalExpression (("AND"^|"OR"^) relationalExpression)* 
  ;
  
 class L extends Lexer;

options {
  charVocabulary = '\0'..'\377';
  testLiterals=false;    // don't automatically test for literals
  k=2;                   // two characters of lookahead
}

// Literals
protected DIGIT : '0'..'9'
{System.out.println("1" + getText());};

INTLIT  :  (DIGIT)+
{System.out.println("2" + getText());};
CHARLIT : '\''! . '\''!
{System.out.println("3" + getText());};

// string literals
STRING_LITERAL
  : '"'!
    ( '"' '"'!
    | ~('"'|'\n'|'\r')
    )*
    ( '"'!
    | // nothing -- write error message
    )
{System.out.println("4" + getText());};


// Keywords are literals in the parser grammar

// Operators
DOT        : '.'   ;
BECOMES    : ":="  ;
COLON      : ':'   ;
SEMI       : ';'   ;
COMMA      : ','   ;
EQUALS     : '='   ;
LBRACKET   : '['   ;
RBRACKET   : ']'   ;
DOTDOT     : ".."  ;
LPAREN     : '('   
{System.out.println("5" + getText());};
RPAREN     : ')'   
{System.out.println("6" + getText());};
NOT_EQUALS : "/="  ;
LT         : '<'   
{System.out.println("7" + getText());};
LTE        : "<="  ;
GT         : '>'   ;
GTE        : ">="  ;
PLUS       : '+'   
{System.out.println("8" + getText());};
MINUS      : '-'   ;
TIMES      : '*'   ;
DIV        : '/'   ;



// Whitespace -- ignored
WS
  : ( ' '
    | '\t'
    | '\f'

    // handle newlines
    | ( "\r\n"  // Evil DOS
      | '\r'    // Macintosh
      | '\n'    // Unix (the right way)
      )
      { newline(); }
    )
    { $setType(Token.SKIP); }
  ;


// an identifier.  Note that testLiterals is set to true!  This means
// that after we match the rule, we look in the literals table to see
// if it's a literal or really an identifer
IDENT
  options {testLiterals=true;}
  : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9')*
{System.out.println("10" + getText());};


  




More information about the antlr-interest mailing list