"FailedParse: [...] Expecting end of text" 尝试解析 grako 中带括号的表达式时
"FailedParse: [...] Expecting end of text" when trying to parse parenthesized expressions in grako
在 search_query.ebnf
中,我对 grako
3.14.0 有以下语法定义:
@@grammar :: SearchQuery
start = search_query $;
search_query = parenthesized_query | combined_query | search_term;
parenthesized_query = '(' search_query ')';
combined_query = search_query binary_operator search_query;
binary_operator = '&' | '|';
search_term = /\w+/;
我生成解析器
grako search_query.ebnf --outfile search_query_parser.py
这些输入的结果符合我的预期:
import search_query_parser
parser = search_query_parser.SearchQueryParser()
parser.parse('a') # -> 'a'
parser.parse('(a)') # -> ['(', 'a', ')']
parser.parse('a & b') # -> ['a', '&', 'b']
parser.parse('a | b') # -> ['a', '|', 'b']
parser.parse('(a|b)&c') # -> ['(', ['a', '|', 'b'], ')', '&', 'c']
但是如果我在运算符的右侧有一个带括号的表达式,解析器会给我一条错误消息:
parser.parse('c&(a|b)')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/search_query_parser.py", line 82, in parse
return super(SearchQueryParser, self).parse(text, *args, **kwargs)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 227, in parse
result = rule()
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 86, in wrapper
return self._call(rule, name, params, kwparams)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 475, in _call
node, newpos, newstate = self._invoke_rule(rule, name, params, kwparams)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 511, in _invoke_rule
rule(self)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/search_query_parser.py", line 87, in _start_
self._check_eof()
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 650, in _check_eof
self._error('Expecting end of text.')
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 450, in _error
item
grako.exceptions.FailedParse: (1:2) Expecting end of text. :
c&(a|b)
^
start
我是不是做错了什么?
Am I doing something wrong?
我不这么认为。
这看起来像 grako
中关于 "left recursion" 的 known bug。
错误中提到的解决方法似乎也适用于您的情况:
@@grammar :: SearchQuery
start = search_query $;
search_query = parenthesized_query | combined_query | search_term;
parenthesized_query = '(' search_query | search_term ')'; ## Workaround
combined_query = search_query binary_operator search_query;
binary_operator = '&' | '|';
search_term = /\w+/;
即在括号内明确提及 search_term
,即使 search_query
规则也应该能够产生它。
在 search_query.ebnf
中,我对 grako
3.14.0 有以下语法定义:
@@grammar :: SearchQuery
start = search_query $;
search_query = parenthesized_query | combined_query | search_term;
parenthesized_query = '(' search_query ')';
combined_query = search_query binary_operator search_query;
binary_operator = '&' | '|';
search_term = /\w+/;
我生成解析器
grako search_query.ebnf --outfile search_query_parser.py
这些输入的结果符合我的预期:
import search_query_parser
parser = search_query_parser.SearchQueryParser()
parser.parse('a') # -> 'a'
parser.parse('(a)') # -> ['(', 'a', ')']
parser.parse('a & b') # -> ['a', '&', 'b']
parser.parse('a | b') # -> ['a', '|', 'b']
parser.parse('(a|b)&c') # -> ['(', ['a', '|', 'b'], ')', '&', 'c']
但是如果我在运算符的右侧有一个带括号的表达式,解析器会给我一条错误消息:
parser.parse('c&(a|b)')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/search_query_parser.py", line 82, in parse
return super(SearchQueryParser, self).parse(text, *args, **kwargs)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 227, in parse
result = rule()
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 86, in wrapper
return self._call(rule, name, params, kwparams)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 475, in _call
node, newpos, newstate = self._invoke_rule(rule, name, params, kwparams)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 511, in _invoke_rule
rule(self)
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/search_query_parser.py", line 87, in _start_
self._check_eof()
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 650, in _check_eof
self._error('Expecting end of text.')
File "/home/das-g/.virtualenvs/tmp-d0fd5a9428f7612a/lib/python3.5/site-packages/grako/contexts.py", line 450, in _error
item
grako.exceptions.FailedParse: (1:2) Expecting end of text. :
c&(a|b)
^
start
我是不是做错了什么?
Am I doing something wrong?
我不这么认为。
这看起来像 grako
中关于 "left recursion" 的 known bug。
错误中提到的解决方法似乎也适用于您的情况:
@@grammar :: SearchQuery
start = search_query $;
search_query = parenthesized_query | combined_query | search_term;
parenthesized_query = '(' search_query | search_term ')'; ## Workaround
combined_query = search_query binary_operator search_query;
binary_operator = '&' | '|';
search_term = /\w+/;
即在括号内明确提及 search_term
,即使 search_query
规则也应该能够产生它。