ANTLR4意外的解析行为
我正试图用ANTLR构建一种新的语言,但我遇到了一个问题。我试图支持数字表达式和数字的数学运算(我认为这很重要),但解析器似乎并没有按照我的预期运行。这是我的语法:ANTLR4意外的解析行为,antlr,grammar,antlr4,Antlr,Grammar,Antlr4,我正试图用ANTLR构建一种新的语言,但我遇到了一个问题。我试图支持数字表达式和数字的数学运算(我认为这很重要),但解析器似乎并没有按照我的预期运行。这是我的语法: grammar Lumos; /* * Parser Rules */ program : 'start' stat+ 'stop'; block : stat* ; stat : assign |
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 : '"' (~["{}])+ '"' ;
语法Lumos;
/*
*解析器规则
*/
程序:“开始”状态+停止;
区块:统计*
;
统计:分配
|努莫
|如果统计
|而_stat
|展示
;
assign:让ID为expr;
显示:显示表达式;
numop:加|减|乘|除;
添加:“添加”表达式到ID;
subtract:'从'ID'中减去'expr';
divide:“divide”ID被expr分割;
乘法:将ID乘以expr;
追加:“追加”expr到ID;
如果统计
:如果条件块(否则如果条件块)*(否则状态块)?
;
条件块
:expr stat_块
;
静态块
:正面块C面
|统计
;
而_stat
:当expr stat\u块
;
expr:expr POW expr#powExpr
|负表达式#一元表达式
|非expr#notExpr
|expr op=(乘以| DIV | MOD)expr#乘法expr
|expr op=(加|减)expr#加法expr
|expr op=RELATIONALOPERATOR expr#relationalExpr
|expr op=EQUALITYOPERATOR expr#equalityExpr
|expr和expr#andExpr
|expr或expr#orExpr
//|数组#arrayExpr
|原子#原子xpr
;
atom:LPAREN expr RPAREN#parExpr
|(INT | FLOAT)#numberxpr
|(真|假)#布尔原子
|我是汤姆
|字符串#stringAtom
|尼克松
;
编译单元:EOF;
/*
*Lexer规则
*/
碎片字母:[a-zA-Z];
马托普:还有
|减去
|时代
|DIV
|国防部
|战俘
;
关系操作员:LTEQ
|GTEQ
|中尉
|燃气轮机
;
等式运算符:EQ
|NEQ
;
LPAREN:'(';
RPAREN:')';
LBRACE:“{”;
RBRACE:'}';
或:‘或’;
和:'和';
BY:'BY';
至:‘至’;
FROM:'FROM';
LET:‘LET’;
是‘是’;
等式:'=';
NEQ:“!=”;
LTEQ:“=”;
LT:'';
//不同的语句将在这两者之间进行选择,但它们几乎是相同的
一样。
加:"加";;
加:'加';
减:'减';
减去:'sub';
时代:"时代",;
骡子:“乘”;
部门:'划分';
MOD:'MOD';
战俘:“战俘”;
不:'不';
真:“真”;
假:“假”;
尼克斯:“尼克斯”;
如果:'如果';
然后:'然后';
ELSE:‘ELSE’;
WHILE:‘WHILE’;
显示:'DISPLAY';
数组:“[”(INT | FLOAT)(“,”(INT | FLOAT))+”;
ID:[a-z]+;
字:字母+;
//编号:INT | FLOAT;
内部:[0-9]+;
浮动:[0-9]+'.[0-9]*
| '.'[0-9]+
;
注释:“#”~[\r\n]*->频道(隐藏);
WS:[\n\t\r]+->频道(隐藏);
字符串:“”(~[“{}])+“”;
当输入让foo为5乘以3
时,访问者会看到让foo为5
和一个无关的乘以3
。我想我设置了expr
规则,以便它在识别原子之前识别乘法表达式,这样就不会发生这种情况。我不知道哪里出错了,但它不起作用我多么期待
如果有人知道我哪里出了问题,或者我如何解决这个问题,我将非常感谢您的输入。您在解析器规则中使用了
时间
,但是MATHOP
也匹配时间
,因为MATHOP
是在时间
规则之前定义的,所以它具有优先权。这就是TIexpr op=(TIMES | DIV | MOD)expr
中的MES
规则不匹配
我没有看到您在解析器规则中的任何地方使用此
MATHOP
规则,因此我建议您将MATHOP
规则一起删除。正是这样的事情让我觉得自己像个白痴。感谢您的快速回答!