Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ANTLR4 Grammar doesn't recognize Boolean literals

Tags:

antlr4

Why won't the below grammar recognize boolean values?

I've compared this to the grammars for both Java and GraphQL, and cannot see why it doesn't work.

Given the below grammar, parses is as follows:

foo = null // foo = value:nullValue
foo = 123 // foo = value:numberValue
foo = "Hello" // foo = value:stringValue
foo = true // line 1:6 mismatched input 'true' expecting {'null', STRING, BOOLEAN, NUMBER}

What is wrong?

grammar issue;

elementValuePair
    :   Identifier '=' value
    ;

Identifier : [_A-Za-z] [_0-9A-Za-z]* ;

value
   : STRING # stringValue | NUMBER # numberValue | BOOLEAN # booleanValue | 'null' #nullValue
   ;

STRING
   : '"' ( ESC | ~ ["\\] )* '"'
   ;

BOOLEAN
   : 'true' | 'false'
   ;

NUMBER
   : '-'? INT '.' [0-9]+| '-'? INT | '-'? INT
   ;

fragment INT
   : '0' | [1-9] [0-9]*
   ;

fragment ESC
   : '\\' ( ["\\/bfnrt]  )
   ;

fragment HEX
   : [0-9a-fA-F]
   ;

WS
   : [ \t\n\r]+ -> skip
   ;
like image 599
Marty Pitt Avatar asked Oct 30 '25 18:10

Marty Pitt


1 Answers

It doesn't work because the token 'true' matches lexer rule Identifier:

[@0,0:2='foo',<Identifier>,1:0]
[@1,4:4='=',<'='>,1:4]
[@2,6:9='true',<Identifier>,1:6] <== lexed as an Identifier!
[@3,14:13='<EOF>',<EOF>,3:0]
line 1:6 mismatched input 'true' expecting {'null', STRING, BOOLEAN, NUMBER}

Move your definition of Identifier down farther to be among the lexer rules and it works:

NUMBER
   : '-'? INT '.' [0-9]+| '-'? INT | '-'? INT
   ;

Identifier : [_A-Za-z] [_0-9A-Za-z]* ;

Remember stuff at the top trumps stuff at the bottom. In a combined grammar like yours, don't intersperse the lexer rules (which start with a capital letter) with parser rules (which start with a lowercase letter).

like image 150
TomServo Avatar answered Nov 04 '25 07:11

TomServo