2017-05-26 75 views
1

为什么不会以下语法识别布尔值?ANTLR4语法不承认布尔文字

我比较这对语法为Java和GraphQL,并不能明白为什么它不工作。

鉴于以下语法,分析如下:

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} 

有什么不对?

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 
    ; 

回答

2

它不起作用,因为令牌“真”的词法规则标识符匹配:

[@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} 

下移的标识符的定义更远的是词法规则中,它的工作原理:

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

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

记住的东西在顶部底部胜过东西。在像你这样的组合语法中,不要使用解析器规则(以小写字母开头)来分隔词法分析器规则(以大写字母开头)。

+1

请记住,第一词法分析器尝试最长的匹配。如果'BOOLEAN'匹配比'Identifier'规则可以匹配的任何内容更多的输入,那么''BOOLEAN''将由词法分析器选择。例如,你可以使用一个谓词来限制由'Identifier'匹配的字符数(对于'false'和'true',将会是3,),那么语法就会按照原样匹配这些关键字。 –

+0

感谢@MikeLischke并且足够真实。然而,OP将词法规则非正统地混合成文法中的第二条规则是他描述的问题的根源。我之前也曾遭受过类似的苦难,只是在-Tokens模式下运行TestRig就给了我“a-ha!”时刻。 – TomServo

+0

确实是一个非常普遍的问题。 –