The following is a portion of a larger grammar. What I need is to understand why it doesn't work the way I think it should. I don't need a solution (I already found an alternative).
Next is the grammar:
grammar CommaSeparatorField;
document : field ( COMMA field)* EOF ;
field : value[false]+ ; //in real grammar, "value[false]+" is "value[getCustomLogic()]+"
value[ boolean commaAllow]
: TEXT
| NUMBER
| {$commaAllow}? COMMA
;
TEXT : [a-zA-Z]+ ;
NUMBER : [0-9]+ ;
COMMA : ',' ;
if input text is:
ab12cd,ef34gh
My logic tells me that since commaAllow is false, it will never enter into 'value' rule by COMMA, so the tree should be built:
document
|
-------------------------------------------------
field (COMMA field )* <EOF>
| | |
| -------------- |
| | | |
value[false]+ | value[false]+ |
| | | |
------------------ | ------------------ |
value value value | value value value |
| | | | | | | |
TEXT NUMBER TEXT COMMA TEXT NUMBER TEXT |
| | | | | | | |
ab 12 cd , ef 34 gh <EOF>
but instead I get:
line 1:6 no viable alternative at input ','
From my point of view it shoud work next way:
enter document, LT(1)=ab
enter field, LT(1)=ab
enter value, LT(1)=ab
consume [@0,0:1='ab',<1>,1:0] rule value
exit value, LT(1)=12
enter value, LT(1)=12
consume [@1,2:3='12',<2>,1:2] rule value
exit value, LT(1)=cd
enter value, LT(1)=cd
consume [@2,4:5='cd',<1>,1:4] rule value
exit value, LT(1)=, <-It should exit from 'value' and 'field' without to enter again value because 'commaAllow' is false
exit field, LT(1)=,
consume [@3,6:6=',',<3>,1:6] rule document
enter field, LT(1)=ef
enter value, LT(1)=ef
consume [@4,7:8='ef',<1>,1:7] rule value
exit value, LT(1)=34
enter value, LT(1)=34
consume [@5,9:10='34',<2>,1:9] rule value
exit value, LT(1)=gh
enter value, LT(1)=gh
consume [@6,11:12='gh',<1>,1:11] rule value
exit value, LT(1)=<EOF>
exit field, LT(1)=<EOF>
consume [@7,13:12='<EOF>',<-1>,1:13] rule document
exit document, LT(1)=<EOF>
but it is actually working this way:
enter document, LT(1)=ab
enter field, LT(1)=ab
enter value, LT(1)=ab
consume [@0,0:1='ab',<1>,1:0] rule value
exit value, LT(1)=12
enter value, LT(1)=12
consume [@1,2:3='12',<2>,1:2] rule value
exit value, LT(1)=cd
enter value, LT(1)=cd
consume [@2,4:5='cd',<1>,1:4] rule value
exit value, LT(1)=,
enter value, LT(1)=, <- why it tries to enter into value if commaAllow==false and LT(1)=, ?
Shouldn't it to:
- exit field
- consume ',' (COMMA) in rule 'document'
- enter again in rule 'field'
?
**** no viable alternative at input ',' is throw
exit value, LT(1)=,
enter value, LT(1)=,
exit value, LT(1)=ef
enter value, LT(1)=ef
consume [@4,7:8='ef',<1>,1:7] rule value
exit value, LT(1)=34
enter value, LT(1)=34
consume [@5,9:10='34',<2>,1:9] rule value
exit value, LT(1)=gh
enter value, LT(1)=gh
consume [@6,11:12='gh',<1>,1:11] rule value
exit value, LT(1)=<EOF>
exit field, LT(1)=<EOF>
consume [@7,13:12='<EOF>',<-1>,1:13] rule document
exit document, LT(1)=<EOF>
(note: I need to keep {$commaAllow}? COMMA option in value rule for a reason that does not make sense to raise it here)
What is failing in my logic? Am I misunderstanding something?
If i remove option:
| {$commaAllow}? COMMA // from 'value' rule
it works... but if it is not removed and 'commaAllow' is always false, Shouldn't it work as if it didn't exist?