2

以下の文法は( left part = right part # comment )# commentオプションです。

2つの質問:

  1. 時々警告(ANTLRWorks 1.4.2): 決定は、複数の選択肢を使用して「{Int、Word}」などの入力と一致する可能性があります:1、2(参照id2
    しかし、たまにしかありません!
  2. 次の拡張は、コメント(id2)にchars'('および')'を含めることができることです。

文法:

grammar NestedBrackets1a1;

//==========================================================
// Lexer Rules
//==========================================================

Int
  :  Digit+
  ;

fragment Digit
  :  '0'..'9'
  ;

Special
  : ( TCUnderscore | TCQuote )
  ;
TCListStart   : '(' ; 
TCListEnd     : ')' ;   
fragment TCUnderscore  : '_' ;
fragment TCQuote       : '"' ;

// A word must start with a letter
Word
  :  ( 'a'..'z' | 'A'..'Z' | Special ) ('a'..'z' | 'A'..'Z' | Special | Digit )*
  ;

Space
  :  ( ' ' | '\t' | '\r' | '\n' ) { $channel = HIDDEN; }
  ;

//==========================================================
// Parser Rules
//==========================================================

assignment
  :  TCListStart id1 '=' id1 ( comment )? TCListEnd
  ;

id1
  :  Word+
  ;

comment
  : '#' ( id2 )*
  ;

id2
  :  ( Word | Int )+
  ;
4

1 に答える 1

0

ANTLRStarterは次のように書いています。

時々警告(ANTLRWorks 1.4.2):決定は、複数の選択肢を使用して「{Int、Word}」などの入力と一致する可能性があります:1、2(id2を参照)しかし、たまにしかありません!

いいえ、投稿した文法は常にこの警告を生成します。おそらく、常に気付くとは限りませんが(IDEプラグインまたはANTLRWorksは、開いていないタブに表示される場合があります)、警告が表示されます。コマンドラインからレクサー/パーサーを作成して、自分を納得させます。

java -cp antlr-3.4-complete.jar org.antlr.Tool NestedBrackets1a1.g

生成されます:

warning(200): NestedBrackets1a1.g:49:19:
Decision can match input such as "{Int, Word}" using multiple alternatives: 1, 2

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

これは、ルール内に*アフターがあり、トークンの繰り返しであるためです。入力が(aの後に2つのトークンが続く)であるとしましょう。ANTLRは、入力を複数の方法で解析できるようになりました。2つのトークンは、で一致する可能性があります。ここで、一度に1つのトークンに一致しますが、ルールの1回の実行でも一致する可能性があります 。( id2 )commentid2( Word | Int )+"# foo bar"#Word"foo""bar"( id2 )*id2Word"foo""bar"id2

マージされたルールを見てください。

comment
  :  '#' ( ( Word | Int )+ )*
  ;

繰り返しをどのように繰り返しているかを確認してください( ( ... )+ )*。あなたの場合のように、これは通常問題です。

*?:に置き換えることで、この問題を解決します。

comment
  :  '#' ( id2 )?
  ;

id2
  :  ( Word | Int )+
  ;

+または:を削除することによって

comment
  :  '#' ( id2 )*
  ;

id2
  :  ( Word | Int )
  ;

ANTLRStarterは次のように書いています。

次の拡張は、コメント(id2)にchars'('および')'を含めることができることです。

コメントの後には。が続くので、これは問題を引き起こしTCListEndます)。コメントを一致させることはお勧めしません)

編集

コメントは通常、入力ソースをトークン化するときにソースファイルから削除されることに注意してください。そうすれば、パーサールールでそれらを考慮する必要がありません。これを行うには、レクサールールでこれらのトークンを「スキップ」します。

Comment
  :  '#' ~('\r' | '\n')* {skip();}
  ; 
于 2011-07-31T18:47:09.050 に答える