"FailedParse: [...] Expecting end of text" when trying to parse parenthesized expressions in grako
<p>In <code>search_query.ebnf</code>, I have the following grammar definition for <code>grako</code> 3.14.0:</p>

<pre class="lang-none prettyprint-override"><code>@@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 = '&amp;' | '|';
search_term = /\w+/;
</code></pre>

<p>I generate the parser with
</p>

<pre><code>grako search_query.ebnf --outfile search_query_parser.py
</code></pre>

<p>The result works as I expected for these inputs:</p>

<pre><code>import search_query_parser

parser = search_query_parser.SearchQueryParser()
parser.parse('a')  # -&gt; 'a'
parser.parse('(a)')  # -&gt; ['(', 'a', ')']
parser.parse('a &amp; b')  # -&gt; ['a', '&amp;', 'b']
parser.parse('a | b')  # -&gt; ['a', '|', 'b']
parser.parse('(a|b)&amp;c')  # -&gt; ['(', ['a', '|', 'b'], ')', '&amp;', 'c']
</code></pre>

<p>but if I have a parenthesized expression at the right hand side of an operator, the parser gives me an error message:</p>

<pre><code>parser.parse('c&amp;(a|b)')
</code></pre>

<pre class="lang-none prettyprint-override"><code>Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
  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&amp;(a|b)
 ^
start
</code></pre>

<p>Am I doing something wrong?</p>

<blockquote>
  <p>Am I doing something wrong?</p>
</blockquote>

<p>I don't think so.</p>

<p>This looks like a <a href="https://bitbucket.org/apalala/grako/issues/81/left-recursion" rel="nofollow">known bug</a> in <code>grako</code> concerning "left recursion".</p>

<p>The workaround mentioned in the bug seems to work for your case, too:</p>

<pre class="lang-none prettyprint-override"><code>@@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 = '&amp;' | '|';
search_term = /\w+/;
</code></pre>

<p>i.e. mention <code>search_term</code> explicitly inside the parentheses, even though the <code>search_query</code> rule should be able to produce it, too.</p>

python ebnf grako