3

私はしばらくの間これで立ち往生しています。私は次のような単純なものを解析したいと思います:

好きなもの:word1 word2 .. wordN嫌いなもの:word1 word2 .. wordN

Lemon+Flexを使用しています。現時点では、私の文法は次のようになっています。

%left LIKES MOODS FROM HATES INFO.

%syntax_error {  
  std::cout << "Syntax error!" << std::endl;  
}   

final ::= likes_stmt.
final ::= hates_stmt.

likes_stmt ::= LIKES list(A). { Data *data=Data::getInstance();data->likes.push_back(A);}
hates_stmt ::= HATES list(A). { Data *data=Data::getInstance();data->hates.push_back(A);}

list ::= likes_stmt VALUE(A).   { Data *data=Data::getInstance();data->likes.push_back(A);}
list ::= hates_stmt VALUE(A).   { Data *data=Data::getInstance();data->hates.push_back(A); }

list(A) ::= VALUE(B).           {A=B;}

ただし、これは最初の2単語でのみ機能します。明らかに、おそらく再帰的定義で、私は何か間違ったことをしていますか?どんな頭を上げても大歓迎です:)

4

2 に答える 2

2

あなたのlikes_stmtはlistで定義されており、listはlikesで定義されているように見えます。私はそれがどんな言葉でもうまくいくことに驚いています。LEMON構文を理解していない可能性があります(list(A)ビットを取得していないことは確かです)が、文法のBNFは非常に似ている傾向があります。

あなたの文法はもっと次のようになると思います:

 final = likes_stmt ;

 likes_stmt = LIKES list ;
 likes_stmt = HATES list ;


  list = value ;
  list = list value ;

もちろん、これは1つのLIKESフレーズまたは1つのHATESフレーズのみを認識しますが、質問の2行目で示されているように同じ時間または順序で両方を認識することはありません。

于 2011-07-20T22:48:53.590 に答える
2

@ crozzfire、Iraはあなたの元の質問に正しい答えを提供しました、それに投票することを検討してください。

解析された値を2つのリストに分割するという追加の要件について、質問に答えさせてください。リストの文法はどちらの場合も同じであるため、これらのリストの解析に異なるルールを作成しないでください。必要なのは、リストの前にLIKESまたはHATESが見つかったかどうかを示すフラグです。レモンのParse関数の4番目のパラメーターは、このニーズに最適です。Lemonドキュメントの「パーサーインターフェイス」セクションを参照してください。

以下は、そのようなフラグ変数を設定およびチェックするIraの文法を更新したものです。set_likes_stateルールは、トークンが削減されたときに関連するアクションを実行するために、LIKESおよびset_hites_stateHATESトークンの直前に配置する必要があることに注意してください。

    %extra_argument {unsigned* state}

    final ::= likes_stmt.
    final ::= hates_stmt.

    likes_stmt ::= set_likes_state LIKES list(A).
    hates_stmt ::= set_hites_state HATES list(A).

    list ::= list VALUE(A).   { if (*state == 0) {/*add A to list1*/} else {/*add A to list2*/}; }
    list ::= VALUE(A).        { if (*state == 0) {/*add A to list1*/} else {/*add A to list2*/}; }

    set_likes_state ::= .     { *state = 0; }
    set_hites_state ::= .     { *state = 1; }
于 2012-08-10T08:24:23.377 に答える