首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ANTLR4意外分析行为

ANTLR4意外分析行为
EN

Stack Overflow用户
提问于 2018-12-24 16:12:27
回答 1查看 79关注 0票数 1

我正试图用ANTLR构建一种新的语言,但我遇到了一个问题。我试图支持关于数字的数值表达式和数学运算(我认为非常重要),但是解析器似乎并不像我所期望的那样。这是我的语法:

代码语言:javascript
复制
grammar Lumos;

/*
 * Parser Rules
 */

 program        : 'start' stat+ 'stop';

 block          : stat*
                ;

 stat           : assign
                | numop
                | if_stat
                | while_stat
                | display
                ;



 assign         : LET ID BE expr ;

 display        : DISPLAY expr ;
 numop          : add | subtract | multiply | divide ; 


 add            : 'add' expr TO ID ;
 subtract       : 'subtract' expr 'from' ID ;
 divide         : 'divide' ID BY expr ; 
 multiply       : 'multiply' ID BY expr ;

 append         : 'append' expr TO ID ;

 if_stat
 : IF condition_block (ELSE IF condition_block)* (ELSE stat_block)?
 ;

condition_block
 : expr stat_block
 ;

stat_block
 : OBRACE block CBRACE
 | stat
 ;

while_stat
 : WHILE expr stat_block
 ;



 expr           : expr POW<assoc=right> expr        #powExpr
                | MINUS expr                        #unaryExpr
                | NOT expr                          #notExpr
                | expr op=(TIMES|DIV|MOD) expr      #multiplicativeExpr
                | expr op=(PLUS|MINUS) expr         #additiveExpr
                | expr op=RELATIONALOPERATOR expr   #relationalExpr
                | expr op=EQUALITYOPERATOR expr     #equalityExpr
                | expr AND expr                     #andExpr
                | expr OR expr                      #orExpr
                //| ARRAY                               #arrayExpr
                | atom                              #atomExpr
                ;                                   

 atom           : LPAREN expr RPAREN                #parExpr
                | (INT|FLOAT)                       #numberExpr

                | (TRUE|FALSE)                      #booleanAtom
                | ID                                #idAtom
                | STRING                            #stringAtom
                | NIX                               #nixAtom
                ;


compileUnit                     : EOF ;

/*
 * Lexer Rules
 */

 fragment LETTER    : [a-zA-Z] ;

 MATHOP             : PLUS
                    | MINUS
                    | TIMES
                    | DIV
                    | MOD
                    | POW
                    ;

    RELATIONALOPERATOR  : LTEQ
                        | GTEQ
                        | LT
                        | GT
                        ;  

    EQUALITYOPERATOR    : EQ
                        | NEQ
                        ;

 LPAREN             : '(' ;
 RPAREN             : ')' ;
 LBRACE             : '{' ;
 RBRACE             : '}' ;

 OR                 : 'or' ;
 AND                : 'and' ;

 BY                 : 'by' ;
 TO                 : 'to' ;
 FROM               : 'from' ;
 LET                : 'let' ;
 BE                 : 'be' ;


 EQ                 :'==' ;
 NEQ                :'!=' ;
 LTEQ               :'<=' ;
 GTEQ               :'>=' ;
 LT                 :'<' ;
 GT                 :'>' ;

 //Different statements will choose between these, but they are pretty much the 
 same.
 PLUS               :'plus' ;
 ADD                :'add' ;
 MINUS              :'minus' ;
 SUBTRACT           :'sub' ;
 TIMES              :'times' ;
 MULT               :'multiply' ;

 DIV                :'divide' ; 
 MOD                :'mod' ;
 POW                :'pow' ;

 NOT                :'not' ;
 TRUE               :'true' ;
 FALSE              :'false' ;
 NIX                :'nix' ;
 IF                 :'if' ;
 THEN               :'then' ;
 ELSE               :'else' ;
 WHILE              :'while' ;
 DISPLAY            :'display' ;

 ARRAY              : '['(INT|FLOAT)(','(INT|FLOAT))+']';
 ID                 : [a-z]+ ;
 WORD               : LETTER+ ;

 //NUMBER               : INT | FLOAT ;

 INT                : [0-9]+ ; 

 FLOAT              : [0-9]+ '.' [0-9]*
                    | '.'[0-9]+ 
                    ;

 COMMENT            : '#' ~[\r\n]* -> channel(HIDDEN) ;
 WS                 : [ \n\t\r]+ -> channel(HIDDEN) ;
 STRING             : '"' (~["{}])+ '"' ;

当给定输入let foo be 5 times 3时,访问者将看到let foo be 5和一个无关的times 3。我想我设置了expr规则,这样它就能在识别原子之前识别一个乘法表达式,这样就不会发生这种情况。我不知道我哪里出了问题,但这不符合我的预期。

如果有人知道我哪里出了问题或者如何解决这个问题,我会感谢你的意见。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-12-24 16:29:46

您在解析器规则中使用TIMES,但是MATHOP也与TIMES匹配,因为MATHOP是在TIMES规则之前定义的,因此它具有优先权。这就是为什么TIMES规则在expr op=(TIMES|DIV|MOD) expr中不匹配的原因。

我不认为您在解析器规则中任何地方都使用这个MATHOP规则,所以我建议将MATHOP规则全部删除。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53915594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档