2012-05-08 6 views
1

Antlr 3.2を使用していますが、コメント行を無視する文法を書くのに問題があります。具体的には、コメント行が入力の最後の行で、その後に改行がない場合はエラーになります。ANTLR構文解析 - 最後の行のコメントを無視する

私の入力は効果的なアセンブリ言語です。コメントは、セミコロンで行のどこからでも始まり、行の最後に移動します。他のすべてはコマンドとして解析されます。

問題を呈する私の文法の切開のバージョンは次のとおりです。

grammar Test; 

options { 
    language = Java; 
    output = AST; 
    ASTLabelType = CommonTree; 
} 

@header { 
    package test; 
} 

@lexer::header { 
    package test; 
} 

rule 
    : instruction+ EOF! 
    ; 

instruction 
    : 'SET' NEWLINE!* 
    ; 

COMMENT 
    : ';' .* NEWLINE+ { $channel=HIDDEN; } 
    ; 

NEWLINE 
    : '\r'? '\n' 
    ; 

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

私は次のように入力を使用する場合:line 4:11 required (...)+ loop did not match anything at character '<EOF>'を言って、これを解析するとき、私はエラーを取得する

; comment line 1 with blank line after it 

SET ; comment after command 
; comment line again 

入力の最後の行に改行を追加すると、改行がコメントストリッピングと一致し、EOFがルールの最後に一致するので、正しく動作します。

最終行のコメントを無視するようにするにはどうすればよいですか?エラーはありませんか?私はそれをハックするために元の入力に何かを追加したくない、コメントラインを読むためのよりクリーンな方法はありますか?私はNEWLINE | EOFのすべての種類の組み合わせを試しましたが、何もエラーを取り除くことはありません。

答えて

2

このような何かにそれを行う必要があります。

COMMENT 
    : ';' ~('\r' | '\n')* { $channel=HIDDEN; } 
    ; 

をそしてあなたがCOMMENTをしたい場合は、潜在的に行い、最後に改行を持っている:

COMMENT 
    : ';' ~('\r' | '\n')* NEWLINE? { $channel=HIDDEN; } 
    ; 

しかし、2つのルールNEWLINEWS

NEWLINE 
    : '\r'? '\n' 
    ; 

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

は危険です:ANTLR worこのようなks:できるだけ一致するようにしようとするので、最も「勝つ」ルールに一致します。 2つ(またはそれ以上)のルールが同じ文字数に一致する場合、最初に定義されたルールが「勝利」します。

つまり、レクサーが"\n"のような入力を受け取ると、NEWLINEが作成されます。しかし、レクサーが" \n"(空白に続いて"\n")を見ると、WSトークンが作成され(HIDDENチャネルに置かれます)。

実際にがあなたの言語では(アセンブリ言語AFAIKのフレーバーでない)であることが分かりませんので、NEWLINEルールを削除するだけです。 の場合は、ルールから、\r\nの両方の文字を削除してください。

+0

これはいいですし、エラーを取り除きますが、フォローアップの質問があります。これが改行を隠しているWSルールに当てはまる場合、なぜそのルールを終了する '命令 'の後に1つ必要ですか?あなたの変更を入れて、 'instruction'からNEWLINE *を取り除くと、コメントの最後に'行外の入力がありません '\ n' EOFを期待しています。なぜ私は3行目のコメントの末尾にある\ nが 'WS'レクサールールによって飲み込まれていないのか混乱させます。 –

+0

いいえ、申し訳ありませんが、私は 'NEWLINE'ルールを見逃し、' WS'ルールしか見ていませんでした。 –

+0

最新の回答をありがとう。私はあなたの最初の答えから一緒にそれをつなぎ、そしてここにコメントに戻って来て、あなたが更新されたと知った!あなたは、私はNEWLINEルールを削除しなければならないという点にスポットがあります。彼らは私の場合は重要ではありません。 –