[antlr-interest] Can't figure this one out

Bart Kiers bkiers at gmail.com
Thu May 19 23:12:32 PDT 2011


Hi David,

Your parser does not handle:

ans = 3 * (-x + y) * 4


properly since `ans` is an ANS-token and not an IDENT-token. Therefor it
does not get matched by your `assignmentStatement` rule.

Also, you should probably add the EOF at the end of your `script` rule in
your combined grammar.

Regards,

Bart.


On Fri, May 20, 2011 at 3:47 AM, David Smith <david.smith at cc.gatech.edu>wrote:

> I developed a tree parser by making minor changes to Scott
> Stanchfield's tutorial videos.  I don't know where to start looking
> to explain the problem.
> Here are the pieces:
>
> //                 The grammar:
> grammar GTMat;
>
> options {
>   language = Java;
>   output=AST;
>   ASTLabelType=CommonTree;
> }
>
> tokens {
>         NEGATION;
> }
>
>
> @header {
>   package parser;
> }
>
> @lexer::header {
>   package parser;
> }
>
> script
>         :       statement*
>         ;
>
> statement
>         :       assignmentStatement
>         ;
>
> assignmentStatement
>         :       IDENT GETS^ expression SEMI?
>         ;
>
> actualParameters
>         :       expression (COMMA expression)*
>         ;
>
>
> // expressions -- fun time!
>
> term
>         :       (IDENT OPENP ) => IDENT '(' actualParameters ')'
>         |       OPENP! expression CLOSEP!
>         |       INTEGER
>         |       IDENT
>         ;
>
>
> unary
>         :       (PLUS! | negation^)* term
>         ;
>
> negation
>         :       MINUS -> NEGATION
>         ;
>
> mult
>         :       unary ((MULT^ | DIV^ ) unary)*
>         ;
>
> add
>         :       mult ((PLUS^ | MINUS^) mult)*
>         ;
>
> relation
>         :       add ((EQUALS^ | NOTEQ^ | LESS^ | LESSEQ^ | GT^ | GTEQ^)
> add)*
>         ;
>
> expression
>         :       relation ((AND^ | OR^) relation)*
>         ;
>
> GETS    :       '=';
> SWITCH  :       'switch';
> CASE    :       'case';
> OTHERWISE
>         :       'otherwise';
> IF      :       'if';
> ELSE    :       'else';
> ELSEIF  :       'elseif';
> END     :       'end';
> FOR     :       'for';
> WHILE   :       'while';
> ANS     :       'ans';
> COMMA   :       ',';
> OPENP   :       '(';
> CLOSEP  :       ')';
> NOT     :       '~';
> SEMI    :       ';';
> PLUS    :       '+';
> MINUS   :       '-';
> MULT    :       '*';
> DIV     :       '/';
> EQUALS  :       '==';
> NOTEQ   :       '!=';
> LESS    :       '<';
> LESSEQ  :       '<=';
> GT      :       '>';
> GTEQ    :       '>=';
> AND     :       '&&';
> OR      :       '||';
> SINGLE  :       '\'';
>
> fragment LETTER : ('a'..'z' | 'A'..'Z') ;
> fragment DIGIT : '0'..'9';
> INTEGER : DIGIT+ ;
> IDENT : LETTER (LETTER | DIGIT)*;
> WS : (' ' | '\t' | '\n' | '\r' | '\f')+ {$channel = HIDDEN;};
> COMMENT : '%' .* ('\n'|'\r') {$channel = HIDDEN;};
>
> // The Walker Grammar:
> tree grammar EvaluatorWalker;
>
> options {
>   language = Java;
>   tokenVocab = GTMat;
>   ASTLabelType = CommonTree;
> }
>
> @header {
>   package parser;
>   import java.util.Map;
>   import java.util.HashMap;
> }
>
> @members {
>   private Map<String, Integer> variables = new HashMap<String, Integer>();
> }
>
> evaluator
>         :       assignment* EOF
>         ;
>
> assignment
>         :       ^('=' IDENT e=expression)
>                         { variables.put($IDENT.text, e); }
>         ;
>
> expression returns [int result]
>         :       ^('+' op1=expression op2=expression) { result = op1 + op2;
> }
>         |       ^('-' op1=expression op2=expression) { result = op1 - op2;
> }
>         |       ^('*' op1=expression op2=expression) { result = op1 * op2;
> }
>         |       ^('/' op1=expression op2=expression) { result = op1 / op2;
> }
>         |       ^(NEGATION e=expression)  { result = -e; }
>         |       IDENT { result = variables.get($IDENT.text); }
>         |       INTEGER { result = Integer.parseInt($INTEGER.text); }
>         ;
> // The Test Program:
> package parser;
>
> import org.antlr.runtime.ANTLRFileStream;
> import org.antlr.runtime.CharStream;
> import org.antlr.runtime.CommonTokenStream;
> import org.antlr.runtime.RecognitionException;
> import org.antlr.runtime.TokenStream;
> import org.antlr.runtime.tree.CommonTreeNodeStream;
> import java.io.IOException;
>
> public class Test4 {
>         public static void main(String[] args)
>                 throws RecognitionException, IOException {
>                 CharStream stream =
>                         new ANTLRFileStream("Test.m");
>                 GTMatLexer lexer = new GTMatLexer(stream);
>                 TokenStream tokenStream = new CommonTokenStream(lexer);
>                 GTMatParser parser = new GTMatParser(tokenStream);
>                 GTMatParser.script_return evaluator = parser.script();
>                 System.out.println(evaluator.tree.toStringTree());
>                 CommonTreeNodeStream nodeStream = new
>                                      CommonTreeNodeStream(evaluator.tree);
>                 EvaluatorWalker walker = new EvaluatorWalker(nodeStream);
>                 walker.evaluator();
>                 System.out.println("ok");
>         }
> }
> // The input code:
> x = 8
> y = 2 + 3
> ans = 3 * (-x + y) * 4
>
> // When I run it, I get this:
>
> (= x 8) (= y (+ 2 3))
> C:<snip>src\parser\EvaluatorWalker.g: node from line 1:2 mismatched
> tree node: = expecting EOF
> ok
>
> David M. Smith http://www.cc.gatech.edu/fac/David.Smith
> Georgia Institute of Technology, College of Computing
> Sent from my ASR-33 Teletype
>
>
> List: http://www.antlr.org/mailman/listinfo/antlr-interest
> Unsubscribe:
> http://www.antlr.org/mailman/options/antlr-interest/your-email-address
>


More information about the antlr-interest mailing list