"FailedParse: [...] Expecting end of text" when trying to parse parenthesized expressions in grako
Question: In `search_query.ebnf`, I have the following grammar definition for `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+/;
    

I generate the parser with

    
    
    grako search_query.ebnf --outfile search_query_parser.py
    

The result works as I expected for these inputs:

    
    
    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']
    

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

    
    
    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?


Answer: > Am I doing something wrong?

I don't think so.

This looks like a [known
bug](https://bitbucket.org/apalala/grako/issues/81/left-recursion) in `grako`
concerning "left recursion".

The workaround mentioned in the bug seems to work for your case, too:

    
    
    @@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+/;
    

i.e. mention `search_term` explicitly inside the parentheses, even though the
`search_query` rule should be able to produce it, too.

