Antlr 决策可以匹配输入,例如;ID";使用多个备选方案:1、2

Antlr 决策可以匹配输入,例如;ID";使用多个备选方案:1、2,antlr,antlr3,antlrworks,Antlr,Antlr3,Antlrworks,我正在尝试定义一个简单的函数式语言语法,我的定义差不多完成了,但我无法克服以下歧义 [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): mygr

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

[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的语法树

这是我试图支持的一个粗野的稻草人

hypotenuse(a,b) -> 
  sqr(x) -> x * x,
  sqr(sqr(a) + sqr(b)). 

print(hypotnenuse(2,3)).
因此,我需要能够支持在
函数内部嵌套
语句

其中
->
是我的赋值运算符,这是一种单一的赋值语言

其中
是我的语句结束标记


这甚至可以用ANTLR3解析吗?

一些让语法不那么模棱两可的技巧:

  • 删除作为语句结尾字符的
    。例如,用一个
    “;”替换它。两者都只是一个字符,并且是一个“
    ”;”与浮动内的“
    ”不冲突。
  • 创建与浮点匹配的lexer规则
  • 一个函数后面跟着一个或多个语句,但没有明显的结尾(除了“main”函数,它现在以
    结尾。
    )。您必须告诉解析器函数的结束位置(不仅仅是“main”函数),或者必须引入一个规则来匹配一个“内部”函数,该函数没有多个尾随
    语句,只有一个
    表达式
    
    
  • 您的
    语句
    规则中是否确实需要
    表达式
    ?两者都可以是一个函数(makein,同样是不明确的)
  • 这些只是您定义语言的方式中的一些问题。如果我是你,我不会继续这样做:你可能会用谓词修复一些东西,但在另一个地方修改某些东西会打开另一个蠕虫罐。我建议你彻底重新设计你的语言

    如果不想重新设计,只需从语法中删除所有谓词,并在
    options{…}
    部分中添加以下行:

    backtrack=true;
    

    这将(似乎)神奇地删除所有关于模糊规则的警告,但这不是一个建议的修复。这样,当ANTLR遇到歧义(高度)可能导致意外行为时,它将为您选择解析树,对于较大的输入,它将导致更长的解析时间。再说一次,这不是我想要的!有关全局回溯的更多信息,请参见Wiki:

    这与您的问题相同:语法不明确,因此生成的解析器可以为特定输入选择多个解析。通过在需要的地方放置谓词(不可取)来消除歧义,或者更改语法使其不再含糊不清(可取)。通过在你的文章中解释如何将某个输入解析为两个不同的解析树,我曾希望你能自己解决这个问题…@BartKiers我没有完全理解你的解释,我知道有一个歧义,我只是不知道谓词放在哪里。我已经在谷歌上搜索了语法谓词,并把它们全部读了一遍,我不知道应该把谓词放在哪里,或者如何修改语法使其不含糊,而不把无关字符放在我不想要的地方。每次我改变某件事,似乎都会让事情变得更糟而不是更好:-(这里是完整语法的链接……记住,我是一个新手,如果你不理解我的答案,请说出来。如果你不理解,我想一切都清楚了。我终于明白了,歧义是在
    函数
    赋值定义的末尾,而不是在
    开头
    ,这让我感到厌烦,谢谢p听了你的解释,我想我终于明白问题是什么以及如何开始解决它了。@JarrodRoberson,不客气。我明白要完全理解歧义的确切来源并不容易。函数的结尾只是语法中的歧义之一……祝你好运!