Antlr4 意外停止解析表达式
Antlr4 unexpectedly stops parsing expression
我正在使用公式语法开发一个简单的计算器:
grammar Formula ;
expr : <assoc=right> expr POW expr # pow
| MINUS expr # unaryMinus
| PLUS expr # unaryPlus
| expr PERCENT # percent
| expr op=(MULTIPLICATION|DIVISION) expr # multiplyDivide
| expr op=(PLUS|MINUS) expr # addSubtract
| ABS '(' expr ')' # abs
| '|' expr '|' # absParenthesis
| MAX '(' expr ( ',' expr )* ')' # max
| MIN '(' expr ( ',' expr )* ')' # min
| '(' expr ')' # parenthesis
| NUMBER # number
| '"' COLUMN '"' # column
;
MULTIPLICATION: '*' ;
DIVISION: '/' ;
PLUS: '+' ;
MINUS: '-' ;
PERCENT: '%' ;
POW: '^' ;
ABS: [aA][bB][sS] ;
MAX: [mM][aA][xX] ;
MIN: [mM][iI][nN] ;
NUMBER: [0-9]+('.'[0-9]+)? ;
COLUMN: (~[\r\n"])+ ;
WS : [ \t\r\n]+ -> skip ;
"column a"*"column b"
输入按预期给了我以下树:
但是 "column a" * "column b"
输入意外停止解析:
我错过了什么?
您的 WS
规则被 COLUMN
规则打破,后者具有更高的 。更准确地说,问题是 ~[\r\n"]
也匹配 space 个字符。
"column a"*"column b"
词法如下:'"'
COLUMN
'"'
MULTIPLICATION
'"'
COLUMN
'"'
"column a" * "column b"
词法如下:'"'
COLUMN
'"'
COLUMN
'"'
COLUMN
'"'
是的,“space star space”被词法化为 COLUMN
标记,因为这就是 ANTLR 词法分析器规则的工作方式:更长的标记匹配优先。
如您所见,此令牌流 不 匹配整个 expr
规则,因此 expr
尽可能多地匹配,这是 '"'
COLUMN
'"'
.
像您一样声明仅包含否定规则的词法分析器规则总是一个坏主意。拥有单独的 '"'
令牌也不适合我。
您应该做的是将引号包含在 COLUMN
规则中,因为它们在逻辑上是标记的一部分:
COLUMN: '"' (~["\r\n])* '"';
然后从您的解析器规则中删除独立引号。您可以稍后在处理解析树时取消对文本的引用,或者更改词法分析器中的令牌发射逻辑以更改令牌的基础值。
并且为了不忽略尾随输入,添加另一条规则以确保您已经消耗了整个输入:
formula: expr EOF;
然后在调用解析器时使用此规则而不是 expr
作为入口规则。
But "column a" * "column b" input unexpectedly stops parsing
如果我 运行 你的语法使用 ANTLR 4.6,它不会停止解析,它会解析整个文件并以粉红色显示解析器无法匹配的内容:
圆点代表空格。
还有一条重要的错误信息:
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'}
正如我解释的那样 一旦出现 "mismatched" 错误,请将 -tokens 添加到 g运行.
与"column a"*"column b"
:
$ grun Formula expr -tokens -diagnostics t1.text
[@0,0:0='"',<'"'>,1:0]
[@1,1:8='column a',<COLUMN>,1:1]
[@2,9:9='"',<'"'>,1:9]
[@3,10:10='*',<'*'>,1:10]
[@4,11:11='"',<'"'>,1:11]
[@5,12:19='column b',<COLUMN>,1:12]
[@6,20:20='"',<'"'>,1:20]
[@7,22:21='<EOF>',<EOF>,2:0]
与"column a" * "column b"
:
$ grun Formula expr -tokens -diagnostics t2.text
[@0,0:0='"',<'"'>,1:0]
[@1,1:8='column a',<COLUMN>,1:1]
[@2,9:9='"',<'"'>,1:9]
[@3,10:12=' * ',<COLUMN>,1:10]
[@4,13:13='"',<'"'>,1:13]
[@5,14:21='column b',<COLUMN>,1:14]
[@6,22:22='"',<'"'>,1:22]
[@7,24:23='<EOF>',<EOF>,2:0]
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'}
您会立即看到 " * "
被解释为 COLUMN
。
最近几天有人问了很多关于匹配输入与词法分析器规则的问题:
卢卡斯多次发布了一个错误的问题,只是为了做出一个总结所有问题的答案:。
我正在使用公式语法开发一个简单的计算器:
grammar Formula ;
expr : <assoc=right> expr POW expr # pow
| MINUS expr # unaryMinus
| PLUS expr # unaryPlus
| expr PERCENT # percent
| expr op=(MULTIPLICATION|DIVISION) expr # multiplyDivide
| expr op=(PLUS|MINUS) expr # addSubtract
| ABS '(' expr ')' # abs
| '|' expr '|' # absParenthesis
| MAX '(' expr ( ',' expr )* ')' # max
| MIN '(' expr ( ',' expr )* ')' # min
| '(' expr ')' # parenthesis
| NUMBER # number
| '"' COLUMN '"' # column
;
MULTIPLICATION: '*' ;
DIVISION: '/' ;
PLUS: '+' ;
MINUS: '-' ;
PERCENT: '%' ;
POW: '^' ;
ABS: [aA][bB][sS] ;
MAX: [mM][aA][xX] ;
MIN: [mM][iI][nN] ;
NUMBER: [0-9]+('.'[0-9]+)? ;
COLUMN: (~[\r\n"])+ ;
WS : [ \t\r\n]+ -> skip ;
"column a"*"column b"
输入按预期给了我以下树:
但是 "column a" * "column b"
输入意外停止解析:
我错过了什么?
您的 WS
规则被 COLUMN
规则打破,后者具有更高的 ~[\r\n"]
也匹配 space 个字符。
"column a"*"column b"
词法如下:'"'
COLUMN
'"'
MULTIPLICATION
'"'
COLUMN
'"'
"column a" * "column b"
词法如下:'"'
COLUMN
'"'
COLUMN
'"'
COLUMN
'"'
是的,“space star space”被词法化为 COLUMN
标记,因为这就是 ANTLR 词法分析器规则的工作方式:更长的标记匹配优先。
如您所见,此令牌流 不 匹配整个 expr
规则,因此 expr
尽可能多地匹配,这是 '"'
COLUMN
'"'
.
像您一样声明仅包含否定规则的词法分析器规则总是一个坏主意。拥有单独的 '"'
令牌也不适合我。
您应该做的是将引号包含在 COLUMN
规则中,因为它们在逻辑上是标记的一部分:
COLUMN: '"' (~["\r\n])* '"';
然后从您的解析器规则中删除独立引号。您可以稍后在处理解析树时取消对文本的引用,或者更改词法分析器中的令牌发射逻辑以更改令牌的基础值。
并且为了不忽略尾随输入,添加另一条规则以确保您已经消耗了整个输入:
formula: expr EOF;
然后在调用解析器时使用此规则而不是 expr
作为入口规则。
But "column a" * "column b" input unexpectedly stops parsing
如果我 运行 你的语法使用 ANTLR 4.6,它不会停止解析,它会解析整个文件并以粉红色显示解析器无法匹配的内容:
圆点代表空格。
还有一条重要的错误信息:
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'}
正如我解释的那样
与"column a"*"column b"
:
$ grun Formula expr -tokens -diagnostics t1.text
[@0,0:0='"',<'"'>,1:0]
[@1,1:8='column a',<COLUMN>,1:1]
[@2,9:9='"',<'"'>,1:9]
[@3,10:10='*',<'*'>,1:10]
[@4,11:11='"',<'"'>,1:11]
[@5,12:19='column b',<COLUMN>,1:12]
[@6,20:20='"',<'"'>,1:20]
[@7,22:21='<EOF>',<EOF>,2:0]
与"column a" * "column b"
:
$ grun Formula expr -tokens -diagnostics t2.text
[@0,0:0='"',<'"'>,1:0]
[@1,1:8='column a',<COLUMN>,1:1]
[@2,9:9='"',<'"'>,1:9]
[@3,10:12=' * ',<COLUMN>,1:10]
[@4,13:13='"',<'"'>,1:13]
[@5,14:21='column b',<COLUMN>,1:14]
[@6,22:22='"',<'"'>,1:22]
[@7,24:23='<EOF>',<EOF>,2:0]
line 1:10 mismatched input ' * ' expecting {<EOF>, '*', '/', '+', '-', '%', '^'}
您会立即看到 " * "
被解释为 COLUMN
。
最近几天有人问了很多关于匹配输入与词法分析器规则的问题:
卢卡斯多次发布了一个错误的问题,只是为了做出一个总结所有问题的答案: