在我的antlr语法中添加对数组的支持

问题描述 投票:0回答:1

我正在使用 ANTLR 来解析搜索查询输入,例如:

年龄>25

名字:“约翰”

树通常看起来像这样:

我想添加对 IN 运算符和数组值的支持,以便能够解析如下查询:

名字 IN [“jane”,“joe”]

我尝试在我的值规则中添加数组的语法规则。

array
   : LBRACKET (value (COMMA value)* )? RBRACKET
   ;
   
value
   : array
   | IDENTIFIER
   | STRING
   | ENCODED_STRING
   | NUMBER
   | BOOL
  ;

问题在于解析器将数组本身识别为 ENCODED_STRING。

名字 IN [“约翰”,“简”]

这是我的完整语法文件

grammar Query;

// syntactic rules
input
   : query EOF
   ;

query
   : left=query logicalOp=(AND | OR) right=query #opQuery
   | LPAREN query RPAREN #priorityQuery
   | criteria #atomQuery
   ;

criteria
   : key op value
   ;

key
   : IDENTIFIER
   ;

array
   : LBRACKET (value (COMMA value)* )? RBRACKET
   ;
   
value
   : array
   | IDENTIFIER
   | STRING
   | ENCODED_STRING
   | NUMBER
   | BOOL
  ;

op
   : EQ
   | GT
   | LT
   | NOT_EQ
   | IN
   | NOT_IN
   ;

// lexical rules
BOOL
    : 'true'
    | 'false'
    ;

STRING
 : '"' DoubleStringCharacter* '"'
 | '\'' SingleStringCharacter* '\''
 ;

fragment DoubleStringCharacter
   : ~["\\\r\n]
   | '\\' EscapeSequence
   | LineContinuation
   ;

fragment SingleStringCharacter
    : ~['\\\r\n]
    | '\\' EscapeSequence
    | LineContinuation
    ;

fragment EscapeSequence
    : CharacterEscapeSequence
    | HexEscapeSequence
    | UnicodeEscapeSequence
    ;

fragment CharacterEscapeSequence
 : SingleEscapeCharacter
 | NonEscapeCharacter
 ;

fragment HexEscapeSequence
 : 'x' HexDigit HexDigit
 ;
 
fragment UnicodeEscapeSequence
 : 'u' HexDigit HexDigit HexDigit HexDigit
 ;

fragment SingleEscapeCharacter
 : ['"\\bfnrtv]
 ;

fragment NonEscapeCharacter
 : ~['"\\bfnrtv0-9xu\r\n]
 ;

fragment EscapeCharacter
 : SingleEscapeCharacter
 | DecimalDigit
 | [xu]
 ;

fragment LineContinuation
 : '\\' LineTerminatorSequence
 ;

fragment LineTerminatorSequence
 : '\r\n'
 | LineTerminator
 ;

fragment DecimalDigit
 : [0-9]
 ;
fragment HexDigit
 : [0-9a-fA-F]
 ;
fragment OctalDigit
 : [0-7]
 ;

fragment POINT
   : '.'
   ;

AND
   : 'AND'
   ;

OR
   : 'OR'
   ;

NUMBER
   : ('0' .. '9') ('0' .. '9')* POINT? ('0' .. '9')*
   ;

LPAREN
   : '('
   ;


RPAREN
   : ')'
   ;

LBRACKET
   : '['
   ;

RBRACKET
    : ']'
    ;

GT
   : '>'
   ;


LT
   : '<'
   ;


EQ
   : ':'
   ;

IN
   : 'IN'
   ;

NOT_IN
    : 'NOT IN'
    ;

NOT_EQ
   : '!'
   ;

COMMA
   : ','
   ;

IDENTIFIER
   : [A-Za-z0-9.]+
   ;

ENCODED_STRING
   : ~([ :<>!()])+
   ;

LineTerminator
: [\r\n\u2028\u2029] -> channel(HIDDEN)
;

WS
   : [ \t\r\n]+ -> skip
   ;
parsing antlr antlr4 grammar
1个回答
0
投票

你的

ENCODED_STRING
太贪婪了:它也消耗了
[
["john",
变成单个
ENCODED_STRING
代币),这不是你想要的。

做一些这样的事情:

ENCODED_STRING
   : '"' ( ~[\\"] | '\\' . )* '"'
   ;

然后您的示例输入被解析为:

© www.soinside.com 2019 - 2024. All rights reserved.