决策可以匹配诸如“ID”之类的输入。使用多种替代方案:1、2

发布于 2024-12-15 15:12:31 字数 1480 浏览 2 评论 0原文

我正在尝试定义一个简单的函数语言语法,我几乎完成了我的定义,但我无法克服以下歧义。

[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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

电影里的梦 2024-12-22 15:12:31

一些使语法不那么模糊的提示:

  1. 删除 '.' 作为语句结束字符。例如,将其替换为 ';'。两者都只是一个字符,';' 不会与 float 内的 '.' 冲突;
  2. 创建与浮点数匹配的词法分析器规则;
  3. 函数后面跟着一个或多个语句,但没有明显的结尾(“main”函数除外,它现在以 '.' 结尾)。您必须告诉解析器函数在哪里结束(而不仅仅是“主”函数),或者必须引入与“内部”函数匹配的规则,该函数有多个尾随语句< /code>s,但单个表达式
  4. 您的 statement 规则中真的需要一个 expression 吗?两者都可以是一个函数(再次使其变得不明确)。

这些只是您定义语言的方式中的一些问题。如果我是你,我不会继续这样:你可能会用谓词修复一些东西,但在另一个地方改变一些东西会打开另一罐蠕虫。我建议你彻底重新设计你的语言。

如果您不想重新设计它,只需从语法中删除所有谓词并将以下行放入您的 options {...} 部分:

backtrack=true;

这将(看似)神奇地删除所有有关歧义的警告规则,但这不是推荐的修复方法。这样,当 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:

  1. remove the '.' 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;
  2. create a lexer rule that matches a float;
  3. a function is followed by one or more statements, but has no obvious end (except for the "main" function which now ends with a '.'). 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 trailing statements, but a single expression;
  4. do you really need a expression in your statement 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:

backtrack=true;

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文