Make tests_ast directory use element groups and store mantissa/fraction in AST
authorNick Downing <downing.nick@gmail.com>
Wed, 26 Sep 2018 07:44:47 +0000 (17:44 +1000)
committerNick Downing <downing.nick@gmail.com>
Wed, 26 Sep 2018 07:44:47 +0000 (17:44 +1000)
tests_ast/ast.py
tests_ast/cal_py.l

index ca8c6f0..45edd96 100644 (file)
@@ -1,5 +1,35 @@
 import element
 
+class Text(element.Element):
+  # GENERATE ELEMENT() BEGIN
+  def __init__(
+    self,
+    tag = 'Text',
+    attrib = {},
+    text = '',
+    children = []
+  ):
+    element.Element.__init__(
+      self,
+      tag,
+      attrib,
+      text,
+      children
+    )
+  def copy(self, factory = None):
+    result = element.Element.copy(
+      self,
+      Text if factory is None else factory
+    )
+    return result
+  def __repr__(self):
+    params = []
+    self.repr_serialize(params)
+    return 'ast.Text({0:s})'.format(', '.join(params))
+  # GENERATE END
+  def get_text(self):
+    return element.get_text(self, 0)
+
 class AST(element.Element):
   class Expr(element.Element):
     # GENERATE ELEMENT() BEGIN
@@ -32,6 +62,62 @@ class AST(element.Element):
       raise NotImplementedException()
 
   class Num(Expr):
+    class Mantissa(Text):
+      # GENERATE ELEMENT() BEGIN
+      def __init__(
+        self,
+        tag = 'AST_Num_Mantissa',
+        attrib = {},
+        text = '',
+        children = []
+      ):
+        Text.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+      def copy(self, factory = None):
+        result = Text.copy(
+          self,
+          Mantissa if factory is None else factory
+        )
+        return result
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.AST.Num.Mantissa({0:s})'.format(', '.join(params))
+      # GENERATE END
+
+    class Fraction(Text):
+      # GENERATE ELEMENT() BEGIN
+      def __init__(
+        self,
+        tag = 'AST_Num_Fraction',
+        attrib = {},
+        text = '',
+        children = []
+      ):
+        Text.__init__(
+          self,
+          tag,
+          attrib,
+          text,
+          children
+        )
+      def copy(self, factory = None):
+        result = Text.copy(
+          self,
+          Fraction if factory is None else factory
+        )
+        return result
+      def __repr__(self):
+        params = []
+        self.repr_serialize(params)
+        return 'ast.AST.Num.Fraction({0:s})'.format(', '.join(params))
+      # GENERATE END
+
     # GENERATE ELEMENT() BEGIN
     def __init__(
       self,
@@ -59,7 +145,9 @@ class AST(element.Element):
       return 'ast.AST.Num({0:s})'.format(', '.join(params))
     # GENERATE END
     def eval(self):
-      return float(element.get_text(self, 0))
+      mantissa = self[0].get_text()
+      fraction = self[1].get_text() if len(self) >= 2 else ''
+      return int(mantissa + fraction) * 10 ** -len(fraction)
 
   class Add(element.Element):
     # GENERATE ELEMENT() BEGIN
@@ -240,9 +328,12 @@ class AST(element.Element):
 
 # GENERATE FACTORY(element.Element) BEGIN
 tag_to_class = {
+  'Text': Text,
   'AST': AST,
   'AST_Expr': AST.Expr,
   'AST_Num': AST.Num,
+  'AST_Num_Mantissa': AST.Num.Mantissa,
+  'AST_Num_Fraction': AST.Num.Fraction,
   'AST_Add': AST.Add,
   'AST_Sub': AST.Sub,
   'AST_Mul': AST.Mul,
index d94aef0..54b179d 100644 (file)
@@ -4,19 +4,12 @@ import element
 import y_tab
 %}
 
-DIGIT [0-9]+\.?|[0-9]*\.[0-9]+
+DIGIT (?E{ast.AST.Num.Mantissa}[0-9]+)\.?|(?E{ast.AST.Num.Mantissa}[0-9]*)\.(?E{ast.AST.Num.Fraction}[0-9]+)
 
 %%
 
 [ ]
-{DIGIT}        {
-  global yy_element_token
-  yy_element_token = element.Element(
-    'root',
-    children = [
-      element.concatenate([yy_element_token], ast.AST.Num)
-    ]
-  )
+(?E{ast.AST.Num}{DIGIT})       {
   y_tab.yylval = float(yytext)
   return y_tab.NUM
 }