1

テキストの説明で立ち往生している jison ( http://zaa.ch/jison/docs/ ) を使用して単純なパーサーを作成しようとしました。

%lex

%%
[\s\n\t]+                   return 'TK_SPACE';
[0-9]+("."[0-9]+)?\b        return 'TK_NUMBER';
[a-zA-Z]+([a-zA-Z0-9]+)?\b  return 'TK_WORD';
<<EOF>>                     return 'EOF';

/lex

%start document

%%

document
  : nodes EOF
    { console.log($1); }
  | EOF
  ;

nodes
  : nodes node
    { $1.push($2); $$ = $1; }
  | node
    { $$ = [$1]; }
  ;

node
  : text
  ;

text
  : text text_element
    { $$ = $1 + $2; }
  | text_element
  ;

text_element
  : TK_NUMBER
  | TK_WORD
  | TK_SPACE
  ;

この文法は警告付きでコンパイルされています。

Conflict in grammar: multiple actions possible when lookahead token is TK_SPACE in state 5
- reduce by rule: node -> text
- shift token (then go to state 9)
Conflict in grammar: multiple actions possible when lookahead token is TK_WORD in state 5
- reduce by rule: node -> text
- shift token (then go to state 8)
Conflict in grammar: multiple actions possible when lookahead token is TK_NUMBER in state 5
- reduce by rule: node -> text
- shift token (then go to state 7)

States with conflicts:
State 5
  node -> text . #lookaheads= TK_SPACE TK_WORD TK_NUMBER EOF
  text -> text .text_element #lookaheads= EOF TK_NUMBER TK_WORD TK_SPACE
  text_element -> .TK_NUMBER
  text_element -> .TK_WORD
  text_element -> .TK_SPACE

しかし、テキストを解析しようとすると、うまくいきます。これはコードの完全なバージョンではなく、テキスト付きのバージョンです。nodeフィーチャにノードを追加したい。

4

1 に答える 1

4

問題は、あなたの文法があいまいであることです。 aは、区切り記号のないnodes一連の one または mode で構成されています。nodeAnodeは、区切り記号のないtext1 つ以上の a で構成されます。text_elementそのため、いつnode終了して次が始まるかを知る方法はありません。

text_elements例として、入力に3 のシーケンスがある場合、それはnode3 つすべてを含む 1 つの場合もあれば、3 つnodeそれぞれに 1 つを含む場合もあります。

Bison は常に reduce よりも shift を優先することでこの競合を「解決」します。これは常により大きなtextオブジェクトを作成することを優先するため、ルールnodes: nodes nodeが縮小されることはなく、単に文法から削除されることもあります。これは純粋なあいまいさ (先読みの問題ではない) であるため、結果の文法は同じ言語に一致するため、問題にはならない可能性があります。ジソン(または実際に使用しているパーサージェネレーター)は同じだと思います。

ただし、一般に、競合は問題です。これは、生成されたパーサーによって解析される文法が、指定した文法ではないことを意味するためです。結果のパーサーによって実際に解析される文法を理解することは自明ではなく、shoft-reduce 解析がどのように機能するか、およびパーサージェネレーターによって実際に生成される状態を注意深く理解する必要があります。情報はすべて.outputファイルにあります (bison によって生成されます-v-- 他のジェネレーターは異なる場合があります) が、それを読んで理解する必要があります。

于 2016-04-23T18:03:43.497 に答える