Я плохо знаком с ANTLR и пытаюсь написать парсер для файлов DXF с ANTLRv4. Файлы DXF используют так называемые групповые коды для указания типа следующих данных.
Пример отрывка из некоторого файла DXF:
0
SECTION
2
HEADER
9
$ORTHOMODE
70
0
9
0
ENDSEC
Например, первый 0
означает, что в следующей строке следует строка. Групповой код 70
означает, что за ним последует 16-битное целое число, в примере это 0
. Моя проблема сейчас, например, как можно различить групповой код 0
и целое число 0
. В фрагменте примера кажется, что у целочисленных значений есть какой-то особый отступ, но я не смог найти ничего об этом в справочнике DXF.
Моя идея до сих пор заключалась в соблюдении грамматики ANTLR:
grammar SimpleDXF;
start : HEADER variable* ENDSEC ;
variable : varstart (groupcode NL value NL)+ ;
varstart : VAR ;
groupcode : INT ;
value : INT | ANYCHARSEQ ;
WS : [ \t]+ -> skip ;
NL : '\r'? '\n' ;
HEADER : '0' NL 'SECTION' NL '2' NL 'HEADER' NL ;
ENDSEC : '0' NL 'ENDSEC' NL ;
VAR : '9' NL VARNAME NL ;
VARNAME : '$' LETTER (LETTER | DIGIT)* NL ;
INT : DIGIT+ NL ;
ANYCHARSEQ : ANYCHAR+ NL ;
fragment ANYCHAR : [\u0021-\u00FF] ;
fragment LETTER : [A-Za-z_] ;
fragment DIGIT : [0-9] ;
Но, очевидно, это не удается при попытке синтаксического анализа Integer 0
, так как это рассматривается лексером как групповой код 0
из-за правила header
.
Так что теперь я не знаю, как решить мою проблему. Любая помощь высоко ценится.
ИЗМЕНИТЬ
изменена грамматика ANTLR, чтобы включить больше правил лексера. Теперь проблема в том, что лексер полностью не работает. Первый входной символ - это токен INT
вместо части токена HEADER
, как я предполагал ... Причина в том, что удаление пробелов с помощью -> skip
не будет работать, если оно находится внутри одного токена (см. Следующий пример):
Для ввода A B
(пробел между двумя буквами) эта грамматика будет работать:
start : 'A' 'B' ;
WS : [ \t\r\n]+ -> skip ;
Но эта грамматика работать не будет:
start : AB ;
AB : 'A' 'B' ;
WS : [ \t\r\n]+ -> skip ;