0

ここここで関連する質問をしましたが、新しい質問がありますが、実際には一般的な考え方を求めています。

文法は次のとおりです。

grammar post2;


post2: action_cmd+
        ;

action_cmd
    : cmd_name  action_cmd_def  
    ;

action_cmd_def
    : (cmd_chars | cmd_literal)+   Semi_colon  
    ;

cmd_name
    : 'a'..'z'  ('a'..'z' | '0'..'9' | '_'  )*
    ;

cmd_chars
    : ('a'..'z' | 'A'..'Z' | '0'..'9' | '_' | '.' | ':' | '-' |'\\')
    ;

cmd_literal
    : SINGLE_QUOTE  ~(SINGLE_QUOTE | '\n' | '\r')  SINGLE_QUOTE
    ;

SINGLE_QUOTE
    : '\''
    ;

Semi_colon
    : ';'
    ;

WS : ('\t' | ' ')+  {$channel = HIDDEN;};

New_Line : ('\r' | '\n')+   {$channel = HIDDEN;};

このエラーが発生したのは当然のことです-

warning(200): post2.g:16:45: 
Decision can match input such as "'_'" using multiple alternatives: 1, 2

As a result, alternative(s) 2 were disabled for that input

エラーはルール「cmd_name」に関するものです。

その理由は、バートが別のスレッドで示したように、「abc__」などの入力がある場合、「abc_」(cmd_name) および「_」(action_cmd_def/cmd_chars) または「abc__」(cmd_name) として解析できるためだと思います。 )。

ここに私の質問があります:1)それを修正する方法は?cmd_name の前に「options {greedy=true;}」を追加しようとしましたが、エラーは解決しません。

2) cmd_name と action_cmd_def を 1 つに結合すれば、問題はなくなります。これは、文法の粒度の問題につながります。ANTLR には非常に強力なレクサー/パーサー機能があるため、文法を使用して意味のある文字列を除外するのが本当に好きです。この場合、「action_cmd」の入力データはコマンド名文字列で始まり、いくつかの乱雑なもの、だから私は文法が2つの部分を分けるのが好きです; それ以外の場合は、ターゲット言語 (私の場合は C) を使用してアクション部分を作成する必要がありますが、より深い粒度に進むと非常に多くの問題が発生するため、間違った方向に進んでいるかどうか疑問に思います。

これで、文法の粒度の経験則は何ですか? 私は文法を使うことに夢中になっていますか?

4

1 に答える 1

-1

これは真のあいまいさですが、貪欲なオプションがうまくいくはずです。多分それはサブルールレベルである必要がありますか?これが機能するかどうかを確認します。

cmd_name
    : 'a'..'z' (options {greedy=true;} : 'a'..'z' | '0'..'9' | '_'  )*

質問の 2 番目の部分については、ルールの粒度は問題ないと思います。貪欲なフラグだけでは解決できないあいまいさがある場合は、構文述語を使用することもできます。ANTLR 3 の本には詳しく記載されていますが、Web サイトにはあまり詳しくありません。

これは、述語を構文的に一致させようとすることになります。成功した場合は実際に一致し、失敗した場合は他の代替手段を使用します。たとえば、C では、関数の宣言または定義があるかどうかは、宣言の最後に到達するまでわかりません。宣言の長さには下限がありません。したがって、構文述語を使用して、「それが宣言であるかどうかを見てみましょう。宣言である場合は実際に一致し、そうでない場合は他の代替案を試してください。

externalDef
    :       ( "typedef" | declaration )=> declaration
    |       functionDef
    |       asm_expr
    ;
于 2013-02-15T19:35:31.427 に答える