2015-04-08 6 views
1

Я не очень хорошо знаком с antlr. Я использую версию 4, и у меня есть грамматика, где пробелы не важны в некоторых частях (но это может быть в других, или, скорее, в удаче).Игнорирование пробелов (в некоторых частях) в Antlr4

Так сказать, мы имеем следующую грамматику

grammar Foo; 
program : A* ; 
A : ID '@' ID '(' IDList ')' ';' ; 
ID : [a-zA-Z]+ ; 
IDList : ID (',' IDList)* ; 
WS : [ \t\r\n]+ -> skip ; 

и тестовый вход

[email protected](X,Y); 
[email protected] (z,Z) ; 

Первая строка корректно распознаны а второй нет. Я не хочу публиковать мои правила с местами, где пробелы не актуальны, так как моя фактическая грамматика сложнее, чем пример игрушки. Если неясно, идентификатор идентификатора части ID не должен иметь пробелов. Пробелы в любой другой позиции вообще не должны иметь значения.

ответ

1

Определить ID '@' ID как токен лексера, а не как токен анализатора.

A : AID '(' IDList ')' ';' ; 

AID : [a-zA-Z]+ '@' [a-zA-Z]+; 

Другие варианты

  • включить/отключить пробельные в вашем поток токенов, например, here
  • включить/отключить пробельные с режимами LeXeR (может быть проблемой, поскольку режимы лексера запускаются на условиях, которые не так легко определить, в вашем случае)
3

Даже если вы пропускаете WS, правила лексера являются все еще чувствительный к существованию символов пробела. Пропустить просто означает, что маркер не генерируется для потребления парсером. Таким образом, правило lexer Addr явно не допускает каких-либо внутренних пробельных символов.

С другой стороны, правила парсера a и idList никогда не видят внутренних прожекторов, поэтому эти правила нечувствительны к появлению пробельных символов, возникающих между сгенерированными токенами.

grammar Foo; 

program : a* EOF ; // EOF will require parsing the entire input 

a : Addr LParen IDList RParen Semi ; 
idList : ID (Comma ID)* ; // simpler equivalent construct 

Addr : ID '@' ID 
ID : [a-zA-Z]+ ; 
WS : [ \t\r\n]+ -> skip ; 
Смежные вопросы