Castle: The best Real-Time/Embedded/HighTech language EVER. Attempt 2
Revisión | 6992b47c96dc5027614e470b2482fbcd0894013f (tree) |
---|---|
Tiempo | 2022-02-08 02:48:05 |
Autor | Albert Mietus < albert AT mietus DOT nl > |
Commiter | Albert Mietus < albert AT mietus DOT nl > |
code specific for ast2xml not longer in generic serialization-file (now with new file)
@@ -0,0 +1,89 @@ | ||
1 | +""" Support to translate an AST into XML. | |
2 | +This file should be used directly, instead use :class:`castle.ast.serialization.Serialize` as in ``Serialize('XML')`` | |
3 | +""" | |
4 | + | |
5 | +import logging; logger = logging.getLogger(__name__) | |
6 | +from castle.ast import serialization | |
7 | +from xml.etree import ElementTree as ET | |
8 | + | |
9 | + | |
10 | +class XML_Serialize(serialization.Serialize): | |
11 | + def serialize(self, ast) -> str: | |
12 | + logger.debug(f"ast={ast._valType(ast)}") | |
13 | + | |
14 | + tree = self._ast2xml(ast) | |
15 | + return ET.tostring(tree, encoding="unicode") | |
16 | + | |
17 | + | |
18 | + def _ast2xml(self, ast, parent=None) -> ET.Element: | |
19 | + if parent is None: | |
20 | + parent = ET.Element('AST2XML', version="0.0") | |
21 | + | |
22 | + method_name = f'{type(ast).__name__}2xml' | |
23 | + visitor = getattr(self, method_name, None) | |
24 | + logger.debug(f'visitor={visitor}') | |
25 | + | |
26 | + if visitor: | |
27 | + visitor(ast=ast, parent=parent) # Grow the tree | |
28 | + else: | |
29 | + logger.info(f'No visitor >>{method_name}<<, skipping ... (fingers crossed)') | |
30 | + return parent | |
31 | + | |
32 | + | |
33 | + def ID2xml(self, ast, parent) ->None: | |
34 | + logger.debug(f"ast={ast._valType(ast)} parent={parent} ast.name={ast.name}") | |
35 | + ET.SubElement(parent, 'ID', name=ast.name) | |
36 | + | |
37 | + | |
38 | +#NO_VISITOR_NEEDED: PEG2xml ## Pure Abstract | |
39 | +#NO_VISITOR_NEEDED: MixIn_value_attribute2xml ## MixIn | |
40 | +#NO_VISITOR_NEEDED: MixIn_expr_attribute2xml ## MixIn | |
41 | +#NO_VISITOR_NEEDED: MixIn_children_tuple2xml ## MixIn | |
42 | +#NO_VISITOR_NEEDED: Terminal2xml ## Pure Abstract | |
43 | +#NO_VISITOR_NEEDED: NonTerminal2xml ## Pure Abstract | |
44 | +#NO_VISITOR_NEEDED: Expression2xml ## Pure Abstract | |
45 | +#NO_VISITOR_NEEDED: Predicate2xml ## Pure Abstract | |
46 | +#NO_VISITOR_NEEDED: Group2xml ## Pure Abstract | |
47 | +#NO_VISITOR_NEEDED: Markers2xml ## Pure Abstract | |
48 | + | |
49 | + | |
50 | + def _MixIn_value_attribute2xml(self, ast, parent, cls_name): | |
51 | + logger.debug(f"{cls_name}2xml:: ast={ast._valType(ast.value)}") | |
52 | + ET.SubElement(parent, cls_name, value=ast.value) | |
53 | + | |
54 | + def StrTerm2xml(self, ast, parent): self._MixIn_value_attribute2xml(ast, parent, 'StrTerm') | |
55 | + def RegExpTerm2xml(self, ast, parent): self._MixIn_value_attribute2xml(ast, parent, 'RegExpTerm') | |
56 | + | |
57 | + def Sequence2xml(self, ast, parent) ->None: | |
58 | + logger.debug(f"Sequence2xml::ast={ast._valType(ast.value)}") | |
59 | + seq = ET.SubElement(parent, 'Sequence') | |
60 | + for elm in ast.value: | |
61 | + self._ast2xml(elm, parent=seq) | |
62 | + | |
63 | + def Rule2xml(self, ast, parent) ->None: | |
64 | + logger.debug(f"Rule2xml:: ast:Rule.name={ast.name.name}") | |
65 | + rule = ET.SubElement(parent, 'Rule', name=ast.name.name) | |
66 | + self._ast2xml(ast.expr, parent=rule) | |
67 | + | |
68 | + def Rules2xml(self, ast, parent) ->None: | |
69 | + logger.debug(f"Rules2xml:: ast[{len(ast)}]") | |
70 | + for child in ast: | |
71 | + logger.debug(f'Rules2xml type(child)={type(child)}') | |
72 | + self._ast2xml(child, parent=parent) | |
73 | + | |
74 | +############# | |
75 | + | |
76 | +# def Setting2xml(self, ast, parent) ->None: ... | |
77 | +# def Settings2xml(self, ast, parent) ->None: ... | |
78 | +# def Grammar2xml(self, ast, parent) ->None: ... | |
79 | +# def UnorderedGroup2xml(self, ast, parent) ->None: ... | |
80 | +# def Quantity2xml(self, ast, parent) ->None: ... | |
81 | + | |
82 | +# def OrderedChoice2xml(self, ast, parent) ->None: ... | |
83 | +# def Optional2xml(self, ast, parent) ->None: ... | |
84 | +# def ZeroOrMore2xml(self, ast, parent) ->None: ... | |
85 | +# def OneOrMore2xml(self, ast, parent) ->None: ... | |
86 | +# def AndPredicate2xml(self, ast, parent) ->None: ... | |
87 | +# def NotPredicate2xml(self, ast, parent) ->None: ... | |
88 | + | |
89 | +# def EOF2xml(self, ast, parent) ->None: pass # Needed |