Как мне управлять необязательными пробелами в ANTLR? - PullRequest
7 голосов
/ 31 октября 2009

Я пытаюсь проанализировать файл данных в 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 ' '

Буду признателен за общие объяснения разбора WS в ANTLR.

РЕДАКТИРОВАТЬ @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-February/019423.html

Ответы [ 3 ]

9 голосов
/ 10 ноября 2009
WS : (' ' | '\t')+
     {$channel = HIDDEN;}
   ;
2 голосов
/ 31 октября 2009

Проверьте Лексический анализ с помощью ANTLR , а затем найдите часть, которая начинается с этого заголовка

Игнорирование пробелов в лексере

Вам нужно использовать правило { ignore=WS; }

1 голос
/ 10 ноября 2009

Мне удалось заставить это работать, используя конструкции лексера, такие как:

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

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

но не в NEWLINE. Тогда в парсере такие конструкции как:

num1 num2 NEWLINE;

Ключом было убрать все WS в лексере, кроме NEWLINE.

...