ANTLR でオプションの空白を管理するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/1654186

  •  11-09-2019
  •  | 
  •  

質問

ANTLR でデータ ファイルを解析しようとしています - データ ファイルには、次のようなオプションの空白があります。

 3 6
  97   12
 15 18

以下に、線の開始位置と終了位置を示します。最後に改行があり、タブはありません。

^ 3 6$
^  97   12$
^ 15 18$
^

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

lines   :   line+;
line    :   ws1 {System.out.println("WSOPT :"+$ws1.text+":");} 
                num1 {System.out.println("NUM1 "+$num1.text);} 
                ws2 {System.out.println("WS :"+$ws2.text+":");}
                num2 {System.out.println("NUM2 "+$num2.text);} 
                NEWLINE
    ;
num1    :    INT    ;
num2    :    INT    ;
ws1 :   WSOPT;
ws2 :   WS;

INT     : '0'..'9'+;
NEWLINE :    '\r'? '\n';
//WS    :   (' '|'\t' )+ ;
WS  :   (' ')+ ;
WSOPT   :   (' ')* ;

それは与える

line 1:0 mismatched input ' ' expecting WSOPT
WSOPT :null:
NUM1 3
WS : :
NUM2 6
line 2:0 mismatched input '   ' expecting WSOPT
WSOPT :null:
NUM1 97
WS :   :
NUM2 12
BUILD SUCCESSFUL (total time: 1 second)

(すなわち、先頭の WS が認識されず、最後の行が欠落しています)。

次のような空白なしで始まる行を解析したいと考えています。

^12    34$
^ 23 97$

しかし、次のようなエラーが発生します。

line 1:0 required (...)+ loop did not match anything at input ' '

ANTLR での WS の解析に関する一般的な説明をいただければ幸いです。

編集 @jitter が有益な答えを持っています - {ignore=WS} これは私が使用している「決定版 ANTLR リファレンス」本には載っていないので、明らかに扱いにくい領域です。

まだ助けが必要ですこれを次のように変更しました。

lines   :   line line line;
line
options { ignore=WS; }
        :
                ws1  {System.out.println("WSOPT :"+$ws1.text+":");} 
                num1 {System.out.println("NUM1 "+$num1.text);} 
                ws2  {System.out.println("WS :"+$ws2.text+":");}
                num2 {System.out.println("NUM2 "+$num2.text);} 
                NEWLINE
    ;

しかし、エラーが発生します:

illegal option ignore

編集 どうやらこれは V3 から削除されたようです。http://www.antlr.org/pipermail/antlr-interest/2007-April/019423.html

役に立ちましたか?

解決 3

次のようなレクサー構造を使用して、これを機能させることができました。

WS  :   (' ')+ {skip();};

WSOPT   :       (' ')* {skip();};

ただし、NEWLINE にはありません。次に、パーサーでは次のような構成が行われます。

num1 num2 NEWLINE;

重要なのは、レクサー内の NEWLINE を除くすべての WS を削除することでした。

他のヒント

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

チェック ANTLR による字句解析 この見出しで始まる部分を検索します

レクサー内の空白を無視する

を使用する必要があります。 { ignore=WS; } ルール

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top