__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
--- /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
+++ /dev/null
-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
--- /dev/null
+NDCODE project
+
+# PiTree: Specification Language for Abstract Syntax Trees
--- /dev/null
+export PYTHONPATH=`pwd`
+++ /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 t_def
-import element
-import y_tab
-import sys
-
-element.serialize(y_tab.yyparse(t_def.AST), sys.stdout)
--- /dev/null
+__import__('pkg_resources').declare_namespace(__name__)
--- /dev/null
+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
--- /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 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()
# 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):
*/
%{
- 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
*/
%{
+ from ndcode.pitree import element
import sys
%}
*/
%{
- 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
# files to be licensed under the GNU General Public License without this
# special exception.
-import element
+#import element
import json
# GENERATE SECTION1
+++ /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 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
-)
--- /dev/null
+#!/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']
+)
# special exception.
import bisect
-import element
+#import element
import sys
# GENERATE SECTION1
--- /dev/null
+# 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
--- /dev/null
+# 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