Javacc避免循环

Javacc avoiding cycle

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

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()
}

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

这里有一个类似的语法

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"