Castle: The best Real-Time/Embedded/HighTech language EVER. Attempt 2
修订版 | 5b918e28475e9dac3e412ae971767e2bcd9a1ceb (tree) |
---|---|
时间 | 2022-04-23 06:25:53 |
作者 | Albert Mietus < albert AT mietus DOT nl > |
Commiter | Albert Mietus < albert AT mietus DOT nl > |
REFACTORED: Now we have a sub-package 'grammar' (in castle.reader.parser). It holds the (peg)grammar&vistitor to parser that chunk of of Castlee
@@ -1,63 +0,0 @@ | ||
1 | -from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF | |
2 | -from arpeggio import RegExMatch as _ | |
3 | -from arpeggio import ParserPython | |
4 | - | |
5 | - | |
6 | -def peg_grammar(): return rules, EOF | |
7 | -def rules(): return OneOrMore([parse_rule, setting]) | |
8 | -def parse_rule(): return rule_name, '<-', expression, ";" | |
9 | - | |
10 | -def expression(): return sequence, op_alternative | |
11 | -def sequence(): return OneOrMore(single_expr) | |
12 | -def single_expr(): return [ rule_crossref, term, group, predicate ], op_quantity | |
13 | - | |
14 | -def op_alternative(): return Optional( '|' , expression ) | |
15 | -def op_quantity(): return Optional([ '?' , '*' , '+' , '#' ]) | |
16 | - | |
17 | -def term(): return [ str_term, regex_term ] | |
18 | -def group(): return '(', expression, ')' | |
19 | -def predicate(): return ['&','!'], single_expr | |
20 | - | |
21 | -def str_term(): return [ (S3, str_no_s3, S3), | |
22 | - (D3, str_no_d3, D3), | |
23 | - (S1, str_no_s1, S1), | |
24 | - (D1, str_no_d1, D1) ] | |
25 | -def regex_term(): return [ (RE, re_no_slash, RE), | |
26 | - (REs3, str_no_s3, S3), | |
27 | - (REd3, str_no_d3, D3), | |
28 | - (REs1, str_no_s1, S1), | |
29 | - (REd1, str_no_d1, D1) ] | |
30 | - | |
31 | -def rule_name(): return ID | |
32 | -def rule_crossref(): return ID | |
33 | -def ID(): return _(r"[a-zA-Z_]([a-zA-Z_]|[0-9])*") | |
34 | - | |
35 | -def re_no_slash(): return _(r"((\\/)|[^\/])*") | |
36 | -def str_no_s1(): return _(r"((\\')|[^'\n])*") # Does NOT match multiline -- note 'multiline=False' is not the same | |
37 | -def str_no_d1(): return _(r'((\\")|[^"\n])*') # idem | |
38 | -def str_no_s3(): return _(r"([^']|('[^'])|(''[^']))*") # ALLOW multiline | |
39 | -def str_no_d3(): return _(r'''([^"]|("[^"])|(""[^"]))*''') # idem | |
40 | - | |
41 | -def setting(): return setting_name, '=', value, ';' | |
42 | -def setting_name(): return ID | |
43 | -def value(): return [ str_term, regex_term, number, setting_xref ] | |
44 | -def number(): return [ complex_lit, float_lit, int_lit ] | |
45 | -def setting_xref(): return ID | |
46 | -def complex_lit(): return _(r"[+-]?([0-9](\.[0-9]*)?)[+-][iIjJ]([0-9](\.[0-9]*)?)") | |
47 | -def float_lit(): return _(r"[+-]?[0-9]\.[0-9]+") | |
48 | -def int_lit(): return _(r"[+-]?[1-9][0-9]*") | |
49 | - | |
50 | - | |
51 | -S1 = "'" | |
52 | -D1 = '"' | |
53 | -S3 = "'''" | |
54 | -D3 = '"""' | |
55 | -RE = '/' | |
56 | -REs1 = _(r"[rR]'") | |
57 | -REd1 = _(r'[rR]"') | |
58 | -REs3 = _(r"[rR]'''") | |
59 | -REd3 = _(r'[rR]"""') | |
60 | - | |
61 | -def comment(): return ["#", '//'], _(".*\n") | |
62 | - | |
63 | - |
@@ -0,0 +1,6 @@ | ||
1 | +from .language import peg_grammar | |
2 | +from .language import comment | |
3 | + | |
4 | +from .visitor import PegVisitor | |
5 | +from .visitor import QuantityError, PredicateError | |
6 | + |
@@ -0,0 +1,61 @@ | ||
1 | +from arpeggio import Optional, ZeroOrMore, OneOrMore, EOF | |
2 | +from arpeggio import RegExMatch as _ | |
3 | +from arpeggio import ParserPython | |
4 | + | |
5 | + | |
6 | +def peg_grammar(): return rules, EOF | |
7 | +def rules(): return OneOrMore([parse_rule, setting]) | |
8 | +def parse_rule(): return rule_name, '<-', expression, ";" | |
9 | + | |
10 | +def expression(): return sequence, op_alternative | |
11 | +def sequence(): return OneOrMore(single_expr) | |
12 | +def single_expr(): return [ rule_crossref, term, group, predicate ], op_quantity | |
13 | + | |
14 | +def op_alternative(): return Optional( '|' , expression ) | |
15 | +def op_quantity(): return Optional([ '?' , '*' , '+' , '#' ]) | |
16 | + | |
17 | +def term(): return [ str_term, regex_term ] | |
18 | +def group(): return '(', expression, ')' | |
19 | +def predicate(): return ['&','!'], single_expr | |
20 | + | |
21 | +def str_term(): return [ (S3, str_no_s3, S3), | |
22 | + (D3, str_no_d3, D3), | |
23 | + (S1, str_no_s1, S1), | |
24 | + (D1, str_no_d1, D1) ] | |
25 | +def regex_term(): return [ (RE, re_no_slash, RE), | |
26 | + (REs3, str_no_s3, S3), | |
27 | + (REd3, str_no_d3, D3), | |
28 | + (REs1, str_no_s1, S1), | |
29 | + (REd1, str_no_d1, D1) ] | |
30 | + | |
31 | +def rule_name(): return ID | |
32 | +def rule_crossref(): return ID | |
33 | +def ID(): return _(r"[a-zA-Z_]([a-zA-Z_]|[0-9])*") | |
34 | + | |
35 | +def re_no_slash(): return _(r"((\\/)|[^\/])*") | |
36 | +def str_no_s1(): return _(r"((\\')|[^'\n])*") # Does NOT match multiline -- note 'multiline=False' is not the same | |
37 | +def str_no_d1(): return _(r'((\\")|[^"\n])*') # idem | |
38 | +def str_no_s3(): return _(r"([^']|('[^'])|(''[^']))*") # ALLOW multiline | |
39 | +def str_no_d3(): return _(r'''([^"]|("[^"])|(""[^"]))*''') # idem | |
40 | + | |
41 | +def setting(): return setting_name, '=', value, ';' | |
42 | +def setting_name(): return ID | |
43 | +def value(): return [ str_term, regex_term, number, setting_xref ] | |
44 | +def number(): return [ complex_lit, float_lit, int_lit ] | |
45 | +def setting_xref(): return ID | |
46 | +def complex_lit(): return _(r"[+-]?([0-9](\.[0-9]*)?)[+-][iIjJ]([0-9](\.[0-9]*)?)") | |
47 | +def float_lit(): return _(r"[+-]?[0-9]\.[0-9]+") | |
48 | +def int_lit(): return _(r"[+-]?[1-9][0-9]*") | |
49 | + | |
50 | + | |
51 | +S1 = "'" | |
52 | +D1 = '"' | |
53 | +S3 = "'''" | |
54 | +D3 = '"""' | |
55 | +RE = '/' | |
56 | +REs1 = _(r"[rR]'") | |
57 | +REd1 = _(r'[rR]"') | |
58 | +REs3 = _(r"[rR]'''") | |
59 | +REd3 = _(r'[rR]"""') | |
60 | + | |
61 | +def comment(): return ["#", '//'], _(".*\n") |
@@ -0,0 +1,133 @@ | ||
1 | +import arpeggio | |
2 | + | |
3 | +from castle.ast import grammar | |
4 | + | |
5 | +import logging;logger = logging.getLogger(__name__) | |
6 | +from typing import Union | |
7 | + | |
8 | +class QuantityError(ValueError): pass | |
9 | +class PredicateError(ValueError): pass | |
10 | + | |
11 | + | |
12 | +#NO_VISITOR_NEEDED: visit_str_no_s1 | |
13 | +#NO_VISITOR_NEEDED: visit_str_no_d1 | |
14 | +#NO_VISITOR_NEEDED: visit_str_no_s3 | |
15 | +#NO_VISITOR_NEEDED: visit_str_no_d3 | |
16 | +#NO_VISITOR_NEEDED: visit_comment | |
17 | +#NO_VISITOR_NEEDED: visit_ID | |
18 | +#NO_VISITOR_NEEDED: visit_term | |
19 | +#NO_VISITOR_NEEDED: visit_re_no_slash | |
20 | +#NO_VISITOR_NEEDED: visit_group | |
21 | +#NO_VISITOR_NEEDED: visit_op_quantity -- handled in visit_single_expr | |
22 | +#NO_VISITOR_NEEDED: visit_op_alternative -- handled in visit_expression | |
23 | +#NO_VISITOR_NEEDED: visit_complex_lit -- handled in visit_number | |
24 | +#NO_VISITOR_NEEDED: visit_float_lit -- handled in visit_number | |
25 | +#NO_VISITOR_NEEDED: visit_int_lit -- handled in visit_number | |
26 | +#NO_VISITOR_NEEDED: visit_value | |
27 | + | |
28 | + | |
29 | + | |
30 | +class PegVisitor(arpeggio.PTNodeVisitor): | |
31 | + def _logstr_node_children(self, node, children): | |
32 | + return f'>>{node}<< children[{len(children)}] >>' + ", ".join(f'{c}:{type(c).__name__}' for c in children) + '<<' | |
33 | + | |
34 | + def visit_str_term(self, node, children): | |
35 | + return grammar.StrTerm(value=node[1], parse_tree=node) | |
36 | + | |
37 | + def visit_regex_term(self, node, children): | |
38 | + return grammar.RegExpTerm(value=node[1], parse_tree=node) | |
39 | + | |
40 | + def visit_rule_name(self, node, children): | |
41 | + return grammar.ID(name=str(node), parse_tree=node) | |
42 | + | |
43 | + def visit_rule_crossref(self, node, children): | |
44 | + return grammar.ID(name=str(node), parse_tree=node) | |
45 | + | |
46 | + def visit_parse_rule(self, node, children): # Name '<-' expression ';' | |
47 | + return grammar.Rule(name=children[0],expr=children[1], parse_tree=node) | |
48 | + | |
49 | + | |
50 | + def visit_single_expr(self, node, children): # [ rule_crossref, term, group, predicate ], op_quantity | |
51 | + token_2_class = {'?': grammar.Optional, | |
52 | + '*': grammar.ZeroOrMore, | |
53 | + '+': grammar.OneOrMore, | |
54 | + '#': grammar.UnorderedGroup} | |
55 | + | |
56 | + if len(children) == 1: # No Optional part | |
57 | + logger.debug(f'visit_single_expr==1:: {getattr(children[0], "name", children[0])}:{type(children[0])}') | |
58 | + return children[0] | |
59 | + | |
60 | + elif len(children) == 2: # Optional part | |
61 | + logger.debug(f'visit_single_expr==2::Got: {children[0]}, {children[1]}') | |
62 | + expr = children[0] | |
63 | + token = str(children[1]) | |
64 | + quantum_cls = token_2_class.get(token) | |
65 | + if quantum_cls: | |
66 | + ast=quantum_cls(expr=expr, parse_tree=node) | |
67 | + logger.debug(f'visit_single_expr==2::Pass: {quantum_cls}(expr={expr})') | |
68 | + return ast | |
69 | + else: | |
70 | + raise QuantityError(f"token '{token}' not recognised") | |
71 | + else: # #children not in (1,2) | |
72 | + raise NotImplementedError("visit_single_expr, len>2") # -- Is this possible? | |
73 | + | |
74 | + | |
75 | + # expression <- sequence, op_alternative; op_alternative <- ('|' expression)? | |
76 | + def visit_expression(self, node, children) -> Union[grammar.Sequence, grammar.OrderedChoice]: | |
77 | + logger.debug('visit_expression::' + self._logstr_node_children(node, children)) | |
78 | + if len(children) == 1: #Only sequence | |
79 | + return children[0] | |
80 | + elif len(children) == 2: # So, having 1 or more alternatives in children[1] | |
81 | + # In all cased a (single) OrderedChoice with a list of alternatives should be returned. | |
82 | + if isinstance(children[1], grammar.OrderedChoice): | |
83 | + alternatives = [children[0]] + [alt for alt in children[1]] | |
84 | + else: | |
85 | + alternatives = children | |
86 | + return grammar.OrderedChoice(children = alternatives, parse_tree=node) | |
87 | + else: | |
88 | + raise NotImplementedError("visit_expression, len>2") | |
89 | + | |
90 | + | |
91 | + # OneOrMore(single_expr) | |
92 | + def visit_sequence(self, node, children) -> grammar.Sequence: | |
93 | + logger.debug(f'visit_sequence::{self._logstr_node_children(node, children)}') | |
94 | + return grammar.Sequence(children=children, parse_tree=node) | |
95 | + | |
96 | + | |
97 | + def visit_predicate(self, node, children): | |
98 | + token_2_predicate = {'&': grammar.AndPredicate, | |
99 | + '!': grammar.NotPredicate} | |
100 | + logger.debug(f'visit_predicate:: >>{node}<< #children={len(children)}') | |
101 | + | |
102 | + if len(children) == 2: | |
103 | + token = children[0] | |
104 | + cls = token_2_predicate.get(token) | |
105 | + if cls: | |
106 | + ast = cls(expr=children[1], parse_tree=node) | |
107 | + return ast | |
108 | + else: | |
109 | + raise PredicateError(f"token '{token}' not recognised") | |
110 | + else: | |
111 | + raise NotImplementedError("visit_predicate, len!=2") # -- Is this possible? | |
112 | + | |
113 | + | |
114 | + def visit_rules(self, node, children): # Mix of `ParseRule`(s)`Setting`(s) ; will be sorted out n `Grammar` | |
115 | + logger.debug('visit_rules::' + self._logstr_node_children(node, children)) | |
116 | + return grammar.Rules(children=children[:], parse_tree=node) | |
117 | + | |
118 | + | |
119 | + def visit_peg_grammar(self, node, children): | |
120 | + return grammar.Grammar(all_rules=children[0], parse_tree=node) | |
121 | + | |
122 | + def visit_setting_name(self, node, children): | |
123 | + return grammar.ID(name=str(node), parse_tree=node) | |
124 | + | |
125 | + def visit_number(self, node, children): | |
126 | + return grammar.Number(value=str(node), parse_tree=node) | |
127 | + | |
128 | + def visit_setting_xref(self, node, children): | |
129 | + return grammar.ID(name=str(node), parse_tree=node) | |
130 | + | |
131 | + def visit_setting(self, node, children): | |
132 | + logger.debug('visit_setting::' + self._logstr_node_children(node, children)) | |
133 | + return grammar.Setting(name=children[0], value=children[1] , parse_tree=node) |
@@ -1,133 +0,0 @@ | ||
1 | -import arpeggio | |
2 | - | |
3 | -from castle.ast import grammar | |
4 | - | |
5 | -import logging;logger = logging.getLogger(__name__) | |
6 | -from typing import Union | |
7 | - | |
8 | -class QuantityError(ValueError): pass | |
9 | -class PredicateError(ValueError): pass | |
10 | - | |
11 | - | |
12 | -#NO_VISITOR_NEEDED: visit_str_no_s1 | |
13 | -#NO_VISITOR_NEEDED: visit_str_no_d1 | |
14 | -#NO_VISITOR_NEEDED: visit_str_no_s3 | |
15 | -#NO_VISITOR_NEEDED: visit_str_no_d3 | |
16 | -#NO_VISITOR_NEEDED: visit_comment | |
17 | -#NO_VISITOR_NEEDED: visit_ID | |
18 | -#NO_VISITOR_NEEDED: visit_term | |
19 | -#NO_VISITOR_NEEDED: visit_re_no_slash | |
20 | -#NO_VISITOR_NEEDED: visit_group | |
21 | -#NO_VISITOR_NEEDED: visit_op_quantity -- handled in visit_single_expr | |
22 | -#NO_VISITOR_NEEDED: visit_op_alternative -- handled in visit_expression | |
23 | -#NO_VISITOR_NEEDED: visit_complex_lit -- handled in visit_number | |
24 | -#NO_VISITOR_NEEDED: visit_float_lit -- handled in visit_number | |
25 | -#NO_VISITOR_NEEDED: visit_int_lit -- handled in visit_number | |
26 | -#NO_VISITOR_NEEDED: visit_value | |
27 | - | |
28 | - | |
29 | - | |
30 | -class PegVisitor(arpeggio.PTNodeVisitor): | |
31 | - def _logstr_node_children(self, node, children): | |
32 | - return f'>>{node}<< children[{len(children)}] >>' + ", ".join(f'{c}:{type(c).__name__}' for c in children) + '<<' | |
33 | - | |
34 | - def visit_str_term(self, node, children): | |
35 | - return grammar.StrTerm(value=node[1], parse_tree=node) | |
36 | - | |
37 | - def visit_regex_term(self, node, children): | |
38 | - return grammar.RegExpTerm(value=node[1], parse_tree=node) | |
39 | - | |
40 | - def visit_rule_name(self, node, children): | |
41 | - return grammar.ID(name=str(node), parse_tree=node) | |
42 | - | |
43 | - def visit_rule_crossref(self, node, children): | |
44 | - return grammar.ID(name=str(node), parse_tree=node) | |
45 | - | |
46 | - def visit_parse_rule(self, node, children): # Name '<-' expression ';' | |
47 | - return grammar.Rule(name=children[0],expr=children[1], parse_tree=node) | |
48 | - | |
49 | - | |
50 | - def visit_single_expr(self, node, children): # [ rule_crossref, term, group, predicate ], op_quantity | |
51 | - token_2_class = {'?': grammar.Optional, | |
52 | - '*': grammar.ZeroOrMore, | |
53 | - '+': grammar.OneOrMore, | |
54 | - '#': grammar.UnorderedGroup} | |
55 | - | |
56 | - if len(children) == 1: # No Optional part | |
57 | - logger.debug(f'visit_single_expr==1:: {getattr(children[0], "name", children[0])}:{type(children[0])}') | |
58 | - return children[0] | |
59 | - | |
60 | - elif len(children) == 2: # Optional part | |
61 | - logger.debug(f'visit_single_expr==2::Got: {children[0]}, {children[1]}') | |
62 | - expr = children[0] | |
63 | - token = str(children[1]) | |
64 | - quantum_cls = token_2_class.get(token) | |
65 | - if quantum_cls: | |
66 | - ast=quantum_cls(expr=expr, parse_tree=node) | |
67 | - logger.debug(f'visit_single_expr==2::Pass: {quantum_cls}(expr={expr})') | |
68 | - return ast | |
69 | - else: | |
70 | - raise QuantityError(f"token '{token}' not recognised") | |
71 | - else: # #children not in (1,2) | |
72 | - raise NotImplementedError("visit_single_expr, len>2") # -- Is this possible? | |
73 | - | |
74 | - | |
75 | - # expression <- sequence, op_alternative; op_alternative <- ('|' expression)? | |
76 | - def visit_expression(self, node, children) -> Union[grammar.Sequence, grammar.OrderedChoice]: | |
77 | - logger.debug('visit_expression::' + self._logstr_node_children(node, children)) | |
78 | - if len(children) == 1: #Only sequence | |
79 | - return children[0] | |
80 | - elif len(children) == 2: # So, having 1 or more alternatives in children[1] | |
81 | - # In all cased a (single) OrderedChoice with a list of alternatives should be returned. | |
82 | - if isinstance(children[1], grammar.OrderedChoice): | |
83 | - alternatives = [children[0]] + [alt for alt in children[1]] | |
84 | - else: | |
85 | - alternatives = children | |
86 | - return grammar.OrderedChoice(children = alternatives, parse_tree=node) | |
87 | - else: | |
88 | - raise NotImplementedError("visit_expression, len>2") | |
89 | - | |
90 | - | |
91 | - # OneOrMore(single_expr) | |
92 | - def visit_sequence(self, node, children) -> grammar.Sequence: | |
93 | - logger.debug(f'visit_sequence::{self._logstr_node_children(node, children)}') | |
94 | - return grammar.Sequence(children=children, parse_tree=node) | |
95 | - | |
96 | - | |
97 | - def visit_predicate(self, node, children): | |
98 | - token_2_predicate = {'&': grammar.AndPredicate, | |
99 | - '!': grammar.NotPredicate} | |
100 | - logger.debug(f'visit_predicate:: >>{node}<< #children={len(children)}') | |
101 | - | |
102 | - if len(children) == 2: | |
103 | - token = children[0] | |
104 | - cls = token_2_predicate.get(token) | |
105 | - if cls: | |
106 | - ast = cls(expr=children[1], parse_tree=node) | |
107 | - return ast | |
108 | - else: | |
109 | - raise PredicateError(f"token '{token}' not recognised") | |
110 | - else: | |
111 | - raise NotImplementedError("visit_predicate, len!=2") # -- Is this possible? | |
112 | - | |
113 | - | |
114 | - def visit_rules(self, node, children): # Mix of `ParseRule`(s)`Setting`(s) ; will be sorted out n `Grammar` | |
115 | - logger.debug('visit_rules::' + self._logstr_node_children(node, children)) | |
116 | - return grammar.Rules(children=children[:], parse_tree=node) | |
117 | - | |
118 | - | |
119 | - def visit_peg_grammar(self, node, children): | |
120 | - return grammar.Grammar(all_rules=children[0], parse_tree=node) | |
121 | - | |
122 | - def visit_setting_name(self, node, children): | |
123 | - return grammar.ID(name=str(node), parse_tree=node) | |
124 | - | |
125 | - def visit_number(self, node, children): | |
126 | - return grammar.Number(value=str(node), parse_tree=node) | |
127 | - | |
128 | - def visit_setting_xref(self, node, children): | |
129 | - return grammar.ID(name=str(node), parse_tree=node) | |
130 | - | |
131 | - def visit_setting(self, node, children): | |
132 | - logger.debug('visit_setting::' + self._logstr_node_children(node, children)) | |
133 | - return grammar.Setting(name=children[0], value=children[1] , parse_tree=node) |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar, visitor | |
4 | +from castle.readers.parser import grammar | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | import arpeggio |
@@ -34,7 +34,7 @@ | ||
34 | 34 | parser = arpeggio.ParserPython(grammar.peg_grammar, comment_def = grammar.comment) |
35 | 35 | pt = parser.parse(txt) |
36 | 36 | logger.info(f"Reader:_do_parse::\t parse_tree: start={pt.position} end={pt.position_end}; len(txt)={len(txt)}") |
37 | - ast = arpeggio.visit_parse_tree(pt, visitor.PegVisitor()) | |
37 | + ast = arpeggio.visit_parse_tree(pt, grammar.PegVisitor()) | |
38 | 38 | logger.debug(f"Reader:_do_parse::\t ast: start={ast.position} end={ast.position_end} -- not counting comments.") |
39 | 39 | return ast |
40 | 40 |
@@ -1,7 +1,8 @@ | ||
1 | 1 | import logging;logger = logging.getLogger(__name__) |
2 | -from castle.readers.parser import grammar | |
2 | +import arpeggio | |
3 | 3 | |
4 | -import arpeggio | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | + | |
5 | 6 | |
6 | 7 | def parse(txt, grammer_rule): |
7 | 8 | logger.debug(f'>>{txt}<<') |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging;logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | 5 | |
6 | 6 | import arpeggio |
7 | 7 | RE, S = arpeggio.RegExMatch, arpeggio.StrMatch # shortcut |
@@ -1,7 +1,8 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging;logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | + | |
5 | 6 | |
6 | 7 | import arpeggio |
7 | 8 | RE, S = arpeggio.RegExMatch, arpeggio.StrMatch # shortcut |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging;logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | 5 | |
6 | 6 | import arpeggio |
7 | 7 |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging;logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | 5 | |
6 | 6 | import arpeggio |
7 | 7 | RE, S = arpeggio.RegExMatch, arpeggio.StrMatch # shortcut |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging;logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | 5 | |
6 | 6 | import arpeggio |
7 | 7 | RE, S = arpeggio.RegExMatch, arpeggio.StrMatch # shortcut |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging;logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar | |
4 | +from castle.readers.parser.grammar import language as grammar | |
5 | 5 | |
6 | 6 | import arpeggio |
7 | 7 | RE, S = arpeggio.RegExMatch, arpeggio.StrMatch # shortcut |
@@ -3,7 +3,8 @@ | ||
3 | 3 | from pathlib import Path |
4 | 4 | import os |
5 | 5 | |
6 | -from castle.readers.parser import grammar | |
6 | +from castle.readers.parser.grammar import language as grammar | |
7 | + | |
7 | 8 | import arpeggio |
8 | 9 | |
9 | 10 | def parse_file(filename, dir=Path('..')): |
@@ -2,20 +2,19 @@ | ||
2 | 2 | |
3 | 3 | import arpeggio |
4 | 4 | |
5 | -from castle.readers.parser import visitor | |
6 | -from castle.readers.parser import grammar as rules | |
5 | +from castle.readers.parser import grammar | |
7 | 6 | from castle.ast import grammar as AST |
8 | 7 | |
9 | 8 | def parse(txt, rule, *, |
10 | 9 | with_comments=False, |
11 | 10 | visitor_debug=False): |
12 | 11 | |
13 | - parser = arpeggio.ParserPython(rule, comment_def = rules.comment if with_comments else None) | |
12 | + parser = arpeggio.ParserPython(rule, comment_def = grammar.comment if with_comments else None) | |
14 | 13 | pt = parser.parse(txt) |
15 | 14 | logger.debug('PARSE_TREE\n'+pt.tree_str()) |
16 | 15 | assert pt.position_end == len(txt), f"Did not parse all input txt=>>{txt}<<len={len(txt)} ==> parse_tree: >>{pt}<<_end={pt.position_end}" |
17 | 16 | |
18 | - ast = arpeggio.visit_parse_tree(pt, visitor.PegVisitor(debug=visitor_debug)) | |
17 | + ast = arpeggio.visit_parse_tree(pt, grammar.PegVisitor(debug=visitor_debug)) | |
19 | 18 | logger.debug('AST\n' + f'{ast}:{type(ast).__name__}') |
20 | 19 | |
21 | 20 | if with_comments: # When the txt starts with comments, the AST does start 'after' that comment -- so skip the start-check |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar as rules | |
4 | +from castle.readers.parser.grammar import language as rules | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | from . import parse |
@@ -1,6 +1,6 @@ | ||
1 | 1 | import pytest |
2 | 2 | |
3 | -from castle.readers.parser import grammar as rules | |
3 | +from castle.readers.parser.grammar import language as rules | |
4 | 4 | from castle.ast import grammar as AST |
5 | 5 | |
6 | 6 | from . import parse, assert_ID |
@@ -4,7 +4,7 @@ | ||
4 | 4 | import pytest |
5 | 5 | import logging; logger = logging.getLogger(__name__) |
6 | 6 | |
7 | -from castle.readers.parser import grammar as rules | |
7 | +from castle.readers.parser.grammar import language as rules | |
8 | 8 | from castle.ast import grammar as AST |
9 | 9 | |
10 | 10 | from . import parse, assert_ID, assert_Seq |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar as rules | |
4 | +from castle.readers.parser.grammar import language as rules | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | from . import parse, assert_ID, assert_Seq, assert_ParseRule |
@@ -1,6 +1,6 @@ | ||
1 | 1 | import pytest |
2 | 2 | |
3 | -from castle.readers.parser import grammar as rules | |
3 | +from castle.readers.parser.grammar import language as rules | |
4 | 4 | from castle.ast import grammar as AST |
5 | 5 | |
6 | 6 | from . import parse, assert_Setting |
@@ -3,7 +3,7 @@ | ||
3 | 3 | import pytest |
4 | 4 | import logging; logger = logging.getLogger(__name__) |
5 | 5 | |
6 | -from castle.readers.parser import grammar as rules | |
6 | +from castle.readers.parser.grammar import language as rules | |
7 | 7 | from castle.ast import grammar as AST |
8 | 8 | |
9 | 9 | from . import parse, assert_ID |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar as rules | |
4 | +from castle.readers.parser.grammar import language as rules | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | from . import parse, assert_ID, assert_ParseRule, assert_Seq |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar as rules | |
4 | +from castle.readers.parser.grammar import language as rules | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | from . import parse, assert_ID, precondition_ID, precondition_Expressions |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar as rules | |
4 | +from castle.readers.parser.grammar import language as rules | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | from . import parse, assert_Rule, assert_ParseRule, assert_Setting |
@@ -1,7 +1,7 @@ | ||
1 | 1 | import pytest |
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | -from castle.readers.parser import grammar as rules | |
4 | +from castle.readers.parser.grammar import language as rules | |
5 | 5 | from castle.ast import grammar as AST |
6 | 6 | |
7 | 7 | from . import parse, assert_PEG |
@@ -3,8 +3,7 @@ | ||
3 | 3 | from pathlib import Path |
4 | 4 | import os |
5 | 5 | |
6 | -from castle.readers.parser import grammar as rules | |
7 | - | |
6 | +from castle.readers.parser.grammar import language as rules | |
8 | 7 | |
9 | 8 | from . import parse, assert_PEG |
10 | 9 |
@@ -2,13 +2,13 @@ | ||
2 | 2 | import logging; logger = logging.getLogger(__name__) |
3 | 3 | |
4 | 4 | from castle.readers.parser import FileParser |
5 | -from castle.readers.parser import grammar, visitor | |
5 | +from castle.readers.parser import grammar | |
6 | 6 | |
7 | 7 | |
8 | 8 | def test_file(): |
9 | 9 | reader = FileParser(language_def=grammar.peg_grammar, |
10 | 10 | comment_def=grammar.comment, |
11 | - visitor=visitor.PegVisitor(), | |
11 | + visitor=grammar.PegVisitor(), | |
12 | 12 | read_dirs=('../../../demos/ThinOnion', |
13 | 13 | '../../.././demos/ThinOnion/grammar', |
14 | 14 | '../../.././pytst/readers/parser')) |