ANTLR4 not skipping white spaces in lexical rule

3,324 views
Skip to first unread message

Tal Malul

unread,
Aug 12, 2016, 10:20:26 PM8/12/16
to antlr-discussion
antlr4 not skipiping whitespaces in lexer rule

Hey, im new in ANTLR and i have a problem with a white spaces in a lexer rule.

im using ANTLR4 and wrote this test grammar:

   
 grammar Resturant;
   
    options
   
{
    language
= Java;
   
}
   
    startRule
: reservation+ EOF;
   
    reservation
:
   
   
(
    drink
   
)+
   
;
   
    drink
:
   
(
    furitShake
|
    WATER
   
)
   
;
   
    furitShake
:
   
BulidInShake | CustomFruitShake
   
;


    WS
: [ \t\r\n]+ -> skip ;  
   
   
BulidInShake:
    STRABERRY BANANA
|
    MANGO BANANA
|
    MANGO BANANA MELON
   
;
   
   
CustomFruitShake:
   
(MANGO | BANANA | MELON | WATERMELON | STRABERRY)+
   
;
   
    MANGO
: M A N G O;
    BANANA
: B A N A N A;
    MELON
: M E L O N;
    WATERMELON
: W A T E R M E L O N;
    STRABERRY
: S T R A B E R R Y;
    MILK
: M I L K;
    ICECREAM
: I C E C R E A M;
    WATER
: W A T E R;
   
    fragment A
:('a'|'A');
    fragment B
:('b'|'B');
    fragment C
:('c'|'C');
    fragment D
:('d'|'D');
    fragment E
:('e'|'E');
    fragment F
:('f'|'F');
    fragment G
:('g'|'G');
    fragment H
:('h'|'H');
    fragment I
:('i'|'I');
    fragment J
:('j'|'J');
    fragment K
:('k'|'K');
    fragment L
:('l'|'L');
    fragment M
:('m'|'M');
    fragment N
:('n'|'N');
    fragment O
:('o'|'O');
    fragment P
:('p'|'P');
    fragment Q
:('q'|'Q');
    fragment R
:('r'|'R');
    fragment S
:('s'|'S');
    fragment T
:('t'|'T');
    fragment U
:('u'|'U');
    fragment V
:('v'|'V');
    fragment W
:('w'|'W');
    fragment X
:('x'|'X');
    fragment Y
:('y'|'Y');
    fragment Z
:('z'|'Z');
   
    fragment
Digit : [0-9];
    fragment
Letter : [a-zA-Z] | '-' | '_' | '$';
    fragment
AlphabeticLetter : [a-zA-Z] ;


when i tried to ran the program with the text input: Mango Banana Melon
i excpected that the rule how will capture my input will be BulidInShake but insted the one how captured the input was CustomFruitShake

when i tried to change the rule BulidInShake and added spaces between the words like that:

    BulidInShake:
    STRABERRY ' ' BANANA |
    MANGO ' ' BANANA |
    MANGO ' ' BANANA ' ' MELON
    ;

i did manage to captued the BulidInShake as i wanted.

i dont undestand why this is happening if i added a rule to skip white spaces: 
WS : [ \t\r\n]+ -> skip ;

does it mean that i will need to add spaces between any of my lexical rules if i want to "combo" them one after the other?

Mike Lischke

unread,
Aug 13, 2016, 6:59:19 AM8/13/16
to antlr-di...@googlegroups.com
Hi,


    WS
: [ \t\r\n]+ -> skip ;  
   
   
BulidInShake:
    STRABERRY BANANA
|
    MANGO BANANA
|
    MANGO BANANA MELON
   
;
   
   
CustomFruitShake:
   
(MANGO | BANANA | MELON | WATERMELON | STRABERRY)+
   
;

This rule can match more input than your BulidInShake rule, hence it is matched first. Additionally both can match the same input (here MANGO BANANA MELON), which is therefore matched by BulidInShake (as it comes before CustomFruitShake) for this particular input.

   
    MANGO
: M A N G O;
    BANANA
: B A N A N A;
    MELON
: M E L O N;
    WATERMELON
: W A T E R M E L O N;
    STRABERRY
: S T R A B E R R Y;
    MILK
: M I L K;
    ICECREAM
: I C E C R E A M;
    WATER
: W A T E R;
   
    fragment A
:('a'|'A');

Just a side note. You can write these rules simpler as: fragment A: [aA];




when i tried to ran the program with the text input: Mango Banana Melon
i excpected that the rule how will capture my input will be BulidInShake but insted the one how captured the input was CustomFruitShake

when i tried to change the rule BulidInShake and added spaces between the words like that:

    BulidInShake:
    STRABERRY ' ' BANANA |
    MANGO ' ' BANANA |
    MANGO ' ' BANANA ' ' MELON
    ;

i did manage to captued the BulidInShake as i wanted.

i dont undestand why this is happening if i added a rule to skip white spaces: 
WS : [ \t\r\n]+ -> skip ;

does it mean that i will need to add spaces between any of my lexical rules if i want to "combo" them one after the other?

You are trying to do parser work in the lexer. Make BulidInShake a parser rule (by renaming it to bulidInShake) and it should work as you want. Whitespaces are not passed on to the parser when skipped in the lexer, so you don't have to take special care for your fruit mixes.


Reply all
Reply to author
Forward
0 new messages