| @@ -479,7 +479,7 @@ class Grammar: | |||||
| # =================== | # =================== | ||||
| # Convert terminal-trees to strings/regexps | # Convert terminal-trees to strings/regexps | ||||
| transformer = PrepareLiterals() * TerminalTreeToPattern() | |||||
| for name, (term_tree, priority) in term_defs: | for name, (term_tree, priority) in term_defs: | ||||
| if term_tree is None: # Terminal added through %declare | if term_tree is None: # Terminal added through %declare | ||||
| continue | continue | ||||
| @@ -487,7 +487,8 @@ class Grammar: | |||||
| if len(expansions) == 1 and not expansions[0].children: | if len(expansions) == 1 and not expansions[0].children: | ||||
| raise GrammarError("Terminals cannot be empty (%s)" % name) | raise GrammarError("Terminals cannot be empty (%s)" % name) | ||||
| terminals = [TerminalDef(name, transformer.transform(term_tree), priority) | |||||
| transformer = PrepareLiterals() * TerminalTreeToPattern() | |||||
| terminals = [TerminalDef(name, transformer.transform( term_tree ), priority) | |||||
| for name, (term_tree, priority) in term_defs if term_tree] | for name, (term_tree, priority) in term_defs if term_tree] | ||||
| # ================= | # ================= | ||||
| @@ -638,11 +639,10 @@ def import_from_grammar_into_namespace(grammar, namespace, aliases): | |||||
| def resolve_term_references(term_defs): | def resolve_term_references(term_defs): | ||||
| # TODO Cycles detection | |||||
| # TODO Solve with transitive closure (maybe) | # TODO Solve with transitive closure (maybe) | ||||
| token_dict = {k:t for k, (t,_p) in term_defs} | |||||
| assert len(token_dict) == len(term_defs), "Same name defined twice?" | |||||
| term_dict = {k:t for k, (t,_p) in term_defs} | |||||
| assert len(term_dict) == len(term_defs), "Same name defined twice?" | |||||
| while True: | while True: | ||||
| changed = False | changed = False | ||||
| @@ -655,11 +655,19 @@ def resolve_term_references(term_defs): | |||||
| if item.type == 'RULE': | if item.type == 'RULE': | ||||
| raise GrammarError("Rules aren't allowed inside terminals (%s in %s)" % (item, name)) | raise GrammarError("Rules aren't allowed inside terminals (%s in %s)" % (item, name)) | ||||
| if item.type == 'TERMINAL': | if item.type == 'TERMINAL': | ||||
| exp.children[0] = token_dict[item] | |||||
| term_value = term_dict[item] | |||||
| exp.children[0] = term_value | |||||
| changed = True | changed = True | ||||
| if not changed: | if not changed: | ||||
| break | break | ||||
| for name, term in term_dict.items(): | |||||
| for child in term.children: | |||||
| ids = [id(x) for x in child.iter_subtrees()] | |||||
| if id(term) in ids: | |||||
| raise GrammarError("Recursion in terminal '%s' (recursion is only allowed in rules, not terminals)" % name) | |||||
| def options_from_rule(name, *x): | def options_from_rule(name, *x): | ||||
| if len(x) > 1: | if len(x) > 1: | ||||
| priority, expansions = x | priority, expansions = x | ||||