Compiler construction 如何消除这种左递归

Compiler construction 如何消除这种左递归,compiler-construction,javacc,left-recursion,Compiler Construction,Javacc,Left Recursion,我在编译器构造中做一个赋值,左递归有问题。JavaCC为表达式()和条件()提供了一个错误“检测到左递归”,如下所示。每一行的第二行都是相同的,所以我假设这就是问题所在 A→ Aα|β A→ βA' A'→ ε|αA' 这是用来说明如何消除左递归的公式。我在讲座、在线视频和解释中理解了这个概念,但我不知道如何在这里应用它。有人能告诉我如何消除左递归吗 void expression() : { } { fragment() binary_arith_op() fragment() | <

我在编译器构造中做一个赋值,左递归有问题。JavaCC为表达式()和条件()提供了一个错误“检测到左递归”,如下所示。每一行的第二行都是相同的,所以我假设这就是问题所在

A→ Aα|β

A→ βA'

A'→ ε|αA'

这是用来说明如何消除左递归的公式。我在讲座、在线视频和解释中理解了这个概念,但我不知道如何在这里应用它。有人能告诉我如何消除左递归吗

void expression() :
{ }
{
  fragment() binary_arith_op() fragment()
| <OPAREN> expression() <CPAREN>
| <ID> <OPAREN> arg_list() <CPAREN>
| fragment()
}

void fragment() :
{ }
{ (<MINUS_SIGN>)? <ID> | <NUM> | <TRUE> | <FALSE> | expression() }

void condition() :
{ }
{ <TILDE> condition()
| <OPAREN> condition() <CPAREN>
| expression() comp_op() expression()
| condition() (<OR> | <AND>) condition()
}
void表达式():
{ }
{
fragment()二进制数组
|表达式()
|arg_list()
|片段()
}
无效片段():
{ }
{()?| | | |表达式()}
无效条件():
{ }
{条件()
|条件()
|表达式()comp_op()表达式()
|条件()(|)条件()
}

几乎任何一本关于编译的书都可以找到类似的例子。你也可以看看我的教程。或任何其他免费教程

这里有一个解决方案。首先,我要重写一个有点像这样的表达式

void expression() :
{ }
{
  expression() binary_arith_op() expression()
| 
  simpleExpression() :
}

void simpleExpression() :
{ }
{ (<MINUS_SIGN>)? <ID> | <NUM> | <TRUE> | <FALSE> 
| <OPAREN> expression() <CPAREN>
| <ID> <OPAREN> arg_list() <CPAREN> }
但在JavaCC中,我们也可以使用循环(即Kleene star)

void表达式():
{ }
{
simpleExpression()(二进制算术运算()simpleExpression())*
}
void simpleExpression():
{ }
{ ()?  |  |  |  
|表达式()
|arg_list()}
条件也是如此

void condition() :
{ }
{ 
    simpleCondition() ((<OR> | <AND>) simpleCondition())*
}

void simpleCondition() :
{ }
{
  <TILDE> condition()
| <OPAREN> condition() <CPAREN>
| expression() comp_op() expression()
}
void条件():
{ }
{ 
simpleCondition()((|)simpleCondition())*
}
void simpleCondition():
{ }
{
条件()
|条件()
|表达式()comp_op()表达式()
}
这消除了左递归


它仍然会给你留下一些选择冲突。可以使用语法前瞻消除这些问题。您还需要处理运算符优先级,但这是直截了当的。请参阅我的教程中的“经典”解决方案。

类似的示例可以在任何有关编译的书籍中找到。你也可以看看我的教程。或任何其他免费教程

这里有一个解决方案。首先,我要重写一个有点像这样的表达式

void expression() :
{ }
{
  expression() binary_arith_op() expression()
| 
  simpleExpression() :
}

void simpleExpression() :
{ }
{ (<MINUS_SIGN>)? <ID> | <NUM> | <TRUE> | <FALSE> 
| <OPAREN> expression() <CPAREN>
| <ID> <OPAREN> arg_list() <CPAREN> }
但在JavaCC中,我们也可以使用循环(即Kleene star)

void表达式():
{ }
{
simpleExpression()(二进制算术运算()simpleExpression())*
}
void simpleExpression():
{ }
{ ()?  |  |  |  
|表达式()
|arg_list()}
条件也是如此

void condition() :
{ }
{ 
    simpleCondition() ((<OR> | <AND>) simpleCondition())*
}

void simpleCondition() :
{ }
{
  <TILDE> condition()
| <OPAREN> condition() <CPAREN>
| expression() comp_op() expression()
}
void条件():
{ }
{ 
simpleCondition()((|)simpleCondition())*
}
void simpleCondition():
{ }
{
条件()
|条件()
|表达式()comp_op()表达式()
}
这消除了左递归

它仍然会给你留下一些选择冲突。可以使用语法前瞻消除这些问题。您还需要处理运算符优先级,但这是直截了当的。请参阅我的教程中的“经典”解决方案