4

私は現在、独身プロジェクトの一環としてポーカーハンドヒストリーパーサーに取り組んでいます。私は過去数日間いくつかの調査を行っており、いくつかの優れたパーサージェネレーターに出くわしました(プロジェクト自体はJavaでコーディングされるため、JavaCCを選択しました)。

ハンドヒストリーの文法は非常に基本的でわかりやすいものですが、プレーヤーのニックネームに使用できる文字のセットが原因で、あいまいさの問題があります。

次の形式の行があるとします。

Seat 5: myNickname (1500 in chips)

トークンmyNicknameには、空白だけでなく任意の文字を含めることができます。これは、との両方(1500 in chipSeat 5:有効なニックネームであることを意味します。これは、最終的にあいまいさの問題につながります。長さ(4〜12文字)を除いて、プレーヤーのニックネームに制限はありません。

プレーヤーのニックネーム(たとえば、この特定の場合の座席位置とチップの量)とともにいくつかのデータを解析して保存する必要があるので、私の質問は、ここでの私のオプションは何ですか?

私はJavaCCを使用してそれをやりたいと思っています。

SeatRecord seat() :
{ Token seatPos, nickname, chipStack; }
{
    "Seat" seatPos=<INTEGER> ":" nickname=<NICKNAME> "(" chipStack=<INTEGER> 
    "in chips)"
    {
        return new SeatRecord(seatPos.image, nickname.image, chipStack.image); 
    }
}  

現在は機能しません(前述の問題のため)

また、GLRパーサー(あいまいな文法を処理しているようです)も検索しましたが、Bisonを除いて、ほとんどが放棄されているか、文書化が不十分であるようですが、Java用のGLRパーサーはサポートされておらず、複雑すぎて操作できない可能性がありますとにかく(あいまいさの問題は別として、私が述べたように、文法自体はかなり基本的です)

または、文字列を自分でトークン化することに固執し、indexOf(), lastIndexOf()etcを使用して必要なデータを解析する必要がありますか?それがあまりにも醜い私見であり、いくつかのケースを見逃すかもしれないので、それが残っている唯一のオプションである場合にのみそれを選びます(それは間違った構文解析につながるでしょう)

4

3 に答える 3

7

入力形式が指定したとおりに単純な場合は、おそらく単純な正規表現で解決できます。

^Seat ([0-9]+): (.*) \(([0-9]+) in chips\)$

この場合の正規表現エンジンのNFAはあいまいさを解決し、括弧はキャプチャグループであるため、関心のある情報を抽出できます。

于 2012-06-18T11:35:37.147 に答える
2

2つの解決策があります。

  • 名前にいくつかの制限を追加します。そのようなニックネームを受け入れる広く使われているシステムはほとんど覚えていません。英数字と「_」区切り文字を使用させるだけです。また、座席のキーワードを追加することもできます。たとえば、そのような単語をニックネームにすることはできません。
  • また、文法に基づいて、解析用の有限オートマトンを構築することもできます。FSMはそのような曖昧な文法を処理できると思います。あなたがそれを手に入れたら、あなたはあなたが望むすべてを解析することができます。

とにかく、元のデザインに問題があると思います。ニックネームはそのような名前のセットを許可するべきではありません。また、名前の代わりに識別子を使用できないのはなぜですか。名前はデータベースに保存できます。

于 2012-06-18T11:31:28.450 に答える
2

システムの文法は次のようになります(文脈自由文法として記述されています):

S -> seating nickname chips

seating -> "Seat " number ":"
number -> "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
number -> number number

nickname -> "a" | "b" | "c" ...... | "z" | ...."+" | "?" | number
nickname -> nickname nickname 

chips -> "(" number "in chips)"

フォームのルールに注意してください:

number -> number number

これは基本的に無限の文法を可能にします。「無限の文法」は、すべてをカプセル化することを意味するわけではないことに注意してください。上記の行は、基本的に正規表現に相当し(\d*)ます。

CFGに文法を入力してから、それを正規文法に変換すると、ほとんどの場合に役立ちます。これを行う方法の詳細については、こちらをご覧ください。幸運を!

于 2012-06-18T14:47:36.847 に答える