• R/O
  • SSH

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Castle: The best Real-Time/Embedded/HighTech language EVER. Attempt 2


Commit MetaInfo

Revision2383f011abe75da952ca8a9775e3f8912accacdb (tree)
Time2022-01-29 05:18:19
AuthorAlbert Mietus < albert AT mietus DOT nl >
CommiterAlbert Mietus < albert AT mietus DOT nl >

Log Message

Started with AST-2-XML serialization

Change Summary

Incremental Difference

diff -r 819aed921de1 -r 2383f011abe7 castle/ast/_base.py
--- a/castle/ast/_base.py Wed Jan 26 18:17:36 2022 +0100
+++ b/castle/ast/_base.py Fri Jan 28 21:18:19 2022 +0100
@@ -1,3 +1,7 @@
1+from .serialization import Serialize
2+
3+
4+
15 class AST_BASE:
26 """Base class for all Castle ATS nodes"""
37
@@ -9,26 +13,31 @@
913 def __str__(self): # mostly for debugging
1014 return str(type(self).__name__) + "\n\t" + "\n\t".join(f'{n}\t{str(v)}:{type(v).__name__}' for n,v in self.__dict__.items() if n[0]!='_')
1115
12- @staticmethod
13- def _typeName(x):
14- return type(x).__name__
15-
16- def _valType(self, x):
17- return f'{x}:{self._typeName(x)}'
18- return type(x).__name__
16+ def serialize(self, strategy="XML") -> str:
17+ return Serialize(strategy).serialize(self)
1918
2019 @property
2120 def position(self): return self._parse_tree.position
2221 @property
2322 def position_end(self): return self._parse_tree.position_end
2423
24+ ### Mostly for debugging
25+ @staticmethod
26+ def _typeName(of):
27+ return type(of).__name__
28+
29+ def _valType(self, of:None):
30+ if not of: of=self
31+ return f'{of}:{self._typeName(of)}'
32+
2533
2634 class IDError(ValueError):
2735 "The given ID is not valid as an ID"
2836
29-import re
37+
3038
3139 class ID(AST_BASE):
40+ import re
3241 _pattern = re.compile(r'[A-Za-z_][A-Za-z0-9_]*')
3342
3443 @staticmethod
diff -r 819aed921de1 -r 2383f011abe7 castle/ast/serialization.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/castle/ast/serialization.py Fri Jan 28 21:18:19 2022 +0100
@@ -0,0 +1,86 @@
1+import logging; logger = logging.getLogger(__name__)
2+
3+class Serialize ():
4+ def __new__(cls, strategy=None):
5+ if strategy is None:
6+ return object.__new__(cls)
7+ if str(strategy).upper() == "XML":
8+ return XML_Serialize()
9+ else:
10+ raise NotImplementedError(f"No Serializer of {strategy} available")
11+
12+ def serialize(self, ast):
13+ raise NotImplementedError(f"Implement in subclass")
14+
15+from xml.etree import ElementTree as ET
16+
17+
18+class XML_Serialize(Serialize):
19+ def serialize(self, ast) -> str:
20+ logger.debug(f"ast={ast._valType(ast)}")
21+
22+ tree = self._ast2xml(ast)
23+ return ET.tostring(tree, encoding="unicode")
24+
25+
26+ def _ast2xml(self, ast) -> ET.Element:
27+ top = ET.Element('AST2XML', version="0.0")
28+
29+ method_name = f'{type(ast).__name__}2xml'
30+ visitor = getattr(self, method_name, None)
31+ logger.debug(f'visitor={visitor}')
32+
33+ if visitor:
34+ visitor(ast=ast, parent=top) # Grow the tree
35+ else:
36+ logger.info(f'No visitor >>{method_name}<<, skipping ... (fingers crossed)')
37+
38+ logger.debug(f"XXX top={top}")
39+ return top
40+
41+
42+ def ID2xml(self, ast, parent) ->None:
43+ logger.debug(f"ast={ast._valType(ast)} parent={parent} ast.name={ast.name}")
44+ ET.SubElement(parent, 'ID', name=ast.name)
45+
46+
47+#NO_VISITOR_NEEDED: PEG2xml ## Pure Abstract
48+#NO_VISITOR_NEEDED: MixIn_value_attribute2xml ## MixIn
49+#NO_VISITOR_NEEDED: MixIn_expr_attribute2xml ## MixIn
50+#NO_VISITOR_NEEDED: MixIn_children_as_tuple2xml ## MixIn
51+#NO_VISITOR_NEEDED: Terminal2xml ## Pure Abstract
52+#NO_VISITOR_NEEDED: NonTerminal2xml ## Pure Abstract
53+#NO_VISITOR_NEEDED: Expression2xml ## Pure Abstract
54+#NO_VISITOR_NEEDED: Predicate2xml ## Pure Abstract
55+#NO_VISITOR_NEEDED: Group2xml ## Pure Abstract
56+#NO_VISITOR_NEEDED: Markers2xml ## Pure Abstract
57+
58+
59+ def StrTerm2xml(self, ast, parent) ->None:
60+ logger.debug(f"StrTerm2xml:: value={ast._valType(ast.value)}")
61+ ET.SubElement(parent, 'StrTerm', value=ast.value)
62+
63+ def RegExpTerm2xml(self, ast, parent) ->None:
64+ logger.debug(f"RegExpTerm2xml:: value={ast._valType(ast.value)}")
65+ ET.SubElement(parent, 'RegExpTerm', value=ast.value)
66+
67+
68+
69+#############
70+
71+ def Rule2xml(self, ast, parent) ->None: ...
72+ def Rules2xml(self, ast, parent) ->None: ...
73+ def Setting2xml(self, ast, parent) ->None: ...
74+ def Settings2xml(self, ast, parent) ->None: ...
75+ def Grammar2xml(self, ast, parent) ->None: ...
76+ def UnorderedGroup2xml(self, ast, parent) ->None: ...
77+ def Quantity2xml(self, ast, parent) ->None: ...
78+ def Sequence2xml(self, ast, parent) ->None: ...
79+ def OrderedChoice2xml(self, ast, parent) ->None: ...
80+ def Optional2xml(self, ast, parent) ->None: ...
81+ def ZeroOrMore2xml(self, ast, parent) ->None: ...
82+ def OneOrMore2xml(self, ast, parent) ->None: ...
83+ def AndPredicate2xml(self, ast, parent) ->None: ...
84+ def NotPredicate2xml(self, ast, parent) ->None: ...
85+
86+ def EOF2xml(self, ast, parent) ->None: pass # Needed
diff -r 819aed921de1 -r 2383f011abe7 pytst/ast/XML_serialization/test_1_simple.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/pytst/ast/XML_serialization/test_1_simple.py Fri Jan 28 21:18:19 2022 +0100
@@ -0,0 +1,34 @@
1+import pytest
2+from xml.etree import ElementTree as ET
3+
4+from castle.ast import peg, serialization
5+
6+@pytest.fixture
7+def xml_serialize():
8+ return serialization.Serialize('xml').serialize
9+
10+
11+def assert_xml_Element(txt, tag,
12+ version="0.0",
13+ **attribs,):
14+ tree = ET.fromstring(txt)
15+ if version:
16+ assert tree.attrib['version'] == version
17+ founds = tree.findall(tag)
18+ assert len(founds) == 1, f"Expected only one element; got: {len(founds)} :{founds}"
19+ found = founds[0]
20+ for attrib, value in attribs.items():
21+ assert found.attrib[attrib] == value
22+
23+
24+def test_ID(xml_serialize):
25+ txt = xml_serialize(peg.ID(name='demo_ID'))
26+ assert_xml_Element(txt, tag='ID', name='demo_ID')
27+
28+def test_StrTerm(xml_serialize):
29+ txt = xml_serialize(peg.StrTerm(value='demo string'))
30+ assert_xml_Element(txt, tag='StrTerm', value='demo string')
31+
32+def test_RegExpTerm(xml_serialize):
33+ txt = xml_serialize(peg.RegExpTerm(value='demo RegExp'))
34+ assert_xml_Element(txt, tag='RegExpTerm', value='demo RegExp')