(生成された) 文法を Beaver パーサー ジェネレーターに供給しています。複数の shift-reduce の競合は、このルールで他にぶら下がっているように見えるために発生します。
Condition
= IF LPAR Expression.expression RPAR Statement.trueStatement OptionalStatement_1.elem2
;
OptionalStatement_1
= ELSE StatementArray3.falseStatement
|
;
ツールはデフォルトでSHIFTを選択するため、ダングリングelseは問題にならないと思いました。これは、ダングリングelse問題の解決策として受け入れられています。ただし、他に 16 個の警告があり、その理由がわかりません。
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (ELSE: SHIFT; goto 93) over (ELSE: REDUCE OptionalStatement_1 = ) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (LBR: SHIFT; goto 5) over (LBR: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (IF: SHIFT; goto 18) over (IF: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (RETURN: SHIFT; goto 95) over (RETURN: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (DO: SHIFT; goto 100) over (DO: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (READ: SHIFT; goto 107) over (READ: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (WRITE: SHIFT; goto 110) over (WRITE: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (SEMICOLON: SHIFT; goto 113) over (SEMICOLON: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (WHILE: SHIFT; goto 114) over (WHILE: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (LPAR: SHIFT; goto 63) over (LPAR: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (PLUSPLUS: SHIFT; goto 71) over (PLUSPLUS: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (PLUS: SHIFT; goto 73) over (PLUS: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (EXCL: SHIFT; goto 75) over (EXCL: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (MINUS: SHIFT; goto 77) over (MINUS: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (MINUSMINUS: SHIFT; goto 79) over (MINUSMINUS: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (VALUE: SHIFT; goto 81) over (VALUE: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
grammar.grammar: Warning: Resolved Shift-Reduce conflict by selecting (IDENT: SHIFT; goto 82) over (IDENT: REDUCE OptionalStatement_1 = ELSE StatementArray3.falseStatement) using precedence.
その結果、StatementArray3 では、else ブランチにごみが挿入されます (完全に間違った型、Optional ではなく List であり、次のステートメントからのむさぼり食ったものでいっぱいです)。誰かが私に説明してもらえますか? 文法はクラスモデルから生成されるため、この問題に対する非常に具体的な解決策は最善ではありません。この種の問題を一般的に解決するか、文法を変更する必要があります。
別の方法で生成された以前の文法 (避けたい) から、次の文法が得られます。
Condition
= IF LPAR Expression.expression RPAR Statement.trueStatement
| IF LPAR Expression.expression RPAR Statement.trueStatement ELSE Statement.falseStatement
;
ただし、次の入力については、コンパイル中に競合は発生しません。
{
if(b == 21)
c = 10;
else
c = 15;
}
パーサーは実行時に失敗し、else をスキップして 2 番目の代入をトップレベルとして扱います。
4,4-4,7: Syntax Error: unexpected token "else"
4,4-4,7: Recovered: removed unexpected token "else"
問題のある完全な文法 (%import、%typeof、および を取り除いたもの{: ... :}
):
%terminals PERC, ASSIGNDIV, LT, RPAR, VALUE, DO, ASSIGN, PLUSPLUS, QUESTION, MINUS, WRITE, RETURN, LPAR, SEMICOLON, ASSIGNADD, ELSE, LBR, IF, COMMA, RBR, OR, SLASH, MINUSMINUS, COLON, EQ, GT, READ, ASSIGNMUL, STAR, IDENT, ASSIGNSUB, ASSIGNMOD, AND, GTE, WHILE, NEQ, EXCL, LTE, PLUS;
%left LPAR, RPAR;
%nonassoc PLUSPLUS, MINUSMINUS;
%left PREC_13_1, EXCL, PREC_13_2;
%left PERC, SLASH, STAR;
%left PLUS, MINUS;
%left LT, LTE, GT, GTE;
%left NEQ, EQ;
%left AND;
%left OR;
%left QUESTION, COLON;
%right ASSIGN, ASSIGNADD, ASSIGNMUL, ASSIGNDIV, ASSIGNSUB, ASSIGNMOD;
%goal Program;
Number
= VALUE.value
;
Program
= FunctionArray1.functions Block.main
;
UnaryOperation
= PLUSPLUS Expression.expression
| PLUS Expression.expression @ PREC_13_1
| EXCL Expression.expression
| MINUS Expression.expression @ PREC_13_2
| MINUSMINUS Expression.expression
;
Block
= LBR StatementArray3.statements RBR
;
BinaryOperation
= Expression.expression1 NEQ Expression.expression2
| Expression.expression1 OR Expression.expression2
| Expression.expression1 PERC Expression.expression2
| Expression.expression1 EQ Expression.expression2
| Expression.expression1 PLUS Expression.expression2
| Expression.expression1 LT Expression.expression2
| Expression.expression1 MINUS Expression.expression2
| Expression.expression1 LTE Expression.expression2
| Expression.expression1 SLASH Expression.expression2
| Expression.expression1 GT Expression.expression2
| Expression.expression1 ASSIGN Expression.expression2
| Expression.expression1 STAR Expression.expression2
| AssignmentGeneric.val
| Expression.expression1 GTE Expression.expression2
| Expression.expression1 AND Expression.expression2
;
Expression
= LPAR Expression.val RPAR
| Expression.expression1 QUESTION Expression.expression2 COLON Expression.expression3
| UnaryOperation.val
| Number.val
| Variable.val
| FunctionCall.val
| BinaryOperation.val
;
ParameterArray2
= ParameterArray2.list COMMA Parameter.elem
|
| Parameter.elem
;
Statement
= Block.val
| Condition.val
| ReturnFunction.val
| ExpressionStatement.val
| DoWhile.val
| Read.val
| Write.val
| EmptyStatement.val
| WhileStatement.val
;
Parameter
= IDENT.ident
;
Write
= WRITE Expression.expression SEMICOLON
;
OptionalStatement_1
= ELSE StatementArray3.falseStatement
|
;
FunctionArray1
= FunctionArray1.list Function.elem
|
;
WhileStatement
= WHILE LPAR Expression.expression RPAR Statement.statement
;
ExpressionArray4
= ExpressionArray4.list COMMA Expression.elem
|
| Expression.elem
;
ExpressionStatement
= Expression.expression SEMICOLON
;
Variable
= IDENT.ident
;
EmptyStatement
= SEMICOLON
;
Read
= READ IDENT.ident SEMICOLON
;
FunctionCall
= IDENT.ident LPAR ExpressionArray4.expressions RPAR
;
Condition
= IF LPAR Expression.expression RPAR Statement.trueStatement OptionalStatement_1.elem2
;
DoWhile
= DO Statement.statement WHILE LPAR Expression.expression RPAR SEMICOLON
;
Function
= IDENT.ident LPAR ParameterArray2.parameters RPAR Block.body
;
ReturnFunction
= RETURN Expression.expression SEMICOLON
;
StatementArray3
= StatementArray3.list Statement.elem
|
;
AssignmentGeneric
= Expression.expression1 ASSIGNADD Expression.expression2
| Expression.expression1 ASSIGNMUL Expression.expression2
| Expression.expression1 ASSIGNDIV Expression.expression2
| Expression.expression1 ASSIGNSUB Expression.expression2
| Expression.expression1 ASSIGNMOD Expression.expression2
;