我正在研究 Antlr 语法来解析多个变量中的多项式表达式。因此,我创建了以下语法:
grammar Function;
parseFunction returns [java.util.List<java.util.List<Object>>] : { list = new java.util.ArrayList(); } (p=polypart { list.add($p.list); })+
;
polypart returns [java.util.List<Object> list]:
m=NUMBER { list = new java.util.ArrayList(); list.add("+"); list.add($m.text); list.add("0"); }
| s=SIGN m=NUMBER {list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); }
| v=VARIABLE {list = new java.util.ArrayList(); list.add("+"); list.add($v.text); }
| s=SIGN v=VARIABLE {list = new java.util.ArrayList(); list.add($s.text); list.add($v.text); }
| v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); list.add($v.text); list.add($e.value); }
| s=SIGN v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.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); }
| s=SIGN m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); $list.add($v.text); }
| 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); }
| s=SIGN m=NUMBER v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); list.add($e.value); }
;
exponent returns [int value]: ('^' n=NUMBER) { $value = 1; if ( $n != null && $n.text.length() > 0) $value = Integer.parseInt($n.text); }
;
VARIABLE : ('a'..'z'|'A'..'Z')+
;
NUMBER : ('0'..'9')+
;
SIGN : ('+'|'-')
;
WS : (' '|'\t')+ {skip();} ;
显然,这不起作用。用 Antlr 3.4 编译它,我收到警告
“SIGN NUMBER VARIABLE”使用备选方案 2,8;"SIGN NUMBER VARIABLE '^' NUMBER" 使用备选方案 2,10;“NUMBER VARIABLE”使用备选方案 1,7,“NUMBER VARIABLE '^' NUMBER”使用备选方案 1,9。
我可以忍受这些警告(尽管我对它们为什么弹出非常感兴趣),但困难的是我得到以下错误:
error(201): Function.g:6:47: The following alternatives can never be matched: 7,8,9,10
发生这种情况是因为它们由于警告而被禁用,所以我想我必须先解决警告。
编辑:
在考虑了很多问题之后,我通过切换一些代码行来修改我的代码,现在我至少不再出现任何错误了。但是,我还没有测试它,我也很想摆脱最后两个警告。新代码是:
grammar Function;
parseFunction returns [java.util.List<java.util.List<Object>>] : { list = new java.util.ArrayList(); } (p=polypart { list.add($p.list); })+
;
polypart 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($e.value); }
| 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); }
| s=SIGN m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); $list.add($v.text); }
| m=NUMBER v=VARIABLE { list = new java.util.ArrayList(); list.add("+"); 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($v.text); list.add($e.value); }
| v=VARIABLE e=exponent { list = new java.util.ArrayList(); list.add("+"); 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); }
| v=VARIABLE {list = new java.util.ArrayList(); list.add("+"); list.add(1); list.add($v.text); }
| s=SIGN m=NUMBER {list = new java.util.ArrayList(); list.add($s.text); list.add($m.text); }
| m=NUMBER { list = new java.util.ArrayList(); list.add("+"); 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();}
;
现在我收到以下警告:
"NUMBER VARIABLE" uses mutiple alternatives: 4,10 (10 is disabled).
"SIGN NUMBER VARIABLE" uses multiple alternatives: 3,9 (9 is disabled).
如果有人能向我解释如何摆脱这最后两个警告,我将不胜感激。
在测试解析器后,我可以说它确实接受:
X; +X; -X; X^42; +X^42; -X^42
它不接受:
42; +42; -42; 42X^42; +42X^42; -42X^42