2009-06-04 40 views
0

我试着去建模EBNF表达帮助移动/减少冲突 - 尝试模型(XA)*(XB)*

("declare" "namespace" ";")* ("declare" "variable" ";")* 

我已经建立了YACC(即时通讯使用MPPG)语法,这似乎来表示这一点,但它不符合我的测试表达式。

测试情况下,我试图匹配是

declare variable; 

从词法记号流是

KW_Declare 
KW_Variable 
Separator 

语法解析说,有一个“移进/归约冲突,国家6在KW_Declare上“。我试图用“%left PrologHeaderList PrologBodyList”来解决这个问题,但这两种解决方案都无法解决。

Program      : Prolog; 
Prolog      : PrologHeaderList PrologBodyList; 

PrologHeaderList   : /*EMPTY*/ 
          | PrologHeaderList PrologHeader; 
PrologHeader    : KW_Declare KW_Namespace Separator; 

PrologBodyList    : /*EMPTY*/ 
          | PrologBodyList PrologBody; 
PrologBody     : KW_Declare KW_Variable Separator; 

KW_Declare KW_Namespace KW_Variable隔板用值的所有令牌 “声明”, “naemsapce”, “可变”, “;”。

回答

3

自从我使用了类似yacc的东西以来已经很长时间了,但这里有几条建议可能会帮助或者不会帮助。

在这种情况下,您似乎需要一个2-token预测。解析器获得最后PrologHeader,并且它必须决定下一步的结构是否是PrologHeaderPrologBody,它不能告诉大家,从KW_Declare。如果在这种情况下有一个增加前瞻的指令,它可能会解决问题。

你也可以引入文脉融入你的行动:而不是定义PrologHeaderListPrologBodyList,定义PrologRuleList并有如果头一个身体后出现的动作抛出一个错误。丑陋的,但有时你必须这样做:在语法中出现简单的东西在生成的解析器中可能并不简单。

一个hackish的办法可能是令牌结合:不是KW_DeclareKW_Variable,有你的词法分析器识别的空间和使用KW_Declare_Variable。既然都是关键字,那么你就不会碰到名称空间碰撞问题。

+0

这是我最后采用的方法。我想我可以在代码中进行验证。 – Sprotty 2009-06-04 17:17:20

0

顶部的语法是规则的,所以IIRC可以将其绘制为DFA(或NDA并将其转换为DFA),然后将DFA转换为语法。这是一段时间的豆腐,所以我会把这项工作留给读者作为练习。