regex - Antlr 解析器是贪婪的吗?

标签 regex antlr grammar antlr4

我不明白为什么这个antlr4语法

grammar antmath1;

expr
    :   '(' expr ')'                         # parensExpr
    |   op=('+'|'-') expr                    # unaryExpr
    |   left=expr op=('*'|'/') right=expr    # infixExpr
    |   left=expr op=('+'|'-') right=expr    # infixExpr
    |   value=NUM                            # numberExpr
    ;

NUM :   [0-9]+;
WS  :   [ \t\r\n] -> channel(HIDDEN);

工作正常: antlr tree produced by -(5+9)+1000; result=986

但为什么是这个:

grammar antmath;

expr
    :   '(' expr ')'                         # parensExpr
    |   left=expr op=('*'|'/') right=expr    # infixExpr
    |   left=expr op=('+'|'-') right=expr    # infixExpr
    |   op=('+'|'-') expr                    # unaryExpr
    |   value=NUM                            # numberExpr
    ;

NUM :   [0-9]+;
WS  :   [ \t\r\n] -> channel(HIDDEN);

失败: antlr tree produced by the same expression; result=-1014

我希望第一个语法1(输出正确的结果)产生与语法2(错误的输出)相同的结果。这背后的原因是:承认“-”作为第一个标记的唯一规则是#unaryExpr,因此任何语法生成的解析器都会首先尝试匹配该规则。然后,假设解析器是贪婪的(对于两个语法中的任何一个),我希望它将“(5+9)+1000”作为一个整体并将其与 expr 相匹配,因为它是一个有效的 expr。

我的推理哪里出了问题?

最佳答案

the grammars would try to match that rule first

确实如此。但是,您使一元减号的优先级低于二进制加号。

这意味着表达式被解释为 -((5+9)+1000) 而不是 (-(5+9))+1000

关于regex - Antlr 解析器是贪婪的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54261485/

相关文章:

c# - 正则表达式,在两个词之间找一个词

C# 正则表达式来验证日期?

c - 如何快速对许多正则表达式键进行字符串匹配?

parsing - 表达解析器语法和左联想

Haskell 优先级 : Lambda and operator

javascript - 正则表达式匹配任何长度超过 2 个字符的子字符串

java - Antlr:决策可以与多个替代方案相匹配(从非法 token 开始?)

compilation - 编译语法时出错

regex - 何时使用语法和编写解析器。使用语言特征正则表达式

c++ - 为什么 C++ 编译器在行后而不是行上给出错误?