3

ANTLR 4 のセマンティック述語に問題があります。私の文法は構文があいまいで、あいまいさを解決するには 1 つのトークンを先読みする必要があります。

例として、「2012 年 1 月 19 日から午後 9 時まで」を「2012 年 1 月 19 日」という日付として解析し、パーサーの次のトークンを「まで」に残します。そして、パーサーの次のトークンが「7」で、「1 月 19 日 7 日から午後 9 時まで」を「1 月 19 日」という日付として解析したいと考えています。

したがって、3 番目のトークンを見て、それを取るか、そのままにしておく必要があります。

私の文法の断片は次のとおりです。

date
    :    month d=INTEGER  { isYear(getCurrentToken().getText())}?  y=INTEGER
                                    {//handle date, use $y for year}
    |    month d=INTEGER            {//handle date, use 2013 for year}
    ;                                             

パーサーがいずれかのサンプル入力で実行されると、次のメッセージが表示されます。

line 1:9 rule date failed predicate: { isYear(getCurrentToken().getText())}?

(私は推測していますが) 既に 1 つの余分なトークンを読み取っているため、2 番目のルールの選択肢には到達しません。

誰かがこれを達成する方法を教えてもらえますか?

4

1 に答える 1

6

パーサー ルールでは、ANTLR 4は決定を行うときに左端の述語のみを使用します。上に示したようなインライン述語は検証のみです。

次の変更により、ANTLR は決定を行う際に述語を評価しますが、明らかに、を呼び出す代わりに正しい先読みトークンを使用するように変更する必要がありますgetCurrentToken()

date
  : {isYear(getCurrentToken().getText())}? month d=INTEGER y=INTEGER
                                {//handle date, use $y for year}
  | month d=INTEGER             {//handle date, use 2013 for year}
  ;

PS:monthが常に 1 つのトークンの長さである場合は、_input.LT(3)必要なトークンを提供する必要があります。

于 2013-07-24T19:48:26.130 に答える