Antlr 如何解决;以下选项永远无法匹配”;

Antlr 如何解决;以下选项永远无法匹配”;,antlr,antlr3,antlrworks,Antlr,Antlr3,Antlrworks,几天来,我一直在努力解决解析器中的“多选项”错误,但没有成功。我一直在使用Sam Harwell的ANTLR3和VS2010端口将Bart Kiers优秀的Tiny Language(TL)教程代码转换为C#。这两个人的出色工作都值得称赞。我相信我已经准确地遵循了巴特的教程,但由于我是ANTLR的新手,我不能确定 我确实让TL代码在纯数学基础上运行良好,即没有“函数”或“if-then-else”或“while”(参见一个小应用程序的屏幕截图) 但是,当我为完成本教程而添加缺失部分的代码时,我

几天来,我一直在努力解决解析器中的“多选项”错误,但没有成功。我一直在使用Sam Harwell的ANTLR3和VS2010端口将Bart Kiers优秀的Tiny Language(TL)教程代码转换为C#。这两个人的出色工作都值得称赞。我相信我已经准确地遵循了巴特的教程,但由于我是ANTLR的新手,我不能确定

我确实让TL代码在纯数学基础上运行良好,即没有“函数”或“if-then-else”或“while”(参见一个小应用程序的屏幕截图)

但是,当我为完成本教程而添加缺失部分的代码时,我在“functionCall”和“list”中发现了一个解析错误(请参见下面的代码)

语法平行词2;
选择权{
语言=CS3;
TokenLabelType=CommonToken;
输出=AST;
ASTLabelType=CommonTree;
}
代币{
块
返回;
声明;
分配
FUNC_调用;
经验;
出口清单;
身份证清单;
如果;
三元;
U_SUB;
否定;
功能;
指标;
列表
查找;
}
@lexer::命名空间{Paralex2}
@解析器::命名空间{Paralex2}
/*
*解析器规则
*/
@parser::header{using System;using System.Collections.Generic;}
@解析器::成员{
公共分类列表函数=新分类列表();
私有void定义函数(字符串id、对象idList、对象块){
//'idList'可能为空!在这种情况下创建一个空树。
CommonTree idListTree=idList==null?新建CommonTree():(CommonTree)idList;
//'block'从不为空。
CommonTree blockTree=(CommonTree)块;
//函数名及其后的参数数为唯一键
string key=id+idListTree.Children.Count();
添加(键,新函数(id,idListTree,blockTree));
}
}
公共解析
:block EOF->block
;
块
:(语句| functionDecl)*(返回exp';')?->^(块^(语句*)^(返回exp?)
;
陈述
:赋值“;”->分配
|函数调用“;”->函数调用
|国际单项体育联合会声明
|预告
|whileStatement
;
分配
:标识符索引?'='经验
->^(分配标识符索引?exp)
;
函数调用
:标识符“(“expList?”)”->^(函数调用标识符expList?)
|断言“('exp')”->^(函数调用断言exp)
|大小“(“exp”)”->^(函数调用大小exp)
;
国际单项体育联合会声明
:ifStat elseIfStat*elseStat?结束->^(如果ifStat-elseIfStat*elseStat?)
;
ifStat
:If exp Do block->^(exp exp block)
;
埃尔塞夫斯塔
:Else If exp Do block->^(exp exp block)
;
埃尔塞斯塔特
:Else Do block->^(EXP block)
;
函数DECL
:Def标识符“(“idList?”)”块结束
{defineFunction($Identifier.text、$idList.tree、$block.tree);}
;
预告
:对于标识符“=”exp到exp Do块结束
->^(用于标识符exp块)
;
whileStatement
:While exp Do block End->^(While exp block)
;
懒汉
:标识符(“,”标识符)*->^(ID_列表标识符+)
;
解释者
:exp(','exp)*->^(exp_LIST exp+)
;
经验
:xp
;  
康德
:(orExp->orExp)
|(“?”a=exp':“b=exp->^(三元orExp$a$b)
|在exp->^(在orExp exp中)
)?  
;  
orExp
:andExp(“| |”^andExp)*
;  
安第斯山脉
:eqexp('&&'^eqexp)*
;  
equExp
:relExp((“==”|“!=”)^relExp)*
;  
释放
:addExp((“>=”|“|”=”;
LTEquals:“”;

LT:“在
condExp
规则中,OR运算符太多,使语法不明确

你有:

condExp  
  :  ( orExp               -> orExp)   
  |  ( '?' a=exp ':' b=exp -> ^(TERNARY orExp $a $b)
     |  In exp             -> ^(In orExp exp)
     )?  
  ;  
对应于:

但它应该是:

condExp  
  :  ( orExp               -> orExp)
     ( '?' a=exp ':' b=exp -> ^(TERNARY orExp $a $b)
     |  In exp             -> ^(In orExp exp)
     )?  
  ;  
对应于:


我不知道您试图发布的图像中有什么内容,但看起来您的规则有点模糊,这就是问题的根源。例如,无法区分
标识符(explist?
大小写和
数组(exp)
case…@Stobor感谢您的指点,我坐在这里看ANTLRWorks语法图(遗憾的是,我认为它们很酷:-)并尝试了一些东西。目前为止运气不好,但夜晚还很年轻!嗨,巴特,非常感谢你帮我看这个小东西。这就解决了它!我想经验带来的许多技巧之一是,当整个结构作为一个系统工作时,超越眼前的问题规则。我下次会记住它。我添加了mi为了完成我的问题,我试着给你们投票,但需要15分——我稍后会回来
condExp  
  :  ( orExp               -> orExp)
     ( '?' a=exp ':' b=exp -> ^(TERNARY orExp $a $b)
     |  In exp             -> ^(In orExp exp)
     )?  
  ;