why is 'no viable alternative at input' error throw?

Viewed 51

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?

0 Answers
Related