Initial commit, taken from /tests_ast in piyacc.git commit e4e599c4
authorNick Downing <nick@ndcode.org>
Sat, 14 May 2022 11:17:17 +0000 (21:17 +1000)
committerNick Downing <nick@ndcode.org>
Sat, 14 May 2022 11:32:16 +0000 (21:32 +1000)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
cal.py [new file with mode: 0755]
cal_py.l [new file with mode: 0644]
cal_py.t [new file with mode: 0644]
cal_py.y [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..8f4dc51
--- /dev/null
@@ -0,0 +1,5 @@
+__pycache__
+/element.py
+/lex_yy.py
+/t_def.py
+/y_tab.py
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..4343700
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
+all: element.py lex_yy.py t_def.py y_tab.py
+
+element.py:
+       pitree --install-element
+
+lex_yy.py: cal_py.l
+       pilex --element --groups --python $<
+
+t_def.py: cal_py.t
+       pitree --python $<
+
+y_tab.py: cal_py.y
+       piyacc --element --python $<
+
+clean:
+       rm -f element.py lex_yy.py t_def.py y_tab.py
diff --git a/cal.py b/cal.py
new file mode 100755 (executable)
index 0000000..160da64
--- /dev/null
+++ b/cal.py
@@ -0,0 +1,31 @@
+#!/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 t_def
+import element
+import sys
+import y_tab
+
+sys.stdout.write('Enter the expression: ')
+sys.stdout.flush()
+_ast = y_tab.yyparse(t_def.AST)
+element.serialize(_ast, sys.stdout)
+#element.serialize(_ast, 'a.xml', 'utf-8')
+#_ast = element.deserialize('a.xml', t_def.factory, 'utf-8')
+for i in _ast.children:
+  sys.stdout.write('{0:g}\n'.format(i.eval()))
diff --git a/cal_py.l b/cal_py.l
new file mode 100644 (file)
index 0000000..a1f343e
--- /dev/null
+++ b/cal_py.l
@@ -0,0 +1,36 @@
+/*
+ * 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 t_def
+  import element
+  import y_tab
+%}
+
+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{t_def.AST.Num}{DIGIT})     {
+  y_tab.yylval = float(yytext)
+  return y_tab.NUM
+}
+\n|.   {
+  return ord(yytext[0])
+}
diff --git a/cal_py.t b/cal_py.t
new file mode 100644 (file)
index 0000000..9807fa7
--- /dev/null
+++ b/cal_py.t
@@ -0,0 +1,88 @@
+/*
+ * 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, *args, **kwargs):
+  return tag_to_class[tag](*args, **kwargs)
+
+@method(Text)
+def get_text(self):
+  return self.text[0]
+del get_text
+
+@method(AST.Expr)
+def eval(self):
+  raise NotImplementedException()
+@method(AST.Num)
+def eval(self):
+  mantissa = self.children[0].get_text()
+  fraction = self.children[1].get_text() if len(self.children) >= 2 else ''
+  return int(mantissa + fraction) * 10 ** -len(fraction)
+@method(AST.Add)
+def eval(self):
+  return self.children[0].eval() + self.children[1].eval()
+@method(AST.Sub)
+def eval(self):
+  return self.children[0].eval() - self.children[1].eval()
+@method(AST.Mul)
+def eval(self):
+  return self.children[0].eval() * self.children[1].eval()
+@method(AST.Div)
+def eval(self):
+  return self.children[0].eval() / self.children[1].eval()
+@method(AST.Neg)
+def eval(self):
+  return -self.children[0].eval()
+del eval
diff --git a/cal_py.y b/cal_py.y
new file mode 100644 (file)
index 0000000..8c66253
--- /dev/null
+++ b/cal_py.y
@@ -0,0 +1,68 @@
+/*
+ * 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 t_def
+  import sys
+%}
+
+%locations
+
+%token NUM
+
+%left '+' '-'
+%left '*' '/'
+%right UMINUS
+
+%%
+
+S : S E '\n' {
+    sys.stdout.write('Answer: {0:g}\nEnter:\n'.format($2))
+  }
+  | S '\n'
+  |
+  | error '\n' {
+  yyerror('Error: Enter once more...\n')
+  yyerrok()
+}
+  ;
+E : %space (?E{t_def.AST.Add}E '+' E) {
+    $$ = $1 + $3
+  }
+  | %space (?E{t_def.AST.Sub}E '-' E) {
+    $$ = $1 - $3
+  }
+  | %space (?E{t_def.AST.Mul}E '*' E) {
+    $$ = $1 * $3
+  }
+  | %space (?E{t_def.AST.Div}E '/' E) {
+    $$ = $1 / $3
+  }
+  | '(' E ')' {
+    $$ = $2
+  }
+  | %space (?E{t_def.AST.Neg}'-' E) %prec UMINUS {
+    $$ = -$2
+  }
+  | NUM
+  ;
+%%
+
+def yyerror(s):
+  sys.stdout.write('{0:s}\n'.format(s))
+  sys.exit(1)