决策可以匹配诸如“ID”之类的输入。使用多种替代方案:1、2
我正在尝试定义一个简单的函数语言语法,我几乎完成了我的定义,但我无法克服以下歧义。
[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 替代品 http://www.vertigerated.com/images/id_alternatives.png
这是我试图支持解析的一个粗略的稻草人。
hypotenuse(a,b) ->
sqr(x) -> x * x,
sqr(sqr(a) + sqr(b)).
print(hypotnenuse(2,3)).
所以我需要能够支持在functions
内部嵌套statements
,其中->
是我的赋值运算符,这是一种单一赋值语言
,其中.
是我的语句结束标记
这是否可以用 ANTLR3 进行解析?
I am trying to define a simple functional language grammar, I am almost done with my definitions, but I can't get past the following ambiguities.
[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
here are what I think are the relevant rules the drawing is almost identical for ATOM and 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'|'_')*;
here is the syntax tree from ANTLRWorks
id alternatives http://www.vertigrated.com/images/id_alternatives.png
Here is a rough straw man of what I am trying to support parsing.
hypotenuse(a,b) ->
sqr(x) -> x * x,
sqr(sqr(a) + sqr(b)).
print(hypotnenuse(2,3)).
so I need to be able to support nesting statements
inside of functions
where ->
is my assignment operator, this is a single assignment language
where .
is my statement end marker
Is this even possible to parse with ANTLR3?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一些使语法不那么模糊的提示:
'.'
作为语句结束字符。例如,将其替换为';'
。两者都只是一个字符,';'
不会与 float 内的'.'
冲突;'.'
结尾)。您必须告诉解析器函数在哪里结束(而不仅仅是“主”函数),或者必须引入与“内部”函数匹配的规则,该函数不有多个尾随语句< /code>s,但单个
表达式
;statement
规则中真的需要一个expression
吗?两者都可以是一个函数(再次使其变得不明确)。这些只是您定义语言的方式中的一些问题。如果我是你,我不会继续这样:你可能会用谓词修复一些东西,但在另一个地方改变一些东西会打开另一罐蠕虫。我建议你彻底重新设计你的语言。
如果您不想重新设计它,只需从语法中删除所有谓词并将以下行放入您的
options {...}
部分:这将(看似)神奇地删除所有有关歧义的警告规则,但这不是推荐的修复方法。这样,当 ANTLR 遇到歧义时,它会为您选择解析树,(极有可能)导致意外行为,并且对于大输入,它会导致更长的解析时间。再说一遍,这不是我想要的!有关全局回溯的更多信息,请参阅 Wiki:http://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar
Some tips to make your grammar less ambiguous:
'.'
as an end-of-statement char. Replace it with, say, a';'
. Both are just one character, and a';'
does not conflict with the'.'
inside a float;'.'
). You must either tell your parser where a function ends (not just the "main" function), or must introduce a rule that matches an "inner" function that does not have multiple trailingstatement
s, but a singleexpression
;expression
in yourstatement
rule? Both can be a function (makein it, again, ambiguous).These are just a few of the problems with the way you've defined your language. If I were you, I wouldn't continue this way: you might fix some things with predicates, but altering something on another place will open yet another can of worms. I advise you redesign your language drastically.
If you don't want to redesign it, simply remove all predicates from your grammar and put the following line in your
options {...}
section:which will (seemingly) magically remove all warnings regarding ambiguous rules, but this is not a recommended fix. That way, ANTLR will choose parse trees for you when it encounters an ambiguity, (highly) possibly resulting in unexpected behavior, and for large input, it results in longer parse times. Again, this is not what I'd go for! See the Wiki for more info regarding global backtracking: http://www.antlr.org/wiki/display/ANTLR3/How+to+remove+global+backtracking+from+your+grammar