我正在尝试定义一个简单的函数式语言语法,我几乎完成了我的定义,但是我无法克服以下歧义。
[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ATOM" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input
[14:43:53] warning(200): mygrammar.g:14:11: Decision can match input such as "ID" using multiple alternatives: 1, 2 As a result, alternative(s) 2 were disabled for that input
这里是我认为相关的规则,图纸几乎与ATOM和ID相同:
program : (statement'.')* ;
statement : assignment
| expression;
assignment : func '->' statement ((','statement)=> ',' statement)*
| ID '->' expression
| ATOM '->' ( string | number );
func : (ID '(' args ')')=> ID '(' args ')';
term : func
| '(' expression ')'
| number
| string
| ID
| ATOM ;
ATOM : ('A'..'Z'|'_')+;
ID : ('a'..'z'|'_')('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
这是ANTLRWorks的语法树
id alternatives http://www.vertigrated.com/images/id_alternatives.png
这是我想要支持解析的粗略人物。
hypotenuse(a,b) ->
sqr(x) -> x * x,
sqr(sqr(a) + sqr(b)).
print(hypotnenuse(2,3)).
所以我需要能够在statements
functions
其中->
是我的赋值运算符,这是一种赋值语言
其中.
是我的陈述结束标记
甚至可以用ANTLR3解析吗?
答案 0 :(得分:2)
一些使你的语法不那么模糊的提示:
'.'
作为语句结束字符。将其替换为';'
。两者都只是一个字符,';'
与浮动内的'.'
不冲突; '.'
结尾)。您必须告诉解析器函数结束的位置(不仅仅是“main”函数),或者必须引入一个匹配“内部”函数的规则,该函数不具有多个尾随statement
s,但是一个expression
; expression
规则中确实需要statement
吗?两者都可以是一个功能(再次,使它变得模棱两可)。这些只是您定义语言方式的一些问题。如果我是你,我不会继续这样做:你可能用谓词修复一些东西,但在另一个地方改变一些东西会打开另一种蠕虫。我建议你彻底重新设计你的语言。
如果您不想重新设计它,只需从语法中删除所有谓词,并将以下行放在options {...}
部分中:
backtrack=true;
将(似乎)神奇地删除有关模糊规则的所有警告,但这不是推荐的修复。这样,ANTLR会在遇到歧义时为您选择解析树,(高度)可能导致意外行为,对于大量输入,它会导致更长的解析时间。再说一次,这不是我想要的!有关全局回溯的更多信息,请参阅Wiki:http://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar