我正在使用我的Antlr语法来使用Java解析多个变量中的多项式函数。合法输入的例子是
42; X; +42X; Y^42; 1337HelloWorld; 13,37X^42;
以下语法在没有警告或错误的情况下编译:
grammar Function;
parseFunction returns [java.util.List<java.util.List<Object>> list] :
{ list = new java.util.ArrayList(); } ( f=functionPart { list.add($f.list); } )+
| { list = new java.util.ArrayList(); } ( fb=functionBegin ) { list.add($fb.list); } ( f=functionPart { list.add($f.list); } )*
;
functionBegin returns [java.util.List<Object> list]:
m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add($v.text); list.add($e.value); }
| m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add($v.text); }
| v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add("1"); list.add($v.text); list.add($e.value); }
| v=VARIABLE { list = new java.util.ArrayList(); list.add("+"); list.add("1"); list.add($v.text); }
| m=NUMBER { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); }
;
functionPart returns [java.util.List<Object> list] :
s=SIGN m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($v.text); list.add($e.value); }
| s=SIGN m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($v.text); }
| s=SIGN v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add("1"); list.add($v.text); list.add($e.value); }
| s=SIGN v=VARIABLE { list = new java.util.ArrayList(); list.add($s.text); list.add("1"); list.add($v.text); }
| s=SIGN m=NUMBER { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); }
;
exponent returns [int value]: ('^' n=INTEGER) { $value = 1; if ( $n != null && $n.text.length() > 0) $value = Integer.parseInt($n.text); }
;
VARIABLE : ('a'..'z'|'A'..'Z')+
;
INTEGER : ('0'..'9')+
;
NUMBER : ('0'..'9')+ (','('0'..'9')+)?
;
SIGN : ('+'|'-')
;
WS : (' ' | '\t' | '\r'| '\n')+ {skip();}
;
如果在Java中编译和使用该语法,则接受大多数输入值。显然,并非所有有效输入值都被接受。弹出一个不使用逗号的数字,如输入
+42; 42; 42X^1337;
抛出错误(来自输入“+42”的错误):
line 1:1 no viable alternative at input '+'
如果我将输入修改为
,则不会抛出错误+42,0; 42,0; 42,0X^1337
任何人都可以说,为什么以及如何解决它?
答案 0 :(得分:2)
匹配最长匹配的第一个词法规则获胜,因此42
是INTEGER
,NUMBER
实际上仅在逗号部分存在时匹配,即{{1}时}的匹配时间比NUMBER
长。
可以通过添加解析器规则来修复此问题
INTEGER
并使用其他解析器规则代替number : NUMBER | INTEGER ;
。