1
votes

I have a grammar that I am having trouble disambiguating values that could belong to a Boolean or a String.

The grammar has several fields of type String and type Boolean. A String field can pretty much contain anything inside of quotes, and a Boolean can contain "Y" or "N". The problem: sometimes a String field can contain "Y" or "N" as well (usually as part of a list of multiple single-character values).

Here are the relevant grammar rules. I've tried using a predicate to disambiguate a Boolean comparison to a String, as long as that string is "Y" or "N".

booleanLogical
: booleanAtom (EQ|NE) booleanAtom
| booleanAtom (EQ|NE) {_input.LT(1).getText().equals("\"Y\"") || _input.LT(1).getText().equals("\"N\"")}? STRING
;

booleanAtom
: BOOLEAN_FIELD
;

stringLogical
: stringAtom (EQ|NE|LT|LE|GT|GE) stringAtom
| STRING_FIELD (EQ|NE|LT|LE|GT|GE) ('"Y"'|'"N"')
;

stringAtom
: STRING_FIELD
| STRING
;

BOOLEAN_FIELD: ("BFIELD1","BFIELD2","BFIELD3");
STRING_FIELD: ("SFIELD1","SFIELD2","SFIELD3");

The error message when attempting to parse a boolean expression:

BFIELD1="Y"

is:

line 1:7: no viable alterative at input 'BFIELD1="Y"'

In antlr3, I would have just used a lookahead, but that's no longer an option.

Any assistance out there?

1

1 Answers

3
votes

Due to the use of the literal '"Y"' in the stringLogical rule, the input "Y" is producing a special token which is not STRING. I recommend you stop trying to distinguish between "Y", "N", and other strings in the parser and instead use a listener to validate the strings after the parse is complete.

booleanLogical
  : booleanAtom (EQ|NE) booleanAtom
  | booleanAtom (EQ|NE) STRING
  ;

Also, it's important to note that ANTLR 4 only evaluates predicates that appear on the left edge of a decision. The predicate you used in the original booleanLogical rule is not on the left edge of a decision, so it would never be evaluated.