Javacc - 使用左因子而不是前瞻来消除选择冲突

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Javacc - 使用左因子而不是前瞻来消除选择冲突相关的知识,希望对你有一定的参考价值。

我正在编写一个简单语言的JAVACC程序,我遇到了一个可以使用LOOKAHEAD(2)修复的冲突。我是否能够通过对代码进行左分解而不是使用前瞻来解决这个问题如果没有,为什么?

语法

void expression() : {}
{
    simple_expression() (addition_or_substraction() | {})
}

void simple_expression() : {}
{
    <NUMBER>
    | <LBRAC> expression() <RBRAC> 
}

void condition() : {}
{
     simple_condition() (compare_condition() | {})
} 

void prime_condition() : {}
{
    expression_comparison()
    |<NOT_OPERATOR> condition()
    | LOOKAHEAD(2) <LBRAC> condition() <RBRAC> // Choice conflict for "("
}

void expression_comparison() : {}
{
    expression()
    (   
         <EQUAL> expression()
         <LESS_THAN> expression()
         <GREATER_THAN> expression()
    )
}

void compare_condition() : {}
{
    <AND> condition() | <OR> condition()
}
答案

我真的不认为你可以离开你的方式摆脱问题。我怀疑(但尚未证明)condition生成的语言没有LL(1)语法。

无论如何,让我们尝试左保理。让我们研究一个更简单但类似的语法,其中包含问题的基本要素。终端是number=[]

C --> EXP = EXP  | [ C ]
EXP --> number | [ EXP ]

现在,我不会做更多,因为你应该自己动手。我很确定这是一个家庭作业问题,所以如果我在这里做,我会剥夺你做自己的教育机会,更不用说乐趣了。

第一步是扩大EXP中第一次出现的C。一定要不要停止,直到你的语法是LL(1)或你确定这是一项徒劳无功的任务。

以上是关于Javacc - 使用左因子而不是前瞻来消除选择冲突的主要内容,如果未能解决你的问题,请参考以下文章

C++实现编译原理 免考小队 消除一切左递归

如何在选择查询(MySQL)中仅消除连续重复而不是所有重复?

编译原理实验二:LL语法分析器

形式语言与编译 九 CFG到CNF再到GNF 左递归消除

左因子分解与左递归之间的差异

编译原理 LL文法判别方法