ANTLR parsing and code generation with “-” operator and “-” number sign

岁酱吖の 提交于 2020-01-16 18:53:45

问题


This is my grammar:

grammar FOOL;

@header {
    import java.util.ArrayList;
}

@lexer::members {
   public ArrayList<String> lexicalErrors = new ArrayList<>();
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

prog   : exp SEMIC                      #singleExp
       | let exp SEMIC                  #letInExp
       | (classdec)+ SEMIC (let)? exp SEMIC #classExp
       ;

classdec  : CLASS ID ( EXTENDS ID )? (LPAR (vardec ( COMMA vardec)*)? RPAR)?  (CLPAR ((fun SEMIC)+)? CRPAR)?;

let       : LET (dec SEMIC)+ IN ;

vardec  : type ID ;

varasm     : vardec ASM exp ;

fun    : type ID LPAR ( vardec ( COMMA vardec)* )? RPAR (let)? exp ;

dec   : varasm           #varAssignment
      | fun              #funDeclaration
      ;


type   : INT
        | BOOL
        | ID
      ;

exp    :  MINUS? left=term (operator=(PLUS | MINUS) right=exp)?
      ;

term   : left=factor (operator=(TIMES | DIV) right=term)?
      ;

factor : left=value (operator=(EQ | LESSEQ | GREATEREQ | GREATER | LESS | AND | OR ) right=value)?
      ;

value  :  INTEGER                                     #intVal
      | (NOT)? ( TRUE | FALSE )                       #boolVal
      | LPAR exp RPAR                                 #baseExp
      | IF cond=exp THEN CLPAR thenBranch=exp CRPAR (ELSE CLPAR elseBranch=exp CRPAR)?  #ifExp
      | ID                                             #varExp
      | THIS                                              #thisExp
      | funcall        #funExp
      | (ID | THIS) DOT funcall   #methodExp
      | NEW ID ( LPAR (exp (COMMA exp)* )? RPAR)?             #newExp
      | PRINT ( exp )                                  #print
      ;

funcall
    : ID ( LPAR (exp (COMMA exp)* )? RPAR )
    ;


/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/
SEMIC  : ';' ;
COLON  : ':' ;
COMMA  : ',' ;
EQ     : '==' ;
ASM    : '=' ;
PLUS   : '+' ;
MINUS  : '-' ;
TIMES  : '*' ;
DIV    : '/' ;
TRUE   : 'true' ;
FALSE  : 'false' ;
LPAR   : '(' ;
RPAR   : ')' ;
CLPAR  : '{' ;
CRPAR  : '}' ;
IF        : 'if' ;
THEN   : 'then' ;
ELSE   : 'else' ;
PRINT : 'print' ;
LET    : 'let' ;
IN     : 'in' ;
VAR    : 'var' ;
FUN    : 'fun' ;
INT    : 'int' ;
BOOL   : 'bool' ;
CLASS   : 'class' ;
EXTENDS   : 'extends' ;
THIS   : 'this' ;
NEW    : 'new' ;
DOT    : '.' ;
LESSEQ    : ('<=' | '=<') ;
GREATEREQ    : ('>=' | '=>') ;
GREATER: '>' ;
LESS   : '<' ;
AND    : '&&' ;
OR     : '||' ;
NOT    : '!' ;


//Numbers
fragment DIGIT : '0'..'9';
INTEGER       : DIGIT+;

//IDs
fragment CHAR  : 'a'..'z' |'A'..'Z' ;
ID              : CHAR (CHAR | DIGIT)* ;

//ESCAPED SEQUENCES
WS              : (' '|'\t'|'\n'|'\r')-> skip;
LINECOMENTS    : '//' (~('\n'|'\r'))* -> skip;
BLOCKCOMENTS    : '/*'( ~('/'|'*')|'/'~'*'|'*'~'/'|BLOCKCOMENTS)* '*/' -> skip;

ERR_UNKNOWN_CHAR
    :   . { lexicalErrors.add("UNKNOWN_CHAR " + getText()); }
    ;

Using this grammar, I can compile and successfully execute this:

let int x = 3;
in print(x);

Or this:

let int x = 3;
in print(2-x);

But for example, this prints 5 instead of -1

let
    int x = -3 + 2;
in
    print(x);

This instead, works, it prints -1:

let
    int x = 2 - 3;
in
    print(x);

Is there something wrong or missing in the grammar? Should I post also the java class that implements the code generation step? How can I distinguish correctly between the minus operator and the minus sign?

来源:https://stackoverflow.com/questions/48267834/antlr-parsing-and-code-generation-with-operator-and-number-sign

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!