使用ANTLR从Grammar构建Java

时间:2015-02-10 13:17:35

标签: java parsing antlr grammar abstract-syntax-tree

所以,我从头开始给出了构建AST的任务。到目前为止,我已经使用ANTLR 4定义了语法,但由于它不再支持AST(从ANTLR 4中弃用),构建AST的正确方法是什么?我知道我应该使用ANTLR提供的访问者,监听器和操作并生成接口,但是如何?我应该使用例如带有ASTParser对象的org.eclipse.jdt.core.dom.AST类吗?或究竟是什么?那AST Hierarchy怎么样?

我问这个问题,因为从理论上讲,一切听起来都很完美,但在实践中,这很难。

这是ANTLR语法:

prog    : form+ EOF ;

form    : 'form' ID '{' quest+ stat* decl* '}' ;

quest   : 'question' STRING '=' QuestionLiteral '{' decl stat* expr* '}' ;

stat : value                                // Value, e.g. value = false; value = someX * someY;
 | ifStat                               // If statement
 | ID '=' expr ';'                      // Assignment
 ;

decl : ID ':' primitiveType ';' ;   // The definition of e.g. hasBoughtHouse : boolean -> restricted only to primitive types

expr        : expr EXP<assoc=right> expr                                #Exp
        | expr (MUL | DIV) expr                                     #MulDiv
        | expr (ADD | SUB) expr                                     #AddSub
        | expr (LESS | LESS_EQUAL | GREATER | GREATER_EQUAL) expr   #LessGreater
        | expr ('==' | '!=') expr                                   #Equal_NotEqual
        | expr '&&' expr                                            #LogAnd
        | expr '||' expr                                            #LogOr
        | '(' expr ')'                                              #Par
        | literal                                                   #ExprLit
        ;


ifStat      : 'if' '(' expr ')' '{' quest* stat* decl* '}'
        | 'if' '(' expr ')' '{' stat '}' 'else' '(' quest* stat* decl* ')';

value       : ID '.' 'value' '=' expr ';' ; // hasSoldHouse.value = true; hasSoldHouse.value = 2+3; 

literal     : BooleanLiteral
        | NumberLiteral
        | ID
        ;

QuestionLiteral : 'OrdinaryQuestion'
            | 'ComputableQuestion'
            ;

BooleanLiteral  : 'true'
            | 'false'
            ;

NumberLiteral   : (INT | ('(-'INT')'))
            | (FLOAT | ('(-'FLOAT')'))
            | (CURRENCY | ('(-'CURRENCY')'))
            ;

primitiveType   : 'boolean'
            | 'float'
            | 'currency'
            | 'string'
            ;

WS          : (' ' | NL | '\t') -> skip;

ID          : ID_LETTER (ID_LETTER | INT)* ;

/* It gets form, if etc as an identifier and not as keywords */

ID_LETTER   : 'a'..'z' | 'A'..'Z' | '_' ;

INT         : '0' | [1-9] [0-9]*  ; // We cannot use [0-9]+ because this would mean that 01 + 3 would be acceptable

FLOAT       : INT+ '.' INT* // How to set the precision to for instance 4? That it returns a value of this precision
        | '.' INT+;

CURRENCY    : FLOAT;

STRING      : '"'   (ESC|.)*? '"';
fragment
ESC         : '\\' | '\\\\' ;

LINE_COMMENT: '//' .*? '\n' -> skip;    // Single line comments
COMMENT     : '/*' .*? '*/' -> skip;    // Multi line comments

0 个答案:

没有答案