1

この形式のファイルを読み取るための単純な構成ファイルリーダーを構築しようとしています。

A .-
B -...
C -.-.
D -..
E .

これは私がこれまでに持っている文法です:

grammar def;

@header {
    package mypackage.parser;
}
@lexer::header { package mypackage.parser; }
file
    :   line+;

line    :   ID WS* CODE NEWLINE;

ID  :   ('A'..'Z')*
    ;

CODE    :   ('-'|'.')*;

COMMENT
    :   '//' ~('\n'|'\r')* '\r'? '\n' {$channel=HIDDEN;}
    |   '/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}
    ;

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

そしてこれは私のテストリグです(junit4)

@Test
public void BasicGrammarCheckGood() {
       String CorrectlyFormedLine="A .-;\n";
       ANTLRStringStream input;
        defLexer lexer;
        defParser parser;

         input = new ANTLRStringStream(CorrectlyFormedLine);
        lexer = new defLexer(input);
        CommonTokenStream tokens = new CommonTokenStream(lexer);
         parser = new defParser(tokens);
         try {
        parser.line();
         }
         catch(RecognitionException re) { fail(re.getMessage()); } 
   }

修正されたフォーマットされた文字列を使用してこのテストを正しく実行すると、コードは例外や出力なしで終了します。

ただし、「xA .-; \ n」のような無効な文字列をパーサーにフィードすると、コードはしばらく回転し、「Javaヒープスペース」で終了します。

(トップレベルのルール「ファイル」でテストを開始すると、同じ結果が得られます。「行1:0の不一致の入力」の追加の(繰り返される)出力がCODEを期待しています)

ここで何が問題になっていますか?無効な出力に対して「RecognitionException」が発生することはありませんか?

編集:ここにアドバイスが提供された後、これが私の文法ファイル(フラグメント)です-これにより、「Javaヒープスペース」の問題が回避されます。

file
    :   line+ EOF;

line    :   ID WS* CODE NEWLINE;

ID  :   ('A'..'Z')('A'..'Z')*
    ;

CODE    :   ('-'|'.')('-'|'.')*;
4

1 に答える 1

0

一部のレクサー ルールは、ゼロ文字 (空の文字列) に一致します。

ID  :   ('A'..'Z')*
    ;

CODE    :   ('-'|'.')*;

もちろん、入力には無数の空の文字列が含まれているため、レクサーはトークンを生成し続け、しばらくするとヒープ スペース エラーが発生します。

レクサー ルールが常に少なくとも 1 文字と一致するようにします。

編集

2 つの (小さい) コメント:

  1. 非表示のチャネルにトークンを配置するためWS、パーサー ルールにトークンを追加する必要はありません。そうlineなるline : ID CODE NEWLINE;
  2. のようなものは次のよう('A'..'Z')('A'..'Z')*に書くことができます:('A'..'Z')+
于 2013-01-28T22:35:41.230 に答える