ANTLR4:如何在规则内为同一标签设置不同的上下文?

时间:2019-05-24 12:12:47

标签: parsing antlr antlr4

我有这样的语法:

grammar SearchQuery;

queryDeclaration                        : predicateGroupItem predicateGroupItemWithBooleanOperator* ;
predicateGroupItemWithBooleanOperator   : groupOperator predicateGroupItem ;
predicateGroupItem                      : LEFT_BRACKET variable variableDelimiter
                                                expression expressionWithBoolean* RIGHT_BRACKET ;

variable                                : VARIABLE_STRING ;
variableDelimiter                       : VAR_DELIMITER  ;

expressionWithBoolean                   : boolOperator expression ;

expression                              : value ;

value                                   : polygonType;

boolOperator                            : or
                                        ;

or                                      : OR ;

groupOperator                           : AND ;

polygonType                             : POLYGON LEFT_BRACKET pointList (POLYGON_DELIMITER pointList)* RIGHT_BRACKET ;
longType                                : LONG ;
doubleType                              : DOUBLE ;

pointList                               : point
                                        | LEFT_BRACKET point ( POLYGON_DELIMITER point)* RIGHT_BRACKET
                                        ;

point                                   : latitude longitude ;

latitude                                : longType
                                        | doubleType
                                        ;

longitude                               : longType
                                        | doubleType
                                        ;

POLYGON                                 : [pP] [oO] [lL] [yY] [gG] [oO] [nN] ;


LONG                                    : DIGIT+ ;

DOUBLE                                  : DIGIT+ '.' DIGIT*
                                        | '.' DIGIT+
                                        ;

AND                                     : [aA] [nN] [dD] ;
OR                                      : COMMA
                                        | [oO] [rR]
                                        ;

VARIABLE_STRING                         : [a-zA-Z0-9.]+ ;
COMMA                                   : ',' ;
POLYGON_DELIMITER                       : ';' ;
VAR_DELIMITER                           : ':' ;

RIGHT_BRACKET                           : ')' ;
LEFT_BRACKET                            : '(' ;

WS                                      : [ \t\r\n]+ -> skip ;

fragment DIGIT                          : [0-9] ;

问题是我不能在 polygonType pointList 规则(除POLYGON_DELIMITER外,我需要使用COMMA)和 boolOperator 规则(使用了COMMA) 换句话说,如果我们将POLYGON_DELIMITER更改为COMMA并 用这样的值测试这种语法

(polygons: polygon(20 30.4, 23.4 23),
           polygon(20 30.4, 23.4 23),
           polygon(20 30.4, 23.4 23))

我们会收到错误

mismatch input: ',' expecting {',', ')'}

如果有人能帮助我理解问题,我会很高兴。

P.S。如果我们不更改当前语法,则测试值为

(poligons: polygon(20 30.4; 23.4 23),
           polygon(20 30.4; 23.4 23),
           polygon(20 30.4; 23.4 23))

1 个答案:

答案 0 :(得分:1)

由于这些规则:

OR                                      : COMMA
                                        | [oO] [rR]
                                        ;

COMMA                                   : ',' ;

该词法分析器将永远不会产生COMMA令牌,因为它已经与OR令牌匹配。并且由于OR是在COMMA之前定义的,因此它具有优先权。

这就是错误消息mismatch input: ',' expecting {',', ')'}的真正含义。换句话说:mismatch input: OR expecting {COMMA, RIGHT_BRACKET}

应该让解析器规则orCOMMA匹配(如果OR运算符可以是“ or”或“,”):

or                                      : OR
                                        | COMMA
                                        ;

OR                                      : [oO] [rR]
                                        ;

COMMA                                   : ',' ;