ANTLR4: неверное совпадение с правилом лексера - PullRequest
1 голос
/ 24 апреля 2020

Я в самом начале изучения правил лексера ANTLR4. Моя цель - создать простую грамматику для Java свойств файлов. Вот что у меня есть:

lexer grammar PropertiesLexer;

LineComment
    : ( LineCommentHash
      | LineCommentExcl
      )
      -> skip
    ;

fragment LineCommentHash
    : '#' ~[\r\n]*
    ;

fragment LineCommentExcl
    : '!' ~[\r\n]*
    ;

fragment WrappedLine
    : '\\'
      ( '\r' '\n'?
      | '\n'
      )
    ;

Newline
    : ( '\r' '\n'?
      | '\n'
      )
      -> skip
    ;

Key
    : KeyLetterStart
      ( KeyLetter
      | Escaped
      )*
    ;

fragment KeyLetterStart
    : ~[ \t\r\n:=]
    ;

fragment KeyLetter
    : ~[\t\r\n:=]
    ;

fragment Escaped
    : '\\' .?
    ;

Equal
    : ( '\\'? ':'
      | '\\'? '='
      )
    ;

Value
    : ValueLetterBegin
      ( ValueLetter
      | Escaped
      | WrappedLine
      )*
    ;

fragment ValueLetterBegin
    : ~[ \t\r\n]
    ;

fragment ValueLetter
    : ~ [\r\n]+
    ;

Whitespace
    : [ \t]+
      -> skip
    ;

Мой тестовый файл такой:

# comment 1
# comment 2
# 
.key1= value1
key2\:sub=value2
key3 \= value3

key4=value41\
value42

# comment3
#comment4
key=value

Когда я запускаю grun, я получаю следующий вывод:

[@0,30:42='.key1= value1',<Value>,4:0]
[@1,45:60='key2\:sub=value2',<Value>,5:0]
[@2,63:76='key3 \= value3',<Value>,6:0]
[@3,81:102='key4=value41\\r\nvalue42',<Value>,8:0]
[@4,130:138='key=value',<Value>,13:0]
[@5,141:140='<EOF>',<EOF>,14:0]

Я не понимаю, почему определение Value совпадает. Однако, комментируя определение Value, он распознает определения Key и Equal:

[@0,30:34='.key1',<Key>,4:0]
[@1,35:35='=',<Equal>,4:5]
[@2,37:42='value1',<Key>,4:7]
[@3,45:49='key2\',<Key>,5:0]
[@4,50:50=':',<Equal>,5:5]
[@5,51:53='sub',<Key>,5:6]
[@6,54:54='=',<Equal>,5:9]
[@7,55:60='value2',<Key>,5:10]
[@8,63:68='key3 \',<Key>,6:0]
[@9,69:69='=',<Equal>,6:6]
[@10,71:76='value3',<Key>,6:8]
[@11,81:84='key4',<Key>,8:0]
[@12,85:85='=',<Equal>,8:4]
[@13,86:93='value41\',<Key>,8:5]
[@14,96:102='value42',<Key>,9:0]
[@15,130:132='key',<Key>,13:0]
[@16,133:133='=',<Equal>,13:3]
[@17,134:138='value',<Key>,13:4]
[@18,141:140='<EOF>',<EOF>,14:0]

, но как разрешить ему распознавать Key, Equal и Value определений?

1 Ответ

2 голосов
/ 25 апреля 2020

Правила лексера ANTLR соответствуют максимально возможному количеству символов, поэтому вы видите, как создаются все эти Value токены (они соответствуют большинству символов).

Лексические режимы Похоже, хорошо подходит для использования здесь. Как то так:

lexer grammar PropertiesLexer;

COMMENT
 : [!#] ~[\r\n]* -> skip
 ;

KEY
 : ( '\\' ~[\r\n] | ~[\r\n\\=:] )+
 ;

EQUAL
 : [=:] -> pushMode(VALUE_MODE)
 ;

NL
 : [\r\n]+ -> skip
 ;

mode VALUE_MODE;

  VALUE
   : ( ~[\\\r\n] | '\\' . )+
   ;

  END_VALUE
   : [\r\n]+ -> skip, popMode
   ;
...