| @@ -73,6 +73,8 @@ TERMINALS = { | |||||
| '_RPAR': r'\)', | '_RPAR': r'\)', | ||||
| '_LBRA': r'\[', | '_LBRA': r'\[', | ||||
| '_RBRA': r'\]', | '_RBRA': r'\]', | ||||
| '_LBRACE': r'\{', | |||||
| '_RBRACE': r'\}', | |||||
| 'OP': '[+*]|[?](?![a-z])', | 'OP': '[+*]|[?](?![a-z])', | ||||
| '_COLON': ':', | '_COLON': ':', | ||||
| '_COMMA': ',', | '_COMMA': ',', | ||||
| @@ -97,7 +99,13 @@ TERMINALS = { | |||||
| RULES = { | RULES = { | ||||
| 'start': ['_list'], | 'start': ['_list'], | ||||
| '_list': ['_item', '_list _item'], | '_list': ['_item', '_list _item'], | ||||
| '_item': ['rule', 'term', 'statement', '_NL'], | |||||
| '_item': ['rule', 'rule_template', 'term', 'statement', '_NL'], | |||||
| 'template': ['RULE _LBRACE template_params _RBRACE _COLON expansions _NL', | |||||
| 'RULE _LBRACE template_params _RBRACE _DOT NUMBER _COLON expansions _NL'], | |||||
| 'template_params': ['RULE', | |||||
| 'template_params _COMMA RULE'], | |||||
| 'rule': ['RULE _COLON expansions _NL', | 'rule': ['RULE _COLON expansions _NL', | ||||
| 'RULE _DOT NUMBER _COLON expansions _NL'], | 'RULE _DOT NUMBER _COLON expansions _NL'], | ||||
| @@ -123,7 +131,8 @@ RULES = { | |||||
| 'value': ['terminal', | 'value': ['terminal', | ||||
| 'nonterminal', | 'nonterminal', | ||||
| 'literal', | 'literal', | ||||
| 'range'], | |||||
| 'range', | |||||
| 'template_usage'], | |||||
| 'terminal': ['TERMINAL'], | 'terminal': ['TERMINAL'], | ||||
| 'nonterminal': ['RULE'], | 'nonterminal': ['RULE'], | ||||
| @@ -132,9 +141,13 @@ RULES = { | |||||
| 'maybe': ['_LBRA expansions _RBRA'], | 'maybe': ['_LBRA expansions _RBRA'], | ||||
| 'range': ['STRING _DOTDOT STRING'], | 'range': ['STRING _DOTDOT STRING'], | ||||
| 'template_usage': ['RULE _LBRACE template_args _RBRACE'], | |||||
| 'template_args': ['atom', | |||||
| 'template_args _COMMA atom'], | |||||
| 'term': ['TERMINAL _COLON expansions _NL', | 'term': ['TERMINAL _COLON expansions _NL', | ||||
| 'TERMINAL _DOT NUMBER _COLON expansions _NL'], | |||||
| 'TERMINAL _DOT NUMBER _COLON expansions _NL'], | |||||
| 'statement': ['ignore', 'import', 'declare'], | 'statement': ['ignore', 'import', 'declare'], | ||||
| 'ignore': ['_IGNORE expansions _NL'], | 'ignore': ['_IGNORE expansions _NL'], | ||||
| 'declare': ['_DECLARE _declare_args _NL'], | 'declare': ['_DECLARE _declare_args _NL'], | ||||
| @@ -648,8 +661,8 @@ def resolve_term_references(term_defs): | |||||
| raise GrammarError("Recursion in terminal '%s' (recursion is only allowed in rules, not terminals)" % name) | raise GrammarError("Recursion in terminal '%s' (recursion is only allowed in rules, not terminals)" % name) | ||||
| def options_from_rule(name, *x): | |||||
| if len(x) > 1: | |||||
| def options_from_rule(name, *x,is_template=False): | |||||
| if len(x) > (1+is_template): | |||||
| priority, expansions = x | priority, expansions = x | ||||
| priority = int(priority) | priority = int(priority) | ||||
| else: | else: | ||||
| @@ -728,12 +741,14 @@ class GrammarLoader: | |||||
| defs = classify(tree.children, lambda c: c.data, lambda c: c.children) | defs = classify(tree.children, lambda c: c.data, lambda c: c.children) | ||||
| term_defs = defs.pop('term', []) | term_defs = defs.pop('term', []) | ||||
| rule_defs = defs.pop('rule', []) | rule_defs = defs.pop('rule', []) | ||||
| template_defs = defs.pop('template', []) | |||||
| statements = defs.pop('statement', []) | statements = defs.pop('statement', []) | ||||
| assert not defs | assert not defs | ||||
| term_defs = [td if len(td)==3 else (td[0], 1, td[1]) for td in term_defs] | term_defs = [td if len(td)==3 else (td[0], 1, td[1]) for td in term_defs] | ||||
| term_defs = [(name.value, (t, int(p))) for name, p, t in term_defs] | term_defs = [(name.value, (t, int(p))) for name, p, t in term_defs] | ||||
| rule_defs = [options_from_rule(*x) for x in rule_defs] | rule_defs = [options_from_rule(*x) for x in rule_defs] | ||||
| template_defs = [options_from_rule(*x, is_template=True) for x in rule_defs] | |||||
| # Execute statements | # Execute statements | ||||
| ignore, imports = [], {} | ignore, imports = [], {} | ||||