__pycache__
-/*.xml
/bootstrap/*.xml
/bootstrap/lex_yy.py
/bootstrap/lex_yy_code.py
/tests/y_tab.py
/tests/cal
/tests/cal2
-/tests_ast/*.xml
/tests_ast/lex_yy.py
+/tests_ast/t_def.py
/tests_ast/y_tab.py
/y_tab.py
+++ /dev/null
-#!/usr/bin/env python3
-
-# Copyright (C) 2018 Nick Downing <nick@ndcode.org>
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-
-import re
-import sys
-
-re_begin = re.compile(
- '([\t ]*# GENERATE .*) BEGIN'
-)
-re_end = re.compile(
- '([\t ]*# GENERATE END)'
-)
-
-line = sys.stdin.readline()
-while len(line):
- match = re_begin.match(line)
- if match is not None:
- sys.stdout.write(match.group(1))
- line = sys.stdin.readline()
- while len(line):
- match = re_end.match(line)
- if match is not None:
- sys.stdout.write(line[len(match.group(1)):])
- break
- line = sys.stdin.readline()
- else:
- sys.stdout.write(line)
- line = sys.stdin.readline()
+++ /dev/null
-#!/usr/bin/env python3
-
-# Copyright (C) 2019 Nick Downing <nick@ndcode.org>
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-
-import re
-import sys
-
-if len(sys.argv) >= 2:
- package_name = '{0:s}.'.format(sys.argv[1])
-else:
- package_name = ''
-
-default_value = {
- 'bool': 'False',
- 'int': '-1',
- 'ref': 'None',
- 'str': '\'\'',
- 'list(bool)': '[]',
- 'list(int)': '[]',
- 'list(ref)': '[]',
- 'list(str)': '[]',
- 'set(bool)': 'set()',
- 'set(int)': 'set()',
- 'set(ref)': 'set()',
- 'set(str)': 'set()'
-}
-default_value_str = {
- 'bool': 'false',
- 'int': '-1',
- 'ref': '-1',
- 'str': ''
-}
-
-re_class = re.compile(
- '([\t ]*)class ([A-Za-z_][A-Za-z0-9_]*)\(([A-Za-z_][A-Za-z0-9_.]*)'
-)
-re_element = re.compile(
- '([\t ]*)# GENERATE ELEMENT\((([^()]|\([^()]*\))*)\)( BEGIN)?'
-)
-re_factory = re.compile(
- '([\t ]*)# GENERATE FACTORY\(([^()]*)\)( BEGIN)?'
-)
-stack = []
-classes = []
-base_classes = [{'element.Element': []}] # params
-
-line = sys.stdin.readline()
-while len(line):
- match = re_class.match(line)
- if match is not None:
- sys.stdout.write(line)
- indent = match.group(1)
- class_name = match.group(2)
- base_class = match.group(3)
- while len(stack) and stack[-1][0][:len(indent)] == indent:
- _, temp_class_name, _, _ = stack.pop()
- for temp_base_class, temp_fields in base_classes.pop().items():
- base_classes[-1][
- '{0:s}.{1:s}'.format(temp_class_name, temp_base_class)
- ] = temp_fields
- for i in range(len(base_classes) - 1, -1, -1):
- if base_class in base_classes[i]:
- classes.append(
- '.'.join([j for _, j, _, _ in stack] + [class_name])
- )
- full_base_class = '.'.join(
- [j for _, j, _, _ in stack[:i]] + [base_class]
- )
- base_classes[-1][class_name] = list(base_classes[i][base_class])
- break
- else:
- full_base_class = base_class
- stack.append((indent, class_name, base_class, full_base_class))
- base_classes.append({})
- else:
- match = re_element.match(line)
- if match is not None:
- indent = match.group(1)
- params = match.group(2)
- begin = match.group(4)
-
- while len(stack) and stack[-1][0][:len(indent)] == indent:
- _, temp_class_name, _, _ = stack.pop()
- for temp_base_class, temp_fields in base_classes.pop().items():
- base_classes[-1][
- '{0:s}.{1:s}'.format(temp_class_name, temp_base_class)
- ] = temp_fields
- _, class_name, base_class, full_base_class = stack[-1]
-
- fields = params.split(',')
- if fields[-1] == '':
- del fields[-1:]
- fields = [i.split() for i in fields]
- fields = [(type, name) for [type, name] in fields]
- i = len(base_classes[-2][class_name])
- base_classes[-2][class_name].extend(fields)
-
- sys.stdout.write(
- '''{0:s}# GENERATE ELEMENT({1:s}) BEGIN
-{2:s}def __init__(
-{3:s} self,
-{4:s} tag = '{5:s}',
-{6:s} attrib = {{}},
-{7:s} text = '',
-{8:s} children = []{9:s}
-{10:s}):
-{11:s} {12:s}.__init__(
-{13:s} self,
-{14:s} tag,
-{15:s} attrib,
-{16:s} text,
-{17:s} children{18:s}
-{19:s} )
-{20:s}'''.format(
- indent,
- params,
- indent,
- indent,
- indent,
- '_'.join([i for _, i, _, _ in stack]),
- indent,
- indent,
- indent,
- ''.join(
- [
- ',\n{0:s} {1:s} = {2:s}'.format(
- indent,
- name,
- default_value[type]
- )
- for type, name in base_classes[-2][class_name]
- ]
- ),
- indent,
- indent,
- full_base_class,
- indent,
- indent,
- indent,
- indent,
- indent,
- ''.join(
- [
- ',\n{0:s} {1:s}'.format(
- indent,
- name
- )
- for _, name in base_classes[-2][class_name][:i]
- ]
- ),
- indent,
- ''.join(
- [
- '{0:s} self.{1:s} = {2:s}\n'.format(
- indent,
- name,
- name
- )
- for _, name in fields
- ]
- )
- )
- )
- if len(fields):
- sys.stdout.write(
- '''{0:s}def serialize(self, ref_list):
-{1:s} {2:s}.serialize(self, ref_list)
-'''.format(
- indent,
- indent,
- full_base_class
- )
- )
- for type, name in fields:
- if type[:5] == 'list(' and type[-1:] == ')':
- subtype = type[5:-1]
- sys.stdout.write(
- '''{0:s} self.set(
-{1:s} '{2:s}',
-{3:s} ' '.join(
-{4:s} [
-{5:s} element.serialize_{6:s}(i{7:s})
-{8:s} for i in self.{9:s}
-{10:s} ]
-{11:s} )
-{12:s} )
-'''.format(
- indent,
- indent,
- name,
- indent,
- indent,
- indent,
- subtype,
- ', ref_list' if subtype == 'ref' else '',
- indent,
- name,
- indent,
- indent,
- indent
- )
- )
- elif type[:4] == 'set(' and type[-1:] == ')':
- subtype = type[4:-1]
- sys.stdout.write(
- '''{0:s} self.set(
-{1:s} '{2:s}',
-{3:s} ' '.join(
-{4:s} [
-{5:s} element.serialize_{6:s}(i{7:s})
-{8:s} for i in sorted(self.{9:s})
-{10:s} ]
-{11:s} )
-{12:s} )
-'''.format(
- indent,
- indent,
- name,
- indent,
- indent,
- indent,
- subtype,
- ', ref_list' if subtype == 'ref' else '',
- indent,
- name,
- indent,
- indent,
- indent
- )
- )
- else:
- sys.stdout.write(
- '''{0:s} self.set(
-{1:s} '{2:s}',
-{3:s} element.serialize_{4:s}(self.{5:s}{6:s})
-{7:s} )
-'''.format(
- indent,
- indent,
- name,
- indent,
- type,
- name,
- ', ref_list' if type == 'ref' else '',
- indent
- )
- )
- sys.stdout.write(
- '''{0:s}def deserialize(self, ref_list):
-{1:s} {2:s}.deserialize(self, ref_list)
-'''.format(
- indent,
- indent,
- full_base_class
- )
- )
- for type, name in fields:
- if type[:5] == 'list(' and type[-1:] == ')':
- subtype = type[5:-1]
- sys.stdout.write(
- '''{0:s} self.{1:s} = [
-{2:s} element.deserialize_{3:s}(i{4:s})
-{5:s} for i in self.get('{6:s}', '').split()
-{7:s} ]
-'''.format(
- indent,
- name,
- indent,
- subtype,
- ', ref_list' if subtype == 'ref' else '',
- indent,
- name,
- indent
- )
- )
- elif type[:4] == 'set(' and type[-1:] == ')':
- subtype = type[4:-1]
- sys.stdout.write(
- '''{0:s} self.{1:s} = set(
-{2:s} [
-{3:s} element.deserialize_{4:s}(i{5:s})
-{6:s} for i in self.get('{7:s}', '').split()
-{8:s} ]
-{9:s} )
-'''.format(
- indent,
- name,
- indent,
- indent,
- subtype,
- ', ref_list' if subtype == 'ref' else '',
- indent,
- name,
- indent,
- indent
- )
- )
- else:
- sys.stdout.write(
- '''{0:s} self.{1:s} = element.deserialize_{2:s}(self.get('{3:s}', '{4:s}'){5:s})
-'''.format(
- indent,
- name,
- type,
- name,
- default_value_str[type],
- ', ref_list' if type == 'ref' else ''
- )
- )
- sys.stdout.write(
- '''{0:s}def copy(self, factory = None):
-{1:s} result = {2:s}.copy(
-{3:s} self,
-{4:s} {5:s} if factory is None else factory
-{6:s} ){7:s}
-{8:s} return result
-'''.format(
- indent,
- indent,
- full_base_class,
- indent,
- indent,
- class_name,
- indent,
- ''.join(
- [
- '\n{0:s} result.{1:s} = self.{2:s}'.format(
- indent,
- name,
- name
- )
- for _, name in fields
- ]
- ),
- indent
- )
- )
- sys.stdout.write(
- '''{0:s}# GENERATE END
-'''.format(
- indent
- )
- )
- if begin is not None:
- line = sys.stdin.readline()
- while len(line):
- if line.strip() == '# GENERATE END':
- break
- line = sys.stdin.readline()
- else:
- assert False
- else:
- match = re_factory.match(line)
- if match is not None:
- indent = match.group(1)
- param = match.group(2)
- begin = match.group(3)
-
- sys.stdout.write(
- '''{0:s}# GENERATE FACTORY({1:s}) BEGIN
-{2:s}tag_to_class = {{{3:s}
-{4:s}}}
-{5:s}def factory(tag, attrib = {{}}, *args, **kwargs):
-{6:s} return tag_to_class.get(tag, {7:s})(tag, attrib, *args, **kwargs)
-{8:s}# GENERATE END
-'''.format(
- indent,
- param,
- indent,
- ','.join(
- [
- '\n{0:s} \'{1:s}\': {2:s}'.format(
- indent,
- i.replace('.', '_'),
- i
- )
- for i in classes
- ]
- ),
- indent,
- indent,
- indent,
- param,
- indent
- )
- )
-
- if begin is not None:
- line = sys.stdin.readline()
- while len(line):
- if line.strip() == '# GENERATE END':
- break
- line = sys.stdin.readline()
- else:
- assert False
- else:
- sys.stdout.write(line)
- line = sys.stdin.readline()
-all: lex_yy.py y_tab.py
+all: lex_yy.py t_def.py y_tab.py
lex_yy.py: cal_py.l
- ../../bootstrap_flex.git/src/flex -o /dev/null $< 2>$<.xml
- ../../pilex.git/pilex.py --element --python $<.xml
+ ../../pilex.git/pilex.py --element --python $<
+
+t_def.py: cal_py.t
+ ../../pitree.git/pitree.py --python $<
y_tab.py: cal_py.y
- ../../bootstrap_bison.git/src/bison -o /dev/null $< 2>$<.xml
- ../piyacc.py --element --python $<.xml
+ ../piyacc.py --element --python $<
clean:
- rm -f lex_yy.py y_tab.py *.xml
+ rm -f lex_yy.py t_def.py y_tab.py
+++ /dev/null
-# Copyright (C) 2018 Nick Downing <nick@ndcode.org>
-# SPDX-License-Identifier: GPL-2.0-only
-#
-# This program is free software; you can redistribute it and/or modify it under
-# the terms of the GNU General Public License as published by the Free Software
-# Foundation; version 2.
-#
-# This program is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
-# details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 51
-# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-
-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
- # GENERATE END
- def get_text(self):
- return element.get_text(self, 0)
-
-class AST(element.Element):
- class Expr(element.Element):
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST_Expr',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- Expr if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- 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
- # 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
- # GENERATE END
-
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST_Num',
- attrib = {},
- text = '',
- children = []
- ):
- AST.Expr.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = AST.Expr.copy(
- self,
- Num if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- 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
- def __init__(
- self,
- tag = 'AST_Add',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- Add if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- return self[0].eval() + self[1].eval()
-
- class Sub(element.Element):
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST_Sub',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- Sub if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- return self[0].eval() - self[1].eval()
-
- class Mul(element.Element):
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST_Mul',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- Mul if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- return self[0].eval() * self[1].eval()
-
- class Div(element.Element):
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST_Div',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- Div if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- return self[0].eval() / self[1].eval()
-
- class Neg(element.Element):
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST_Neg',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- Neg if factory is None else factory
- )
- return result
- # GENERATE END
- def eval(self):
- return -self[0].eval()
-
- # GENERATE ELEMENT() BEGIN
- def __init__(
- self,
- tag = 'AST',
- attrib = {},
- text = '',
- children = []
- ):
- element.Element.__init__(
- self,
- tag,
- attrib,
- text,
- children
- )
- def copy(self, factory = None):
- result = element.Element.copy(
- self,
- AST if factory is None else factory
- )
- return result
- # GENERATE END
-
-# 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,
- 'AST_Div': AST.Div,
- 'AST_Neg': AST.Neg
-}
-def factory(tag, attrib = {}, *args, **kwargs):
- return tag_to_class.get(tag, element.Element)(tag, attrib, *args, **kwargs)
-# GENERATE END
+++ /dev/null
-#!/bin/sh
-if ../generate_ast.py ast <ast.py >ast.py.new && ! diff -q ast.py ast.py.new
-then
- mv ast.py.new ast.py
-else
- rm -f ast.py.new
-fi
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-import ast
+import t_def
import element
import sys
import xml.etree.ElementTree
sys.stdout.write('Enter the expression: ')
sys.stdout.flush()
-_ast = y_tab.yyparse(ast.AST)
+_ast = y_tab.yyparse(t_def.AST)
xml.etree.ElementTree.dump(_ast)
element.serialize(_ast, 'a.xml', 'utf-8')
-_ast = element.deserialize('a.xml', ast.factory, 'utf-8')
+_ast = element.deserialize('a.xml', t_def.factory, 'utf-8')
for i in _ast:
sys.stdout.write('{0:g}\n'.format(i.eval()))
*/
%{
-import ast
+import t_def
import element
import y_tab
%}
-DIGIT (?E{ast.AST.Num.Mantissa}[0-9]+)\.?|(?E{ast.AST.Num.Mantissa}[0-9]*)\.(?E{ast.AST.Num.Fraction}[0-9]+)
+DIGIT (?E{t_def.AST.Num.Mantissa}[0-9]+)\.?|(?E{t_def.AST.Num.Mantissa}[0-9]*)\.(?E{t_def.AST.Num.Fraction}[0-9]+)
%%
[ ]
-(?E{ast.AST.Num}{DIGIT}) {
+(?E{t_def.AST.Num}{DIGIT}) {
y_tab.yylval = float(yytext)
return y_tab.NUM
}
--- /dev/null
+/*
+ * Copyright (C) 2019 Nick Downing <nick@ndcode.org>
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; version 2.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+%{
+ import element
+%}
+
+%%
+
+class Text;
+class AST {
+ class Expr;
+ class Num: Expr {
+ class Mantissa: Text;
+ class Fraction: Text;
+ };
+ class Add;
+ class Sub;
+ class Mul;
+ class Div;
+ class Neg;
+};
+
+%%
+
+# Copyright (C) 2018 Nick Downing <nick@ndcode.org>
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free Software
+# Foundation; version 2.
+#
+# This program is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+# details.
+#
+# You should have received a copy of the GNU General Public License along with
+# this program; if not, write to the Free Software Foundation, Inc., 51
+# Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+
+def factory(tag, attrib = {}, *args, **kwargs):
+ return tag_to_class.get(tag, element.Element)(tag, attrib, *args, **kwargs)
+
+@method(Text)
+def get_text(self):
+ return element.get_text(self, 0)
+del get_text
+
+@method(AST.Expr)
+def eval(self):
+ raise NotImplementedException()
+@method(AST.Num)
+def eval(self):
+ mantissa = self[0].get_text()
+ fraction = self[1].get_text() if len(self) >= 2 else ''
+ return int(mantissa + fraction) * 10 ** -len(fraction)
+@method(AST.Add)
+def eval(self):
+ return self[0].eval() + self[1].eval()
+@method(AST.Sub)
+def eval(self):
+ return self[0].eval() - self[1].eval()
+@method(AST.Mul)
+def eval(self):
+ return self[0].eval() * self[1].eval()
+@method(AST.Div)
+def eval(self):
+ return self[0].eval() / self[1].eval()
+@method(AST.Neg)
+def eval(self):
+ return -self[0].eval()
+del eval
*/
%{
-import ast
+import t_def
import sys
%}
%token NUM
yyerrok()
}
;
-E : %space (?E{ast.AST.Add}E '+' E) {
+E : %space (?E{t_def.AST.Add}E '+' E) {
$$ = $1 + $3
}
- | %space (?E{ast.AST.Sub}E '-' E) {
+ | %space (?E{t_def.AST.Sub}E '-' E) {
$$ = $1 - $3
}
- | %space (?E{ast.AST.Mul}E '*' E) {
+ | %space (?E{t_def.AST.Mul}E '*' E) {
$$ = $1 * $3
}
- | %space (?E{ast.AST.Div}E '/' E) {
+ | %space (?E{t_def.AST.Div}E '/' E) {
$$ = $1 / $3
}
| '(' E ')' {
$$ = $2
}
- | %space (?E{ast.AST.Neg}'-' E) %prec UMINUS {
+ | %space (?E{t_def.AST.Neg}'-' E) %prec UMINUS {
$$ = -$2
}
| NUM
-# Copyright (C) 2018 Nick Downing <nick@ndcode.org>
+# Copyright (C) 2019 Nick Downing <nick@ndcode.org>
# SPDX-License-Identifier: GPL-2.0-only
#
# This program is free software; you can redistribute it and/or modify it under
str_to_bool = {'false': False, 'true': True}
def deserialize_bool(text):
+ assert text is not None
return str_to_bool[text]
def serialize_int(value):
return str(value)
def deserialize_int(text):
+ assert text is not None
return int(text)
def serialize_ref(value, ref_list):
+ assert text is not None
if value is None:
ref = -1
else:
return str(ref)
def deserialize_ref(text, ref_list):
+ assert text is not None
ref = int(text)
return None if ref < 0 else ref_list[ref]
return value
def deserialize_str(text):
+ assert text is not None
return text
def serialize(value, fout, encoding = 'unicode'):
else:
root[i - 1].tail = text
+def to_text(root):
+ return ''.join(
+ [
+ j
+ for i in range(len(root))
+ for j in [get_text(root, i), to_text(root[i])]
+ ] +
+ [get_text(root, len(root))]
+ )
+
def concatenate(children, factory = Element, *args, **kwargs):
root = factory(*args, **kwargs)
for child in children: