2016-09-12 2 views
1
parenthésées

En search_query.ebnf, j'ai la définition de la grammaire suivante pour grako 3.14.0:« FailedParse: [...] Attendons la fin du texte » lorsque vous essayez d'analyser les expressions dans grako

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

je produis l'analyseur avec

grako search_query.ebnf --outfile search_query_parser.py 

Le résultat fonctionne comme je m'y attendais pour ces entrées:

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

mais si j'ai une expression parenthésée à la droite d'un opérateur, l'analyseur me donne un message d'erreur:

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 

Est-ce que je fais quelque chose de mal?

Répondre

1

Est-ce que je fais quelque chose de mal?

Je ne pense pas.

Cela ressemble à un known bug dans grako concernant "la récursivité gauche".

La solution mentionnée dans le bug semble fonctionner pour votre cas aussi:

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

dire mentionner explicitement search_term dans les parenthèses, même si la règle search_query devrait être en mesure de produire aussi.

+0

Il s'agit d'un bug connu dans la gestion par Grako de la récursion gauche (indirecte). – Apalala

+0

@Apalala N'est-ce pas ce que j'ai écrit? (Ou est-ce que je me trompe de phrasé?) Je ne suis pas très familier avec le jargon grammatical/grammatical en anglais.) –

+0

Je ne faisais que réaffirmer ce que vous avez écrit. Je suis l'auteur de Grako. – Apalala