在JavaCC中消除了左重复(直接和间接)消除

时间:2017-03-16 12:56:05

标签: java parsing recursion grammar javacc

我在消除JavaCC中的左递归时遇到问题。我找到了Epsilon tokens的解决方案,但似乎JavaCC无法与Epsilon令牌(如TOKEN : <eps : "">)很好地协作。下面我准备一个我的问题的例子:

void prod1() : 
{}
{
    <beta1>
    | prod2() <alpha1>
}

void prod2() : 
{}
{
    <beta2>
    | [prod2()] <alpha2>
    | prod1() <alpha3>
}

这里我们看到直接和非直接左递归。它是我真正语法的简化示例(我的JavaCC语法基于现有的BNF语法,因此我不得不以这种形式使用它。)

2 个答案:

答案 0 :(得分:1)

我找到了一个解决方案,它似乎适合我。

void prod1() : 
{}
{
    <beta1>
    | prod2() <alpha1>
}

void prod2() : 
{}
{
    <beta2>
    | [prod2()] <alpha2> // (1)
    | prod1() <alpha3>
}

步骤1.展开(1)

void prod1() : 
{}
{
    <beta1>
    | prod2() <alpha1>
}

void prod2() : 
{}
{
    <beta2>
    | <alpha2>
    | prod2() <alpha2>
    | prod1() <alpha3>
}

步骤2.将prod1插入prod2

void prod1() : 
{}
{
    <beta1>
    | prod2() <alpha1>
}

void prod2() : 
{}
{
    <beta2>
    | <alpha2>
    | prod2() <alpha2>
    | <beta1> <alpha3>
    | prod2() <alpha1> <alpha3>
}

步骤3.使用epsilon产生消除prod2中的左递归(在此处描述https://en.wikipedia.org/wiki/Left_recursion

void prod1() : 
{}
{
    <beta1>
    | prod2() <alpha1>
}

void prod2() : 
{}
{
    <beta2> prod2_()
    | <alpha2> prod2_()
    | <beta1> <alpha3> prod2_()
}

void prod2_() :
{}
{
    prod2() <alpha2> prod2_()
    | prod2() <alpha1> <alpha3> prod2_()
    | <epsilon>
}

步骤4.从prod2_()中消除epsilon产生(此处描述http://www.d.umn.edu/~hudson/5641/l11m.pdf

void prod1() : 
{}
{
    <beta1>
    | prod2() <alpha1>
}

void prod2() : 
{}
{
    <beta2> [prod2_()]
    | <alpha2> [prod2_()]
    | <beta1> <alpha3> [prod2_()]
}

void prod2_() :
{}
{
    prod2() <alpha2> [prod2_()]
    | prod2() <alpha1> <alpha3> [prod2_()]
}

答案 1 :(得分:0)

prod1 --> beta1 | prod2 alpha1
prod2 --> beta2 | [prod2] alpha2 | prod1 alpha3

展开选项

prod1 --> beta1 | prod2 alpha1
prod2 --> beta2 | alpha2 | prod2 alpha2 | prod1 alpha3

替换prod2中的prod1

prod1 --> beta1 | prod2 alpha1
prod2 --> beta2 | alpha2 | prod2 alpha2 | (beta1 | prod2 alpha1) alpha3

分发

prod1 --> beta1 | prod2 alpha1
prod2 --> beta2 | alpha2 | prod2 alpha2 | beta1 alpha3 | prod2 alpha1 alpha3

重新排列和因子

prod1 --> beta1 | prod2 alpha1
prod2 --> (beta2 | alpha2 | beta1 alpha3) | prod2 (alpha2 | alpha1 alpha3)

消除左递归

prod1 --> beta1 | prod2 alpha1
prod2 --> (beta2 | alpha2 | beta1 alpha3) (alpha2 | alpha1 alpha3)*