4

JavaCC構文は、これらの種類の行を解析できる文法を実装します。

[b]content[/b]
content[/b]
[b]content

JavaCCパーサーはすべての行を解析する必要がありますが、正しいタグ付け動作と誤ったタグ付け動作を区別する必要があります。

正しいタグは1行目のようなもので、開始タグと終了タグがあります。タグが一致すると、太字のテキストが出力されます。

正しくないタグは、行の2と3のようなもので、一致する開始タグまたは終了タグがありません。これらが発生すると、そのまま出力に書き込まれ、タグとして解釈されません。

以下のJavaCCコードを試しました(LOOKAHEAD = 999999)。問題は、この構文は常にbold ()ではなくinvalidTag()としてすべてに一致することです。可能な限り、JavaCCパーサーがbold()と一致することを確認するにはどうすればよいですか?

String parse() :
{}
{
    body() <EOF>
    { return buffer; }
}

void body() :
{}
{
    (content())*
}

void content() :
{}
{ 
    (text()|bold()|invalidTag)
}

void bold() :
{}
{
    { buffer += "<b>";  }
    <BOLDSTART>(content())*<BOLDEND>
    { buffer += "</b>"; }
}

void invalidTag() :
{
}
{
    <BOLDSTART> | <BOLDEND>
    { // todo: just output token
    }
}

TOKEN :
{
    <TEXT : (<LETTER>|<DIGIT>|<PUNCT>|<OTHER>)+ >
    |<BOLDSTART : "[b]" >
    |<BOLDEND : "[/b]" >

    |<LETTER : ["a"-"z","A"-"Z"] >
    |<DIGIT : ["0"-"9"] >
    |<PUNCT : [".", ":", ",", ";", "\t", "!", "?", " "] >
    |<OTHER : ["*", "'", "$", "|", "+", "(", ")", "{", "}", "/", "%", "_", "-", "\"", "#", "<", ">", "=", "&", "\\"]     >
}
4

2 に答える 2

5

あなたの文法は曖昧です。これはおそらくあなたのせいではありません。あなたが解決しようとしている問題に対して明確な文法を作成することはおそらく非常に難しいからです。

LL(k)パーサーは、おそらくこのジョブに最適なツールではありません。

ただし、トークナイザーは便利な場合があり、スタックを使用して一致するタグと一致しないタグのペアを見つけることが適切な代替手段になる場合があります。

于 2010-10-06T22:15:59.260 に答える
2

少し前に、構文レベルでは非常に困難または不可能であることが証明されている一方で、いくつかの些細な問題は意味レベルまたは語彙レベルで簡単に解決できることを学びました。

注:私はJavaCCにあまり精通していませんが、過去に複数のコンパイラージェネレーターを使用したことがあります(私のお気に入りはsableccです)。

おそらく、「コンテンツ」を次のように定義することができます。

(text()|boldstart()|boldend()|invalidTag)

boldstart()は、開始タグとboldend()(終了タグ)を盲目的に出力します。

ただし、すべてをフィルタリングして正しく終了するタグのみを生成する場合は、そのためのステートフルオートマトンを作成し、開始タグと終了タグをフィードして、(たとえば)太字で開始、停止、または続行する必要があるかどうかに注意することをお勧めします(おそらくネストの深さを含む)、その出力に応じて、開始、停止、またはタグなしのいずれか。これは、JavaCCにある構文ツールや字句ツールを使用するのとは対照的に、非常に簡単に実装できます。

于 2010-10-07T08:47:31.640 に答える