2016-09-20 6 views
1

Я пытаюсь создать грамматику для определения булевого литерала с помощью ANTLR4. Он может принимать форму «BOOL # TRUE» или просто «TRUE».Как создать лексические правила с необязательной частью в ANTLR4

если определить его как лексическое правило, как это:

Bool_Literal : ('BOOL' '#')? ('FALSE' | 'TRUE');  

Antlr может не совпадать вход:

isHigh := FALSE; 

ошибка является "несовпадающим ввод 'FALSE' ожидает Bool_Literal".

Но если я изменить его правила грамматики:

bool_literal : ('BOOL' '#')? ('FALSE' | 'TRUE'); 

может правильно подобрать либо «BOOL FALSE #» или просто «FALSE».

Кажется, что лексическое правило не может обнаружить токен, который начинается с необязательной части, кто-нибудь знает почему?

Спасибо!

Wayne

Вот моя грамматика:


grammar TT; 

pou 
    : assignment + 
    ; 

assignment : Identifier ':=' expression ';' ; 
expression : primary_expr ; 
primary_expr : Bool_Literal; 

//bool_literal   : ('BOOL' '#')? ('FALSE' | 'TRUE'); 

// lexical 
fragment Letter   : [a-zA-Z]|'_' ; 
fragment Digit   : [0-9]; 
fragment Bit   : [0-1]; 
fragment Octal_Digit : [0-7]; 
fragment Hex_Digit  : [0-9a-fA-F]; 

Identifier   : Letter (Letter|Digit)*; 

Bool_Literal   : ('BOOL' '#')? ('FALSE' | 'TRUE'); 

WS  : [ \n\r\t]+ -> channel(HIDDEN) ; 
Comment  : '//' .*? '\n' -> channel(HIDDEN); // channel COMMENTS) //  
EOL   : '\n'; 

мой тестовый вход:

isLow := BOOL#TRUE; 
isLow2 := BOOL#FALSE; 
isHigh := FALSE; 

ответ

2

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

В вашей грамматике TRUE и FALSE могут быть сопоставлены либо в качестве идентификаторов, либо в виде булевых литералов. Так как правило идентификатора предшествует грамматике, оно будет выигрывать, и, таким образом, FALSE будет идентификатором.

Итак, установите правило Bool_literal, где появляется правило bool_literal - или, по крайней мере, до правила identifier, - и затем оно будет выиграно вместо этого.

См. Вопрос «Почему мои ключевые слова рассматриваются как идентификаторы?» в this Antlr4 FAQ.

+0

он работает после того, как я перехожу к правилу Bool_Literal. Благодаря! – Wayne