Move everything into ndcode/pitree/, import from ndcode.pitree, add packaging
authorNick Downing <nick@ndcode.org>
Mon, 18 Feb 2019 14:12:06 +0000 (01:12 +1100)
committerNick Downing <nick@ndcode.org>
Mon, 18 Feb 2019 14:12:06 +0000 (01:12 +1100)
27 files changed:
.gitignore
LICENSE [new file with mode: 0644]
Makefile [deleted file]
README.md [new file with mode: 0644]
env.sh [new file with mode: 0644]
markup.py [deleted file]
ndcode/__init__.py [new file with mode: 0644]
ndcode/pitree/Makefile [new file with mode: 0644]
ndcode/pitree/__init__.py [new file with mode: 0644]
ndcode/pitree/cli.py [new file with mode: 0755]
ndcode/pitree/generate_c.py [moved from generate_c.py with 100% similarity]
ndcode/pitree/generate_py.py [moved from generate_py.py with 97% similarity]
ndcode/pitree/pitree.l [moved from pitree.l with 96% similarity]
ndcode/pitree/pitree.t [moved from pitree.t with 99% similarity]
ndcode/pitree/pitree.y [moved from pitree.y with 96% similarity]
ndcode/pitree/skel/element.py [moved from skel/element.py with 100% similarity]
ndcode/pitree/skel/skel_py.py [moved from skel/skel_py.py with 98% similarity]
old/ast_to_pitree.py [moved from ast_to_pitree.py with 100% similarity]
old/children.sed [moved from children.sed with 100% similarity]
old/expected.sed [moved from expected.sed with 100% similarity]
old/expected.sh [moved from expected.sh with 100% similarity]
old/text.sed [moved from text.sed with 100% similarity]
pitree.py [deleted file]
setup.py [new file with mode: 0755]
skel_lex_yy.py
skel_t_def.py [new file with mode: 0644]
skel_y_tab.py [new file with mode: 0644]

index cbf7d33..edca3ab 100644 (file)
@@ -1,6 +1,9 @@
 __pycache__
-/element.py
-/lex_yy.py
-/t_def.py
+/build
+/dist
+/ndcode/pitree/element.py
+/ndcode/pitree/lex_yy.py
+/ndcode/pitree/t_def.py
+/ndcode/pitree/y_tab.py
+/pitree.egg-info
 /tests
-/y_tab.py
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..111e079
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,15 @@
+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
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index 0c5e510..0000000
--- a/Makefile
+++ /dev/null
@@ -1,16 +0,0 @@
-all: element.py lex_yy.py t_def.py y_tab.py
-
-element.py: bootstrap_pitree/skel/element.py
-       cat $< >$@
-
-lex_yy.py: pitree.l
-       bootstrap_pilex/pilex.py --element --python --skel skel_lex_yy.py $<
-
-t_def.py: pitree.t
-       bootstrap_pitree/pitree.py --python $<
-
-y_tab.py: pitree.y
-       bootstrap_piyacc/piyacc.py --element --python $<
-
-clean:
-       rm -f element.py lex_yy.py t_def.py y_tab.py
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..35d8180
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+NDCODE project
+
+# PiTree: Specification Language for Abstract Syntax Trees
diff --git a/env.sh b/env.sh
new file mode 100644 (file)
index 0000000..4a2b5b6
--- /dev/null
+++ b/env.sh
@@ -0,0 +1 @@
+export PYTHONPATH=`pwd`
diff --git a/markup.py b/markup.py
deleted file mode 100755 (executable)
index 54ef8ed..0000000
--- a/markup.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/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 t_def
-import element
-import y_tab
-import sys
-
-element.serialize(y_tab.yyparse(t_def.AST), sys.stdout)
diff --git a/ndcode/__init__.py b/ndcode/__init__.py
new file mode 100644 (file)
index 0000000..de40ea7
--- /dev/null
@@ -0,0 +1 @@
+__import__('pkg_resources').declare_namespace(__name__)
diff --git a/ndcode/pitree/Makefile b/ndcode/pitree/Makefile
new file mode 100644 (file)
index 0000000..c435353
--- /dev/null
@@ -0,0 +1,16 @@
+all: element.py lex_yy.py t_def.py y_tab.py
+
+element.py: ../../bootstrap_pitree/skel/element.py
+       cat $< >$@
+
+lex_yy.py: pitree.l ../../skel_lex_yy.py
+       ../../bootstrap_pilex/pilex.py --element --python --skel ../../skel_lex_yy.py $<
+
+t_def.py: pitree.t ../../skel_t_def.py
+       ../../bootstrap_pitree/pitree.py --python --skel ../../skel_t_def.py $<
+
+y_tab.py: pitree.y ../../skel_y_tab.py
+       ../../bootstrap_piyacc/piyacc.py --element --python --skel ../../skel_y_tab.py $<
+
+clean:
+       rm -f element.py lex_yy.py t_def.py y_tab.py
diff --git a/ndcode/pitree/__init__.py b/ndcode/pitree/__init__.py
new file mode 100644 (file)
index 0000000..1bb8bf6
--- /dev/null
@@ -0,0 +1 @@
+# empty
diff --git a/ndcode/pitree/cli.py b/ndcode/pitree/cli.py
new file mode 100755 (executable)
index 0000000..7b3c990
--- /dev/null
@@ -0,0 +1,80 @@
+#!/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 getopt
+from ndcode.pitree import element
+from ndcode.pitree import generate_c
+from ndcode.pitree import generate_py
+from ndcode.pitree import lex_yy
+from ndcode.pitree import t_def
+from ndcode.pitree import y_tab
+import os
+import sys
+
+def main():
+  home_dir = os.path.dirname(__file__)
+  try:
+    opts, args = getopt.getopt(
+      sys.argv[1:],
+      'o:pS:',
+      ['outfile=', 'python', 'skel=']
+    )
+  except getopt.GetoptError as err:
+    sys.stderr.write('{0:s}\n'.format(str(err)))
+    sys.exit(1)
+
+  out_file = None
+  python = False
+  skel_file = None
+  for opt, arg in opts:
+    if opt == '-e' or opt == '--element':
+      _element = True
+    elif opt == '-o' or opt == '--outfile':
+      out_file = arg
+    elif opt == '-p' or opt == '--python':
+      python = True
+    elif opt == '-S' or opt == '--skel':
+      skel_file = arg
+    else:
+      assert False
+  if len(args) < 1:
+    sys.stdout.write(
+      'usage: {0:s} [options] defs.t\n'.format(
+        sys.argv[0]
+      )
+    )
+    sys.exit(1)
+  in_file = args[0]
+
+  with open(in_file) as fin:
+    lex_yy.yyin = fin
+    ast = y_tab.yyparse(t_def.AST)
+  #element.serialize(ast, 'a.xml', 'utf-8')
+  #ast = element.deserialize('a.xml', t_def.factory, 'utf-8')
+  ast.post_process()
+  #element.serialize(ast, 'b.xml', 'utf-8')
+  #ast = element.deserialize('b.xml', t_def.factory, 'utf-8')
+  (generate_py.generate_py if python else generate_c.generate_c)(
+    ast,
+    home_dir,
+    skel_file,
+    out_file
+  )
+
+if __name__ == '__main__':
+  main()
similarity index 100%
rename from generate_c.py
rename to ndcode/pitree/generate_c.py
similarity index 97%
rename from generate_py.py
rename to ndcode/pitree/generate_py.py
index d5e0f1b..996609a 100644 (file)
@@ -14,8 +14,8 @@
 # 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
+from ndcode.pitree import t_def
+from ndcode.pitree import element
 import os
 
 def text_to_python(text, indent):
similarity index 96%
rename from pitree.l
rename to ndcode/pitree/pitree.l
index f8c544f..20709f0 100644 (file)
--- a/pitree.l
@@ -17,8 +17,9 @@
  */
 
 %{
-  import t_def
-  import y_tab
+  from ndcode.pitree import element
+  from ndcode.pitree import t_def
+  from ndcode.pitree import y_tab
 %}
 
 %option nodefault
similarity index 99%
rename from pitree.t
rename to ndcode/pitree/pitree.t
index 4d032ef..1063ce3 100644 (file)
--- a/pitree.t
@@ -17,6 +17,7 @@
  */
 
 %{
+  from ndcode.pitree import element
   import sys
 %}
 
similarity index 96%
rename from pitree.y
rename to ndcode/pitree/pitree.y
index 9878e22..7d9852a 100644 (file)
--- a/pitree.y
@@ -17,7 +17,9 @@
  */
 
 %{
-  import t_def
+  from ndcode.pitree import element
+  from ndcode.pitree import lex_yy
+  from ndcode.pitree import t_def
 %}
 
 %token CODEBLOCK_START CODEBLOCK_END SECTION2_START SECTION3_START
similarity index 98%
rename from skel/skel_py.py
rename to ndcode/pitree/skel/skel_py.py
index 919f858..fb3b973 100644 (file)
@@ -24,7 +24,7 @@
 # files to be licensed under the GNU General Public License without this
 # special exception.
 
-import element
+#import element
 import json
 
 # GENERATE SECTION1
similarity index 100%
rename from ast_to_pitree.py
rename to old/ast_to_pitree.py
similarity index 100%
rename from children.sed
rename to old/children.sed
similarity index 100%
rename from expected.sed
rename to old/expected.sed
similarity index 100%
rename from expected.sh
rename to old/expected.sh
similarity index 100%
rename from text.sed
rename to old/text.sed
diff --git a/pitree.py b/pitree.py
deleted file mode 100755 (executable)
index f77a553..0000000
--- a/pitree.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/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 t_def
-import element
-import generate_c
-import generate_py
-import getopt
-import os
-import sys
-
-home_dir = os.path.dirname(sys.argv[0])
-try:
-  opts, args = getopt.getopt(
-    sys.argv[1:],
-    'o:pS:',
-    ['outfile=', 'python', 'skel=']
-  )
-except getopt.GetoptError as err:
-  sys.stderr.write('{0:s}\n'.format(str(err)))
-  sys.exit(1)
-
-out_file = None
-python = False
-skel_file = None
-for opt, arg in opts:
-  if opt == '-e' or opt == '--element':
-    _element = True
-  elif opt == '-o' or opt == '--outfile':
-    out_file = arg
-  elif opt == '-p' or opt == '--python':
-    python = True
-  elif opt == '-S' or opt == '--skel':
-    skel_file = arg
-  else:
-    assert False
-if len(args) < 1:
-  sys.stdout.write(
-    'usage: {0:s} [options] defs.t\n'.format(
-      sys.argv[0]
-    )
-  )
-  sys.exit(1)
-in_file = args[0]
-
-with open(in_file) as fin:
-  if in_file[-4:] == '.xml':
-    ast = element.deserialize(fin, t_def.factory)
-  else:
-    import lex_yy
-    import y_tab
-    lex_yy.yyin = fin
-    ast = y_tab.yyparse(t_def.AST)
-#element.serialize(ast, 'a.xml', 'utf-8')
-#ast = element.deserialize('a.xml', t_def.factory, 'utf-8')
-ast.post_process()
-#element.serialize(ast, 'b.xml', 'utf-8')
-#ast = element.deserialize('b.xml', t_def.factory, 'utf-8')
-(generate_py.generate_py if python else generate_c.generate_c)(
-  ast,
-  home_dir,
-  skel_file,
-  out_file
-)
diff --git a/setup.py b/setup.py
new file mode 100755 (executable)
index 0000000..34f8609
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,206 @@
+#!/usr/bin/env python3
+
+import setuptools
+import os.path
+
+here = os.path.abspath(os.path.dirname(__file__))
+
+with open(os.path.join(here, 'README.md'), encoding = 'utf-8') as fin:
+  long_description = fin.read()
+
+setuptools.setup(
+  # This is the name of your project. The first time you publish this
+  # package, this name will be registered for you. It will determine how
+  # users can install this project, e.g.:
+  #
+  # $ pip install sampleproject
+  #
+  # And where it will live on PyPI: https://pypi.org/project/sampleproject/
+  #
+  # There are some restrictions on what makes a valid project name
+  # specification here:
+  # https://packaging.python.org/specifications/core-metadata/#name
+  name = 'pitree', # required
+
+  # Versions should comply with PEP 440:
+  # https://www.python.org/dev/peps/pep-0440/
+  #
+  # For a discussion on single-sourcing the version across setup.py and the
+  # project code, see
+  # https://packaging.python.org/en/latest/single_source_version.html
+  version = '0.0.1', # required
+
+  # This is a one-line description or tagline of what your project does. This
+  # corresponds to the "Summary" metadata field:
+  # https://packaging.python.org/specifications/core-metadata/#summary
+  description='Specification language for abstract syntax trees', # optional
+
+  # This is an optional longer description of your project that represents
+  # the body of text which users will see when they visit PyPI.
+  #
+  # Often, this is the same as your README, so you can just read it in from
+  # that file directly (as we have already done above)
+  #
+  # This field corresponds to the "Description" metadata field:
+  # https://packaging.python.org/specifications/core-metadata/#description-optional
+  long_description = long_description, # optional
+
+  # Denotes that our long_description is in Markdown; valid values are
+  # text/plain, text/x-rst, and text/markdown
+  #
+  # Optional if long_description is written in reStructuredText (rst) but
+  # required for plain-text or Markdown; if unspecified, "applications should
+  # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and
+  # fall back to text/plain if it is not valid rst" (see link below)
+  #
+  # This field corresponds to the "Description-Content-Type" metadata field:
+  # https://packaging.python.org/specifications/core-metadata/#description-content-type-optional
+  long_description_content_type = 'text/markdown', # optional (see note above)
+
+  # This should be a valid link to your project's main homepage.
+  #
+  # This field corresponds to the "Home-Page" metadata field:
+  # https://packaging.python.org/specifications/core-metadata/#home-page-optional
+  url = 'https://git.ndcode.org/public/pitree.git', # optional
+
+  # This should be your name or the name of the organization which owns the
+  # project.
+  author = 'Nick Downing', # optional
+
+  # This should be a valid email address corresponding to the author listed
+  # above.
+  author_email = 'nick@ndcode.org', # optional
+
+  ## Classifiers help users find your project by categorizing it.
+  ##
+  ## For a list of valid classifiers, see https://pypi.org/classifiers/
+  #classifiers=[ # optional
+  #  # How mature is this project? Common values are
+  #  #   3 - Alpha
+  #  #   4 - Beta
+  #  #   5 - Production/Stable
+  #  'Development Status :: 3 - Alpha',
+
+  #  # Indicate who your project is intended for
+  #  'Intended Audience :: Developers',
+  #  'Topic :: Software Development :: Build Tools',
+
+  #  # Pick your license as you wish
+  #  'License :: OSI Approved :: MIT License',
+
+  #  # Specify the Python versions you support here. In particular, ensure
+  #  # that you indicate whether you support Python 2, Python 3 or both.
+  #  # These classifiers are *not* checked by 'pip install'. See instead
+  #  # 'python_requires' below.
+  #  'Programming Language :: Python :: 2',
+  #  'Programming Language :: Python :: 2.7',
+  #  'Programming Language :: Python :: 3',
+  #  'Programming Language :: Python :: 3.4',
+  #  'Programming Language :: Python :: 3.5',
+  #  'Programming Language :: Python :: 3.6',
+  #  'Programming Language :: Python :: 3.7',
+  #],
+
+  # This field adds keywords for your project which will appear on the
+  # project page. What does your project relate to?
+  #
+  # Note that this is a string of words separated by whitespace, not a list.
+  keywords = 'specification language abstract syntax tree xml', # optional
+
+  # You can just specify package directories manually here if your project is
+  # simple. Or you can use find_packages().
+  #
+  # Alternatively, if you just want to distribute a single Python file, use
+  # the `py_modules` argument instead as follows, which will expect a file
+  # called `my_module.py` to exist:
+  #
+  #   py_modules=["my_module"],
+  #
+  packages = setuptools.find_packages(
+    exclude = ['contrib', 'docs', 'tests']
+  ), # required
+
+  # Specify which Python versions you support. In contrast to the
+  # 'Programming Language' classifiers above, 'pip install' will check this
+  # and refuse to install the project if the version does not match. If you
+  # do not support Python 2, you can simplify this to '>=3.5' or similar, see
+  # https://packaging.python.org/guides/distributing-packages-using-setuptools/#python-requires
+  python_requires = '>=3.0',
+
+  ## This field lists other packages that your project depends on to run.
+  ## Any package you put here will be installed by pip when your project is
+  ## installed, so they must be valid existing projects.
+  ##
+  ## For an analysis of "install_requires" vs pip's requirements files see:
+  ## https://packaging.python.org/en/latest/requirements.html
+  #install_requires = ['peppercorn'], # optional
+
+  ## List additional groups of dependencies here (e.g. development
+  ## dependencies). Users will be able to install these using the "extras"
+  ## syntax, for example:
+  ##
+  ##   $ pip install sampleproject[dev]
+  ##
+  ## Similar to `install_requires` above, these must be valid existing
+  ## projects.
+  #extras_require = { # optional
+  #  'dev': ['check-manifest'],
+  #  'test': ['coverage'],
+  #},
+
+  ## If there are data files included in your packages that need to be
+  ## installed, specify them here.
+  ##
+  ## If using Python 2.6 or earlier, then these have to be included in
+  ## MANIFEST.in as well.
+  #package_data = { # optional
+  #  'sample': ['package_data.dat'],
+  #},
+
+  # Although 'package_data' is the preferred approach, in some case you may
+  # need to place data files outside of your packages. See:
+  # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
+  #
+  # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
+  data_files = [
+    (
+      'ndcode/pitree/skel',
+      [
+        'ndcode/pitree/skel/element.py',
+        'ndcode/pitree/skel/skel_py.py'
+      ]
+    )
+  ], # optional
+
+  # To provide executable scripts, use entry points in preference to the
+  # "scripts" keyword. Entry points provide cross-platform support and allow
+  # `pip` to create the appropriate form of executable for the target
+  # platform.
+  #
+  # For example, the following would provide a command called `sample` which
+  # executes the function `main` from this package when invoked:
+  entry_points = {  # Optional
+    'console_scripts': [
+      'pitree=ndcode.pitree.cli:main',
+    ],
+  },
+
+  ## List additional URLs that are relevant to your project as a dict.
+  ##
+  ## This field corresponds to the "Project-URL" metadata fields:
+  ## https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use
+  ##
+  ## Examples listed include a pattern for specifying where the package tracks
+  ## issues, where the source is hosted, where to say thanks to the package
+  ## maintainers, and where to support the project financially. The key is
+  ## what's used to render the link text on PyPI.
+  #project_urls = { # optional
+  #  'Bug Reports': 'https://github.com/pypa/sampleproject/issues',
+  #  'Funding': 'https://donate.pypi.org',
+  #  'Say Thanks!': 'http://saythanks.io/to/example',
+  #  'Source': 'https://github.com/pypa/sampleproject/',
+  #},
+
+  # Nick
+  namespace_packages = ['ndcode']
+)
index 688fc95..5d45b69 100644 (file)
@@ -25,7 +25,7 @@
 # special exception.
 
 import bisect
-import element
+#import element
 import sys
 
 # GENERATE SECTION1
diff --git a/skel_t_def.py b/skel_t_def.py
new file mode 100644 (file)
index 0000000..fb3b973
--- /dev/null
@@ -0,0 +1,40 @@
+# Copyright (C) 2019 Nick Downing <nick@ndcode.org>
+# SPDX-License-Identifier: GPL-2.0-with-bison-exception
+#
+# 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
+#
+# As a special exception, you may create a larger work that contains part or
+# all of the pitree class definition skeleton and distribute that work under
+# terms of your choice, so long as that work isn't itself a class definition
+# generator using the skeleton or a modified version thereof as a class
+# definition skeleton. Alternatively, if you modify or redistribute the class
+# definition skeleton itself, you may (at your option) remove this special
+# exception, which will cause the skeleton and the resulting pitree output
+# files to be licensed under the GNU General Public License without this
+# special exception.
+
+#import element
+import json
+
+# GENERATE SECTION1
+
+# GENERATE SECTION2
+
+def method(_class):
+  def decorator(func):
+    setattr(_class, func.__name__, func)
+    return func
+  return decorator
+
+# GENERATE SECTION3
diff --git a/skel_y_tab.py b/skel_y_tab.py
new file mode 100644 (file)
index 0000000..d78e0e8
--- /dev/null
@@ -0,0 +1,138 @@
+# Copyright (C) 2019 Nick Downing <nick@ndcode.org>
+# SPDX-License-Identifier: GPL-2.0-with-bison-exception
+#
+# 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
+#
+# As a special exception, you may create a larger work that contains part or
+# all of the piyacc parser skeleton and distribute that work under terms of
+# your choice, so long as that work isn't itself a parser generator using the
+# skeleton or a modified version thereof as a parser skeleton. Alternatively,
+# if you modify or redistribute the parser skeleton itself, you may (at your
+# option) remove this special exception, which will cause the skeleton and the
+# resulting piyacc output files to be licensed under the GNU General Public
+# License without this special exception.
+
+import bisect
+#import element
+#import lex_yy
+#import xml.etree.ElementTree
+
+# this can be redefined in SECTION1
+class YYLTYPE:
+  def __init__(
+    self,
+    first_line = 0,
+    first_column = 0,
+    last_line = 0,
+    last_column = 0
+  ):
+    self.first_line = first_line
+    self.first_column = first_column
+    self.last_line = last_line
+    self.last_column = last_column
+# GENERATE SECTION1
+
+# GENERATE TOKENS
+
+yystack = None
+yychar = None
+YYEMPTY = -1
+
+yyval = None
+yyloc = None
+
+yylval = None
+yylloc = YYLTYPE()
+
+yy_element_stack = None
+
+# GENERATE SECTION2
+
+def yyparse(factory, *args, **kwargs):
+  global yystack, yychar, yyval, yyloc, yylval, yylloc, yy_element_stack
+
+  # GENERATE INITIALACTION
+
+  state = 0
+  yystack = []
+  yylval = None
+  yychar = -1
+  yy_element_stack = []
+  while True:
+    #print('state', state, 'yystack', yystack)
+    assert len(yy_element_stack) == len(yystack) * 2
+    reduce = yy_lr1dfa_states[state][4]
+    if reduce == -1:
+      if yychar == -1:
+        yylval = None
+        yylloc = YYLTYPE() # temporary until lex_yy updated, should be None
+        yychar = lex_yy.yylex()
+        #print('yychar', yychar, 'yylval', yylval, 'yylloc', yylloc, 'lex_yy.yytext', lex_yy.yytext)
+        #print('lex_yy.yy_element_space')
+        #xml.etree.ElementTree.dump(lex_yy.yy_element_space)
+        #print('lex_yy.yy_element_token')
+        #xml.etree.ElementTree.dump(lex_yy.yy_element_token)
+      action = yy_lr1dfa_states[state][1][
+        bisect.bisect_right(yy_lr1dfa_states[state][0], yychar)
+      ]
+      if action == -1:
+        raise Exception('syntax error')
+      if (action & 1) == 0:
+        yystack.append((state, yylval, yylloc))
+
+        # push space then AST element contiguously onto yy_element_stack
+        # even numbered elements are spaces, odd numbered elements are AST
+        yy_element_stack.extend(
+          [lex_yy.yy_element_space, lex_yy.yy_element_token]
+        )
+
+        state = action >> 1
+        #print('shift', state)
+        yychar = -1
+        continue
+      reduce = action >> 1
+    #print('reduce', reduce)
+    len_symbols, ref_data = yy_lr1dfa_productions[reduce]
+    base = len(yystack) - len_symbols
+    yystack.append((state, None, None))
+    state, yyval, yyloc = yystack[base]
+    ref_data()
+    del yystack[base:]
+    if reduce == 0:
+      assert base == 0
+      break
+    yystack.append((state, yyval, yyloc))
+
+    # action creates empty space in yy_element_stack[base * 2] if needed
+    assert len(yy_element_stack) > base * 2
+
+    # concatenate yy_element_stack[base * 2 + 1:] to a single AST element
+    yy_element_stack[base * 2 + 1:] = [
+      element.concatenate(
+        yy_element_stack[base * 2 + 1:],
+        element.Element
+      )
+    ]
+
+    state = yy_lr1dfa_states[state][3][
+      bisect.bisect_right(yy_lr1dfa_states[state][2], reduce)
+    ]
+    assert state != -1
+
+  # return space then AST then space in the user's choice of element type
+  yy_element_stack.append(lex_yy.yy_element_space)
+  return element.concatenate(yy_element_stack, factory, *args, **kwargs)
+
+# GENERATE SECTION3