ANTLR3规则评估具有非LL(*)决策
这是我的语法:ANTLR3规则评估具有非LL(*)决策,antlr3,ll,Antlr3,Ll,这是我的语法: grammar esi_exp; /* This will be the entry point of our parser. */ eval : booleanExp ; /* Addition and subtraction have the lowest precedence. */ booleanExp : orExp ; orExp : andExpr (OR andExpr)* ; andExpr
grammar esi_exp;
/* This will be the entry point of our parser. */
eval
: booleanExp
;
/* Addition and subtraction have the lowest precedence. */
booleanExp
: orExp
;
orExp
: andExpr (OR andExpr)*
;
andExpr
: notExpr (AND notExpr)*
;
notExpr
: NOT comparisonExpr
| comparisonExpr
;
comparisonExpr
: varOrLiteral ('==' varOrLiteral)*
;
varOrLiteral
: functionExpr
| literalExpr
| variableExpr
;
literalExpr : QUOTE VAR_ID QUOTE ;
variableExpr
: OPEN_VAR VAR_ID CLOSE_PAREN // $(HTTP_HOST)
| OPEN_VAR varWithArg CLOSE_PAREN // $(QUERY_STRING{param})
| OPEN_VAR varWithArgQuoted CLOSE_PAREN // $(QUERY_STRING{'param'})
| OPEN_PAREN booleanExp CLOSE_PAREN
;
varWithArg : VAR_ID OPEN_ARG VAR_ID CLOSE_ARG ;
varWithArgQuoted : VAR_ID OPEN_QUOTED_ARG VAR_ID CLOSE_QUOTED_ARG ;
matchValue : MATCH_VALUE_REGEX ;
functionExpr
: '$' FunctionName functionArgs;
FunctionName :
'exists'
| 'is_empty'
;
functionArgs
: '()'
| OPEN_PAREN VAR_ID CLOSE_PAREN
| OPEN_PAREN variableExpr CLOSE_PAREN
;
EQUALS : '==' ;
MATCH_FUNC : 'matches' ;
TRIPLE_QUOTE : '\'\'\'' ;
QUOTE : '\'' ;
OPEN_VAR : '$(' ;
OPEN_PAREN : '(' ;
CLOSE_PAREN : ')' ;
OPEN_ARG : '{' ;
CLOSE_ARG : '}' ;
OPEN_QUOTED_ARG : '{\'' ;
CLOSE_QUOTED_ARG : '\'}' ;
VAR_ID : ('a'..'z'|'A'..'Z'|'_')+ ; // match identifiers
AND : '&&' | '&' ;
OR : '|' | '||' ;
NOT : '!' ;
/* A number: can be an integer value */
Number
: ('0'..'9')+
;
WS
: (
' '
| '\r'
| '\t'
| '\u000C'
| '\n'
)
{
skip();
}
;
MATCH_VALUE_REGEX : TRIPLE_QUOTE ~(QUOTE)* TRIPLE_QUOTE;
这对于测试用例非常有用:
$exists($(id)) && (($(pagetype) == 'roster') || ($(pagetype) == 'cheerleaders') || ($(pagetype) == 'coaches') || ($(pagetype) == 'staff'))
但是,我还需要让它能够识别:
$(REQUEST_PATH) matches '''(matchup)/([^/]*)/([^/]*)/([^/]*)/([^/]*)'''
语法规则如下:
varOrLiteral MATCH_FUNC matchValue
应该匹配它并生成正确解析的语法。该规则在早期版本中有效,但在我修改语法以支持表达式中包含paren时被删除
我已经读到,启用回溯应该能够在这些情况下有所帮助,但是文档似乎表明,通常应该避免回溯
如何在不存在LL和/或Left递归问题的情况下添加此项?您可以预期规则的开头,以便指定方法 你为什么不试试这个
varOrLiteral
:
(QUOTE QUOTE) => matchValue
|(QUOTE) => literalExpr
| variableExpr
|functionExpr
;
这样,你就告诉语法,只有varOrLiteral以引号开头,它才是literalExpr。等等
你可以预测你想要多少
最后一条规则,默认选项
祝你好运 最终找到了答案,只需将比较表达式更改为:
: varOrLiteral (EQUALS varOrLiteral | MATCH_FUNC matchValue)*
现在就足够了。这有助于实现/集成“MATCH_FUNC matchValue”到语法中吗?刚刚尝试了重构,得到了一个FailedPredicateException。这不会通过现有工作案例的回归。我编辑了我的答案。我本想帮你,但我错过了消息。非常抱歉。试试这个。仅凭头脑编译语法很复杂,但我现在还没有“开发人员工具包”:pI非常感谢您的帮助。这对我的第一个问题更有意义。尽管如此,这仍然会导致回归失败,并伴有FailedPredicateException。关于失败谓词有什么想法吗?我修正了一件事。matchValue应该是驼峰样式,就像您的规则:')