【问题标题】:Javacc avoiding cycleJavacc 避免循环
【发布时间】:2015-03-29 12:47:52
【问题描述】:

我的语法中有一个循环,它会产生以下错误消息

Error: Line 395, Column 1: Left recursion detected:
 "PostfixExpression... --> FunctionCall... --> FunctionCallOrMethod... --> FunctionCallGeneric... --> FunctionCallHeaderWithParameters... --> FunctionCallHeader... --> FunctionIdentifier... --> PostfixExpression..."
Detected 1 errors and 1 warnings.

来自以下语法

void PostfixExpression() : {}
{
/* recursive version:
  PrimaryExpression()
| PostfixExpression() <LEFT_BRACKET> IntegerExpression() <RIGHT_BRACKET>
| FunctionCall()
| PostfixExpression() <DOT> FieldSelection()
| PostfixExpression() <INC_OP>
| PostfixExpression() <DEC_OP>
*/
  PrimaryExpression() [PostfixExpressionPrime()]
| FunctionCall() [PostfixExpressionPrime()]
}

void PostfixExpressionPrime() : {}
{
  <LEFT_BRACKET> IntegerExpression() <RIGHT_BRACKET> [PostfixExpressionPrime()]
| <DOT> FieldSelection() [PostfixExpressionPrime()]
| <INC_OP> [PostfixExpressionPrime()]
| <DEC_OP> [PostfixExpressionPrime()]
}

void FunctionCall() : {}
{
  FunctionCallOrMethod()
}

void FunctionCallOrMethod() : {}
{
  FunctionCallGeneric()
}

void FunctionCallGeneric() : {}
{
  FunctionCallHeaderWithParameters() <RIGHT_PAREN>
| FunctionCallHeaderNoParameters() <RIGHT_PAREN>
}

void FunctionCallHeaderWithParameters() : {}
{
/* recursive version:
  FunctionCallHeader() AssignmentExpression()
| FunctionCallHeaderWithParameters() <COMMA> AssignmentExpression()
*/
  FunctionCallHeader() AssignmentExpression() [FunctionCallHeaderWithParametersPrime()]
}

void FunctionCallHeaderWithParametersPrime() : {}
{
  <COMMA> AssignmentExpression() [FunctionCallHeaderWithParametersPrime()]
}

void FunctionCallHeader() : {}
{
  FunctionIdentifier() <LEFT_PAREN>
}

void FunctionIdentifier() : {}
{
  TypeSpecifier()
| PostfixExpression()
}

我可以应用某种算法来消除这个问题吗?如果没有,在这种情况下我该怎么做?

【问题讨论】:

    标签: javacc


    【解决方案1】:

    这是一个类似的语法

    PostfixEx --> FuncCall [PostfixEx'] | Primary [PostfixEx']
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    FuncCall --> FuncID "(" ")"
    FuncID --> PostfixEx | TypeSpecifier
    TypeSpecifier --> "int"
    

    所以例如“ID ++ ( )”是可以的,“int ( ) ++”也是如此,但是“int ++”是不允许的

    这是您可以做的一件事。

    (a) 消除 FuncID

    PostfixEx --> FuncCall [PostfixEx'] | Primary [PostfixEx']
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    FuncCall --> (PostfixEx | TypeSpecifier) "(" ")"
    TypeSpecifier --> "int"
    

    (b) 分发 FuncCall

    PostfixEx --> FuncCall [PostfixEx'] | Primary [PostfixEx']
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    FuncCall --> PostfixEx "(" ")" | TypeSpecifier"(" ")"
    TypeSpecifier --> "int"
    

    (c) 消除 FuncCall

    PostfixEx --> (PostfixEx "(" ")" | TypeSpecifier"(" ")")  [PostfixEx']
                 | Primary [PostfixEx']
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    TypeSpecifier --> "int"
    

    (c) 分发 PostfixEx

    PostfixEx --> PostfixEx "(" ")" [PostfixEx']
                 | TypeSpecifier"(" ")"  [PostfixEx']
                 | Primary [PostfixEx']
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    TypeSpecifier --> "int"
    

    (d) 左递归删除 A -> A w | x ==> A --> x (w)*

    PostfixEx -->  ( TypeSpecifier"(" ")"  [PostfixEx'] | Primary [PostfixEx'] )
                   ("(" ")" [PostfixEx'])*
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    TypeSpecifier --> "int"
    

    (e) 分发 PostfixEx

    PostfixEx -->    TypeSpecifier"(" ")"  [PostfixEx'] ("(" ")" [PostfixEx'])*
                   | Primary [PostfixEx'] ("(" ")" [PostfixEx'])*
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    TypeSpecifier --> "int"
    

    (e) 创建非终结符 PostfixExOperators

    PostfixEx -->    TypeSpecifier"(" ")"  PostFixOperators
                   | Primary PostFixOperators
    Primary --> ID
    PostFixOperators --> [PostfixEx'] ("(" ")" [PostfixEx'])*   
    PostfixEx' --> "++" [PostfixEx']        
    TypeSpecifier --> "int"
    

    (f) 创建非终结符 PostFixOperand

    PostfixEx -->    PostFixOperand  PostFixOperators
    PostFixOperand --> Primary | TypeSpecifier "(" ")"
    Primary --> ID
    PostfixEx' --> "++" [PostfixEx']
    PostFixOperators --> [PostfixEx'] ("(" ")" [PostfixEx'])*           
    TypeSpecifier --> "int"
    

    (g) 清理 PostFixOperators

    PostFixEx --> PostFixOperand PostFixOperators
    PostFixOperand --> Primary | TypeSpecifier "(" ")"
    Primary --> ID
    PostFixOperators --> ( "++" | "(" ")" )*
    TypeSpecifier --> "int"
    

    【讨论】:

    • 我内联了所有内容,直到函数成为左递归的一个小例子,然后像往常一样分解。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 2015-09-05
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-02-15
    相关资源
    最近更新 更多