0

私は Jison パッケージを使用して clike 言語コンパイラに取り組んでいます。クラスを導入するまでは本当にうまくいっていたTypeので、今はできますLITERAL。単純化された文法は次のとおりです。

%lex

%%
\s+                       /* skip whitespace */

int                       return 'INTEGER'
string                    return 'STRING'
boolean                   return 'BOOLEAN'
void                      return 'VOID'
[0-9]+                    return 'NUMBER'
[a-zA-Z_][0-9a-zA-Z_]*    return 'LITERAL'
"--"                      return 'DECR'
<<EOF>>                   return 'EOF'
"="                       return '='
";"                       return ';'


/lex

%%

Program
  : EOF
  | Stmt EOF
  ;

Stmt
  : Type Ident ';'
  | Ident '=' NUMBER ';'
  ;

Type
  : INTEGER
  | STRING
  | BOOLEAN
  | LITERAL
  | VOID
  ;

Ident
  : LITERAL
  ;

そして、ジソンの競合:

Conflict in grammar: multiple actions possible when lookahead token is LITERAL in state 10
- reduce by rule: Ident -> LITERAL
- reduce by rule: Type -> LITERAL
Conflict in grammar: multiple actions possible when lookahead token is = in state 10
- reduce by rule: Ident -> LITERAL
- reduce by rule: Type -> LITERAL

States with conflicts:
State 10
  Type -> LITERAL . #lookaheads= LITERAL =
  Ident -> LITERAL . #lookaheads= LITERAL =

回答されていない非常によく似た質問を見つけましたが、これを解決する方法の手がかりはありますか?

4

1 に答える 1

1

文法は確かに LALR(1) であり、bison によって問題なく処理されるため、これは明らかに jison のバグです。どうやら、jison は競合が発生した状態の先読みを誤って計算しています。(更新: 2014 年 1 月に報告されたバグ 205のようです。)

LALR(1) 文法の代わりに LR(1) パーサーを生成するように jison に依頼すると、先読みが正しく計算され、文法は警告なしでパスします。しかし、それは持続可能な解決策ではないと思います。

ここに別の回避策があります。DeclAssignプロダクションは必要ありません。「修正」は、別のプロダクションを削除LITERALして追加することでした。Type

Program
  : EOF
  | Stmt EOF
  ;

Decl
  : Type Ident ';'
  | LITERAL Ident ';'
  ;

Assign
  : Ident '=' NUMBER ';'
  ;

Stmt
  : Decl
  | Assign
  ;

Type
  : INTEGER
  | STRING
  | BOOLEAN
  | VOID
  ;

Ident
  : LITERAL
  ;

複数のステートメントを認識することを検討したい場合があります。

Program
  : EOF
  | Stmts EOF
  ;

Stmts
  : Stmt
  | Stmts Stmt
  ;
于 2015-12-17T16:17:21.237 に答える