Snap for 6439596 from 775e41a49bd0233ed94f379fd99b5a5837e257b2 to qt-aml-tzdata-release
Change-Id: I7c228c7365b5846aeb7e34ab44f14cf435a8f02b
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 5ce5b00..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,17 +0,0 @@
-*.pyc
-tests/parser.out
-tests/*tab.py
-build
-yacctab.py
-lextab.py
-dist
-MANIFEST
-*.exe
-*.o
-parser.out
-*.orig
-*.rej
-.tox
-utils/z.c
-*.egg-info
-
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 25c9df6..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-language: python
-python:
- - "2.7"
- - "3.4"
- - "3.5"
- - "3.6"
-script: python tests/all_tests.py
diff --git a/CHANGES b/CHANGES
deleted file mode 100644
index 711c263..0000000
--- a/CHANGES
+++ /dev/null
@@ -1,259 +0,0 @@
-+ Version 2.19 (2018.09.19)
-
- - PR #277: Fix parsing of floating point literals
- - PR #254: Add support for parsing empty structs
- - PR #240: Fix enum formatting in generated C code (also #216)
- - PR #222: Add support for #pragma in struct declarations
-
-+ Version 2.18 (2017.07.04)
-
- - PR #161 & #184: Update bundled PLY version to 3.10
- - PR #158: Add support for the __int128 type.
- - PR #169: Handle more tricky TYPEID in declarators.
- - PR #178: Add columns to the coord of each node
-
-+ Version 2.17 (2016.10.29)
-
- - Again functionality identical to 2.15 and 2.16; the difference is that the
- tarball now contains Python files with properly set permissions.
-
-+ Version 2.16 (2016.10.18)
-
- - Functionally identical to 2.15, but fixes a packaging problem that caused
- failed installation (_build_tables wasn't rerun in the pycparser/ dir).
-
-+ Version 2.15 (2016.10.18)
-
- - PR #121: Update bundled PLY version to 3.8
- - Issue #117: Fix parsing of extra semi-colons inside structure declarations.
- - PR #109: Update c_generator to add {} around nested named initializers.
- - PR #101: Added support for parsing pragmas into the AST.
- - Additional fake headers and typedefs, manifest fixes (#97, #106, #111).
- - Testing with Python 3.5 instead of 3.3 now (3.4 and 3.5 are the 3.x versions
- tested).
- - PR #145: More complete support for offsetof()
- - Issue #116: Fix line numbers recorded for empty and compound statements.
- - Minor performance improvement to the invalid string literal regex.
-
-+ Version 2.14 (2015.06.09)
-
- - Added CParser parameter to specify output directory for generated parsing
- tables (#84).
- - Removed lcc's cpp and its license from the distribution. Using lcc's cpp
- is no longer recommended, now that Clang has binary builds available for
- Windows.
-
-+ Version 2.13 (2015.05.12)
-
- - Added support for offsetof() the way gcc implements it (special builtin
- that takes a type as an argument).
- - Added faked va_* macros (these are expected to come from stdarg.h)
- - Added a bunch more fake headers and typedefs to support parsing C projects
- like Git and SQLite without modifications to pycparser.
- - Added support for empty initializer lists (#79).
-
-+ Version 2.12 (2015.04.21)
-
- - This is a fix release for 2.11; the memory optimization with __slots__ on
- Coord and AST nodes didn't take weakrefs into account, which broke cffi and
- its many dependents (issue #76). Fixed by adding __weakref__ to __slots__.
-
-+ Version 2.11 (2015.04.21)
-
- - Add support for C99 6.5.3.7 p7 - qualifiers within array dimensions in
- function declarations. Started with issue #21 (reported with initial patch
- by Robin Martinjak).
- - Issue #27: bug in handling of unified wstring literals.
- - Issue #28: fix coord reporting for 'for' loops.
- - Added ``examples/using_gcc_E_libc.py`` to demonstrate how ``gcc -E`` can
- be used instead of ``cpp`` for preprocessing.
- - Pull request #64: support keywords like const, volatile, restrict and static
- in dimensions in array declarations.
- - Reduce memory usage of AST nodes (issue #72).
- - Parsing order of nested pointer declarations fixed (issue #68).
-
-+ Version 2.10 (2013.08.03)
-
- - A number of improvements in the handling of typedef-name ambiguities,
- contributed by Sye van der Veen in GitHub issue #1:
-
- * Allow shadowing of types by identifiers in inner scopes.
- * Allow struct field names to reside in a separate namespace and have
- the same names as types.
- * Allow duplicate typedefs in some cases to mimic real compiler behavior.
-
- - c_generator error for ExprList in expression context.
- - Assume default int type for functions whose argument or return types were
- not specified.
- - Relax the lexer a bit w.r.t. some integer suffixes and $ in identifier names
- (which is supported by some other compilers).
-
-+ Version 2.09.1 (2012.12.29)
-
- - No actual functionality changes.
- - The source distribution was re-packaged to contain the pre-generated Lex and
- Yacc tables of PLY.
-
-+ Version 2.09 (2012.12.27)
-
- - The pycparser project has moved to Bitbucket. For this version, issue
- numbers still refer to the old Googlecode project, unless stated otherwise.
- Starting with the next version all issue numbers will refer to the new
- Bitbucket project.
- - pycparser now carries its PLY dependency along. The pycparser/ply directory
- contains the source of PLY for the currently supported version. This makes
- distribution and testing easier.
- - Issue #79: fix generation of new switch/case AST nodes.
- - Issue #83: fix parsing and C generation to distinguish between initializer
- lists in declarations and initializing variables with parenthesized
- comma-separated expressions.
- - Issue #84: fix C generation for some statements.
- - Issues #86 and #87: improve location reporting for parse errors.
- - Issue #89: fix C generation for K&R-style function definitions.
-
-+ Version 2.08 (2012.08.10)
-
- - Issue 73: initial support for #pragma directives. Consume them without
- errors and ignore (no tokens are returned). Line numbers are preserved.
- - Issue 68: more correct handling of source files without any actual content.
- - Issue 69: running all tests will now set appropriate return code.
- - Better error reporting in case where multiple type specifiers are provided.
- Also fixes Issue 60.
- - Issue 63: line endings cleanup for consistent LF ending.
- - Issues 64 & 65: added some more headers and typedefs to fake includes.
- - Refactoring the cpp invocation in parse_file into a separate function, which
- can also be used as a utility.
- - Issue 74: some Windows include paths were handled incorrectly.
-
-+ Version 2.07 (2012.06.16)
-
- - Issue 54: added an optional parser argument to parse_file
- - Issue 59: added some more fake headers for C99
- - Issue 62: correct coord for Ellipsis nodes
- - Issue 57: support for C99 hexadecimal float constants
- - Made running tests that call on 'cpp' a bit more robust.
-
-+ Version 2.06 (2012.02.04)
-
- - Issue 48: gracefully handle parsing of empty files
- - Issues 49 & 50: handle more escaped chars in paths to #line - "..\..\test.h".
- - Support for C99 _Complex type.
- - CGenerator moves from examples/ to pycparser/ as a first-class citizen, and
- added some fixes to it. examples/c-to-c.py still stays as a convenience
- wrapper.
- - Fix problem with parsing a file in which the first statement is just a
- semicolon.
- - Improved the AST created for switch statements, making it closer to the
- semantic meaning than to the grammar.
-
-+ Version 2.05 (2011.10.16)
-
- - Added support for the C99 ``_Bool`` type and ``stdbool.h`` header file
- - Expanded ``examples/explore_ast.py`` with more details on working with the
- AST
- - Relaxed the rules on parsing unnamed struct members (helps parse ``windows.h``)
- - Bug fixes:
-
- * Fixed spacing issue for some type declarations
- * Issue 47: display empty statements (lone ';') correctly after parsing
-
-+ Version 2.04 (2011.05.21)
-
- - License changed from LGPL to BSD
- - Bug fixes:
-
- * Issue 31: constraining the scope of typedef definitions
- * Issues 33, 35: fixes for the c-to-c.py example
-
- - Added C99 integer types to fake headers
- - Added unit tests for the c-to-c.py example
-
-+ Version 2.03 (2011.03.06)
-
- - Bug fixes:
-
- * Issue 17: empty file-level declarations
- * Issue 18: empty statements and declarations in functions
- * Issue 19: anonymous structs & union fields
- * Issue 23: fix coordinates of Cast nodes
-
- - New example added (``examples/c-to-c.py``) for translating ASTs generated
- by ``pycparser`` back into C code.
- - ``pycparser`` is now on PyPI (Python Package Index)
- - Created `FAQ <http://code.google.com/p/pycparser/wiki/FAQ>`_ on
- the ``pycparser`` project page
- - Removed support for Python 2.5. ``pycparser`` supports Python 2
- from 2.6 and on, and Python 3.
-
-+ Version 2.02 (2010.12.10)
-
- * The name of a ``NamedInitializer`` node was turned into a sequence of nodes
- instead of an attribute, to make it discoverable by the AST node visitor.
- * Documentation updates
-
-+ Version 2.01 (04.12.2010)
-
- * Removed dependency on YAML. Parsing of the AST node configuration file
- is done with a simple parser.
- * Fixed issue 12: installation problems
-
-+ Version 2.00 (2010.10.31)
-
- * Support for C99 (read
- `this wiki page <http://code.google.com/p/pycparser/wiki/C99support>`_
- for more information).
-
-+ Version 1.08 (2010.10.09)
-
- * Bug fixes:
-
- + Correct handling of ``do{} ... while`` statements in some cases
- + Issues 6 & 7: Concatenation of string literals
- + Issue 9: Support for unnamed bitfields in structs
-
-+ Version 1.07 (2010.05.18)
-
- * Python 3.1 compatibility: ``pycparser`` was modified to run
- on Python 3.1 as well as 2.6
-
-+ Version 1.06 (2010.04.10)
-
- * Bug fixes:
-
- + coord not propagated to FuncCall nodes
- + lexing of the ^= token (XOREQUALS)
- + parsing failed on some abstract declarator rules
-
- * Linux compatibility: fixed end-of-line and ``cpp`` path issues to allow
- all tests and examples run on Linux
-
-+ Version 1.05 (2009.10.16)
-
- * Fixed the ``parse_file`` auxiliary function to handle multiple arguments to
- ``cpp`` correctly
-
-+ Version 1.04 (2009.05.22)
-
- * Added the ``fake_libc_include`` directory to allow parsing of C code that
- uses standard C library include files without dependency on a real C
- library.
- * Tested with Python 2.6 and PLY 3.2
-
-+ Version 1.03 (2009.01.31)
-
- * Accept enumeration lists with a comma after the last item (C99 feature).
-
-+ Version 1.02 (2009.01.16)
-
- * Fixed problem of parsing struct/enum/union names that were named similarly
- to previously defined ``typedef`` types.
-
-+ Version 1.01 (2009.01.09)
-
- * Fixed subprocess invocation in the helper function parse_file - now
- it's more portable
-
-+ Version 1.0 (2008.11.15)
-
- * Initial release
- * Support for ANSI C89
diff --git a/CONTRIBUTORS b/CONTRIBUTORS
deleted file mode 100644
index 481737f..0000000
--- a/CONTRIBUTORS
+++ /dev/null
@@ -1,25 +0,0 @@
-This is a list of people who have contributed to pycparser by supplying patches,
-opening issues, or generally helping out, before the project moved to Github.
-
-For more recent contributions, check out the "Contributors" page of the
-pycparser Github project.
-
-The list is sorted in increasing alphabetic order by first name.
-
-* Andreas Klöckner
-* Andrew de los Reyes
-* Benoit Pradelle
-* Dov Feldstern
-* Even Wiik Thomassen
-* Greg Smith
-* Jaroslav Franek
-* Li Xuan Ji
-* Mateusz Czaplinski
-* Paolo Di Maio
-* Rory Yorke
-* Rubin
-* Scott Tsai
-* Sye van der Veen
-* Thomas W. Barr
-* Tomer Segal
-* Weyllor
diff --git a/LICENSE b/LICENSE
deleted file mode 100644
index 79b7547..0000000
--- a/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-pycparser -- A C parser in Python
-
-Copyright (c) 2008-2017, Eli Bendersky
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-* Neither the name of Eli Bendersky nor the names of its contributors may
- be used to endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
-GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/MANIFEST.in b/MANIFEST.in
deleted file mode 100644
index 8017b7e..0000000
--- a/MANIFEST.in
+++ /dev/null
@@ -1,12 +0,0 @@
-recursive-include examples *.c *.h *.py
-recursive-include tests *.c *.h *.py
-recursive-include pycparser *.py *.cfg
-recursive-include utils/fake_libc_include *.h
-include README.*
-include LICENSE
-include CHANGES
-include setup.*
-exclude setup.pyc
-
-recursive-exclude tests yacctab.* lextab.*
-recursive-exclude examples yacctab.* lextab.*
diff --git a/METADATA b/METADATA
deleted file mode 100644
index e07b7a2..0000000
--- a/METADATA
+++ /dev/null
@@ -1,19 +0,0 @@
-name: "pycparser"
-description: "pycparser is a parser for the C language, written in pure Python. It is a module designed to be easily integrated into applications that need to parse C source code."
-third_party {
- url {
- type: HOMEPAGE
- value: "https://github.com/eliben/pycparser"
- }
- url {
- type: GIT
- value: "https://github.com/eliben/pycparser"
- }
- version: "release_v2.19"
- license_type: NOTICE
- last_upgrade_date {
- year: 2019
- month: 5
- day: 2
- }
-}
diff --git a/MODULE_LICENSE_MIT b/MODULE_LICENSE_MIT
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_MIT
+++ /dev/null
diff --git a/NOTICE b/NOTICE
deleted file mode 120000
index 7a694c9..0000000
--- a/NOTICE
+++ /dev/null
@@ -1 +0,0 @@
-LICENSE
\ No newline at end of file
diff --git a/README.rst b/README.rst
deleted file mode 100644
index df9025c..0000000
--- a/README.rst
+++ /dev/null
@@ -1,257 +0,0 @@
-===============
-pycparser v2.19
-===============
-
-:Author: `Eli Bendersky <https://eli.thegreenplace.net/>`_
-
-
-.. contents::
- :backlinks: none
-
-.. sectnum::
-
-
-Introduction
-============
-
-What is pycparser?
-------------------
-
-**pycparser** is a parser for the C language, written in pure Python. It is a
-module designed to be easily integrated into applications that need to parse
-C source code.
-
-What is it good for?
---------------------
-
-Anything that needs C code to be parsed. The following are some uses for
-**pycparser**, taken from real user reports:
-
-* C code obfuscator
-* Front-end for various specialized C compilers
-* Static code checker
-* Automatic unit-test discovery
-* Adding specialized extensions to the C language
-
-One of the most popular uses of **pycparser** is in the `cffi
-<https://cffi.readthedocs.io/en/latest/>`_ library, which uses it to parse the
-declarations of C functions and types in order to auto-generate FFIs.
-
-**pycparser** is unique in the sense that it's written in pure Python - a very
-high level language that's easy to experiment with and tweak. To people familiar
-with Lex and Yacc, **pycparser**'s code will be simple to understand. It also
-has no external dependencies (except for a Python interpreter), making it very
-simple to install and deploy.
-
-Which version of C does pycparser support?
-------------------------------------------
-
-**pycparser** aims to support the full C99 language (according to the standard
-ISO/IEC 9899). Some features from C11 are also supported, and patches to support
-more are welcome.
-
-**pycparser** supports very few GCC extensions, but it's fairly easy to set
-things up so that it parses code with a lot of GCC-isms successfully. See the
-`FAQ <https://github.com/eliben/pycparser/wiki/FAQ>`_ for more details.
-
-What grammar does pycparser follow?
------------------------------------
-
-**pycparser** very closely follows the C grammar provided in Annex A of the C99
-standard (ISO/IEC 9899).
-
-How is pycparser licensed?
---------------------------
-
-`BSD license <https://github.com/eliben/pycparser/blob/master/LICENSE>`_.
-
-Contact details
----------------
-
-For reporting problems with **pycparser** or submitting feature requests, please
-open an `issue <https://github.com/eliben/pycparser/issues>`_, or submit a
-pull request.
-
-
-Installing
-==========
-
-Prerequisites
--------------
-
-* **pycparser** was tested on Python 2.7, 3.4-3.6, on both Linux and
- Windows. It should work on any later version (in both the 2.x and 3.x lines)
- as well.
-
-* **pycparser** has no external dependencies. The only non-stdlib library it
- uses is PLY, which is bundled in ``pycparser/ply``. The current PLY version is
- 3.10, retrieved from `<http://www.dabeaz.com/ply/>`_
-
-Note that **pycparser** (and PLY) uses docstrings for grammar specifications.
-Python installations that strip docstrings (such as when using the Python
-``-OO`` option) will fail to instantiate and use **pycparser**. You can try to
-work around this problem by making sure the PLY parsing tables are pre-generated
-in normal mode; this isn't an officially supported/tested mode of operation,
-though.
-
-Installation process
---------------------
-
-Installing **pycparser** is very simple. Once you download and unzip the
-package, you just have to execute the standard ``python setup.py install``. The
-setup script will then place the ``pycparser`` module into ``site-packages`` in
-your Python's installation library.
-
-Alternatively, since **pycparser** is listed in the `Python Package Index
-<https://pypi.org/project/pycparser/>`_ (PyPI), you can install it using your
-favorite Python packaging/distribution tool, for example with::
-
- > pip install pycparser
-
-Known problems
---------------
-
-* Some users who've installed a new version of **pycparser** over an existing
- version ran into a problem using the newly installed library. This has to do
- with parse tables staying around as ``.pyc`` files from the older version. If
- you see unexplained errors from **pycparser** after an upgrade, remove it (by
- deleting the ``pycparser`` directory in your Python's ``site-packages``, or
- wherever you installed it) and install again.
-
-
-Using
-=====
-
-Interaction with the C preprocessor
------------------------------------
-
-In order to be compilable, C code must be preprocessed by the C preprocessor -
-``cpp``. ``cpp`` handles preprocessing directives like ``#include`` and
-``#define``, removes comments, and performs other minor tasks that prepare the C
-code for compilation.
-
-For all but the most trivial snippets of C code **pycparser**, like a C
-compiler, must receive preprocessed C code in order to function correctly. If
-you import the top-level ``parse_file`` function from the **pycparser** package,
-it will interact with ``cpp`` for you, as long as it's in your PATH, or you
-provide a path to it.
-
-Note also that you can use ``gcc -E`` or ``clang -E`` instead of ``cpp``. See
-the ``using_gcc_E_libc.py`` example for more details. Windows users can download
-and install a binary build of Clang for Windows `from this website
-<http://llvm.org/releases/download.html>`_.
-
-What about the standard C library headers?
-------------------------------------------
-
-C code almost always ``#include``\s various header files from the standard C
-library, like ``stdio.h``. While (with some effort) **pycparser** can be made to
-parse the standard headers from any C compiler, it's much simpler to use the
-provided "fake" standard includes in ``utils/fake_libc_include``. These are
-standard C header files that contain only the bare necessities to allow valid
-parsing of the files that use them. As a bonus, since they're minimal, it can
-significantly improve the performance of parsing large C files.
-
-The key point to understand here is that **pycparser** doesn't really care about
-the semantics of types. It only needs to know whether some token encountered in
-the source is a previously defined type. This is essential in order to be able
-to parse C correctly.
-
-See `this blog post
-<https://eli.thegreenplace.net/2015/on-parsing-c-type-declarations-and-fake-headers>`_
-for more details.
-
-Basic usage
------------
-
-Take a look at the |examples|_ directory of the distribution for a few examples
-of using **pycparser**. These should be enough to get you started. Please note
-that most realistic C code samples would require running the C preprocessor
-before passing the code to **pycparser**; see the previous sections for more
-details.
-
-.. |examples| replace:: ``examples``
-.. _examples: examples
-
-
-Advanced usage
---------------
-
-The public interface of **pycparser** is well documented with comments in
-``pycparser/c_parser.py``. For a detailed overview of the various AST nodes
-created by the parser, see ``pycparser/_c_ast.cfg``.
-
-There's also a `FAQ available here <https://github.com/eliben/pycparser/wiki/FAQ>`_.
-In any case, you can always drop me an `email <eliben@gmail.com>`_ for help.
-
-
-Modifying
-=========
-
-There are a few points to keep in mind when modifying **pycparser**:
-
-* The code for **pycparser**'s AST nodes is automatically generated from a
- configuration file - ``_c_ast.cfg``, by ``_ast_gen.py``. If you modify the AST
- configuration, make sure to re-generate the code.
-* Make sure you understand the optimized mode of **pycparser** - for that you
- must read the docstring in the constructor of the ``CParser`` class. For
- development you should create the parser without optimizations, so that it
- will regenerate the Yacc and Lex tables when you change the grammar.
-
-
-Package contents
-================
-
-Once you unzip the ``pycparser`` package, you'll see the following files and
-directories:
-
-README.rst:
- This README file.
-
-LICENSE:
- The pycparser license
-
-setup.py:
- Installation script
-
-examples/:
- A directory with some examples of using **pycparser**
-
-pycparser/:
- The **pycparser** module source code.
-
-tests/:
- Unit tests.
-
-utils/fake_libc_include:
- Minimal standard C library include files that should allow to parse any C code.
-
-utils/internal/:
- Internal utilities for my own use. You probably don't need them.
-
-
-Contributors
-============
-
-Some people have contributed to **pycparser** by opening issues on bugs they've
-found and/or submitting patches. The list of contributors is in the CONTRIBUTORS
-file in the source distribution. After **pycparser** moved to Github I stopped
-updating this list because Github does a much better job at tracking
-contributions.
-
-
-CI Status
-=========
-
-**pycparser** has automatic testing enabled through the convenient
-`Travis CI project <https://travis-ci.org>`_. Here is the latest build status:
-
-.. image:: https://travis-ci.org/eliben/pycparser.png?branch=master
- :align: center
- :target: https://travis-ci.org/eliben/pycparser
-
-AppVeyor also helps run tests on Windows:
-
-.. image:: https://ci.appveyor.com/api/projects/status/wrup68o5y8nuk1i9?svg=true
- :align: center
- :target: https://ci.appveyor.com/project/eliben/pycparser/
diff --git a/TEST_MAPPING b/TEST_MAPPING
deleted file mode 100644
index 61a80b2..0000000
--- a/TEST_MAPPING
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "presubmit" : [
- {
- "name" : "acloud_test",
- "host" : true
- }
- ]
-}
diff --git a/TODO.txt b/TODO.txt
deleted file mode 100644
index 3737893..0000000
--- a/TODO.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-Todo
-----
-
-Version Update
---------------
-
-setup.py, __init__.py, README, CHANGES
-- Make sure _build_tables was run in pycparser/
-- If PLY version changes, note it in README and ply/LICENSE
-- Run tox tests
-
-python setup.py sdist
-
-Copy the newly created tarball and untar it; check that the permissions of
-Python files in the pycparser/ directory are OK. Check to see that lextab.py and
-yacctab.py are there.
-
-Now create a new virtualenv and in it install the tarball with
-`pip install <tarballname>`. See that pycparser is importable in the Python
-interpreter of this virtualenv; run pycparser tests from this virtualenv.
-
-After this it's OK to rerun `python3.6 setup.py sdist upload` to push to PyPI
-(older Pythons use a deprecated API for PyPI uploading).
-
-- Tag in git. When pushing to GitHub, git push --tags
-
-Misc
-----
-
-yacc optimization:
-- If parsetab.py/pyc doesn't exist in the path, the table will be reconstructed
- anyway, regardless of the optimize parameter
-- If it does exist:
- - If optimize=True, the table will be loaded unconditionally
- - If optimize=False, the table will be loaded only if it's older than the
- grammar
-
-lex optimization:
-- If optimize=False, the lexical table is re-computed and is not saved to a
- lextab file
-- If optimize=True:
- - If lextab.py/pyc exists in the path, it will be loaded unconditionally
- - If lextab.py/pyc doesn't exist, it will be created and loaded
diff --git a/_clean_tables.py b/_clean_tables.py
deleted file mode 100644
index 5b0f1c3..0000000
--- a/_clean_tables.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Cleanup all tables and PYC files to ensure no PLY stuff is cached
-from __future__ import print_function
-import itertools
-import fnmatch
-import os, shutil
-
-file_patterns = ('yacctab.*', 'lextab.*', '*.pyc', '__pycache__')
-
-
-def do_cleanup(root):
- for path, dirs, files in os.walk(root):
- for file in itertools.chain(dirs, files):
- try:
- for pattern in file_patterns:
- if fnmatch.fnmatch(file, pattern):
- fullpath = os.path.join(path, file)
- if os.path.isdir(fullpath):
- shutil.rmtree(fullpath, ignore_errors=False)
- else:
- os.unlink(fullpath)
- print('Deleted', fullpath)
- except OSError:
- pass
-
-
-if __name__ == "__main__":
- do_cleanup('.')
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 05c1c7e..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-environment:
-
- matrix:
- - PYTHON: "C:\\Python27"
- - PYTHON: "C:\\Python34"
- - PYTHON: "C:\\Python35"
- - PYTHON: "C:\\Python36"
-
-build: off
-
-test_script:
- - "%PYTHON%\\python.exe tests\\all_tests.py"
diff --git a/examples/README.rst b/examples/README.rst
deleted file mode 100644
index 048f5a4..0000000
--- a/examples/README.rst
+++ /dev/null
@@ -1,8 +0,0 @@
-Run these examples from the root directory of pycparser.
-
-Please note that most realistic C code samples would require running the C
-preprocessor before passing the code to **pycparser**; see the `README file
-<https://github.com/eliben/pycparser/blob/master/README.rst>`_ and
-`this blog post
-<https://eli.thegreenplace.net/2015/on-parsing-c-type-declarations-and-fake-headers>`_
-more details.
diff --git a/examples/c-to-c.py b/examples/c-to-c.py
deleted file mode 100644
index cc14598..0000000
--- a/examples/c-to-c.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#------------------------------------------------------------------------------
-# pycparser: c-to-c.py
-#
-# Example of using pycparser.c_generator, serving as a simplistic translator
-# from C to AST and back to C.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#------------------------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import parse_file, c_parser, c_generator
-
-
-def translate_to_c(filename):
- """ Simply use the c_generator module to emit a parsed AST.
- """
- ast = parse_file(filename, use_cpp=True)
- generator = c_generator.CGenerator()
- print(generator.visit(ast))
-
-
-def _zz_test_translate():
- # internal use
- src = r'''
-
- void f(char * restrict joe){}
-
-int main(void)
-{
- unsigned int long k = 4;
- int p = - - k;
- return 0;
-}
-'''
- parser = c_parser.CParser()
- ast = parser.parse(src)
- ast.show()
- generator = c_generator.CGenerator()
-
- print(generator.visit(ast))
-
- # tracing the generator for debugging
- #~ import trace
- #~ tr = trace.Trace(countcallers=1)
- #~ tr.runfunc(generator.visit, ast)
- #~ tr.results().write_results()
-
-
-#------------------------------------------------------------------------------
-if __name__ == "__main__":
- #_zz_test_translate()
- if len(sys.argv) > 1:
- translate_to_c(sys.argv[1])
- else:
- print("Please provide a filename as argument")
diff --git a/examples/c_files/funky.c b/examples/c_files/funky.c
deleted file mode 100644
index 5ebf7b2..0000000
--- a/examples/c_files/funky.c
+++ /dev/null
@@ -1,20 +0,0 @@
-char foo(void)
-{
- return '1';
-}
-
-int maxout_in(int paste, char** matrix)
-{
- char o = foo();
- return (int) matrix[1][2] * 5 - paste;
-}
-
-int main()
-{
- auto char* multi = "a multi";
-
-
-}
-
-
-
diff --git a/examples/c_files/hash.c b/examples/c_files/hash.c
deleted file mode 100644
index c11fe45..0000000
--- a/examples/c_files/hash.c
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-** C implementation of a hash table ADT
-*/
-typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
-
-
-typedef struct tagEntry
-{
- char* key;
- char* value;
-} Entry;
-
-
-
-typedef struct tagNode
-{
- Entry* entry;
-
- struct tagNode* next;
-} Node;
-
-
-typedef struct tagHash
-{
- unsigned int table_size;
-
- Node** heads;
-
-} Hash;
-
-
-static unsigned int hash_func(const char* str, unsigned int table_size)
-{
- unsigned int hash_value;
- unsigned int a = 127;
-
- for (hash_value = 0; *str != 0; ++str)
- hash_value = (a*hash_value + *str) % table_size;
-
- return hash_value;
-}
-
-
-ReturnCode HashCreate(Hash** hash, unsigned int table_size)
-{
- unsigned int i;
-
- if (table_size < 1)
- return FAIL;
-
- //
- // Allocate space for the Hash
- //
- if (((*hash) = malloc(sizeof(**hash))) == NULL)
- return FAIL;
-
- //
- // Allocate space for the array of list heads
- //
- if (((*hash)->heads = malloc(table_size*sizeof(*((*hash)->heads)))) == NULL)
- return FAIL;
-
- //
- // Initialize Hash info
- //
- for (i = 0; i < table_size; ++i)
- {
- (*hash)->heads[i] = NULL;
- }
-
- (*hash)->table_size = table_size;
-
- return SUCCESS;
-}
-
-
-ReturnCode HashInsert(Hash* hash, const Entry* entry)
-{
- unsigned int index = hash_func(entry->key, hash->table_size);
- Node* temp = hash->heads[index];
-
- HashRemove(hash, entry->key);
-
- if ((hash->heads[index] = malloc(sizeof(Node))) == NULL)
- return FAIL;
-
- hash->heads[index]->entry = malloc(sizeof(Entry));
- hash->heads[index]->entry->key = malloc(strlen(entry->key)+1);
- hash->heads[index]->entry->value = malloc(strlen(entry->value)+1);
- strcpy(hash->heads[index]->entry->key, entry->key);
- strcpy(hash->heads[index]->entry->value, entry->value);
-
- hash->heads[index]->next = temp;
-
- return SUCCESS;
-}
-
-
-
-const Entry* HashFind(const Hash* hash, const char* key)
-{
- unsigned int index = hash_func(key, hash->table_size);
- Node* temp = hash->heads[index];
-
- while (temp != NULL)
- {
- if (!strcmp(key, temp->entry->key))
- return temp->entry;
-
- temp = temp->next;
- }
-
- return NULL;
-}
-
-
-ReturnCode HashRemove(Hash* hash, const char* key)
-{
- unsigned int index = hash_func(key, hash->table_size);
- Node* temp1 = hash->heads[index];
- Node* temp2 = temp1;
-
- while (temp1 != NULL)
- {
- if (!strcmp(key, temp1->entry->key))
- {
- if (temp1 == hash->heads[index])
- hash->heads[index] = hash->heads[index]->next;
- else
- temp2->next = temp1->next;
-
- free(temp1->entry->key);
- free(temp1->entry->value);
- free(temp1->entry);
- free(temp1);
- temp1 = NULL;
-
- return SUCCESS;
- }
-
- temp2 = temp1;
- temp1 = temp1->next;
- }
-
- return FAIL;
-}
-
-
-void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
-{
- unsigned int i;
-
- if (hash == NULL || hash->heads == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- PrintFunc(temp->entry->key, temp->entry->value);
- temp = temp->next;
- }
- }
-}
-
-
-
-void HashDestroy(Hash* hash)
-{
- unsigned int i;
-
- if (hash == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- Node* temp2 = temp;
-
- free(temp->entry->key);
- free(temp->entry->value);
- free(temp->entry);
-
- temp = temp->next;
-
- free(temp2);
- }
- }
-
- free(hash->heads);
- hash->heads = NULL;
-
- free(hash);
-}
-
diff --git a/examples/c_files/memmgr.c b/examples/c_files/memmgr.c
deleted file mode 100644
index d9bc290..0000000
--- a/examples/c_files/memmgr.c
+++ /dev/null
@@ -1,206 +0,0 @@
-//----------------------------------------------------------------
-// Statically-allocated memory manager
-//
-// by Eli Bendersky (eliben@gmail.com)
-//
-// This code is in the public domain.
-//----------------------------------------------------------------
-#include "memmgr.h"
-
-typedef ulong Align;
-
-union mem_header_union
-{
- struct
- {
- // Pointer to the next block in the free list
- //
- union mem_header_union* next;
-
- // Size of the block (in quantas of sizeof(mem_header_t))
- //
- ulong size;
- } s;
-
- // Used to align headers in memory to a boundary
- //
- Align align_dummy;
-};
-
-typedef union mem_header_union mem_header_t;
-
-// Initial empty list
-//
-static mem_header_t base;
-
-// Start of free list
-//
-static mem_header_t* freep = 0;
-
-// Static pool for new allocations
-//
-static byte pool[POOL_SIZE] = {0};
-static ulong pool_free_pos = 0;
-
-
-void memmgr_init()
-{
- base.s.next = 0;
- base.s.size = 0;
- freep = 0;
- pool_free_pos = 0;
-}
-
-
-static mem_header_t* get_mem_from_pool(ulong nquantas)
-{
- ulong total_req_size;
-
- mem_header_t* h;
-
- if (nquantas < MIN_POOL_ALLOC_QUANTAS)
- nquantas = MIN_POOL_ALLOC_QUANTAS;
-
- total_req_size = nquantas * sizeof(mem_header_t);
-
- if (pool_free_pos + total_req_size <= POOL_SIZE)
- {
- h = (mem_header_t*) (pool + pool_free_pos);
- h->s.size = nquantas;
- memmgr_free((void*) (h + 1));
- pool_free_pos += total_req_size;
- }
- else
- {
- return 0;
- }
-
- return freep;
-}
-
-
-// Allocations are done in 'quantas' of header size.
-// The search for a free block of adequate size begins at the point 'freep'
-// where the last block was found.
-// If a too-big block is found, it is split and the tail is returned (this
-// way the header of the original needs only to have its size adjusted).
-// The pointer returned to the user points to the free space within the block,
-// which begins one quanta after the header.
-//
-void* memmgr_alloc(ulong nbytes)
-{
- mem_header_t* p;
- mem_header_t* prevp;
-
- // Calculate how many quantas are required: we need enough to house all
- // the requested bytes, plus the header. The -1 and +1 are there to make sure
- // that if nbytes is a multiple of nquantas, we don't allocate too much
- //
- ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;
-
- // First alloc call, and no free list yet ? Use 'base' for an initial
- // denegerate block of size 0, which points to itself
- //
- if ((prevp = freep) == 0)
- {
- base.s.next = freep = prevp = &base;
- base.s.size = 0;
- }
-
- for (p = prevp->s.next; ; prevp = p, p = p->s.next)
- {
- // big enough ?
- if (p->s.size >= nquantas)
- {
- // exactly ?
- if (p->s.size == nquantas)
- {
- // just eliminate this block from the free list by pointing
- // its prev's next to its next
- //
- prevp->s.next = p->s.next;
- }
- else // too big
- {
- p->s.size -= nquantas;
- p += p->s.size;
- p->s.size = nquantas;
- }
-
- freep = prevp;
- return (void*) (p + 1);
- }
- // Reached end of free list ?
- // Try to allocate the block from the pool. If that succeeds,
- // get_mem_from_pool adds the new block to the free list and
- // it will be found in the following iterations. If the call
- // to get_mem_from_pool doesn't succeed, we've run out of
- // memory
- //
- else if (p == freep)
- {
- if ((p = get_mem_from_pool(nquantas)) == 0)
- {
- #ifdef DEBUG_MEMMGR_FATAL
- printf("!! Memory allocation failed !!\n");
- #endif
- return 0;
- }
- }
- }
-}
-
-
-// Scans the free list, starting at freep, looking the the place to insert the
-// free block. This is either between two existing blocks or at the end of the
-// list. In any case, if the block being freed is adjacent to either neighbor,
-// the adjacent blocks are combined.
-//
-void memmgr_free(void* ap)
-{
- mem_header_t* block;
- mem_header_t* p;
-
- // acquire pointer to block header
- block = ((mem_header_t*) ap) - 1;
-
- // Find the correct place to place the block in (the free list is sorted by
- // address, increasing order)
- //
- for (p = freep; !(block > p && block < p->s.next); p = p->s.next)
- {
- // Since the free list is circular, there is one link where a
- // higher-addressed block points to a lower-addressed block.
- // This condition checks if the block should be actually
- // inserted between them
- //
- if (p >= p->s.next && (block > p || block < p->s.next))
- break;
- }
-
- // Try to combine with the higher neighbor
- //
- if (block + block->s.size == p->s.next)
- {
- block->s.size += p->s.next->s.size;
- block->s.next = p->s.next->s.next;
- }
- else
- {
- block->s.next = p->s.next;
- }
-
- // Try to combine with the lower neighbor
- //
- if (p + p->s.size == block)
- {
- p->s.size += block->s.size;
- p->s.next = block->s.next;
- }
- else
- {
- p->s.next = block;
- }
-
- freep = p;
-}
diff --git a/examples/c_files/memmgr.h b/examples/c_files/memmgr.h
deleted file mode 100644
index e792fb8..0000000
--- a/examples/c_files/memmgr.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//----------------------------------------------------------------
-// Statically-allocated memory manager
-//
-// by Eli Bendersky (eliben@gmail.com)
-//
-// This code is in the public domain.
-//----------------------------------------------------------------
-#ifndef MEMMGR_H
-#define MEMMGR_H
-
-//
-// Memory manager: dynamically allocates memory from
-// a fixed pool that is allocated statically at link-time.
-//
-// Usage: after calling memmgr_init() in your
-// initialization routine, just use memmgr_alloc() instead
-// of malloc() and memmgr_free() instead of free().
-// Naturally, you can use the preprocessor to define
-// malloc() and free() as aliases to memmgr_alloc() and
-// memmgr_free(). This way the manager will be a drop-in
-// replacement for the standard C library allocators, and can
-// be useful for debugging memory allocation problems and
-// leaks.
-//
-// Preprocessor flags you can define to customize the
-// memory manager:
-//
-// DEBUG_MEMMGR_FATAL
-// Allow printing out a message when allocations fail
-//
-// DEBUG_MEMMGR_SUPPORT_STATS
-// Allow printing out of stats in function
-// memmgr_print_stats When this is disabled,
-// memmgr_print_stats does nothing.
-//
-// Note that in production code on an embedded system
-// you'll probably want to keep those undefined, because
-// they cause printf to be called.
-//
-// POOL_SIZE
-// Size of the pool for new allocations. This is
-// effectively the heap size of the application, and can
-// be changed in accordance with the available memory
-// resources.
-//
-// MIN_POOL_ALLOC_QUANTAS
-// Internally, the memory manager allocates memory in
-// quantas roughly the size of two ulong objects. To
-// minimize pool fragmentation in case of multiple allocations
-// and deallocations, it is advisable to not allocate
-// blocks that are too small.
-// This flag sets the minimal ammount of quantas for
-// an allocation. If the size of a ulong is 4 and you
-// set this flag to 16, the minimal size of an allocation
-// will be 4 * 2 * 16 = 128 bytes
-// If you have a lot of small allocations, keep this value
-// low to conserve memory. If you have mostly large
-// allocations, it is best to make it higher, to avoid
-// fragmentation.
-//
-// Notes:
-// 1. This memory manager is *not thread safe*. Use it only
-// for single thread/task applications.
-//
-
-#define DEBUG_MEMMGR_SUPPORT_STATS 1
-
-#define POOL_SIZE 8 * 1024
-#define MIN_POOL_ALLOC_QUANTAS 16
-
-
-typedef unsigned char byte;
-typedef unsigned long ulong;
-
-
-
-// Initialize the memory manager. This function should be called
-// only once in the beginning of the program.
-//
-void memmgr_init();
-
-// 'malloc' clone
-//
-void* memmgr_alloc(ulong nbytes);
-
-// 'free' clone
-//
-void memmgr_free(void* ap);
-
-// Prints statistics about the current state of the memory
-// manager
-//
-void memmgr_print_stats();
-
-
-#endif // MEMMGR_H
diff --git a/examples/c_files/year.c b/examples/c_files/year.c
deleted file mode 100644
index 12c4a33..0000000
--- a/examples/c_files/year.c
+++ /dev/null
@@ -1,53 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-void convert(int thousands, int hundreds, int tens, int ones)
-{
-char *num[] = {"", "One", "Two", "Three", "Four", "Five", "Six",
- "Seven", "Eight", "Nine"};
-
-char *for_ten[] = {"", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty",
- "Seventy", "Eighty", "Ninty"};
-
-char *af_ten[] = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen",
- "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Ninteen"};
-
- printf("\nThe year in words is:\n");
-
- printf("%s thousand", num[thousands]);
- if (hundreds != 0)
- printf(" %s hundred", num[hundreds]);
-
- if (tens != 1)
- printf(" %s %s", for_ten[tens], num[ones]);
- else
- printf(" %s", af_ten[ones]);
-}
-
-
-int main()
-{
-int year;
-int n1000, n100, n10, n1;
-
- printf("\nEnter the year (4 digits): ");
- scanf("%d", &year);
-
- if (year > 9999 || year < 1000)
- {
- printf("\nError !! The year must contain 4 digits.");
- exit(EXIT_FAILURE);
- }
-
- n1000 = year/1000;
- n100 = ((year)%1000)/100;
- n10 = (year%100)/10;
- n1 = ((year%10)%10);
-
- convert(n1000, n100, n10, n1);
-
-return 0;
-}
-
-
diff --git a/examples/c_json.py b/examples/c_json.py
deleted file mode 100644
index 2b33360..0000000
--- a/examples/c_json.py
+++ /dev/null
@@ -1,203 +0,0 @@
-#------------------------------------------------------------------------------
-# pycparser: c_json.py
-#
-# by Michael White (@mypalmike)
-#
-# This example includes functions to serialize and deserialize an ast
-# to and from json format. Serializing involves walking the ast and converting
-# each node from a python Node object into a python dict. Deserializing
-# involves the opposite conversion, walking the tree formed by the
-# dict and converting each dict into the specific Node object it represents.
-# The dict itself is serialized and deserialized using the python json module.
-#
-# The dict representation is a fairly direct transformation of the object
-# attributes. Each node in the dict gets one metadata field referring to the
-# specific node class name, _nodetype. Each local attribute (i.e. not linking
-# to child nodes) has a string value or array of string values. Each child
-# attribute is either another dict or an array of dicts, exactly as in the
-# Node object representation. The "coord" attribute, representing the
-# node's location within the source code, is serialized/deserialized from
-# a Coord object into a string of the format "filename:line[:column]".
-#
-# Example TypeDecl node, with IdentifierType child node, represented as a dict:
-# "type": {
-# "_nodetype": "TypeDecl",
-# "coord": "c_files/funky.c:8",
-# "declname": "o",
-# "quals": [],
-# "type": {
-# "_nodetype": "IdentifierType",
-# "coord": "c_files/funky.c:8",
-# "names": [
-# "char"
-# ]
-# }
-# }
-#------------------------------------------------------------------------------
-from __future__ import print_function
-
-import json
-import sys
-import re
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import parse_file, c_ast
-from pycparser.plyparser import Coord
-
-
-RE_CHILD_ARRAY = re.compile(r'(.*)\[(.*)\]')
-RE_INTERNAL_ATTR = re.compile('__.*__')
-
-
-class CJsonError(Exception):
- pass
-
-
-def memodict(fn):
- """ Fast memoization decorator for a function taking a single argument """
- class memodict(dict):
- def __missing__(self, key):
- ret = self[key] = fn(key)
- return ret
- return memodict().__getitem__
-
-
-@memodict
-def child_attrs_of(klass):
- """
- Given a Node class, get a set of child attrs.
- Memoized to avoid highly repetitive string manipulation
-
- """
- non_child_attrs = set(klass.attr_names)
- all_attrs = set([i for i in klass.__slots__ if not RE_INTERNAL_ATTR.match(i)])
- return all_attrs - non_child_attrs
-
-
-def to_dict(node):
- """ Recursively convert an ast into dict representation. """
- klass = node.__class__
-
- result = {}
-
- # Metadata
- result['_nodetype'] = klass.__name__
-
- # Local node attributes
- for attr in klass.attr_names:
- result[attr] = getattr(node, attr)
-
- # Coord object
- if node.coord:
- result['coord'] = str(node.coord)
- else:
- result['coord'] = None
-
- # Child attributes
- for child_name, child in node.children():
- # Child strings are either simple (e.g. 'value') or arrays (e.g. 'block_items[1]')
- match = RE_CHILD_ARRAY.match(child_name)
- if match:
- array_name, array_index = match.groups()
- array_index = int(array_index)
- # arrays come in order, so we verify and append.
- result[array_name] = result.get(array_name, [])
- if array_index != len(result[array_name]):
- raise CJsonError('Internal ast error. Array {} out of order. '
- 'Expected index {}, got {}'.format(
- array_name, len(result[array_name]), array_index))
- result[array_name].append(to_dict(child))
- else:
- result[child_name] = to_dict(child)
-
- # Any child attributes that were missing need "None" values in the json.
- for child_attr in child_attrs_of(klass):
- if child_attr not in result:
- result[child_attr] = None
-
- return result
-
-
-def to_json(node, **kwargs):
- """ Convert ast node to json string """
- return json.dumps(to_dict(node), **kwargs)
-
-
-def file_to_dict(filename):
- """ Load C file into dict representation of ast """
- ast = parse_file(filename, use_cpp=True)
- return to_dict(ast)
-
-
-def file_to_json(filename, **kwargs):
- """ Load C file into json string representation of ast """
- ast = parse_file(filename, use_cpp=True)
- return to_json(ast, **kwargs)
-
-
-def _parse_coord(coord_str):
- """ Parse coord string (file:line[:column]) into Coord object. """
- if coord_str is None:
- return None
-
- vals = coord_str.split(':')
- vals.extend([None] * 3)
- filename, line, column = vals[:3]
- return Coord(filename, line, column)
-
-
-def _convert_to_obj(value):
- """
- Convert an object in the dict representation into an object.
- Note: Mutually recursive with from_dict.
-
- """
- value_type = type(value)
- if value_type == dict:
- return from_dict(value)
- elif value_type == list:
- return [_convert_to_obj(item) for item in value]
- else:
- # String
- return value
-
-
-def from_dict(node_dict):
- """ Recursively build an ast from dict representation """
- class_name = node_dict.pop('_nodetype')
-
- klass = getattr(c_ast, class_name)
-
- # Create a new dict containing the key-value pairs which we can pass
- # to node constructors.
- objs = {}
- for key, value in node_dict.items():
- if key == 'coord':
- objs[key] = _parse_coord(value)
- else:
- objs[key] = _convert_to_obj(value)
-
- # Use keyword parameters, which works thanks to beautifully consistent
- # ast Node initializers.
- return klass(**objs)
-
-
-def from_json(ast_json):
- """ Build an ast from json string representation """
- return from_dict(json.loads(ast_json))
-
-
-#------------------------------------------------------------------------------
-if __name__ == "__main__":
- if len(sys.argv) > 1:
- # Some test code...
- # Do trip from C -> ast -> dict -> ast -> json, then print.
- ast_dict = file_to_dict(sys.argv[1])
- ast = from_dict(ast_dict)
- print(to_json(ast, sort_keys=True, indent=4))
- else:
- print("Please provide a filename as argument")
diff --git a/examples/cdecl.py b/examples/cdecl.py
deleted file mode 100644
index 351efc2..0000000
--- a/examples/cdecl.py
+++ /dev/null
@@ -1,199 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: cdecl.py
-#
-# Example of the CDECL tool using pycparser. CDECL "explains" C type
-# declarations in plain English.
-#
-# The AST generated by pycparser from the given declaration is traversed
-# recursively to build the explanation. Note that the declaration must be a
-# valid external declaration in C. As shown below, typedef can be optionally
-# expanded.
-#
-# For example:
-#
-# c_decl = 'typedef int Node; const Node* (*ar)[10];'
-#
-# explain_c_declaration(c_decl)
-# => ar is a pointer to array[10] of pointer to const Node
-#
-# struct and typedef can be optionally expanded:
-#
-# explain_c_declaration(c_decl, expand_typedef=True)
-# => ar is a pointer to array[10] of pointer to const int
-#
-# c_decl = 'struct P {int x; int y;} p;'
-#
-# explain_c_declaration(c_decl)
-# => p is a struct P
-#
-# explain_c_declaration(c_decl, expand_struct=True)
-# => p is a struct P containing {x is a int, y is a int}
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-import copy
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast
-
-
-def explain_c_declaration(c_decl, expand_struct=False, expand_typedef=False):
- """ Parses the declaration in c_decl and returns a text
- explanation as a string.
-
- The last external node of the string is used, to allow earlier typedefs
- for used types.
-
- expand_struct=True will spell out struct definitions recursively.
- expand_typedef=True will expand typedef'd types.
- """
- parser = c_parser.CParser()
-
- try:
- node = parser.parse(c_decl, filename='<stdin>')
- except c_parser.ParseError:
- e = sys.exc_info()[1]
- return "Parse error:" + str(e)
-
- if (not isinstance(node, c_ast.FileAST) or
- not isinstance(node.ext[-1], c_ast.Decl)
- ):
- return "Not a valid declaration"
-
- try:
- expanded = expand_struct_typedef(node.ext[-1], node,
- expand_struct=expand_struct,
- expand_typedef=expand_typedef)
- except Exception as e:
- return "Not a valid declaration: " + str(e)
-
- return _explain_decl_node(expanded)
-
-
-def _explain_decl_node(decl_node):
- """ Receives a c_ast.Decl note and returns its explanation in
- English.
- """
- storage = ' '.join(decl_node.storage) + ' ' if decl_node.storage else ''
-
- return (decl_node.name +
- " is a " +
- storage +
- _explain_type(decl_node.type))
-
-
-def _explain_type(decl):
- """ Recursively explains a type decl node
- """
- typ = type(decl)
-
- if typ == c_ast.TypeDecl:
- quals = ' '.join(decl.quals) + ' ' if decl.quals else ''
- return quals + _explain_type(decl.type)
- elif typ == c_ast.Typename or typ == c_ast.Decl:
- return _explain_type(decl.type)
- elif typ == c_ast.IdentifierType:
- return ' '.join(decl.names)
- elif typ == c_ast.PtrDecl:
- quals = ' '.join(decl.quals) + ' ' if decl.quals else ''
- return quals + 'pointer to ' + _explain_type(decl.type)
- elif typ == c_ast.ArrayDecl:
- arr = 'array'
- if decl.dim: arr += '[%s]' % decl.dim.value
-
- return arr + " of " + _explain_type(decl.type)
-
- elif typ == c_ast.FuncDecl:
- if decl.args:
- params = [_explain_type(param) for param in decl.args.params]
- args = ', '.join(params)
- else:
- args = ''
-
- return ('function(%s) returning ' % (args) +
- _explain_type(decl.type))
-
- elif typ == c_ast.Struct:
- decls = [_explain_decl_node(mem_decl) for mem_decl in decl.decls]
- members = ', '.join(decls)
-
- return ('struct%s ' % (' ' + decl.name if decl.name else '') +
- ('containing {%s}' % members if members else ''))
-
-
-def expand_struct_typedef(cdecl, file_ast,
- expand_struct=False,
- expand_typedef=False):
- """Expand struct & typedef and return a new expanded node."""
- decl_copy = copy.deepcopy(cdecl)
- _expand_in_place(decl_copy, file_ast, expand_struct, expand_typedef)
- return decl_copy
-
-
-def _expand_in_place(decl, file_ast, expand_struct=False, expand_typedef=False):
- """Recursively expand struct & typedef in place, throw RuntimeError if
- undeclared struct or typedef are used
- """
- typ = type(decl)
-
- if typ in (c_ast.Decl, c_ast.TypeDecl, c_ast.PtrDecl, c_ast.ArrayDecl):
- decl.type = _expand_in_place(decl.type, file_ast, expand_struct,
- expand_typedef)
-
- elif typ == c_ast.Struct:
- if not decl.decls:
- struct = _find_struct(decl.name, file_ast)
- if not struct:
- raise RuntimeError('using undeclared struct %s' % decl.name)
- decl.decls = struct.decls
-
- for i, mem_decl in enumerate(decl.decls):
- decl.decls[i] = _expand_in_place(mem_decl, file_ast, expand_struct,
- expand_typedef)
- if not expand_struct:
- decl.decls = []
-
- elif (typ == c_ast.IdentifierType and
- decl.names[0] not in ('int', 'char')):
- typedef = _find_typedef(decl.names[0], file_ast)
- if not typedef:
- raise RuntimeError('using undeclared type %s' % decl.names[0])
-
- if expand_typedef:
- return typedef.type
-
- return decl
-
-
-def _find_struct(name, file_ast):
- """Receives a struct name and return declared struct object in file_ast
- """
- for node in file_ast.ext:
- if (type(node) == c_ast.Decl and
- type(node.type) == c_ast.Struct and
- node.type.name == name):
- return node.type
-
-
-def _find_typedef(name, file_ast):
- """Receives a type name and return typedef object in file_ast
- """
- for node in file_ast.ext:
- if type(node) == c_ast.Typedef and node.name == name:
- return node
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 1:
- c_decl = sys.argv[1]
- else:
- c_decl = "char *(*(**foo[][8])())[];"
-
- print("Explaining the declaration: " + c_decl + "\n")
- print(explain_c_declaration(c_decl) + "\n")
diff --git a/examples/dump_ast.py b/examples/dump_ast.py
deleted file mode 100644
index 2cff874..0000000
--- a/examples/dump_ast.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: dump_ast.py
-#
-# Basic example of parsing a file and dumping its parsed AST.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import argparse
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast, parse_file
-
-if __name__ == "__main__":
- argparser = argparse.ArgumentParser('Dump AST')
- argparser.add_argument('filename', help='name of file to parse')
- args = argparser.parse_args()
-
- ast = parse_file(args.filename, use_cpp=False)
- ast.show()
diff --git a/examples/explore_ast.py b/examples/explore_ast.py
deleted file mode 100644
index 1f6e0ae..0000000
--- a/examples/explore_ast.py
+++ /dev/null
@@ -1,159 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: explore_ast.py
-#
-# This example demonstrates how to "explore" the AST created by
-# pycparser to understand its structure. The AST is a n-nary tree
-# of nodes, each node having several children, each with a name.
-# Just read the code, and let the comments guide you. The lines
-# beginning with #~ can be uncommented to print out useful
-# information from the AST.
-# It helps to have the pycparser/_c_ast.cfg file in front of you.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast
-
-# This is some C source to parse. Note that pycparser must begin
-# at the top level of the C file, i.e. with either declarations
-# or function definitions (this is called "external declarations"
-# in C grammar lingo)
-#
-# Also, a C parser must have all the types declared in order to
-# build the correct AST. It doesn't matter what they're declared
-# to, so I've inserted the dummy typedef in the code to let the
-# parser know Hash and Node are types. You don't need to do it
-# when parsing real, correct C code.
-
-text = r"""
- typedef int Node, Hash;
-
- void HashPrint(Hash* hash, void (*PrintFunc)(char*, char*))
- {
- unsigned int i;
-
- if (hash == NULL || hash->heads == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- PrintFunc(temp->entry->key, temp->entry->value);
- temp = temp->next;
- }
- }
- }
-"""
-
-# Create the parser and ask to parse the text. parse() will throw
-# a ParseError if there's an error in the code
-#
-parser = c_parser.CParser()
-ast = parser.parse(text, filename='<none>')
-
-# Uncomment the following line to see the AST in a nice, human
-# readable way. show() is the most useful tool in exploring ASTs
-# created by pycparser. See the c_ast.py file for the options you
-# can pass it.
-
-#ast.show(showcoord=True)
-
-# OK, we've seen that the top node is FileAST. This is always the
-# top node of the AST. Its children are "external declarations",
-# and are stored in a list called ext[] (see _c_ast.cfg for the
-# names and types of Nodes and their children).
-# As you see from the printout, our AST has two Typedef children
-# and one FuncDef child.
-# Let's explore FuncDef more closely. As I've mentioned, the list
-# ext[] holds the children of FileAST. Since the function
-# definition is the third child, it's ext[2]. Uncomment the
-# following line to show it:
-
-#ast.ext[2].show()
-
-# A FuncDef consists of a declaration, a list of parameter
-# declarations (for K&R style function definitions), and a body.
-# First, let's examine the declaration.
-
-function_decl = ast.ext[2].decl
-
-# function_decl, like any other declaration, is a Decl. Its type child
-# is a FuncDecl, which has a return type and arguments stored in a
-# ParamList node
-
-#function_decl.type.show()
-#function_decl.type.args.show()
-
-# The following displays the name and type of each argument:
-
-#for param_decl in function_decl.type.args.params:
- #print('Arg name: %s' % param_decl.name)
- #print('Type:')
- #param_decl.type.show(offset=6)
-
-# The body is of FuncDef is a Compound, which is a placeholder for a block
-# surrounded by {} (You should be reading _c_ast.cfg parallel to this
-# explanation and seeing these things with your own eyes).
-# Let's see the block's declarations:
-
-function_body = ast.ext[2].body
-
-# The following displays the declarations and statements in the function
-# body
-
-#for decl in function_body.block_items:
- #decl.show()
-
-# We can see a single variable declaration, i, declared to be a simple type
-# declaration of type 'unsigned int', followed by statements.
-
-# block_items is a list, so the third element is the For statement:
-
-for_stmt = function_body.block_items[2]
-#for_stmt.show()
-
-# As you can see in _c_ast.cfg, For's children are 'init, cond,
-# next' for the respective parts of the 'for' loop specifier,
-# and stmt, which is either a single stmt or a Compound if there's
-# a block.
-#
-# Let's dig deeper, to the while statement inside the for loop:
-
-while_stmt = for_stmt.stmt.block_items[1]
-#while_stmt.show()
-
-# While is simpler, it only has a condition node and a stmt node.
-# The condition:
-
-while_cond = while_stmt.cond
-#while_cond.show()
-
-# Note that it's a BinaryOp node - the basic constituent of
-# expressions in our AST. BinaryOp is the expression tree, with
-# left and right nodes as children. It also has the op attribute,
-# which is just the string representation of the operator.
-
-#print(while_cond.op)
-#while_cond.left.show()
-#while_cond.right.show()
-
-
-# That's it for the example. I hope you now see how easy it is to explore the
-# AST created by pycparser. Although on the surface it is quite complex and has
-# a lot of node types, this is the inherent complexity of the C language every
-# parser/compiler designer has to cope with.
-# Using the tools provided by the c_ast package it's easy to explore the
-# structure of AST nodes and write code that processes them.
-# Specifically, see the cdecl.py example for a non-trivial demonstration of what
-# you can do by recursively going through the AST.
diff --git a/examples/func_calls.py b/examples/func_calls.py
deleted file mode 100644
index ec31fe5..0000000
--- a/examples/func_calls.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: func_calls.py
-#
-# Using pycparser for printing out all the calls of some function
-# in a C file.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast, parse_file
-
-
-# A visitor with some state information (the funcname it's
-# looking for)
-#
-class FuncCallVisitor(c_ast.NodeVisitor):
- def __init__(self, funcname):
- self.funcname = funcname
-
- def visit_FuncCall(self, node):
- if node.name.name == self.funcname:
- print('%s called at %s' % (self.funcname, node.name.coord))
-
-
-def show_func_calls(filename, funcname):
- ast = parse_file(filename, use_cpp=True)
- v = FuncCallVisitor(funcname)
- v.visit(ast)
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 2:
- filename = sys.argv[1]
- func = sys.argv[2]
- else:
- filename = 'examples/c_files/hash.c'
- func = 'malloc'
-
- show_func_calls(filename, func)
diff --git a/examples/func_defs.py b/examples/func_defs.py
deleted file mode 100644
index 8fe9889..0000000
--- a/examples/func_defs.py
+++ /dev/null
@@ -1,46 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: func_defs.py
-#
-# Using pycparser for printing out all the functions defined in a
-# C file.
-#
-# This is a simple example of traversing the AST generated by
-# pycparser. Call it from the root directory of pycparser.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-sys.path.extend(['.', '..'])
-
-from pycparser import c_parser, c_ast, parse_file
-
-
-# A simple visitor for FuncDef nodes that prints the names and
-# locations of function definitions.
-class FuncDefVisitor(c_ast.NodeVisitor):
- def visit_FuncDef(self, node):
- print('%s at %s' % (node.decl.name, node.decl.coord))
-
-
-def show_func_defs(filename):
- # Note that cpp is used. Provide a path to your own cpp or
- # make sure one exists in PATH.
- ast = parse_file(filename, use_cpp=True,
- cpp_args=r'-Iutils/fake_libc_include')
-
- v = FuncDefVisitor()
- v.visit(ast)
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 1:
- filename = sys.argv[1]
- else:
- filename = 'examples/c_files/memmgr.c'
-
- show_func_defs(filename)
diff --git a/examples/rewrite_ast.py b/examples/rewrite_ast.py
deleted file mode 100644
index 2c42f99..0000000
--- a/examples/rewrite_ast.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: rewrite_ast.py
-#
-# Tiny example of rewriting a AST node
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import sys
-
-from pycparser import c_parser
-
-text = r"""
-void func(void)
-{
- x = 1;
-}
-"""
-
-parser = c_parser.CParser()
-ast = parser.parse(text)
-print("Before:")
-ast.show(offset=2)
-
-assign = ast.ext[0].body.block_items[0]
-assign.lvalue.name = "y"
-assign.rvalue.value = 2
-
-print("After:")
-ast.show(offset=2)
diff --git a/examples/serialize_ast.py b/examples/serialize_ast.py
deleted file mode 100644
index e0f8aa3..0000000
--- a/examples/serialize_ast.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: serialize_ast.py
-#
-# Simple example of serializing AST
-#
-# Hart Chu [https://github.com/CtheSky]
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-from __future__ import print_function
-import pickle
-
-from pycparser import c_parser
-
-text = r"""
-void func(void)
-{
- x = 1;
-}
-"""
-
-parser = c_parser.CParser()
-ast = parser.parse(text)
-
-# Since AST nodes use __slots__ for faster attribute access and
-# space saving, it needs Pickle's protocol version >= 2.
-# The default version is 3 for python 3.x and 1 for python 2.7.
-# You can always select the highest available protocol with the -1 argument.
-
-with open('ast', 'wb') as f:
- pickle.dump(ast, f, protocol=-1)
-
-# Deserialize.
-with open('ast', 'rb') as f:
- ast = pickle.load(f)
- ast.show()
diff --git a/examples/using_cpp_libc.py b/examples/using_cpp_libc.py
deleted file mode 100644
index e930f5b..0000000
--- a/examples/using_cpp_libc.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: using_cpp_libc.py
-#
-# Shows how to use the provided 'cpp' (on Windows, substitute for
-# the 'real' cpp if you're on Linux/Unix) and "fake" libc includes
-# to parse a file that includes standard C headers.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import parse_file
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 1:
- filename = sys.argv[1]
- else:
- filename = 'examples/c_files/year.c'
-
- ast = parse_file(filename, use_cpp=True,
- cpp_path='cpp',
- cpp_args=r'-Iutils/fake_libc_include')
- ast.show()
diff --git a/examples/using_gcc_E_libc.py b/examples/using_gcc_E_libc.py
deleted file mode 100644
index bba4d3d..0000000
--- a/examples/using_gcc_E_libc.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#-------------------------------------------------------------------------------
-# pycparser: using_gcc_E_libc.py
-#
-# Similar to the using_cpp_libc.py example, but uses 'gcc -E' instead
-# of 'cpp'. The same can be achieved with Clang instead of gcc. If you have
-# Clang installed, simply replace 'gcc' with 'clang' here.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-------------------------------------------------------------------------------
-import sys
-
-# This is not required if you've installed pycparser into
-# your site-packages/ with setup.py
-#
-sys.path.extend(['.', '..'])
-
-from pycparser import parse_file
-
-
-if __name__ == "__main__":
- if len(sys.argv) > 1:
- filename = sys.argv[1]
- else:
- filename = 'examples/c_files/year.c'
-
- ast = parse_file(filename, use_cpp=True,
- cpp_path='gcc',
- cpp_args=['-E', r'-Iutils/fake_libc_include'])
- ast.show()
diff --git a/pycparser/Android.bp b/pycparser/Android.bp
deleted file mode 100644
index 4fee1fb..0000000
--- a/pycparser/Android.bp
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2019 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-python_library {
- name: "py-pycparser",
- host_supported: true,
- srcs: [
- "*.py",
- "ply/*.py",
- ],
- data: [
- "_c_ast.cfg",
- ],
- version: {
- py2: {
- enabled: true,
- },
- py3: {
- enabled: true,
- },
- },
- pkg_path: "pycparser",
-}
diff --git a/pycparser/__init__.py b/pycparser/__init__.py
deleted file mode 100644
index b67389f..0000000
--- a/pycparser/__init__.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: __init__.py
-#
-# This package file exports some convenience functions for
-# interacting with pycparser
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-__all__ = ['c_lexer', 'c_parser', 'c_ast']
-__version__ = '2.19'
-
-import io
-from subprocess import check_output
-from .c_parser import CParser
-
-
-def preprocess_file(filename, cpp_path='cpp', cpp_args=''):
- """ Preprocess a file using cpp.
-
- filename:
- Name of the file you want to preprocess.
-
- cpp_path:
- cpp_args:
- Refer to the documentation of parse_file for the meaning of these
- arguments.
-
- When successful, returns the preprocessed file's contents.
- Errors from cpp will be printed out.
- """
- path_list = [cpp_path]
- if isinstance(cpp_args, list):
- path_list += cpp_args
- elif cpp_args != '':
- path_list += [cpp_args]
- path_list += [filename]
-
- try:
- # Note the use of universal_newlines to treat all newlines
- # as \n for Python's purpose
- text = check_output(path_list, universal_newlines=True)
- except OSError as e:
- raise RuntimeError("Unable to invoke 'cpp'. " +
- 'Make sure its path was passed correctly\n' +
- ('Original error: %s' % e))
-
- return text
-
-
-def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',
- parser=None):
- """ Parse a C file using pycparser.
-
- filename:
- Name of the file you want to parse.
-
- use_cpp:
- Set to True if you want to execute the C pre-processor
- on the file prior to parsing it.
-
- cpp_path:
- If use_cpp is True, this is the path to 'cpp' on your
- system. If no path is provided, it attempts to just
- execute 'cpp', so it must be in your PATH.
-
- cpp_args:
- If use_cpp is True, set this to the command line arguments strings
- to cpp. Be careful with quotes - it's best to pass a raw string
- (r'') here. For example:
- r'-I../utils/fake_libc_include'
- If several arguments are required, pass a list of strings.
-
- parser:
- Optional parser object to be used instead of the default CParser
-
- When successful, an AST is returned. ParseError can be
- thrown if the file doesn't parse successfully.
-
- Errors from cpp will be printed out.
- """
- if use_cpp:
- text = preprocess_file(filename, cpp_path, cpp_args)
- else:
- with io.open(filename) as f:
- text = f.read()
-
- if parser is None:
- parser = CParser()
- return parser.parse(text, filename)
diff --git a/pycparser/_ast_gen.py b/pycparser/_ast_gen.py
deleted file mode 100644
index 5ec2d3d..0000000
--- a/pycparser/_ast_gen.py
+++ /dev/null
@@ -1,338 +0,0 @@
-#-----------------------------------------------------------------
-# _ast_gen.py
-#
-# Generates the AST Node classes from a specification given in
-# a configuration file
-#
-# The design of this module was inspired by astgen.py from the
-# Python 2.5 code-base.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-import pprint
-from string import Template
-
-
-class ASTCodeGenerator(object):
- def __init__(self, cfg_filename='_c_ast.cfg'):
- """ Initialize the code generator from a configuration
- file.
- """
- self.cfg_filename = cfg_filename
- self.node_cfg = [NodeCfg(name, contents)
- for (name, contents) in self.parse_cfgfile(cfg_filename)]
-
- def generate(self, file=None):
- """ Generates the code into file, an open file buffer.
- """
- src = Template(_PROLOGUE_COMMENT).substitute(
- cfg_filename=self.cfg_filename)
-
- src += _PROLOGUE_CODE
- for node_cfg in self.node_cfg:
- src += node_cfg.generate_source() + '\n\n'
-
- file.write(src)
-
- def parse_cfgfile(self, filename):
- """ Parse the configuration file and yield pairs of
- (name, contents) for each node.
- """
- with open(filename, "r") as f:
- for line in f:
- line = line.strip()
- if not line or line.startswith('#'):
- continue
- colon_i = line.find(':')
- lbracket_i = line.find('[')
- rbracket_i = line.find(']')
- if colon_i < 1 or lbracket_i <= colon_i or rbracket_i <= lbracket_i:
- raise RuntimeError("Invalid line in %s:\n%s\n" % (filename, line))
-
- name = line[:colon_i]
- val = line[lbracket_i + 1:rbracket_i]
- vallist = [v.strip() for v in val.split(',')] if val else []
- yield name, vallist
-
-
-class NodeCfg(object):
- """ Node configuration.
-
- name: node name
- contents: a list of contents - attributes and child nodes
- See comment at the top of the configuration file for details.
- """
-
- def __init__(self, name, contents):
- self.name = name
- self.all_entries = []
- self.attr = []
- self.child = []
- self.seq_child = []
-
- for entry in contents:
- clean_entry = entry.rstrip('*')
- self.all_entries.append(clean_entry)
-
- if entry.endswith('**'):
- self.seq_child.append(clean_entry)
- elif entry.endswith('*'):
- self.child.append(clean_entry)
- else:
- self.attr.append(entry)
-
- def generate_source(self):
- src = self._gen_init()
- src += '\n' + self._gen_children()
- src += '\n' + self._gen_iter()
-
- src += '\n' + self._gen_attr_names()
- return src
-
- def _gen_init(self):
- src = "class %s(Node):\n" % self.name
-
- if self.all_entries:
- args = ', '.join(self.all_entries)
- slots = ', '.join("'{0}'".format(e) for e in self.all_entries)
- slots += ", 'coord', '__weakref__'"
- arglist = '(self, %s, coord=None)' % args
- else:
- slots = "'coord', '__weakref__'"
- arglist = '(self, coord=None)'
-
- src += " __slots__ = (%s)\n" % slots
- src += " def __init__%s:\n" % arglist
-
- for name in self.all_entries + ['coord']:
- src += " self.%s = %s\n" % (name, name)
-
- return src
-
- def _gen_children(self):
- src = ' def children(self):\n'
-
- if self.all_entries:
- src += ' nodelist = []\n'
-
- for child in self.child:
- src += (
- ' if self.%(child)s is not None:' +
- ' nodelist.append(("%(child)s", self.%(child)s))\n') % (
- dict(child=child))
-
- for seq_child in self.seq_child:
- src += (
- ' for i, child in enumerate(self.%(child)s or []):\n'
- ' nodelist.append(("%(child)s[%%d]" %% i, child))\n') % (
- dict(child=seq_child))
-
- src += ' return tuple(nodelist)\n'
- else:
- src += ' return ()\n'
-
- return src
-
- def _gen_iter(self):
- src = ' def __iter__(self):\n'
-
- if self.all_entries:
- for child in self.child:
- src += (
- ' if self.%(child)s is not None:\n' +
- ' yield self.%(child)s\n') % (dict(child=child))
-
- for seq_child in self.seq_child:
- src += (
- ' for child in (self.%(child)s or []):\n'
- ' yield child\n') % (dict(child=seq_child))
-
- if not (self.child or self.seq_child):
- # Empty generator
- src += (
- ' return\n' +
- ' yield\n')
- else:
- # Empty generator
- src += (
- ' return\n' +
- ' yield\n')
-
- return src
-
- def _gen_attr_names(self):
- src = " attr_names = (" + ''.join("%r, " % nm for nm in self.attr) + ')'
- return src
-
-
-_PROLOGUE_COMMENT = \
-r'''#-----------------------------------------------------------------
-# ** ATTENTION **
-# This code was automatically generated from the file:
-# $cfg_filename
-#
-# Do not modify it directly. Modify the configuration file and
-# run the generator again.
-# ** ** *** ** **
-#
-# pycparser: c_ast.py
-#
-# AST Node classes.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-
-'''
-
-_PROLOGUE_CODE = r'''
-import sys
-
-def _repr(obj):
- """
- Get the representation of an object, with dedicated pprint-like format for lists.
- """
- if isinstance(obj, list):
- return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]'
- else:
- return repr(obj)
-
-class Node(object):
- __slots__ = ()
- """ Abstract base class for AST nodes.
- """
- def __repr__(self):
- """ Generates a python representation of the current node
- """
- result = self.__class__.__name__ + '('
-
- indent = ''
- separator = ''
- for name in self.__slots__[:-2]:
- result += separator
- result += indent
- result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__)))))
-
- separator = ','
- indent = '\n ' + (' ' * len(self.__class__.__name__))
-
- result += indent + ')'
-
- return result
-
- def children(self):
- """ A sequence of all children that are Nodes
- """
- pass
-
- def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):
- """ Pretty print the Node and all its attributes and
- children (recursively) to a buffer.
-
- buf:
- Open IO buffer into which the Node is printed.
-
- offset:
- Initial offset (amount of leading spaces)
-
- attrnames:
- True if you want to see the attribute names in
- name=value pairs. False to only see the values.
-
- nodenames:
- True if you want to see the actual node names
- within their parents.
-
- showcoord:
- Do you want the coordinates of each Node to be
- displayed.
- """
- lead = ' ' * offset
- if nodenames and _my_node_name is not None:
- buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ')
- else:
- buf.write(lead + self.__class__.__name__+ ': ')
-
- if self.attr_names:
- if attrnames:
- nvlist = [(n, getattr(self,n)) for n in self.attr_names]
- attrstr = ', '.join('%s=%s' % nv for nv in nvlist)
- else:
- vlist = [getattr(self, n) for n in self.attr_names]
- attrstr = ', '.join('%s' % v for v in vlist)
- buf.write(attrstr)
-
- if showcoord:
- buf.write(' (at %s)' % self.coord)
- buf.write('\n')
-
- for (child_name, child) in self.children():
- child.show(
- buf,
- offset=offset + 2,
- attrnames=attrnames,
- nodenames=nodenames,
- showcoord=showcoord,
- _my_node_name=child_name)
-
-
-class NodeVisitor(object):
- """ A base NodeVisitor class for visiting c_ast nodes.
- Subclass it and define your own visit_XXX methods, where
- XXX is the class name you want to visit with these
- methods.
-
- For example:
-
- class ConstantVisitor(NodeVisitor):
- def __init__(self):
- self.values = []
-
- def visit_Constant(self, node):
- self.values.append(node.value)
-
- Creates a list of values of all the constant nodes
- encountered below the given node. To use it:
-
- cv = ConstantVisitor()
- cv.visit(node)
-
- Notes:
-
- * generic_visit() will be called for AST nodes for which
- no visit_XXX method was defined.
- * The children of nodes for which a visit_XXX was
- defined will not be visited - if you need this, call
- generic_visit() on the node.
- You can use:
- NodeVisitor.generic_visit(self, node)
- * Modeled after Python's own AST visiting facilities
- (the ast module of Python 3.0)
- """
-
- _method_cache = None
-
- def visit(self, node):
- """ Visit a node.
- """
-
- if self._method_cache is None:
- self._method_cache = {}
-
- visitor = self._method_cache.get(node.__class__.__name__, None)
- if visitor is None:
- method = 'visit_' + node.__class__.__name__
- visitor = getattr(self, method, self.generic_visit)
- self._method_cache[node.__class__.__name__] = visitor
-
- return visitor(node)
-
- def generic_visit(self, node):
- """ Called if no explicit visitor function exists for a
- node. Implements preorder visiting of the node.
- """
- for c in node:
- self.visit(c)
-
-'''
diff --git a/pycparser/_build_tables.py b/pycparser/_build_tables.py
deleted file mode 100644
index 94a3891..0000000
--- a/pycparser/_build_tables.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: _build_tables.py
-#
-# A dummy for generating the lexing/parsing tables and and
-# compiling them into .pyc for faster execution in optimized mode.
-# Also generates AST code from the configuration file.
-# Should be called from the pycparser directory.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-
-# Generate c_ast.py
-from _ast_gen import ASTCodeGenerator
-ast_gen = ASTCodeGenerator('_c_ast.cfg')
-ast_gen.generate(open('c_ast.py', 'w'))
-
-import sys
-sys.path[0:0] = ['.', '..']
-from pycparser import c_parser
-
-# Generates the tables
-#
-c_parser.CParser(
- lex_optimize=True,
- yacc_debug=False,
- yacc_optimize=True)
-
-# Load to compile into .pyc
-#
-import lextab
-import yacctab
-import c_ast
diff --git a/pycparser/_c_ast.cfg b/pycparser/_c_ast.cfg
deleted file mode 100644
index b93d50b..0000000
--- a/pycparser/_c_ast.cfg
+++ /dev/null
@@ -1,191 +0,0 @@
-#-----------------------------------------------------------------
-# pycparser: _c_ast.cfg
-#
-# Defines the AST Node classes used in pycparser.
-#
-# Each entry is a Node sub-class name, listing the attributes
-# and child nodes of the class:
-# <name>* - a child node
-# <name>** - a sequence of child nodes
-# <name> - an attribute
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-
-# ArrayDecl is a nested declaration of an array with the given type.
-# dim: the dimension (for example, constant 42)
-# dim_quals: list of dimension qualifiers, to support C99's allowing 'const'
-# and 'static' within the array dimension in function declarations.
-ArrayDecl: [type*, dim*, dim_quals]
-
-ArrayRef: [name*, subscript*]
-
-# op: =, +=, /= etc.
-#
-Assignment: [op, lvalue*, rvalue*]
-
-BinaryOp: [op, left*, right*]
-
-Break: []
-
-Case: [expr*, stmts**]
-
-Cast: [to_type*, expr*]
-
-# Compound statement in C99 is a list of block items (declarations or
-# statements).
-#
-Compound: [block_items**]
-
-# Compound literal (anonymous aggregate) for C99.
-# (type-name) {initializer_list}
-# type: the typename
-# init: InitList for the initializer list
-#
-CompoundLiteral: [type*, init*]
-
-# type: int, char, float, etc. see CLexer for constant token types
-#
-Constant: [type, value]
-
-Continue: []
-
-# name: the variable being declared
-# quals: list of qualifiers (const, volatile)
-# funcspec: list function specifiers (i.e. inline in C99)
-# storage: list of storage specifiers (extern, register, etc.)
-# type: declaration type (probably nested with all the modifiers)
-# init: initialization value, or None
-# bitsize: bit field size, or None
-#
-Decl: [name, quals, storage, funcspec, type*, init*, bitsize*]
-
-DeclList: [decls**]
-
-Default: [stmts**]
-
-DoWhile: [cond*, stmt*]
-
-# Represents the ellipsis (...) parameter in a function
-# declaration
-#
-EllipsisParam: []
-
-# An empty statement (a semicolon ';' on its own)
-#
-EmptyStatement: []
-
-# Enumeration type specifier
-# name: an optional ID
-# values: an EnumeratorList
-#
-Enum: [name, values*]
-
-# A name/value pair for enumeration values
-#
-Enumerator: [name, value*]
-
-# A list of enumerators
-#
-EnumeratorList: [enumerators**]
-
-# A list of expressions separated by the comma operator.
-#
-ExprList: [exprs**]
-
-# This is the top of the AST, representing a single C file (a
-# translation unit in K&R jargon). It contains a list of
-# "external-declaration"s, which is either declarations (Decl),
-# Typedef or function definitions (FuncDef).
-#
-FileAST: [ext**]
-
-# for (init; cond; next) stmt
-#
-For: [init*, cond*, next*, stmt*]
-
-# name: Id
-# args: ExprList
-#
-FuncCall: [name*, args*]
-
-# type <decl>(args)
-#
-FuncDecl: [args*, type*]
-
-# Function definition: a declarator for the function name and
-# a body, which is a compound statement.
-# There's an optional list of parameter declarations for old
-# K&R-style definitions
-#
-FuncDef: [decl*, param_decls**, body*]
-
-Goto: [name]
-
-ID: [name]
-
-# Holder for types that are a simple identifier (e.g. the built
-# ins void, char etc. and typedef-defined types)
-#
-IdentifierType: [names]
-
-If: [cond*, iftrue*, iffalse*]
-
-# An initialization list used for compound literals.
-#
-InitList: [exprs**]
-
-Label: [name, stmt*]
-
-# A named initializer for C99.
-# The name of a NamedInitializer is a sequence of Nodes, because
-# names can be hierarchical and contain constant expressions.
-#
-NamedInitializer: [name**, expr*]
-
-# a list of comma separated function parameter declarations
-#
-ParamList: [params**]
-
-PtrDecl: [quals, type*]
-
-Return: [expr*]
-
-# name: struct tag name
-# decls: declaration of members
-#
-Struct: [name, decls**]
-
-# type: . or ->
-# name.field or name->field
-#
-StructRef: [name*, type, field*]
-
-Switch: [cond*, stmt*]
-
-# cond ? iftrue : iffalse
-#
-TernaryOp: [cond*, iftrue*, iffalse*]
-
-# A base type declaration
-#
-TypeDecl: [declname, quals, type*]
-
-# A typedef declaration.
-# Very similar to Decl, but without some attributes
-#
-Typedef: [name, quals, storage, type*]
-
-Typename: [name, quals, type*]
-
-UnaryOp: [op, expr*]
-
-# name: union tag name
-# decls: declaration of members
-#
-Union: [name, decls**]
-
-While: [cond*, stmt*]
-
-Pragma: [string]
diff --git a/pycparser/ast_transforms.py b/pycparser/ast_transforms.py
deleted file mode 100644
index ba50966..0000000
--- a/pycparser/ast_transforms.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#------------------------------------------------------------------------------
-# pycparser: ast_transforms.py
-#
-# Some utilities used by the parser to create a friendlier AST.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#------------------------------------------------------------------------------
-
-from . import c_ast
-
-
-def fix_switch_cases(switch_node):
- """ The 'case' statements in a 'switch' come out of parsing with one
- child node, so subsequent statements are just tucked to the parent
- Compound. Additionally, consecutive (fall-through) case statements
- come out messy. This is a peculiarity of the C grammar. The following:
-
- switch (myvar) {
- case 10:
- k = 10;
- p = k + 1;
- return 10;
- case 20:
- case 30:
- return 20;
- default:
- break;
- }
-
- Creates this tree (pseudo-dump):
-
- Switch
- ID: myvar
- Compound:
- Case 10:
- k = 10
- p = k + 1
- return 10
- Case 20:
- Case 30:
- return 20
- Default:
- break
-
- The goal of this transform is to fix this mess, turning it into the
- following:
-
- Switch
- ID: myvar
- Compound:
- Case 10:
- k = 10
- p = k + 1
- return 10
- Case 20:
- Case 30:
- return 20
- Default:
- break
-
- A fixed AST node is returned. The argument may be modified.
- """
- assert isinstance(switch_node, c_ast.Switch)
- if not isinstance(switch_node.stmt, c_ast.Compound):
- return switch_node
-
- # The new Compound child for the Switch, which will collect children in the
- # correct order
- new_compound = c_ast.Compound([], switch_node.stmt.coord)
-
- # The last Case/Default node
- last_case = None
-
- # Goes over the children of the Compound below the Switch, adding them
- # either directly below new_compound or below the last Case as appropriate
- for child in switch_node.stmt.block_items:
- if isinstance(child, (c_ast.Case, c_ast.Default)):
- # If it's a Case/Default:
- # 1. Add it to the Compound and mark as "last case"
- # 2. If its immediate child is also a Case or Default, promote it
- # to a sibling.
- new_compound.block_items.append(child)
- _extract_nested_case(child, new_compound.block_items)
- last_case = new_compound.block_items[-1]
- else:
- # Other statements are added as children to the last case, if it
- # exists.
- if last_case is None:
- new_compound.block_items.append(child)
- else:
- last_case.stmts.append(child)
-
- switch_node.stmt = new_compound
- return switch_node
-
-
-def _extract_nested_case(case_node, stmts_list):
- """ Recursively extract consecutive Case statements that are made nested
- by the parser and add them to the stmts_list.
- """
- if isinstance(case_node.stmts[0], (c_ast.Case, c_ast.Default)):
- stmts_list.append(case_node.stmts.pop())
- _extract_nested_case(stmts_list[-1], stmts_list)
-
diff --git a/pycparser/c_ast.py b/pycparser/c_ast.py
deleted file mode 100644
index b7bbbee..0000000
--- a/pycparser/c_ast.py
+++ /dev/null
@@ -1,1084 +0,0 @@
-#-----------------------------------------------------------------
-# ** ATTENTION **
-# This code was automatically generated from the file:
-# _c_ast.cfg
-#
-# Do not modify it directly. Modify the configuration file and
-# run the generator again.
-# ** ** *** ** **
-#
-# pycparser: c_ast.py
-#
-# AST Node classes.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-
-
-import sys
-
-def _repr(obj):
- """
- Get the representation of an object, with dedicated pprint-like format for lists.
- """
- if isinstance(obj, list):
- return '[' + (',\n '.join((_repr(e).replace('\n', '\n ') for e in obj))) + '\n]'
- else:
- return repr(obj)
-
-class Node(object):
- __slots__ = ()
- """ Abstract base class for AST nodes.
- """
- def __repr__(self):
- """ Generates a python representation of the current node
- """
- result = self.__class__.__name__ + '('
-
- indent = ''
- separator = ''
- for name in self.__slots__[:-2]:
- result += separator
- result += indent
- result += name + '=' + (_repr(getattr(self, name)).replace('\n', '\n ' + (' ' * (len(name) + len(self.__class__.__name__)))))
-
- separator = ','
- indent = '\n ' + (' ' * len(self.__class__.__name__))
-
- result += indent + ')'
-
- return result
-
- def children(self):
- """ A sequence of all children that are Nodes
- """
- pass
-
- def show(self, buf=sys.stdout, offset=0, attrnames=False, nodenames=False, showcoord=False, _my_node_name=None):
- """ Pretty print the Node and all its attributes and
- children (recursively) to a buffer.
-
- buf:
- Open IO buffer into which the Node is printed.
-
- offset:
- Initial offset (amount of leading spaces)
-
- attrnames:
- True if you want to see the attribute names in
- name=value pairs. False to only see the values.
-
- nodenames:
- True if you want to see the actual node names
- within their parents.
-
- showcoord:
- Do you want the coordinates of each Node to be
- displayed.
- """
- lead = ' ' * offset
- if nodenames and _my_node_name is not None:
- buf.write(lead + self.__class__.__name__+ ' <' + _my_node_name + '>: ')
- else:
- buf.write(lead + self.__class__.__name__+ ': ')
-
- if self.attr_names:
- if attrnames:
- nvlist = [(n, getattr(self,n)) for n in self.attr_names]
- attrstr = ', '.join('%s=%s' % nv for nv in nvlist)
- else:
- vlist = [getattr(self, n) for n in self.attr_names]
- attrstr = ', '.join('%s' % v for v in vlist)
- buf.write(attrstr)
-
- if showcoord:
- buf.write(' (at %s)' % self.coord)
- buf.write('\n')
-
- for (child_name, child) in self.children():
- child.show(
- buf,
- offset=offset + 2,
- attrnames=attrnames,
- nodenames=nodenames,
- showcoord=showcoord,
- _my_node_name=child_name)
-
-
-class NodeVisitor(object):
- """ A base NodeVisitor class for visiting c_ast nodes.
- Subclass it and define your own visit_XXX methods, where
- XXX is the class name you want to visit with these
- methods.
-
- For example:
-
- class ConstantVisitor(NodeVisitor):
- def __init__(self):
- self.values = []
-
- def visit_Constant(self, node):
- self.values.append(node.value)
-
- Creates a list of values of all the constant nodes
- encountered below the given node. To use it:
-
- cv = ConstantVisitor()
- cv.visit(node)
-
- Notes:
-
- * generic_visit() will be called for AST nodes for which
- no visit_XXX method was defined.
- * The children of nodes for which a visit_XXX was
- defined will not be visited - if you need this, call
- generic_visit() on the node.
- You can use:
- NodeVisitor.generic_visit(self, node)
- * Modeled after Python's own AST visiting facilities
- (the ast module of Python 3.0)
- """
-
- _method_cache = None
-
- def visit(self, node):
- """ Visit a node.
- """
-
- if self._method_cache is None:
- self._method_cache = {}
-
- visitor = self._method_cache.get(node.__class__.__name__, None)
- if visitor is None:
- method = 'visit_' + node.__class__.__name__
- visitor = getattr(self, method, self.generic_visit)
- self._method_cache[node.__class__.__name__] = visitor
-
- return visitor(node)
-
- def generic_visit(self, node):
- """ Called if no explicit visitor function exists for a
- node. Implements preorder visiting of the node.
- """
- for c in node:
- self.visit(c)
-
-class ArrayDecl(Node):
- __slots__ = ('type', 'dim', 'dim_quals', 'coord', '__weakref__')
- def __init__(self, type, dim, dim_quals, coord=None):
- self.type = type
- self.dim = dim
- self.dim_quals = dim_quals
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- if self.dim is not None: nodelist.append(("dim", self.dim))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
- if self.dim is not None:
- yield self.dim
-
- attr_names = ('dim_quals', )
-
-class ArrayRef(Node):
- __slots__ = ('name', 'subscript', 'coord', '__weakref__')
- def __init__(self, name, subscript, coord=None):
- self.name = name
- self.subscript = subscript
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.name is not None: nodelist.append(("name", self.name))
- if self.subscript is not None: nodelist.append(("subscript", self.subscript))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.name is not None:
- yield self.name
- if self.subscript is not None:
- yield self.subscript
-
- attr_names = ()
-
-class Assignment(Node):
- __slots__ = ('op', 'lvalue', 'rvalue', 'coord', '__weakref__')
- def __init__(self, op, lvalue, rvalue, coord=None):
- self.op = op
- self.lvalue = lvalue
- self.rvalue = rvalue
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.lvalue is not None: nodelist.append(("lvalue", self.lvalue))
- if self.rvalue is not None: nodelist.append(("rvalue", self.rvalue))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.lvalue is not None:
- yield self.lvalue
- if self.rvalue is not None:
- yield self.rvalue
-
- attr_names = ('op', )
-
-class BinaryOp(Node):
- __slots__ = ('op', 'left', 'right', 'coord', '__weakref__')
- def __init__(self, op, left, right, coord=None):
- self.op = op
- self.left = left
- self.right = right
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.left is not None: nodelist.append(("left", self.left))
- if self.right is not None: nodelist.append(("right", self.right))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.left is not None:
- yield self.left
- if self.right is not None:
- yield self.right
-
- attr_names = ('op', )
-
-class Break(Node):
- __slots__ = ('coord', '__weakref__')
- def __init__(self, coord=None):
- self.coord = coord
-
- def children(self):
- return ()
-
- def __iter__(self):
- return
- yield
-
- attr_names = ()
-
-class Case(Node):
- __slots__ = ('expr', 'stmts', 'coord', '__weakref__')
- def __init__(self, expr, stmts, coord=None):
- self.expr = expr
- self.stmts = stmts
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.expr is not None: nodelist.append(("expr", self.expr))
- for i, child in enumerate(self.stmts or []):
- nodelist.append(("stmts[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.expr is not None:
- yield self.expr
- for child in (self.stmts or []):
- yield child
-
- attr_names = ()
-
-class Cast(Node):
- __slots__ = ('to_type', 'expr', 'coord', '__weakref__')
- def __init__(self, to_type, expr, coord=None):
- self.to_type = to_type
- self.expr = expr
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.to_type is not None: nodelist.append(("to_type", self.to_type))
- if self.expr is not None: nodelist.append(("expr", self.expr))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.to_type is not None:
- yield self.to_type
- if self.expr is not None:
- yield self.expr
-
- attr_names = ()
-
-class Compound(Node):
- __slots__ = ('block_items', 'coord', '__weakref__')
- def __init__(self, block_items, coord=None):
- self.block_items = block_items
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.block_items or []):
- nodelist.append(("block_items[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.block_items or []):
- yield child
-
- attr_names = ()
-
-class CompoundLiteral(Node):
- __slots__ = ('type', 'init', 'coord', '__weakref__')
- def __init__(self, type, init, coord=None):
- self.type = type
- self.init = init
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- if self.init is not None: nodelist.append(("init", self.init))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
- if self.init is not None:
- yield self.init
-
- attr_names = ()
-
-class Constant(Node):
- __slots__ = ('type', 'value', 'coord', '__weakref__')
- def __init__(self, type, value, coord=None):
- self.type = type
- self.value = value
- self.coord = coord
-
- def children(self):
- nodelist = []
- return tuple(nodelist)
-
- def __iter__(self):
- return
- yield
-
- attr_names = ('type', 'value', )
-
-class Continue(Node):
- __slots__ = ('coord', '__weakref__')
- def __init__(self, coord=None):
- self.coord = coord
-
- def children(self):
- return ()
-
- def __iter__(self):
- return
- yield
-
- attr_names = ()
-
-class Decl(Node):
- __slots__ = ('name', 'quals', 'storage', 'funcspec', 'type', 'init', 'bitsize', 'coord', '__weakref__')
- def __init__(self, name, quals, storage, funcspec, type, init, bitsize, coord=None):
- self.name = name
- self.quals = quals
- self.storage = storage
- self.funcspec = funcspec
- self.type = type
- self.init = init
- self.bitsize = bitsize
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- if self.init is not None: nodelist.append(("init", self.init))
- if self.bitsize is not None: nodelist.append(("bitsize", self.bitsize))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
- if self.init is not None:
- yield self.init
- if self.bitsize is not None:
- yield self.bitsize
-
- attr_names = ('name', 'quals', 'storage', 'funcspec', )
-
-class DeclList(Node):
- __slots__ = ('decls', 'coord', '__weakref__')
- def __init__(self, decls, coord=None):
- self.decls = decls
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.decls or []):
- nodelist.append(("decls[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.decls or []):
- yield child
-
- attr_names = ()
-
-class Default(Node):
- __slots__ = ('stmts', 'coord', '__weakref__')
- def __init__(self, stmts, coord=None):
- self.stmts = stmts
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.stmts or []):
- nodelist.append(("stmts[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.stmts or []):
- yield child
-
- attr_names = ()
-
-class DoWhile(Node):
- __slots__ = ('cond', 'stmt', 'coord', '__weakref__')
- def __init__(self, cond, stmt, coord=None):
- self.cond = cond
- self.stmt = stmt
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.cond is not None: nodelist.append(("cond", self.cond))
- if self.stmt is not None: nodelist.append(("stmt", self.stmt))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.cond is not None:
- yield self.cond
- if self.stmt is not None:
- yield self.stmt
-
- attr_names = ()
-
-class EllipsisParam(Node):
- __slots__ = ('coord', '__weakref__')
- def __init__(self, coord=None):
- self.coord = coord
-
- def children(self):
- return ()
-
- def __iter__(self):
- return
- yield
-
- attr_names = ()
-
-class EmptyStatement(Node):
- __slots__ = ('coord', '__weakref__')
- def __init__(self, coord=None):
- self.coord = coord
-
- def children(self):
- return ()
-
- def __iter__(self):
- return
- yield
-
- attr_names = ()
-
-class Enum(Node):
- __slots__ = ('name', 'values', 'coord', '__weakref__')
- def __init__(self, name, values, coord=None):
- self.name = name
- self.values = values
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.values is not None: nodelist.append(("values", self.values))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.values is not None:
- yield self.values
-
- attr_names = ('name', )
-
-class Enumerator(Node):
- __slots__ = ('name', 'value', 'coord', '__weakref__')
- def __init__(self, name, value, coord=None):
- self.name = name
- self.value = value
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.value is not None: nodelist.append(("value", self.value))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.value is not None:
- yield self.value
-
- attr_names = ('name', )
-
-class EnumeratorList(Node):
- __slots__ = ('enumerators', 'coord', '__weakref__')
- def __init__(self, enumerators, coord=None):
- self.enumerators = enumerators
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.enumerators or []):
- nodelist.append(("enumerators[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.enumerators or []):
- yield child
-
- attr_names = ()
-
-class ExprList(Node):
- __slots__ = ('exprs', 'coord', '__weakref__')
- def __init__(self, exprs, coord=None):
- self.exprs = exprs
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.exprs or []):
- nodelist.append(("exprs[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.exprs or []):
- yield child
-
- attr_names = ()
-
-class FileAST(Node):
- __slots__ = ('ext', 'coord', '__weakref__')
- def __init__(self, ext, coord=None):
- self.ext = ext
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.ext or []):
- nodelist.append(("ext[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.ext or []):
- yield child
-
- attr_names = ()
-
-class For(Node):
- __slots__ = ('init', 'cond', 'next', 'stmt', 'coord', '__weakref__')
- def __init__(self, init, cond, next, stmt, coord=None):
- self.init = init
- self.cond = cond
- self.next = next
- self.stmt = stmt
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.init is not None: nodelist.append(("init", self.init))
- if self.cond is not None: nodelist.append(("cond", self.cond))
- if self.next is not None: nodelist.append(("next", self.next))
- if self.stmt is not None: nodelist.append(("stmt", self.stmt))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.init is not None:
- yield self.init
- if self.cond is not None:
- yield self.cond
- if self.next is not None:
- yield self.next
- if self.stmt is not None:
- yield self.stmt
-
- attr_names = ()
-
-class FuncCall(Node):
- __slots__ = ('name', 'args', 'coord', '__weakref__')
- def __init__(self, name, args, coord=None):
- self.name = name
- self.args = args
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.name is not None: nodelist.append(("name", self.name))
- if self.args is not None: nodelist.append(("args", self.args))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.name is not None:
- yield self.name
- if self.args is not None:
- yield self.args
-
- attr_names = ()
-
-class FuncDecl(Node):
- __slots__ = ('args', 'type', 'coord', '__weakref__')
- def __init__(self, args, type, coord=None):
- self.args = args
- self.type = type
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.args is not None: nodelist.append(("args", self.args))
- if self.type is not None: nodelist.append(("type", self.type))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.args is not None:
- yield self.args
- if self.type is not None:
- yield self.type
-
- attr_names = ()
-
-class FuncDef(Node):
- __slots__ = ('decl', 'param_decls', 'body', 'coord', '__weakref__')
- def __init__(self, decl, param_decls, body, coord=None):
- self.decl = decl
- self.param_decls = param_decls
- self.body = body
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.decl is not None: nodelist.append(("decl", self.decl))
- if self.body is not None: nodelist.append(("body", self.body))
- for i, child in enumerate(self.param_decls or []):
- nodelist.append(("param_decls[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.decl is not None:
- yield self.decl
- if self.body is not None:
- yield self.body
- for child in (self.param_decls or []):
- yield child
-
- attr_names = ()
-
-class Goto(Node):
- __slots__ = ('name', 'coord', '__weakref__')
- def __init__(self, name, coord=None):
- self.name = name
- self.coord = coord
-
- def children(self):
- nodelist = []
- return tuple(nodelist)
-
- def __iter__(self):
- return
- yield
-
- attr_names = ('name', )
-
-class ID(Node):
- __slots__ = ('name', 'coord', '__weakref__')
- def __init__(self, name, coord=None):
- self.name = name
- self.coord = coord
-
- def children(self):
- nodelist = []
- return tuple(nodelist)
-
- def __iter__(self):
- return
- yield
-
- attr_names = ('name', )
-
-class IdentifierType(Node):
- __slots__ = ('names', 'coord', '__weakref__')
- def __init__(self, names, coord=None):
- self.names = names
- self.coord = coord
-
- def children(self):
- nodelist = []
- return tuple(nodelist)
-
- def __iter__(self):
- return
- yield
-
- attr_names = ('names', )
-
-class If(Node):
- __slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
- def __init__(self, cond, iftrue, iffalse, coord=None):
- self.cond = cond
- self.iftrue = iftrue
- self.iffalse = iffalse
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.cond is not None: nodelist.append(("cond", self.cond))
- if self.iftrue is not None: nodelist.append(("iftrue", self.iftrue))
- if self.iffalse is not None: nodelist.append(("iffalse", self.iffalse))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.cond is not None:
- yield self.cond
- if self.iftrue is not None:
- yield self.iftrue
- if self.iffalse is not None:
- yield self.iffalse
-
- attr_names = ()
-
-class InitList(Node):
- __slots__ = ('exprs', 'coord', '__weakref__')
- def __init__(self, exprs, coord=None):
- self.exprs = exprs
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.exprs or []):
- nodelist.append(("exprs[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.exprs or []):
- yield child
-
- attr_names = ()
-
-class Label(Node):
- __slots__ = ('name', 'stmt', 'coord', '__weakref__')
- def __init__(self, name, stmt, coord=None):
- self.name = name
- self.stmt = stmt
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.stmt is not None: nodelist.append(("stmt", self.stmt))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.stmt is not None:
- yield self.stmt
-
- attr_names = ('name', )
-
-class NamedInitializer(Node):
- __slots__ = ('name', 'expr', 'coord', '__weakref__')
- def __init__(self, name, expr, coord=None):
- self.name = name
- self.expr = expr
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.expr is not None: nodelist.append(("expr", self.expr))
- for i, child in enumerate(self.name or []):
- nodelist.append(("name[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.expr is not None:
- yield self.expr
- for child in (self.name or []):
- yield child
-
- attr_names = ()
-
-class ParamList(Node):
- __slots__ = ('params', 'coord', '__weakref__')
- def __init__(self, params, coord=None):
- self.params = params
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.params or []):
- nodelist.append(("params[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.params or []):
- yield child
-
- attr_names = ()
-
-class PtrDecl(Node):
- __slots__ = ('quals', 'type', 'coord', '__weakref__')
- def __init__(self, quals, type, coord=None):
- self.quals = quals
- self.type = type
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
-
- attr_names = ('quals', )
-
-class Return(Node):
- __slots__ = ('expr', 'coord', '__weakref__')
- def __init__(self, expr, coord=None):
- self.expr = expr
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.expr is not None: nodelist.append(("expr", self.expr))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.expr is not None:
- yield self.expr
-
- attr_names = ()
-
-class Struct(Node):
- __slots__ = ('name', 'decls', 'coord', '__weakref__')
- def __init__(self, name, decls, coord=None):
- self.name = name
- self.decls = decls
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.decls or []):
- nodelist.append(("decls[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.decls or []):
- yield child
-
- attr_names = ('name', )
-
-class StructRef(Node):
- __slots__ = ('name', 'type', 'field', 'coord', '__weakref__')
- def __init__(self, name, type, field, coord=None):
- self.name = name
- self.type = type
- self.field = field
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.name is not None: nodelist.append(("name", self.name))
- if self.field is not None: nodelist.append(("field", self.field))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.name is not None:
- yield self.name
- if self.field is not None:
- yield self.field
-
- attr_names = ('type', )
-
-class Switch(Node):
- __slots__ = ('cond', 'stmt', 'coord', '__weakref__')
- def __init__(self, cond, stmt, coord=None):
- self.cond = cond
- self.stmt = stmt
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.cond is not None: nodelist.append(("cond", self.cond))
- if self.stmt is not None: nodelist.append(("stmt", self.stmt))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.cond is not None:
- yield self.cond
- if self.stmt is not None:
- yield self.stmt
-
- attr_names = ()
-
-class TernaryOp(Node):
- __slots__ = ('cond', 'iftrue', 'iffalse', 'coord', '__weakref__')
- def __init__(self, cond, iftrue, iffalse, coord=None):
- self.cond = cond
- self.iftrue = iftrue
- self.iffalse = iffalse
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.cond is not None: nodelist.append(("cond", self.cond))
- if self.iftrue is not None: nodelist.append(("iftrue", self.iftrue))
- if self.iffalse is not None: nodelist.append(("iffalse", self.iffalse))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.cond is not None:
- yield self.cond
- if self.iftrue is not None:
- yield self.iftrue
- if self.iffalse is not None:
- yield self.iffalse
-
- attr_names = ()
-
-class TypeDecl(Node):
- __slots__ = ('declname', 'quals', 'type', 'coord', '__weakref__')
- def __init__(self, declname, quals, type, coord=None):
- self.declname = declname
- self.quals = quals
- self.type = type
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
-
- attr_names = ('declname', 'quals', )
-
-class Typedef(Node):
- __slots__ = ('name', 'quals', 'storage', 'type', 'coord', '__weakref__')
- def __init__(self, name, quals, storage, type, coord=None):
- self.name = name
- self.quals = quals
- self.storage = storage
- self.type = type
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
-
- attr_names = ('name', 'quals', 'storage', )
-
-class Typename(Node):
- __slots__ = ('name', 'quals', 'type', 'coord', '__weakref__')
- def __init__(self, name, quals, type, coord=None):
- self.name = name
- self.quals = quals
- self.type = type
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.type is not None: nodelist.append(("type", self.type))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.type is not None:
- yield self.type
-
- attr_names = ('name', 'quals', )
-
-class UnaryOp(Node):
- __slots__ = ('op', 'expr', 'coord', '__weakref__')
- def __init__(self, op, expr, coord=None):
- self.op = op
- self.expr = expr
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.expr is not None: nodelist.append(("expr", self.expr))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.expr is not None:
- yield self.expr
-
- attr_names = ('op', )
-
-class Union(Node):
- __slots__ = ('name', 'decls', 'coord', '__weakref__')
- def __init__(self, name, decls, coord=None):
- self.name = name
- self.decls = decls
- self.coord = coord
-
- def children(self):
- nodelist = []
- for i, child in enumerate(self.decls or []):
- nodelist.append(("decls[%d]" % i, child))
- return tuple(nodelist)
-
- def __iter__(self):
- for child in (self.decls or []):
- yield child
-
- attr_names = ('name', )
-
-class While(Node):
- __slots__ = ('cond', 'stmt', 'coord', '__weakref__')
- def __init__(self, cond, stmt, coord=None):
- self.cond = cond
- self.stmt = stmt
- self.coord = coord
-
- def children(self):
- nodelist = []
- if self.cond is not None: nodelist.append(("cond", self.cond))
- if self.stmt is not None: nodelist.append(("stmt", self.stmt))
- return tuple(nodelist)
-
- def __iter__(self):
- if self.cond is not None:
- yield self.cond
- if self.stmt is not None:
- yield self.stmt
-
- attr_names = ()
-
-class Pragma(Node):
- __slots__ = ('string', 'coord', '__weakref__')
- def __init__(self, string, coord=None):
- self.string = string
- self.coord = coord
-
- def children(self):
- nodelist = []
- return tuple(nodelist)
-
- def __iter__(self):
- return
- yield
-
- attr_names = ('string', )
-
diff --git a/pycparser/c_generator.py b/pycparser/c_generator.py
deleted file mode 100644
index f789742..0000000
--- a/pycparser/c_generator.py
+++ /dev/null
@@ -1,428 +0,0 @@
-#------------------------------------------------------------------------------
-# pycparser: c_generator.py
-#
-# C code generator from pycparser AST nodes.
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#------------------------------------------------------------------------------
-from . import c_ast
-
-
-class CGenerator(object):
- """ Uses the same visitor pattern as c_ast.NodeVisitor, but modified to
- return a value from each visit method, using string accumulation in
- generic_visit.
- """
- def __init__(self):
- # Statements start with indentation of self.indent_level spaces, using
- # the _make_indent method
- #
- self.indent_level = 0
-
- def _make_indent(self):
- return ' ' * self.indent_level
-
- def visit(self, node):
- method = 'visit_' + node.__class__.__name__
- return getattr(self, method, self.generic_visit)(node)
-
- def generic_visit(self, node):
- #~ print('generic:', type(node))
- if node is None:
- return ''
- else:
- return ''.join(self.visit(c) for c_name, c in node.children())
-
- def visit_Constant(self, n):
- return n.value
-
- def visit_ID(self, n):
- return n.name
-
- def visit_Pragma(self, n):
- ret = '#pragma'
- if n.string:
- ret += ' ' + n.string
- return ret
-
- def visit_ArrayRef(self, n):
- arrref = self._parenthesize_unless_simple(n.name)
- return arrref + '[' + self.visit(n.subscript) + ']'
-
- def visit_StructRef(self, n):
- sref = self._parenthesize_unless_simple(n.name)
- return sref + n.type + self.visit(n.field)
-
- def visit_FuncCall(self, n):
- fref = self._parenthesize_unless_simple(n.name)
- return fref + '(' + self.visit(n.args) + ')'
-
- def visit_UnaryOp(self, n):
- operand = self._parenthesize_unless_simple(n.expr)
- if n.op == 'p++':
- return '%s++' % operand
- elif n.op == 'p--':
- return '%s--' % operand
- elif n.op == 'sizeof':
- # Always parenthesize the argument of sizeof since it can be
- # a name.
- return 'sizeof(%s)' % self.visit(n.expr)
- else:
- return '%s%s' % (n.op, operand)
-
- def visit_BinaryOp(self, n):
- lval_str = self._parenthesize_if(n.left,
- lambda d: not self._is_simple_node(d))
- rval_str = self._parenthesize_if(n.right,
- lambda d: not self._is_simple_node(d))
- return '%s %s %s' % (lval_str, n.op, rval_str)
-
- def visit_Assignment(self, n):
- rval_str = self._parenthesize_if(
- n.rvalue,
- lambda n: isinstance(n, c_ast.Assignment))
- return '%s %s %s' % (self.visit(n.lvalue), n.op, rval_str)
-
- def visit_IdentifierType(self, n):
- return ' '.join(n.names)
-
- def _visit_expr(self, n):
- if isinstance(n, c_ast.InitList):
- return '{' + self.visit(n) + '}'
- elif isinstance(n, c_ast.ExprList):
- return '(' + self.visit(n) + ')'
- else:
- return self.visit(n)
-
- def visit_Decl(self, n, no_type=False):
- # no_type is used when a Decl is part of a DeclList, where the type is
- # explicitly only for the first declaration in a list.
- #
- s = n.name if no_type else self._generate_decl(n)
- if n.bitsize: s += ' : ' + self.visit(n.bitsize)
- if n.init:
- s += ' = ' + self._visit_expr(n.init)
- return s
-
- def visit_DeclList(self, n):
- s = self.visit(n.decls[0])
- if len(n.decls) > 1:
- s += ', ' + ', '.join(self.visit_Decl(decl, no_type=True)
- for decl in n.decls[1:])
- return s
-
- def visit_Typedef(self, n):
- s = ''
- if n.storage: s += ' '.join(n.storage) + ' '
- s += self._generate_type(n.type)
- return s
-
- def visit_Cast(self, n):
- s = '(' + self._generate_type(n.to_type) + ')'
- return s + ' ' + self._parenthesize_unless_simple(n.expr)
-
- def visit_ExprList(self, n):
- visited_subexprs = []
- for expr in n.exprs:
- visited_subexprs.append(self._visit_expr(expr))
- return ', '.join(visited_subexprs)
-
- def visit_InitList(self, n):
- visited_subexprs = []
- for expr in n.exprs:
- visited_subexprs.append(self._visit_expr(expr))
- return ', '.join(visited_subexprs)
-
- def visit_Enum(self, n):
- return self._generate_struct_union_enum(n, name='enum')
-
- def visit_Enumerator(self, n):
- if not n.value:
- return '{indent}{name},\n'.format(
- indent=self._make_indent(),
- name=n.name,
- )
- else:
- return '{indent}{name} = {value},\n'.format(
- indent=self._make_indent(),
- name=n.name,
- value=self.visit(n.value),
- )
-
- def visit_FuncDef(self, n):
- decl = self.visit(n.decl)
- self.indent_level = 0
- body = self.visit(n.body)
- if n.param_decls:
- knrdecls = ';\n'.join(self.visit(p) for p in n.param_decls)
- return decl + '\n' + knrdecls + ';\n' + body + '\n'
- else:
- return decl + '\n' + body + '\n'
-
- def visit_FileAST(self, n):
- s = ''
- for ext in n.ext:
- if isinstance(ext, c_ast.FuncDef):
- s += self.visit(ext)
- elif isinstance(ext, c_ast.Pragma):
- s += self.visit(ext) + '\n'
- else:
- s += self.visit(ext) + ';\n'
- return s
-
- def visit_Compound(self, n):
- s = self._make_indent() + '{\n'
- self.indent_level += 2
- if n.block_items:
- s += ''.join(self._generate_stmt(stmt) for stmt in n.block_items)
- self.indent_level -= 2
- s += self._make_indent() + '}\n'
- return s
-
- def visit_CompoundLiteral(self, n):
- return '(' + self.visit(n.type) + '){' + self.visit(n.init) + '}'
-
-
- def visit_EmptyStatement(self, n):
- return ';'
-
- def visit_ParamList(self, n):
- return ', '.join(self.visit(param) for param in n.params)
-
- def visit_Return(self, n):
- s = 'return'
- if n.expr: s += ' ' + self.visit(n.expr)
- return s + ';'
-
- def visit_Break(self, n):
- return 'break;'
-
- def visit_Continue(self, n):
- return 'continue;'
-
- def visit_TernaryOp(self, n):
- s = '(' + self._visit_expr(n.cond) + ') ? '
- s += '(' + self._visit_expr(n.iftrue) + ') : '
- s += '(' + self._visit_expr(n.iffalse) + ')'
- return s
-
- def visit_If(self, n):
- s = 'if ('
- if n.cond: s += self.visit(n.cond)
- s += ')\n'
- s += self._generate_stmt(n.iftrue, add_indent=True)
- if n.iffalse:
- s += self._make_indent() + 'else\n'
- s += self._generate_stmt(n.iffalse, add_indent=True)
- return s
-
- def visit_For(self, n):
- s = 'for ('
- if n.init: s += self.visit(n.init)
- s += ';'
- if n.cond: s += ' ' + self.visit(n.cond)
- s += ';'
- if n.next: s += ' ' + self.visit(n.next)
- s += ')\n'
- s += self._generate_stmt(n.stmt, add_indent=True)
- return s
-
- def visit_While(self, n):
- s = 'while ('
- if n.cond: s += self.visit(n.cond)
- s += ')\n'
- s += self._generate_stmt(n.stmt, add_indent=True)
- return s
-
- def visit_DoWhile(self, n):
- s = 'do\n'
- s += self._generate_stmt(n.stmt, add_indent=True)
- s += self._make_indent() + 'while ('
- if n.cond: s += self.visit(n.cond)
- s += ');'
- return s
-
- def visit_Switch(self, n):
- s = 'switch (' + self.visit(n.cond) + ')\n'
- s += self._generate_stmt(n.stmt, add_indent=True)
- return s
-
- def visit_Case(self, n):
- s = 'case ' + self.visit(n.expr) + ':\n'
- for stmt in n.stmts:
- s += self._generate_stmt(stmt, add_indent=True)
- return s
-
- def visit_Default(self, n):
- s = 'default:\n'
- for stmt in n.stmts:
- s += self._generate_stmt(stmt, add_indent=True)
- return s
-
- def visit_Label(self, n):
- return n.name + ':\n' + self._generate_stmt(n.stmt)
-
- def visit_Goto(self, n):
- return 'goto ' + n.name + ';'
-
- def visit_EllipsisParam(self, n):
- return '...'
-
- def visit_Struct(self, n):
- return self._generate_struct_union_enum(n, 'struct')
-
- def visit_Typename(self, n):
- return self._generate_type(n.type)
-
- def visit_Union(self, n):
- return self._generate_struct_union_enum(n, 'union')
-
- def visit_NamedInitializer(self, n):
- s = ''
- for name in n.name:
- if isinstance(name, c_ast.ID):
- s += '.' + name.name
- else:
- s += '[' + self.visit(name) + ']'
- s += ' = ' + self._visit_expr(n.expr)
- return s
-
- def visit_FuncDecl(self, n):
- return self._generate_type(n)
-
- def _generate_struct_union_enum(self, n, name):
- """ Generates code for structs, unions, and enums. name should be
- 'struct', 'union', or 'enum'.
- """
- if name in ('struct', 'union'):
- members = n.decls
- body_function = self._generate_struct_union_body
- else:
- assert name == 'enum'
- members = None if n.values is None else n.values.enumerators
- body_function = self._generate_enum_body
- s = name + ' ' + (n.name or '')
- if members is not None:
- # None means no members
- # Empty sequence means an empty list of members
- s += '\n'
- s += self._make_indent()
- self.indent_level += 2
- s += '{\n'
- s += body_function(members)
- self.indent_level -= 2
- s += self._make_indent() + '}'
- return s
-
- def _generate_struct_union_body(self, members):
- return ''.join(self._generate_stmt(decl) for decl in members)
-
- def _generate_enum_body(self, members):
- # `[:-2] + '\n'` removes the final `,` from the enumerator list
- return ''.join(self.visit(value) for value in members)[:-2] + '\n'
-
- def _generate_stmt(self, n, add_indent=False):
- """ Generation from a statement node. This method exists as a wrapper
- for individual visit_* methods to handle different treatment of
- some statements in this context.
- """
- typ = type(n)
- if add_indent: self.indent_level += 2
- indent = self._make_indent()
- if add_indent: self.indent_level -= 2
-
- if typ in (
- c_ast.Decl, c_ast.Assignment, c_ast.Cast, c_ast.UnaryOp,
- c_ast.BinaryOp, c_ast.TernaryOp, c_ast.FuncCall, c_ast.ArrayRef,
- c_ast.StructRef, c_ast.Constant, c_ast.ID, c_ast.Typedef,
- c_ast.ExprList):
- # These can also appear in an expression context so no semicolon
- # is added to them automatically
- #
- return indent + self.visit(n) + ';\n'
- elif typ in (c_ast.Compound,):
- # No extra indentation required before the opening brace of a
- # compound - because it consists of multiple lines it has to
- # compute its own indentation.
- #
- return self.visit(n)
- else:
- return indent + self.visit(n) + '\n'
-
- def _generate_decl(self, n):
- """ Generation from a Decl node.
- """
- s = ''
- if n.funcspec: s = ' '.join(n.funcspec) + ' '
- if n.storage: s += ' '.join(n.storage) + ' '
- s += self._generate_type(n.type)
- return s
-
- def _generate_type(self, n, modifiers=[]):
- """ Recursive generation from a type node. n is the type node.
- modifiers collects the PtrDecl, ArrayDecl and FuncDecl modifiers
- encountered on the way down to a TypeDecl, to allow proper
- generation from it.
- """
- typ = type(n)
- #~ print(n, modifiers)
-
- if typ == c_ast.TypeDecl:
- s = ''
- if n.quals: s += ' '.join(n.quals) + ' '
- s += self.visit(n.type)
-
- nstr = n.declname if n.declname else ''
- # Resolve modifiers.
- # Wrap in parens to distinguish pointer to array and pointer to
- # function syntax.
- #
- for i, modifier in enumerate(modifiers):
- if isinstance(modifier, c_ast.ArrayDecl):
- if (i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl)):
- nstr = '(' + nstr + ')'
- nstr += '[' + self.visit(modifier.dim) + ']'
- elif isinstance(modifier, c_ast.FuncDecl):
- if (i != 0 and isinstance(modifiers[i - 1], c_ast.PtrDecl)):
- nstr = '(' + nstr + ')'
- nstr += '(' + self.visit(modifier.args) + ')'
- elif isinstance(modifier, c_ast.PtrDecl):
- if modifier.quals:
- nstr = '* %s %s' % (' '.join(modifier.quals), nstr)
- else:
- nstr = '*' + nstr
- if nstr: s += ' ' + nstr
- return s
- elif typ == c_ast.Decl:
- return self._generate_decl(n.type)
- elif typ == c_ast.Typename:
- return self._generate_type(n.type)
- elif typ == c_ast.IdentifierType:
- return ' '.join(n.names) + ' '
- elif typ in (c_ast.ArrayDecl, c_ast.PtrDecl, c_ast.FuncDecl):
- return self._generate_type(n.type, modifiers + [n])
- else:
- return self.visit(n)
-
- def _parenthesize_if(self, n, condition):
- """ Visits 'n' and returns its string representation, parenthesized
- if the condition function applied to the node returns True.
- """
- s = self._visit_expr(n)
- if condition(n):
- return '(' + s + ')'
- else:
- return s
-
- def _parenthesize_unless_simple(self, n):
- """ Common use case for _parenthesize_if
- """
- return self._parenthesize_if(n, lambda d: not self._is_simple_node(d))
-
- def _is_simple_node(self, n):
- """ Returns True for nodes that are "simple" - i.e. nodes that always
- have higher precedence than operators.
- """
- return isinstance(n, (c_ast.Constant, c_ast.ID, c_ast.ArrayRef,
- c_ast.StructRef, c_ast.FuncCall))
diff --git a/pycparser/c_lexer.py b/pycparser/c_lexer.py
deleted file mode 100644
index de8445e..0000000
--- a/pycparser/c_lexer.py
+++ /dev/null
@@ -1,484 +0,0 @@
-#------------------------------------------------------------------------------
-# pycparser: c_lexer.py
-#
-# CLexer class: lexer for the C language
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#------------------------------------------------------------------------------
-import re
-import sys
-
-from .ply import lex
-from .ply.lex import TOKEN
-
-
-class CLexer(object):
- """ A lexer for the C language. After building it, set the
- input text with input(), and call token() to get new
- tokens.
-
- The public attribute filename can be set to an initial
- filaneme, but the lexer will update it upon #line
- directives.
- """
- def __init__(self, error_func, on_lbrace_func, on_rbrace_func,
- type_lookup_func):
- """ Create a new Lexer.
-
- error_func:
- An error function. Will be called with an error
- message, line and column as arguments, in case of
- an error during lexing.
-
- on_lbrace_func, on_rbrace_func:
- Called when an LBRACE or RBRACE is encountered
- (likely to push/pop type_lookup_func's scope)
-
- type_lookup_func:
- A type lookup function. Given a string, it must
- return True IFF this string is a name of a type
- that was defined with a typedef earlier.
- """
- self.error_func = error_func
- self.on_lbrace_func = on_lbrace_func
- self.on_rbrace_func = on_rbrace_func
- self.type_lookup_func = type_lookup_func
- self.filename = ''
-
- # Keeps track of the last token returned from self.token()
- self.last_token = None
-
- # Allow either "# line" or "# <num>" to support GCC's
- # cpp output
- #
- self.line_pattern = re.compile(r'([ \t]*line\W)|([ \t]*\d+)')
- self.pragma_pattern = re.compile(r'[ \t]*pragma\W')
-
- def build(self, **kwargs):
- """ Builds the lexer from the specification. Must be
- called after the lexer object is created.
-
- This method exists separately, because the PLY
- manual warns against calling lex.lex inside
- __init__
- """
- self.lexer = lex.lex(object=self, **kwargs)
-
- def reset_lineno(self):
- """ Resets the internal line number counter of the lexer.
- """
- self.lexer.lineno = 1
-
- def input(self, text):
- self.lexer.input(text)
-
- def token(self):
- self.last_token = self.lexer.token()
- return self.last_token
-
- def find_tok_column(self, token):
- """ Find the column of the token in its line.
- """
- last_cr = self.lexer.lexdata.rfind('\n', 0, token.lexpos)
- return token.lexpos - last_cr
-
- ######################-- PRIVATE --######################
-
- ##
- ## Internal auxiliary methods
- ##
- def _error(self, msg, token):
- location = self._make_tok_location(token)
- self.error_func(msg, location[0], location[1])
- self.lexer.skip(1)
-
- def _make_tok_location(self, token):
- return (token.lineno, self.find_tok_column(token))
-
- ##
- ## Reserved keywords
- ##
- keywords = (
- '_BOOL', '_COMPLEX', 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST',
- 'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN',
- 'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG',
- 'REGISTER', 'OFFSETOF',
- 'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT',
- 'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID',
- 'VOLATILE', 'WHILE', '__INT128',
- )
-
- keyword_map = {}
- for keyword in keywords:
- if keyword == '_BOOL':
- keyword_map['_Bool'] = keyword
- elif keyword == '_COMPLEX':
- keyword_map['_Complex'] = keyword
- else:
- keyword_map[keyword.lower()] = keyword
-
- ##
- ## All the tokens recognized by the lexer
- ##
- tokens = keywords + (
- # Identifiers
- 'ID',
-
- # Type identifiers (identifiers previously defined as
- # types with typedef)
- 'TYPEID',
-
- # constants
- 'INT_CONST_DEC', 'INT_CONST_OCT', 'INT_CONST_HEX', 'INT_CONST_BIN',
- 'FLOAT_CONST', 'HEX_FLOAT_CONST',
- 'CHAR_CONST',
- 'WCHAR_CONST',
-
- # String literals
- 'STRING_LITERAL',
- 'WSTRING_LITERAL',
-
- # Operators
- 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
- 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
- 'LOR', 'LAND', 'LNOT',
- 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
-
- # Assignment
- 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL',
- 'PLUSEQUAL', 'MINUSEQUAL',
- 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL',
- 'OREQUAL',
-
- # Increment/decrement
- 'PLUSPLUS', 'MINUSMINUS',
-
- # Structure dereference (->)
- 'ARROW',
-
- # Conditional operator (?)
- 'CONDOP',
-
- # Delimeters
- 'LPAREN', 'RPAREN', # ( )
- 'LBRACKET', 'RBRACKET', # [ ]
- 'LBRACE', 'RBRACE', # { }
- 'COMMA', 'PERIOD', # . ,
- 'SEMI', 'COLON', # ; :
-
- # Ellipsis (...)
- 'ELLIPSIS',
-
- # pre-processor
- 'PPHASH', # '#'
- 'PPPRAGMA', # 'pragma'
- 'PPPRAGMASTR',
- )
-
- ##
- ## Regexes for use in tokens
- ##
- ##
-
- # valid C identifiers (K&R2: A.2.3), plus '$' (supported by some compilers)
- identifier = r'[a-zA-Z_$][0-9a-zA-Z_$]*'
-
- hex_prefix = '0[xX]'
- hex_digits = '[0-9a-fA-F]+'
- bin_prefix = '0[bB]'
- bin_digits = '[01]+'
-
- # integer constants (K&R2: A.2.5.1)
- integer_suffix_opt = r'(([uU]ll)|([uU]LL)|(ll[uU]?)|(LL[uU]?)|([uU][lL])|([lL][uU]?)|[uU])?'
- decimal_constant = '(0'+integer_suffix_opt+')|([1-9][0-9]*'+integer_suffix_opt+')'
- octal_constant = '0[0-7]*'+integer_suffix_opt
- hex_constant = hex_prefix+hex_digits+integer_suffix_opt
- bin_constant = bin_prefix+bin_digits+integer_suffix_opt
-
- bad_octal_constant = '0[0-7]*[89]'
-
- # character constants (K&R2: A.2.5.2)
- # Note: a-zA-Z and '.-~^_!=&;,' are allowed as escape chars to support #line
- # directives with Windows paths as filenames (..\..\dir\file)
- # For the same reason, decimal_escape allows all digit sequences. We want to
- # parse all correct code, even if it means to sometimes parse incorrect
- # code.
- #
- simple_escape = r"""([a-zA-Z._~!=&\^\-\\?'"])"""
- decimal_escape = r"""(\d+)"""
- hex_escape = r"""(x[0-9a-fA-F]+)"""
- bad_escape = r"""([\\][^a-zA-Z._~^!=&\^\-\\?'"x0-7])"""
-
- escape_sequence = r"""(\\("""+simple_escape+'|'+decimal_escape+'|'+hex_escape+'))'
- cconst_char = r"""([^'\\\n]|"""+escape_sequence+')'
- char_const = "'"+cconst_char+"'"
- wchar_const = 'L'+char_const
- unmatched_quote = "('"+cconst_char+"*\\n)|('"+cconst_char+"*$)"
- bad_char_const = r"""('"""+cconst_char+"""[^'\n]+')|('')|('"""+bad_escape+r"""[^'\n]*')"""
-
- # string literals (K&R2: A.2.6)
- string_char = r"""([^"\\\n]|"""+escape_sequence+')'
- string_literal = '"'+string_char+'*"'
- wstring_literal = 'L'+string_literal
- bad_string_literal = '"'+string_char+'*?'+bad_escape+string_char+'*"'
-
- # floating constants (K&R2: A.2.5.3)
- exponent_part = r"""([eE][-+]?[0-9]+)"""
- fractional_constant = r"""([0-9]*\.[0-9]+)|([0-9]+\.)"""
- floating_constant = '(((('+fractional_constant+')'+exponent_part+'?)|([0-9]+'+exponent_part+'))[FfLl]?)'
- binary_exponent_part = r'''([pP][+-]?[0-9]+)'''
- hex_fractional_constant = '((('+hex_digits+r""")?\."""+hex_digits+')|('+hex_digits+r"""\.))"""
- hex_floating_constant = '('+hex_prefix+'('+hex_digits+'|'+hex_fractional_constant+')'+binary_exponent_part+'[FfLl]?)'
-
- ##
- ## Lexer states: used for preprocessor \n-terminated directives
- ##
- states = (
- # ppline: preprocessor line directives
- #
- ('ppline', 'exclusive'),
-
- # pppragma: pragma
- #
- ('pppragma', 'exclusive'),
- )
-
- def t_PPHASH(self, t):
- r'[ \t]*\#'
- if self.line_pattern.match(t.lexer.lexdata, pos=t.lexer.lexpos):
- t.lexer.begin('ppline')
- self.pp_line = self.pp_filename = None
- elif self.pragma_pattern.match(t.lexer.lexdata, pos=t.lexer.lexpos):
- t.lexer.begin('pppragma')
- else:
- t.type = 'PPHASH'
- return t
-
- ##
- ## Rules for the ppline state
- ##
- @TOKEN(string_literal)
- def t_ppline_FILENAME(self, t):
- if self.pp_line is None:
- self._error('filename before line number in #line', t)
- else:
- self.pp_filename = t.value.lstrip('"').rstrip('"')
-
- @TOKEN(decimal_constant)
- def t_ppline_LINE_NUMBER(self, t):
- if self.pp_line is None:
- self.pp_line = t.value
- else:
- # Ignore: GCC's cpp sometimes inserts a numeric flag
- # after the file name
- pass
-
- def t_ppline_NEWLINE(self, t):
- r'\n'
- if self.pp_line is None:
- self._error('line number missing in #line', t)
- else:
- self.lexer.lineno = int(self.pp_line)
-
- if self.pp_filename is not None:
- self.filename = self.pp_filename
-
- t.lexer.begin('INITIAL')
-
- def t_ppline_PPLINE(self, t):
- r'line'
- pass
-
- t_ppline_ignore = ' \t'
-
- def t_ppline_error(self, t):
- self._error('invalid #line directive', t)
-
- ##
- ## Rules for the pppragma state
- ##
- def t_pppragma_NEWLINE(self, t):
- r'\n'
- t.lexer.lineno += 1
- t.lexer.begin('INITIAL')
-
- def t_pppragma_PPPRAGMA(self, t):
- r'pragma'
- return t
-
- t_pppragma_ignore = ' \t'
-
- def t_pppragma_STR(self, t):
- '.+'
- t.type = 'PPPRAGMASTR'
- return t
-
- def t_pppragma_error(self, t):
- self._error('invalid #pragma directive', t)
-
- ##
- ## Rules for the normal state
- ##
- t_ignore = ' \t'
-
- # Newlines
- def t_NEWLINE(self, t):
- r'\n+'
- t.lexer.lineno += t.value.count("\n")
-
- # Operators
- t_PLUS = r'\+'
- t_MINUS = r'-'
- t_TIMES = r'\*'
- t_DIVIDE = r'/'
- t_MOD = r'%'
- t_OR = r'\|'
- t_AND = r'&'
- t_NOT = r'~'
- t_XOR = r'\^'
- t_LSHIFT = r'<<'
- t_RSHIFT = r'>>'
- t_LOR = r'\|\|'
- t_LAND = r'&&'
- t_LNOT = r'!'
- t_LT = r'<'
- t_GT = r'>'
- t_LE = r'<='
- t_GE = r'>='
- t_EQ = r'=='
- t_NE = r'!='
-
- # Assignment operators
- t_EQUALS = r'='
- t_TIMESEQUAL = r'\*='
- t_DIVEQUAL = r'/='
- t_MODEQUAL = r'%='
- t_PLUSEQUAL = r'\+='
- t_MINUSEQUAL = r'-='
- t_LSHIFTEQUAL = r'<<='
- t_RSHIFTEQUAL = r'>>='
- t_ANDEQUAL = r'&='
- t_OREQUAL = r'\|='
- t_XOREQUAL = r'\^='
-
- # Increment/decrement
- t_PLUSPLUS = r'\+\+'
- t_MINUSMINUS = r'--'
-
- # ->
- t_ARROW = r'->'
-
- # ?
- t_CONDOP = r'\?'
-
- # Delimeters
- t_LPAREN = r'\('
- t_RPAREN = r'\)'
- t_LBRACKET = r'\['
- t_RBRACKET = r'\]'
- t_COMMA = r','
- t_PERIOD = r'\.'
- t_SEMI = r';'
- t_COLON = r':'
- t_ELLIPSIS = r'\.\.\.'
-
- # Scope delimiters
- # To see why on_lbrace_func is needed, consider:
- # typedef char TT;
- # void foo(int TT) { TT = 10; }
- # TT x = 5;
- # Outside the function, TT is a typedef, but inside (starting and ending
- # with the braces) it's a parameter. The trouble begins with yacc's
- # lookahead token. If we open a new scope in brace_open, then TT has
- # already been read and incorrectly interpreted as TYPEID. So, we need
- # to open and close scopes from within the lexer.
- # Similar for the TT immediately outside the end of the function.
- #
- @TOKEN(r'\{')
- def t_LBRACE(self, t):
- self.on_lbrace_func()
- return t
- @TOKEN(r'\}')
- def t_RBRACE(self, t):
- self.on_rbrace_func()
- return t
-
- t_STRING_LITERAL = string_literal
-
- # The following floating and integer constants are defined as
- # functions to impose a strict order (otherwise, decimal
- # is placed before the others because its regex is longer,
- # and this is bad)
- #
- @TOKEN(floating_constant)
- def t_FLOAT_CONST(self, t):
- return t
-
- @TOKEN(hex_floating_constant)
- def t_HEX_FLOAT_CONST(self, t):
- return t
-
- @TOKEN(hex_constant)
- def t_INT_CONST_HEX(self, t):
- return t
-
- @TOKEN(bin_constant)
- def t_INT_CONST_BIN(self, t):
- return t
-
- @TOKEN(bad_octal_constant)
- def t_BAD_CONST_OCT(self, t):
- msg = "Invalid octal constant"
- self._error(msg, t)
-
- @TOKEN(octal_constant)
- def t_INT_CONST_OCT(self, t):
- return t
-
- @TOKEN(decimal_constant)
- def t_INT_CONST_DEC(self, t):
- return t
-
- # Must come before bad_char_const, to prevent it from
- # catching valid char constants as invalid
- #
- @TOKEN(char_const)
- def t_CHAR_CONST(self, t):
- return t
-
- @TOKEN(wchar_const)
- def t_WCHAR_CONST(self, t):
- return t
-
- @TOKEN(unmatched_quote)
- def t_UNMATCHED_QUOTE(self, t):
- msg = "Unmatched '"
- self._error(msg, t)
-
- @TOKEN(bad_char_const)
- def t_BAD_CHAR_CONST(self, t):
- msg = "Invalid char constant %s" % t.value
- self._error(msg, t)
-
- @TOKEN(wstring_literal)
- def t_WSTRING_LITERAL(self, t):
- return t
-
- # unmatched string literals are caught by the preprocessor
-
- @TOKEN(bad_string_literal)
- def t_BAD_STRING_LITERAL(self, t):
- msg = "String contains invalid escape code"
- self._error(msg, t)
-
- @TOKEN(identifier)
- def t_ID(self, t):
- t.type = self.keyword_map.get(t.value, "ID")
- if t.type == 'ID' and self.type_lookup_func(t.value):
- t.type = "TYPEID"
- return t
-
- def t_error(self, t):
- msg = 'Illegal character %s' % repr(t.value[0])
- self._error(msg, t)
diff --git a/pycparser/c_parser.py b/pycparser/c_parser.py
deleted file mode 100644
index 0e6e755..0000000
--- a/pycparser/c_parser.py
+++ /dev/null
@@ -1,1850 +0,0 @@
-#------------------------------------------------------------------------------
-# pycparser: c_parser.py
-#
-# CParser class: Parser and AST builder for the C language
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#------------------------------------------------------------------------------
-import re
-
-from .ply import yacc
-
-from . import c_ast
-from .c_lexer import CLexer
-from .plyparser import PLYParser, Coord, ParseError, parameterized, template
-from .ast_transforms import fix_switch_cases
-
-
-@template
-class CParser(PLYParser):
- def __init__(
- self,
- lex_optimize=True,
- lexer=CLexer,
- lextab='pycparser.lextab',
- yacc_optimize=True,
- yacctab='pycparser.yacctab',
- yacc_debug=False,
- taboutputdir=''):
- """ Create a new CParser.
-
- Some arguments for controlling the debug/optimization
- level of the parser are provided. The defaults are
- tuned for release/performance mode.
- The simple rules for using them are:
- *) When tweaking CParser/CLexer, set these to False
- *) When releasing a stable parser, set to True
-
- lex_optimize:
- Set to False when you're modifying the lexer.
- Otherwise, changes in the lexer won't be used, if
- some lextab.py file exists.
- When releasing with a stable lexer, set to True
- to save the re-generation of the lexer table on
- each run.
-
- lexer:
- Set this parameter to define the lexer to use if
- you're not using the default CLexer.
-
- lextab:
- Points to the lex table that's used for optimized
- mode. Only if you're modifying the lexer and want
- some tests to avoid re-generating the table, make
- this point to a local lex table file (that's been
- earlier generated with lex_optimize=True)
-
- yacc_optimize:
- Set to False when you're modifying the parser.
- Otherwise, changes in the parser won't be used, if
- some parsetab.py file exists.
- When releasing with a stable parser, set to True
- to save the re-generation of the parser table on
- each run.
-
- yacctab:
- Points to the yacc table that's used for optimized
- mode. Only if you're modifying the parser, make
- this point to a local yacc table file
-
- yacc_debug:
- Generate a parser.out file that explains how yacc
- built the parsing table from the grammar.
-
- taboutputdir:
- Set this parameter to control the location of generated
- lextab and yacctab files.
- """
- self.clex = lexer(
- error_func=self._lex_error_func,
- on_lbrace_func=self._lex_on_lbrace_func,
- on_rbrace_func=self._lex_on_rbrace_func,
- type_lookup_func=self._lex_type_lookup_func)
-
- self.clex.build(
- optimize=lex_optimize,
- lextab=lextab,
- outputdir=taboutputdir)
- self.tokens = self.clex.tokens
-
- rules_with_opt = [
- 'abstract_declarator',
- 'assignment_expression',
- 'declaration_list',
- 'declaration_specifiers_no_type',
- 'designation',
- 'expression',
- 'identifier_list',
- 'init_declarator_list',
- 'id_init_declarator_list',
- 'initializer_list',
- 'parameter_type_list',
- 'block_item_list',
- 'type_qualifier_list',
- 'struct_declarator_list'
- ]
-
- for rule in rules_with_opt:
- self._create_opt_rule(rule)
-
- self.cparser = yacc.yacc(
- module=self,
- start='translation_unit_or_empty',
- debug=yacc_debug,
- optimize=yacc_optimize,
- tabmodule=yacctab,
- outputdir=taboutputdir)
-
- # Stack of scopes for keeping track of symbols. _scope_stack[-1] is
- # the current (topmost) scope. Each scope is a dictionary that
- # specifies whether a name is a type. If _scope_stack[n][name] is
- # True, 'name' is currently a type in the scope. If it's False,
- # 'name' is used in the scope but not as a type (for instance, if we
- # saw: int name;
- # If 'name' is not a key in _scope_stack[n] then 'name' was not defined
- # in this scope at all.
- self._scope_stack = [dict()]
-
- # Keeps track of the last token given to yacc (the lookahead token)
- self._last_yielded_token = None
-
- def parse(self, text, filename='', debuglevel=0):
- """ Parses C code and returns an AST.
-
- text:
- A string containing the C source code
-
- filename:
- Name of the file being parsed (for meaningful
- error messages)
-
- debuglevel:
- Debug level to yacc
- """
- self.clex.filename = filename
- self.clex.reset_lineno()
- self._scope_stack = [dict()]
- self._last_yielded_token = None
- return self.cparser.parse(
- input=text,
- lexer=self.clex,
- debug=debuglevel)
-
- ######################-- PRIVATE --######################
-
- def _push_scope(self):
- self._scope_stack.append(dict())
-
- def _pop_scope(self):
- assert len(self._scope_stack) > 1
- self._scope_stack.pop()
-
- def _add_typedef_name(self, name, coord):
- """ Add a new typedef name (ie a TYPEID) to the current scope
- """
- if not self._scope_stack[-1].get(name, True):
- self._parse_error(
- "Typedef %r previously declared as non-typedef "
- "in this scope" % name, coord)
- self._scope_stack[-1][name] = True
-
- def _add_identifier(self, name, coord):
- """ Add a new object, function, or enum member name (ie an ID) to the
- current scope
- """
- if self._scope_stack[-1].get(name, False):
- self._parse_error(
- "Non-typedef %r previously declared as typedef "
- "in this scope" % name, coord)
- self._scope_stack[-1][name] = False
-
- def _is_type_in_scope(self, name):
- """ Is *name* a typedef-name in the current scope?
- """
- for scope in reversed(self._scope_stack):
- # If name is an identifier in this scope it shadows typedefs in
- # higher scopes.
- in_scope = scope.get(name)
- if in_scope is not None: return in_scope
- return False
-
- def _lex_error_func(self, msg, line, column):
- self._parse_error(msg, self._coord(line, column))
-
- def _lex_on_lbrace_func(self):
- self._push_scope()
-
- def _lex_on_rbrace_func(self):
- self._pop_scope()
-
- def _lex_type_lookup_func(self, name):
- """ Looks up types that were previously defined with
- typedef.
- Passed to the lexer for recognizing identifiers that
- are types.
- """
- is_type = self._is_type_in_scope(name)
- return is_type
-
- def _get_yacc_lookahead_token(self):
- """ We need access to yacc's lookahead token in certain cases.
- This is the last token yacc requested from the lexer, so we
- ask the lexer.
- """
- return self.clex.last_token
-
- # To understand what's going on here, read sections A.8.5 and
- # A.8.6 of K&R2 very carefully.
- #
- # A C type consists of a basic type declaration, with a list
- # of modifiers. For example:
- #
- # int *c[5];
- #
- # The basic declaration here is 'int c', and the pointer and
- # the array are the modifiers.
- #
- # Basic declarations are represented by TypeDecl (from module c_ast) and the
- # modifiers are FuncDecl, PtrDecl and ArrayDecl.
- #
- # The standard states that whenever a new modifier is parsed, it should be
- # added to the end of the list of modifiers. For example:
- #
- # K&R2 A.8.6.2: Array Declarators
- #
- # In a declaration T D where D has the form
- # D1 [constant-expression-opt]
- # and the type of the identifier in the declaration T D1 is
- # "type-modifier T", the type of the
- # identifier of D is "type-modifier array of T"
- #
- # This is what this method does. The declarator it receives
- # can be a list of declarators ending with TypeDecl. It
- # tacks the modifier to the end of this list, just before
- # the TypeDecl.
- #
- # Additionally, the modifier may be a list itself. This is
- # useful for pointers, that can come as a chain from the rule
- # p_pointer. In this case, the whole modifier list is spliced
- # into the new location.
- def _type_modify_decl(self, decl, modifier):
- """ Tacks a type modifier on a declarator, and returns
- the modified declarator.
-
- Note: the declarator and modifier may be modified
- """
- #~ print '****'
- #~ decl.show(offset=3)
- #~ modifier.show(offset=3)
- #~ print '****'
-
- modifier_head = modifier
- modifier_tail = modifier
-
- # The modifier may be a nested list. Reach its tail.
- #
- while modifier_tail.type:
- modifier_tail = modifier_tail.type
-
- # If the decl is a basic type, just tack the modifier onto
- # it
- #
- if isinstance(decl, c_ast.TypeDecl):
- modifier_tail.type = decl
- return modifier
- else:
- # Otherwise, the decl is a list of modifiers. Reach
- # its tail and splice the modifier onto the tail,
- # pointing to the underlying basic type.
- #
- decl_tail = decl
-
- while not isinstance(decl_tail.type, c_ast.TypeDecl):
- decl_tail = decl_tail.type
-
- modifier_tail.type = decl_tail.type
- decl_tail.type = modifier_head
- return decl
-
- # Due to the order in which declarators are constructed,
- # they have to be fixed in order to look like a normal AST.
- #
- # When a declaration arrives from syntax construction, it has
- # these problems:
- # * The innermost TypeDecl has no type (because the basic
- # type is only known at the uppermost declaration level)
- # * The declaration has no variable name, since that is saved
- # in the innermost TypeDecl
- # * The typename of the declaration is a list of type
- # specifiers, and not a node. Here, basic identifier types
- # should be separated from more complex types like enums
- # and structs.
- #
- # This method fixes these problems.
- #
- def _fix_decl_name_type(self, decl, typename):
- """ Fixes a declaration. Modifies decl.
- """
- # Reach the underlying basic type
- #
- type = decl
- while not isinstance(type, c_ast.TypeDecl):
- type = type.type
-
- decl.name = type.declname
- type.quals = decl.quals
-
- # The typename is a list of types. If any type in this
- # list isn't an IdentifierType, it must be the only
- # type in the list (it's illegal to declare "int enum ..")
- # If all the types are basic, they're collected in the
- # IdentifierType holder.
- #
- for tn in typename:
- if not isinstance(tn, c_ast.IdentifierType):
- if len(typename) > 1:
- self._parse_error(
- "Invalid multiple types specified", tn.coord)
- else:
- type.type = tn
- return decl
-
- if not typename:
- # Functions default to returning int
- #
- if not isinstance(decl.type, c_ast.FuncDecl):
- self._parse_error(
- "Missing type in declaration", decl.coord)
- type.type = c_ast.IdentifierType(
- ['int'],
- coord=decl.coord)
- else:
- # At this point, we know that typename is a list of IdentifierType
- # nodes. Concatenate all the names into a single list.
- #
- type.type = c_ast.IdentifierType(
- [name for id in typename for name in id.names],
- coord=typename[0].coord)
- return decl
-
- def _add_declaration_specifier(self, declspec, newspec, kind, append=False):
- """ Declaration specifiers are represented by a dictionary
- with the entries:
- * qual: a list of type qualifiers
- * storage: a list of storage type qualifiers
- * type: a list of type specifiers
- * function: a list of function specifiers
-
- This method is given a declaration specifier, and a
- new specifier of a given kind.
- If `append` is True, the new specifier is added to the end of
- the specifiers list, otherwise it's added at the beginning.
- Returns the declaration specifier, with the new
- specifier incorporated.
- """
- spec = declspec or dict(qual=[], storage=[], type=[], function=[])
-
- if append:
- spec[kind].append(newspec)
- else:
- spec[kind].insert(0, newspec)
-
- return spec
-
- def _build_declarations(self, spec, decls, typedef_namespace=False):
- """ Builds a list of declarations all sharing the given specifiers.
- If typedef_namespace is true, each declared name is added
- to the "typedef namespace", which also includes objects,
- functions, and enum constants.
- """
- is_typedef = 'typedef' in spec['storage']
- declarations = []
-
- # Bit-fields are allowed to be unnamed.
- #
- if decls[0].get('bitsize') is not None:
- pass
-
- # When redeclaring typedef names as identifiers in inner scopes, a
- # problem can occur where the identifier gets grouped into
- # spec['type'], leaving decl as None. This can only occur for the
- # first declarator.
- #
- elif decls[0]['decl'] is None:
- if len(spec['type']) < 2 or len(spec['type'][-1].names) != 1 or \
- not self._is_type_in_scope(spec['type'][-1].names[0]):
- coord = '?'
- for t in spec['type']:
- if hasattr(t, 'coord'):
- coord = t.coord
- break
- self._parse_error('Invalid declaration', coord)
-
- # Make this look as if it came from "direct_declarator:ID"
- decls[0]['decl'] = c_ast.TypeDecl(
- declname=spec['type'][-1].names[0],
- type=None,
- quals=None,
- coord=spec['type'][-1].coord)
- # Remove the "new" type's name from the end of spec['type']
- del spec['type'][-1]
-
- # A similar problem can occur where the declaration ends up looking
- # like an abstract declarator. Give it a name if this is the case.
- #
- elif not isinstance(decls[0]['decl'],
- (c_ast.Struct, c_ast.Union, c_ast.IdentifierType)):
- decls_0_tail = decls[0]['decl']
- while not isinstance(decls_0_tail, c_ast.TypeDecl):
- decls_0_tail = decls_0_tail.type
- if decls_0_tail.declname is None:
- decls_0_tail.declname = spec['type'][-1].names[0]
- del spec['type'][-1]
-
- for decl in decls:
- assert decl['decl'] is not None
- if is_typedef:
- declaration = c_ast.Typedef(
- name=None,
- quals=spec['qual'],
- storage=spec['storage'],
- type=decl['decl'],
- coord=decl['decl'].coord)
- else:
- declaration = c_ast.Decl(
- name=None,
- quals=spec['qual'],
- storage=spec['storage'],
- funcspec=spec['function'],
- type=decl['decl'],
- init=decl.get('init'),
- bitsize=decl.get('bitsize'),
- coord=decl['decl'].coord)
-
- if isinstance(declaration.type,
- (c_ast.Struct, c_ast.Union, c_ast.IdentifierType)):
- fixed_decl = declaration
- else:
- fixed_decl = self._fix_decl_name_type(declaration, spec['type'])
-
- # Add the type name defined by typedef to a
- # symbol table (for usage in the lexer)
- #
- if typedef_namespace:
- if is_typedef:
- self._add_typedef_name(fixed_decl.name, fixed_decl.coord)
- else:
- self._add_identifier(fixed_decl.name, fixed_decl.coord)
-
- declarations.append(fixed_decl)
-
- return declarations
-
- def _build_function_definition(self, spec, decl, param_decls, body):
- """ Builds a function definition.
- """
- assert 'typedef' not in spec['storage']
-
- declaration = self._build_declarations(
- spec=spec,
- decls=[dict(decl=decl, init=None)],
- typedef_namespace=True)[0]
-
- return c_ast.FuncDef(
- decl=declaration,
- param_decls=param_decls,
- body=body,
- coord=decl.coord)
-
- def _select_struct_union_class(self, token):
- """ Given a token (either STRUCT or UNION), selects the
- appropriate AST class.
- """
- if token == 'struct':
- return c_ast.Struct
- else:
- return c_ast.Union
-
- ##
- ## Precedence and associativity of operators
- ##
- precedence = (
- ('left', 'LOR'),
- ('left', 'LAND'),
- ('left', 'OR'),
- ('left', 'XOR'),
- ('left', 'AND'),
- ('left', 'EQ', 'NE'),
- ('left', 'GT', 'GE', 'LT', 'LE'),
- ('left', 'RSHIFT', 'LSHIFT'),
- ('left', 'PLUS', 'MINUS'),
- ('left', 'TIMES', 'DIVIDE', 'MOD')
- )
-
- ##
- ## Grammar productions
- ## Implementation of the BNF defined in K&R2 A.13
- ##
-
- # Wrapper around a translation unit, to allow for empty input.
- # Not strictly part of the C99 Grammar, but useful in practice.
- #
- def p_translation_unit_or_empty(self, p):
- """ translation_unit_or_empty : translation_unit
- | empty
- """
- if p[1] is None:
- p[0] = c_ast.FileAST([])
- else:
- p[0] = c_ast.FileAST(p[1])
-
- def p_translation_unit_1(self, p):
- """ translation_unit : external_declaration
- """
- # Note: external_declaration is already a list
- #
- p[0] = p[1]
-
- def p_translation_unit_2(self, p):
- """ translation_unit : translation_unit external_declaration
- """
- if p[2] is not None:
- p[1].extend(p[2])
- p[0] = p[1]
-
- # Declarations always come as lists (because they can be
- # several in one line), so we wrap the function definition
- # into a list as well, to make the return value of
- # external_declaration homogenous.
- #
- def p_external_declaration_1(self, p):
- """ external_declaration : function_definition
- """
- p[0] = [p[1]]
-
- def p_external_declaration_2(self, p):
- """ external_declaration : declaration
- """
- p[0] = p[1]
-
- def p_external_declaration_3(self, p):
- """ external_declaration : pp_directive
- | pppragma_directive
- """
- p[0] = [p[1]]
-
- def p_external_declaration_4(self, p):
- """ external_declaration : SEMI
- """
- p[0] = None
-
- def p_pp_directive(self, p):
- """ pp_directive : PPHASH
- """
- self._parse_error('Directives not supported yet',
- self._token_coord(p, 1))
-
- def p_pppragma_directive(self, p):
- """ pppragma_directive : PPPRAGMA
- | PPPRAGMA PPPRAGMASTR
- """
- if len(p) == 3:
- p[0] = c_ast.Pragma(p[2], self._token_coord(p, 2))
- else:
- p[0] = c_ast.Pragma("", self._token_coord(p, 1))
-
- # In function definitions, the declarator can be followed by
- # a declaration list, for old "K&R style" function definitios.
- #
- def p_function_definition_1(self, p):
- """ function_definition : id_declarator declaration_list_opt compound_statement
- """
- # no declaration specifiers - 'int' becomes the default type
- spec = dict(
- qual=[],
- storage=[],
- type=[c_ast.IdentifierType(['int'],
- coord=self._token_coord(p, 1))],
- function=[])
-
- p[0] = self._build_function_definition(
- spec=spec,
- decl=p[1],
- param_decls=p[2],
- body=p[3])
-
- def p_function_definition_2(self, p):
- """ function_definition : declaration_specifiers id_declarator declaration_list_opt compound_statement
- """
- spec = p[1]
-
- p[0] = self._build_function_definition(
- spec=spec,
- decl=p[2],
- param_decls=p[3],
- body=p[4])
-
- def p_statement(self, p):
- """ statement : labeled_statement
- | expression_statement
- | compound_statement
- | selection_statement
- | iteration_statement
- | jump_statement
- | pppragma_directive
- """
- p[0] = p[1]
-
- # A pragma is generally considered a decorator rather than an actual statement.
- # Still, for the purposes of analyzing an abstract syntax tree of C code,
- # pragma's should not be ignored and were previously treated as a statement.
- # This presents a problem for constructs that take a statement such as labeled_statements,
- # selection_statements, and iteration_statements, causing a misleading structure
- # in the AST. For example, consider the following C code.
- #
- # for (int i = 0; i < 3; i++)
- # #pragma omp critical
- # sum += 1;
- #
- # This code will compile and execute "sum += 1;" as the body of the for loop.
- # Previous implementations of PyCParser would render the AST for this
- # block of code as follows:
- #
- # For:
- # DeclList:
- # Decl: i, [], [], []
- # TypeDecl: i, []
- # IdentifierType: ['int']
- # Constant: int, 0
- # BinaryOp: <
- # ID: i
- # Constant: int, 3
- # UnaryOp: p++
- # ID: i
- # Pragma: omp critical
- # Assignment: +=
- # ID: sum
- # Constant: int, 1
- #
- # This AST misleadingly takes the Pragma as the body of the loop and the
- # assignment then becomes a sibling of the loop.
- #
- # To solve edge cases like these, the pragmacomp_or_statement rule groups
- # a pragma and its following statement (which would otherwise be orphaned)
- # using a compound block, effectively turning the above code into:
- #
- # for (int i = 0; i < 3; i++) {
- # #pragma omp critical
- # sum += 1;
- # }
- def p_pragmacomp_or_statement(self, p):
- """ pragmacomp_or_statement : pppragma_directive statement
- | statement
- """
- if isinstance(p[1], c_ast.Pragma) and len(p) == 3:
- p[0] = c_ast.Compound(
- block_items=[p[1], p[2]],
- coord=self._token_coord(p, 1))
- else:
- p[0] = p[1]
-
- # In C, declarations can come several in a line:
- # int x, *px, romulo = 5;
- #
- # However, for the AST, we will split them to separate Decl
- # nodes.
- #
- # This rule splits its declarations and always returns a list
- # of Decl nodes, even if it's one element long.
- #
- def p_decl_body(self, p):
- """ decl_body : declaration_specifiers init_declarator_list_opt
- | declaration_specifiers_no_type id_init_declarator_list_opt
- """
- spec = p[1]
-
- # p[2] (init_declarator_list_opt) is either a list or None
- #
- if p[2] is None:
- # By the standard, you must have at least one declarator unless
- # declaring a structure tag, a union tag, or the members of an
- # enumeration.
- #
- ty = spec['type']
- s_u_or_e = (c_ast.Struct, c_ast.Union, c_ast.Enum)
- if len(ty) == 1 and isinstance(ty[0], s_u_or_e):
- decls = [c_ast.Decl(
- name=None,
- quals=spec['qual'],
- storage=spec['storage'],
- funcspec=spec['function'],
- type=ty[0],
- init=None,
- bitsize=None,
- coord=ty[0].coord)]
-
- # However, this case can also occur on redeclared identifiers in
- # an inner scope. The trouble is that the redeclared type's name
- # gets grouped into declaration_specifiers; _build_declarations
- # compensates for this.
- #
- else:
- decls = self._build_declarations(
- spec=spec,
- decls=[dict(decl=None, init=None)],
- typedef_namespace=True)
-
- else:
- decls = self._build_declarations(
- spec=spec,
- decls=p[2],
- typedef_namespace=True)
-
- p[0] = decls
-
- # The declaration has been split to a decl_body sub-rule and
- # SEMI, because having them in a single rule created a problem
- # for defining typedefs.
- #
- # If a typedef line was directly followed by a line using the
- # type defined with the typedef, the type would not be
- # recognized. This is because to reduce the declaration rule,
- # the parser's lookahead asked for the token after SEMI, which
- # was the type from the next line, and the lexer had no chance
- # to see the updated type symbol table.
- #
- # Splitting solves this problem, because after seeing SEMI,
- # the parser reduces decl_body, which actually adds the new
- # type into the table to be seen by the lexer before the next
- # line is reached.
- def p_declaration(self, p):
- """ declaration : decl_body SEMI
- """
- p[0] = p[1]
-
- # Since each declaration is a list of declarations, this
- # rule will combine all the declarations and return a single
- # list
- #
- def p_declaration_list(self, p):
- """ declaration_list : declaration
- | declaration_list declaration
- """
- p[0] = p[1] if len(p) == 2 else p[1] + p[2]
-
- # To know when declaration-specifiers end and declarators begin,
- # we require declaration-specifiers to have at least one
- # type-specifier, and disallow typedef-names after we've seen any
- # type-specifier. These are both required by the spec.
- #
- def p_declaration_specifiers_no_type_1(self, p):
- """ declaration_specifiers_no_type : type_qualifier declaration_specifiers_no_type_opt
- """
- p[0] = self._add_declaration_specifier(p[2], p[1], 'qual')
-
- def p_declaration_specifiers_no_type_2(self, p):
- """ declaration_specifiers_no_type : storage_class_specifier declaration_specifiers_no_type_opt
- """
- p[0] = self._add_declaration_specifier(p[2], p[1], 'storage')
-
- def p_declaration_specifiers_no_type_3(self, p):
- """ declaration_specifiers_no_type : function_specifier declaration_specifiers_no_type_opt
- """
- p[0] = self._add_declaration_specifier(p[2], p[1], 'function')
-
-
- def p_declaration_specifiers_1(self, p):
- """ declaration_specifiers : declaration_specifiers type_qualifier
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'qual', append=True)
-
- def p_declaration_specifiers_2(self, p):
- """ declaration_specifiers : declaration_specifiers storage_class_specifier
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'storage', append=True)
-
- def p_declaration_specifiers_3(self, p):
- """ declaration_specifiers : declaration_specifiers function_specifier
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'function', append=True)
-
- def p_declaration_specifiers_4(self, p):
- """ declaration_specifiers : declaration_specifiers type_specifier_no_typeid
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True)
-
- def p_declaration_specifiers_5(self, p):
- """ declaration_specifiers : type_specifier
- """
- p[0] = self._add_declaration_specifier(None, p[1], 'type')
-
- def p_declaration_specifiers_6(self, p):
- """ declaration_specifiers : declaration_specifiers_no_type type_specifier
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True)
-
-
- def p_storage_class_specifier(self, p):
- """ storage_class_specifier : AUTO
- | REGISTER
- | STATIC
- | EXTERN
- | TYPEDEF
- """
- p[0] = p[1]
-
- def p_function_specifier(self, p):
- """ function_specifier : INLINE
- """
- p[0] = p[1]
-
- def p_type_specifier_no_typeid(self, p):
- """ type_specifier_no_typeid : VOID
- | _BOOL
- | CHAR
- | SHORT
- | INT
- | LONG
- | FLOAT
- | DOUBLE
- | _COMPLEX
- | SIGNED
- | UNSIGNED
- | __INT128
- """
- p[0] = c_ast.IdentifierType([p[1]], coord=self._token_coord(p, 1))
-
- def p_type_specifier(self, p):
- """ type_specifier : typedef_name
- | enum_specifier
- | struct_or_union_specifier
- | type_specifier_no_typeid
- """
- p[0] = p[1]
-
- def p_type_qualifier(self, p):
- """ type_qualifier : CONST
- | RESTRICT
- | VOLATILE
- """
- p[0] = p[1]
-
- def p_init_declarator_list(self, p):
- """ init_declarator_list : init_declarator
- | init_declarator_list COMMA init_declarator
- """
- p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]
-
- # Returns a {decl=<declarator> : init=<initializer>} dictionary
- # If there's no initializer, uses None
- #
- def p_init_declarator(self, p):
- """ init_declarator : declarator
- | declarator EQUALS initializer
- """
- p[0] = dict(decl=p[1], init=(p[3] if len(p) > 2 else None))
-
- def p_id_init_declarator_list(self, p):
- """ id_init_declarator_list : id_init_declarator
- | id_init_declarator_list COMMA init_declarator
- """
- p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]
-
- def p_id_init_declarator(self, p):
- """ id_init_declarator : id_declarator
- | id_declarator EQUALS initializer
- """
- p[0] = dict(decl=p[1], init=(p[3] if len(p) > 2 else None))
-
- # Require at least one type specifier in a specifier-qualifier-list
- #
- def p_specifier_qualifier_list_1(self, p):
- """ specifier_qualifier_list : specifier_qualifier_list type_specifier_no_typeid
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'type', append=True)
-
- def p_specifier_qualifier_list_2(self, p):
- """ specifier_qualifier_list : specifier_qualifier_list type_qualifier
- """
- p[0] = self._add_declaration_specifier(p[1], p[2], 'qual', append=True)
-
- def p_specifier_qualifier_list_3(self, p):
- """ specifier_qualifier_list : type_specifier
- """
- p[0] = self._add_declaration_specifier(None, p[1], 'type')
-
- def p_specifier_qualifier_list_4(self, p):
- """ specifier_qualifier_list : type_qualifier_list type_specifier
- """
- spec = dict(qual=p[1], storage=[], type=[], function=[])
- p[0] = self._add_declaration_specifier(spec, p[2], 'type', append=True)
-
- # TYPEID is allowed here (and in other struct/enum related tag names), because
- # struct/enum tags reside in their own namespace and can be named the same as types
- #
- def p_struct_or_union_specifier_1(self, p):
- """ struct_or_union_specifier : struct_or_union ID
- | struct_or_union TYPEID
- """
- klass = self._select_struct_union_class(p[1])
- # None means no list of members
- p[0] = klass(
- name=p[2],
- decls=None,
- coord=self._token_coord(p, 2))
-
- def p_struct_or_union_specifier_2(self, p):
- """ struct_or_union_specifier : struct_or_union brace_open struct_declaration_list brace_close
- | struct_or_union brace_open brace_close
- """
- klass = self._select_struct_union_class(p[1])
- if len(p) == 4:
- # Empty sequence means an empty list of members
- p[0] = klass(
- name=None,
- decls=[],
- coord=self._token_coord(p, 2))
- else:
- p[0] = klass(
- name=None,
- decls=p[3],
- coord=self._token_coord(p, 2))
-
-
- def p_struct_or_union_specifier_3(self, p):
- """ struct_or_union_specifier : struct_or_union ID brace_open struct_declaration_list brace_close
- | struct_or_union ID brace_open brace_close
- | struct_or_union TYPEID brace_open struct_declaration_list brace_close
- | struct_or_union TYPEID brace_open brace_close
- """
- klass = self._select_struct_union_class(p[1])
- if len(p) == 5:
- # Empty sequence means an empty list of members
- p[0] = klass(
- name=p[2],
- decls=[],
- coord=self._token_coord(p, 2))
- else:
- p[0] = klass(
- name=p[2],
- decls=p[4],
- coord=self._token_coord(p, 2))
-
- def p_struct_or_union(self, p):
- """ struct_or_union : STRUCT
- | UNION
- """
- p[0] = p[1]
-
- # Combine all declarations into a single list
- #
- def p_struct_declaration_list(self, p):
- """ struct_declaration_list : struct_declaration
- | struct_declaration_list struct_declaration
- """
- if len(p) == 2:
- p[0] = p[1] or []
- else:
- p[0] = p[1] + (p[2] or [])
-
- def p_struct_declaration_1(self, p):
- """ struct_declaration : specifier_qualifier_list struct_declarator_list_opt SEMI
- """
- spec = p[1]
- assert 'typedef' not in spec['storage']
-
- if p[2] is not None:
- decls = self._build_declarations(
- spec=spec,
- decls=p[2])
-
- elif len(spec['type']) == 1:
- # Anonymous struct/union, gcc extension, C1x feature.
- # Although the standard only allows structs/unions here, I see no
- # reason to disallow other types since some compilers have typedefs
- # here, and pycparser isn't about rejecting all invalid code.
- #
- node = spec['type'][0]
- if isinstance(node, c_ast.Node):
- decl_type = node
- else:
- decl_type = c_ast.IdentifierType(node)
-
- decls = self._build_declarations(
- spec=spec,
- decls=[dict(decl=decl_type)])
-
- else:
- # Structure/union members can have the same names as typedefs.
- # The trouble is that the member's name gets grouped into
- # specifier_qualifier_list; _build_declarations compensates.
- #
- decls = self._build_declarations(
- spec=spec,
- decls=[dict(decl=None, init=None)])
-
- p[0] = decls
-
- def p_struct_declaration_2(self, p):
- """ struct_declaration : SEMI
- """
- p[0] = None
-
- def p_struct_declaration_3(self, p):
- """ struct_declaration : pppragma_directive
- """
- p[0] = [p[1]]
-
- def p_struct_declarator_list(self, p):
- """ struct_declarator_list : struct_declarator
- | struct_declarator_list COMMA struct_declarator
- """
- p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]
-
- # struct_declarator passes up a dict with the keys: decl (for
- # the underlying declarator) and bitsize (for the bitsize)
- #
- def p_struct_declarator_1(self, p):
- """ struct_declarator : declarator
- """
- p[0] = {'decl': p[1], 'bitsize': None}
-
- def p_struct_declarator_2(self, p):
- """ struct_declarator : declarator COLON constant_expression
- | COLON constant_expression
- """
- if len(p) > 3:
- p[0] = {'decl': p[1], 'bitsize': p[3]}
- else:
- p[0] = {'decl': c_ast.TypeDecl(None, None, None), 'bitsize': p[2]}
-
- def p_enum_specifier_1(self, p):
- """ enum_specifier : ENUM ID
- | ENUM TYPEID
- """
- p[0] = c_ast.Enum(p[2], None, self._token_coord(p, 1))
-
- def p_enum_specifier_2(self, p):
- """ enum_specifier : ENUM brace_open enumerator_list brace_close
- """
- p[0] = c_ast.Enum(None, p[3], self._token_coord(p, 1))
-
- def p_enum_specifier_3(self, p):
- """ enum_specifier : ENUM ID brace_open enumerator_list brace_close
- | ENUM TYPEID brace_open enumerator_list brace_close
- """
- p[0] = c_ast.Enum(p[2], p[4], self._token_coord(p, 1))
-
- def p_enumerator_list(self, p):
- """ enumerator_list : enumerator
- | enumerator_list COMMA
- | enumerator_list COMMA enumerator
- """
- if len(p) == 2:
- p[0] = c_ast.EnumeratorList([p[1]], p[1].coord)
- elif len(p) == 3:
- p[0] = p[1]
- else:
- p[1].enumerators.append(p[3])
- p[0] = p[1]
-
- def p_enumerator(self, p):
- """ enumerator : ID
- | ID EQUALS constant_expression
- """
- if len(p) == 2:
- enumerator = c_ast.Enumerator(
- p[1], None,
- self._token_coord(p, 1))
- else:
- enumerator = c_ast.Enumerator(
- p[1], p[3],
- self._token_coord(p, 1))
- self._add_identifier(enumerator.name, enumerator.coord)
-
- p[0] = enumerator
-
- def p_declarator(self, p):
- """ declarator : id_declarator
- | typeid_declarator
- """
- p[0] = p[1]
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_xxx_declarator_1(self, p):
- """ xxx_declarator : direct_xxx_declarator
- """
- p[0] = p[1]
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_xxx_declarator_2(self, p):
- """ xxx_declarator : pointer direct_xxx_declarator
- """
- p[0] = self._type_modify_decl(p[2], p[1])
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_direct_xxx_declarator_1(self, p):
- """ direct_xxx_declarator : yyy
- """
- p[0] = c_ast.TypeDecl(
- declname=p[1],
- type=None,
- quals=None,
- coord=self._token_coord(p, 1))
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'))
- def p_direct_xxx_declarator_2(self, p):
- """ direct_xxx_declarator : LPAREN xxx_declarator RPAREN
- """
- p[0] = p[2]
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_direct_xxx_declarator_3(self, p):
- """ direct_xxx_declarator : direct_xxx_declarator LBRACKET type_qualifier_list_opt assignment_expression_opt RBRACKET
- """
- quals = (p[3] if len(p) > 5 else []) or []
- # Accept dimension qualifiers
- # Per C99 6.7.5.3 p7
- arr = c_ast.ArrayDecl(
- type=None,
- dim=p[4] if len(p) > 5 else p[3],
- dim_quals=quals,
- coord=p[1].coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_direct_xxx_declarator_4(self, p):
- """ direct_xxx_declarator : direct_xxx_declarator LBRACKET STATIC type_qualifier_list_opt assignment_expression RBRACKET
- | direct_xxx_declarator LBRACKET type_qualifier_list STATIC assignment_expression RBRACKET
- """
- # Using slice notation for PLY objects doesn't work in Python 3 for the
- # version of PLY embedded with pycparser; see PLY Google Code issue 30.
- # Work around that here by listing the two elements separately.
- listed_quals = [item if isinstance(item, list) else [item]
- for item in [p[3],p[4]]]
- dim_quals = [qual for sublist in listed_quals for qual in sublist
- if qual is not None]
- arr = c_ast.ArrayDecl(
- type=None,
- dim=p[5],
- dim_quals=dim_quals,
- coord=p[1].coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
-
- # Special for VLAs
- #
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_direct_xxx_declarator_5(self, p):
- """ direct_xxx_declarator : direct_xxx_declarator LBRACKET type_qualifier_list_opt TIMES RBRACKET
- """
- arr = c_ast.ArrayDecl(
- type=None,
- dim=c_ast.ID(p[4], self._token_coord(p, 4)),
- dim_quals=p[3] if p[3] != None else [],
- coord=p[1].coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
-
- @parameterized(('id', 'ID'), ('typeid', 'TYPEID'), ('typeid_noparen', 'TYPEID'))
- def p_direct_xxx_declarator_6(self, p):
- """ direct_xxx_declarator : direct_xxx_declarator LPAREN parameter_type_list RPAREN
- | direct_xxx_declarator LPAREN identifier_list_opt RPAREN
- """
- func = c_ast.FuncDecl(
- args=p[3],
- type=None,
- coord=p[1].coord)
-
- # To see why _get_yacc_lookahead_token is needed, consider:
- # typedef char TT;
- # void foo(int TT) { TT = 10; }
- # Outside the function, TT is a typedef, but inside (starting and
- # ending with the braces) it's a parameter. The trouble begins with
- # yacc's lookahead token. We don't know if we're declaring or
- # defining a function until we see LBRACE, but if we wait for yacc to
- # trigger a rule on that token, then TT will have already been read
- # and incorrectly interpreted as TYPEID. We need to add the
- # parameters to the scope the moment the lexer sees LBRACE.
- #
- if self._get_yacc_lookahead_token().type == "LBRACE":
- if func.args is not None:
- for param in func.args.params:
- if isinstance(param, c_ast.EllipsisParam): break
- self._add_identifier(param.name, param.coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=func)
-
- def p_pointer(self, p):
- """ pointer : TIMES type_qualifier_list_opt
- | TIMES type_qualifier_list_opt pointer
- """
- coord = self._token_coord(p, 1)
- # Pointer decls nest from inside out. This is important when different
- # levels have different qualifiers. For example:
- #
- # char * const * p;
- #
- # Means "pointer to const pointer to char"
- #
- # While:
- #
- # char ** const p;
- #
- # Means "const pointer to pointer to char"
- #
- # So when we construct PtrDecl nestings, the leftmost pointer goes in
- # as the most nested type.
- nested_type = c_ast.PtrDecl(quals=p[2] or [], type=None, coord=coord)
- if len(p) > 3:
- tail_type = p[3]
- while tail_type.type is not None:
- tail_type = tail_type.type
- tail_type.type = nested_type
- p[0] = p[3]
- else:
- p[0] = nested_type
-
- def p_type_qualifier_list(self, p):
- """ type_qualifier_list : type_qualifier
- | type_qualifier_list type_qualifier
- """
- p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]
-
- def p_parameter_type_list(self, p):
- """ parameter_type_list : parameter_list
- | parameter_list COMMA ELLIPSIS
- """
- if len(p) > 2:
- p[1].params.append(c_ast.EllipsisParam(self._token_coord(p, 3)))
-
- p[0] = p[1]
-
- def p_parameter_list(self, p):
- """ parameter_list : parameter_declaration
- | parameter_list COMMA parameter_declaration
- """
- if len(p) == 2: # single parameter
- p[0] = c_ast.ParamList([p[1]], p[1].coord)
- else:
- p[1].params.append(p[3])
- p[0] = p[1]
-
- # From ISO/IEC 9899:TC2, 6.7.5.3.11:
- # "If, in a parameter declaration, an identifier can be treated either
- # as a typedef name or as a parameter name, it shall be taken as a
- # typedef name."
- #
- # Inside a parameter declaration, once we've reduced declaration specifiers,
- # if we shift in an LPAREN and see a TYPEID, it could be either an abstract
- # declarator or a declarator nested inside parens. This rule tells us to
- # always treat it as an abstract declarator. Therefore, we only accept
- # `id_declarator`s and `typeid_noparen_declarator`s.
- def p_parameter_declaration_1(self, p):
- """ parameter_declaration : declaration_specifiers id_declarator
- | declaration_specifiers typeid_noparen_declarator
- """
- spec = p[1]
- if not spec['type']:
- spec['type'] = [c_ast.IdentifierType(['int'],
- coord=self._token_coord(p, 1))]
- p[0] = self._build_declarations(
- spec=spec,
- decls=[dict(decl=p[2])])[0]
-
- def p_parameter_declaration_2(self, p):
- """ parameter_declaration : declaration_specifiers abstract_declarator_opt
- """
- spec = p[1]
- if not spec['type']:
- spec['type'] = [c_ast.IdentifierType(['int'],
- coord=self._token_coord(p, 1))]
-
- # Parameters can have the same names as typedefs. The trouble is that
- # the parameter's name gets grouped into declaration_specifiers, making
- # it look like an old-style declaration; compensate.
- #
- if len(spec['type']) > 1 and len(spec['type'][-1].names) == 1 and \
- self._is_type_in_scope(spec['type'][-1].names[0]):
- decl = self._build_declarations(
- spec=spec,
- decls=[dict(decl=p[2], init=None)])[0]
-
- # This truly is an old-style parameter declaration
- #
- else:
- decl = c_ast.Typename(
- name='',
- quals=spec['qual'],
- type=p[2] or c_ast.TypeDecl(None, None, None),
- coord=self._token_coord(p, 2))
- typename = spec['type']
- decl = self._fix_decl_name_type(decl, typename)
-
- p[0] = decl
-
- def p_identifier_list(self, p):
- """ identifier_list : identifier
- | identifier_list COMMA identifier
- """
- if len(p) == 2: # single parameter
- p[0] = c_ast.ParamList([p[1]], p[1].coord)
- else:
- p[1].params.append(p[3])
- p[0] = p[1]
-
- def p_initializer_1(self, p):
- """ initializer : assignment_expression
- """
- p[0] = p[1]
-
- def p_initializer_2(self, p):
- """ initializer : brace_open initializer_list_opt brace_close
- | brace_open initializer_list COMMA brace_close
- """
- if p[2] is None:
- p[0] = c_ast.InitList([], self._token_coord(p, 1))
- else:
- p[0] = p[2]
-
- def p_initializer_list(self, p):
- """ initializer_list : designation_opt initializer
- | initializer_list COMMA designation_opt initializer
- """
- if len(p) == 3: # single initializer
- init = p[2] if p[1] is None else c_ast.NamedInitializer(p[1], p[2])
- p[0] = c_ast.InitList([init], p[2].coord)
- else:
- init = p[4] if p[3] is None else c_ast.NamedInitializer(p[3], p[4])
- p[1].exprs.append(init)
- p[0] = p[1]
-
- def p_designation(self, p):
- """ designation : designator_list EQUALS
- """
- p[0] = p[1]
-
- # Designators are represented as a list of nodes, in the order in which
- # they're written in the code.
- #
- def p_designator_list(self, p):
- """ designator_list : designator
- | designator_list designator
- """
- p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]
-
- def p_designator(self, p):
- """ designator : LBRACKET constant_expression RBRACKET
- | PERIOD identifier
- """
- p[0] = p[2]
-
- def p_type_name(self, p):
- """ type_name : specifier_qualifier_list abstract_declarator_opt
- """
- typename = c_ast.Typename(
- name='',
- quals=p[1]['qual'],
- type=p[2] or c_ast.TypeDecl(None, None, None),
- coord=self._token_coord(p, 2))
-
- p[0] = self._fix_decl_name_type(typename, p[1]['type'])
-
- def p_abstract_declarator_1(self, p):
- """ abstract_declarator : pointer
- """
- dummytype = c_ast.TypeDecl(None, None, None)
- p[0] = self._type_modify_decl(
- decl=dummytype,
- modifier=p[1])
-
- def p_abstract_declarator_2(self, p):
- """ abstract_declarator : pointer direct_abstract_declarator
- """
- p[0] = self._type_modify_decl(p[2], p[1])
-
- def p_abstract_declarator_3(self, p):
- """ abstract_declarator : direct_abstract_declarator
- """
- p[0] = p[1]
-
- # Creating and using direct_abstract_declarator_opt here
- # instead of listing both direct_abstract_declarator and the
- # lack of it in the beginning of _1 and _2 caused two
- # shift/reduce errors.
- #
- def p_direct_abstract_declarator_1(self, p):
- """ direct_abstract_declarator : LPAREN abstract_declarator RPAREN """
- p[0] = p[2]
-
- def p_direct_abstract_declarator_2(self, p):
- """ direct_abstract_declarator : direct_abstract_declarator LBRACKET assignment_expression_opt RBRACKET
- """
- arr = c_ast.ArrayDecl(
- type=None,
- dim=p[3],
- dim_quals=[],
- coord=p[1].coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
-
- def p_direct_abstract_declarator_3(self, p):
- """ direct_abstract_declarator : LBRACKET assignment_expression_opt RBRACKET
- """
- p[0] = c_ast.ArrayDecl(
- type=c_ast.TypeDecl(None, None, None),
- dim=p[2],
- dim_quals=[],
- coord=self._token_coord(p, 1))
-
- def p_direct_abstract_declarator_4(self, p):
- """ direct_abstract_declarator : direct_abstract_declarator LBRACKET TIMES RBRACKET
- """
- arr = c_ast.ArrayDecl(
- type=None,
- dim=c_ast.ID(p[3], self._token_coord(p, 3)),
- dim_quals=[],
- coord=p[1].coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=arr)
-
- def p_direct_abstract_declarator_5(self, p):
- """ direct_abstract_declarator : LBRACKET TIMES RBRACKET
- """
- p[0] = c_ast.ArrayDecl(
- type=c_ast.TypeDecl(None, None, None),
- dim=c_ast.ID(p[3], self._token_coord(p, 3)),
- dim_quals=[],
- coord=self._token_coord(p, 1))
-
- def p_direct_abstract_declarator_6(self, p):
- """ direct_abstract_declarator : direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN
- """
- func = c_ast.FuncDecl(
- args=p[3],
- type=None,
- coord=p[1].coord)
-
- p[0] = self._type_modify_decl(decl=p[1], modifier=func)
-
- def p_direct_abstract_declarator_7(self, p):
- """ direct_abstract_declarator : LPAREN parameter_type_list_opt RPAREN
- """
- p[0] = c_ast.FuncDecl(
- args=p[2],
- type=c_ast.TypeDecl(None, None, None),
- coord=self._token_coord(p, 1))
-
- # declaration is a list, statement isn't. To make it consistent, block_item
- # will always be a list
- #
- def p_block_item(self, p):
- """ block_item : declaration
- | statement
- """
- p[0] = p[1] if isinstance(p[1], list) else [p[1]]
-
- # Since we made block_item a list, this just combines lists
- #
- def p_block_item_list(self, p):
- """ block_item_list : block_item
- | block_item_list block_item
- """
- # Empty block items (plain ';') produce [None], so ignore them
- p[0] = p[1] if (len(p) == 2 or p[2] == [None]) else p[1] + p[2]
-
- def p_compound_statement_1(self, p):
- """ compound_statement : brace_open block_item_list_opt brace_close """
- p[0] = c_ast.Compound(
- block_items=p[2],
- coord=self._token_coord(p, 1))
-
- def p_labeled_statement_1(self, p):
- """ labeled_statement : ID COLON pragmacomp_or_statement """
- p[0] = c_ast.Label(p[1], p[3], self._token_coord(p, 1))
-
- def p_labeled_statement_2(self, p):
- """ labeled_statement : CASE constant_expression COLON pragmacomp_or_statement """
- p[0] = c_ast.Case(p[2], [p[4]], self._token_coord(p, 1))
-
- def p_labeled_statement_3(self, p):
- """ labeled_statement : DEFAULT COLON pragmacomp_or_statement """
- p[0] = c_ast.Default([p[3]], self._token_coord(p, 1))
-
- def p_selection_statement_1(self, p):
- """ selection_statement : IF LPAREN expression RPAREN pragmacomp_or_statement """
- p[0] = c_ast.If(p[3], p[5], None, self._token_coord(p, 1))
-
- def p_selection_statement_2(self, p):
- """ selection_statement : IF LPAREN expression RPAREN statement ELSE pragmacomp_or_statement """
- p[0] = c_ast.If(p[3], p[5], p[7], self._token_coord(p, 1))
-
- def p_selection_statement_3(self, p):
- """ selection_statement : SWITCH LPAREN expression RPAREN pragmacomp_or_statement """
- p[0] = fix_switch_cases(
- c_ast.Switch(p[3], p[5], self._token_coord(p, 1)))
-
- def p_iteration_statement_1(self, p):
- """ iteration_statement : WHILE LPAREN expression RPAREN pragmacomp_or_statement """
- p[0] = c_ast.While(p[3], p[5], self._token_coord(p, 1))
-
- def p_iteration_statement_2(self, p):
- """ iteration_statement : DO pragmacomp_or_statement WHILE LPAREN expression RPAREN SEMI """
- p[0] = c_ast.DoWhile(p[5], p[2], self._token_coord(p, 1))
-
- def p_iteration_statement_3(self, p):
- """ iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement """
- p[0] = c_ast.For(p[3], p[5], p[7], p[9], self._token_coord(p, 1))
-
- def p_iteration_statement_4(self, p):
- """ iteration_statement : FOR LPAREN declaration expression_opt SEMI expression_opt RPAREN pragmacomp_or_statement """
- p[0] = c_ast.For(c_ast.DeclList(p[3], self._token_coord(p, 1)),
- p[4], p[6], p[8], self._token_coord(p, 1))
-
- def p_jump_statement_1(self, p):
- """ jump_statement : GOTO ID SEMI """
- p[0] = c_ast.Goto(p[2], self._token_coord(p, 1))
-
- def p_jump_statement_2(self, p):
- """ jump_statement : BREAK SEMI """
- p[0] = c_ast.Break(self._token_coord(p, 1))
-
- def p_jump_statement_3(self, p):
- """ jump_statement : CONTINUE SEMI """
- p[0] = c_ast.Continue(self._token_coord(p, 1))
-
- def p_jump_statement_4(self, p):
- """ jump_statement : RETURN expression SEMI
- | RETURN SEMI
- """
- p[0] = c_ast.Return(p[2] if len(p) == 4 else None, self._token_coord(p, 1))
-
- def p_expression_statement(self, p):
- """ expression_statement : expression_opt SEMI """
- if p[1] is None:
- p[0] = c_ast.EmptyStatement(self._token_coord(p, 2))
- else:
- p[0] = p[1]
-
- def p_expression(self, p):
- """ expression : assignment_expression
- | expression COMMA assignment_expression
- """
- if len(p) == 2:
- p[0] = p[1]
- else:
- if not isinstance(p[1], c_ast.ExprList):
- p[1] = c_ast.ExprList([p[1]], p[1].coord)
-
- p[1].exprs.append(p[3])
- p[0] = p[1]
-
- def p_typedef_name(self, p):
- """ typedef_name : TYPEID """
- p[0] = c_ast.IdentifierType([p[1]], coord=self._token_coord(p, 1))
-
- def p_assignment_expression(self, p):
- """ assignment_expression : conditional_expression
- | unary_expression assignment_operator assignment_expression
- """
- if len(p) == 2:
- p[0] = p[1]
- else:
- p[0] = c_ast.Assignment(p[2], p[1], p[3], p[1].coord)
-
- # K&R2 defines these as many separate rules, to encode
- # precedence and associativity. Why work hard ? I'll just use
- # the built in precedence/associativity specification feature
- # of PLY. (see precedence declaration above)
- #
- def p_assignment_operator(self, p):
- """ assignment_operator : EQUALS
- | XOREQUAL
- | TIMESEQUAL
- | DIVEQUAL
- | MODEQUAL
- | PLUSEQUAL
- | MINUSEQUAL
- | LSHIFTEQUAL
- | RSHIFTEQUAL
- | ANDEQUAL
- | OREQUAL
- """
- p[0] = p[1]
-
- def p_constant_expression(self, p):
- """ constant_expression : conditional_expression """
- p[0] = p[1]
-
- def p_conditional_expression(self, p):
- """ conditional_expression : binary_expression
- | binary_expression CONDOP expression COLON conditional_expression
- """
- if len(p) == 2:
- p[0] = p[1]
- else:
- p[0] = c_ast.TernaryOp(p[1], p[3], p[5], p[1].coord)
-
- def p_binary_expression(self, p):
- """ binary_expression : cast_expression
- | binary_expression TIMES binary_expression
- | binary_expression DIVIDE binary_expression
- | binary_expression MOD binary_expression
- | binary_expression PLUS binary_expression
- | binary_expression MINUS binary_expression
- | binary_expression RSHIFT binary_expression
- | binary_expression LSHIFT binary_expression
- | binary_expression LT binary_expression
- | binary_expression LE binary_expression
- | binary_expression GE binary_expression
- | binary_expression GT binary_expression
- | binary_expression EQ binary_expression
- | binary_expression NE binary_expression
- | binary_expression AND binary_expression
- | binary_expression OR binary_expression
- | binary_expression XOR binary_expression
- | binary_expression LAND binary_expression
- | binary_expression LOR binary_expression
- """
- if len(p) == 2:
- p[0] = p[1]
- else:
- p[0] = c_ast.BinaryOp(p[2], p[1], p[3], p[1].coord)
-
- def p_cast_expression_1(self, p):
- """ cast_expression : unary_expression """
- p[0] = p[1]
-
- def p_cast_expression_2(self, p):
- """ cast_expression : LPAREN type_name RPAREN cast_expression """
- p[0] = c_ast.Cast(p[2], p[4], self._token_coord(p, 1))
-
- def p_unary_expression_1(self, p):
- """ unary_expression : postfix_expression """
- p[0] = p[1]
-
- def p_unary_expression_2(self, p):
- """ unary_expression : PLUSPLUS unary_expression
- | MINUSMINUS unary_expression
- | unary_operator cast_expression
- """
- p[0] = c_ast.UnaryOp(p[1], p[2], p[2].coord)
-
- def p_unary_expression_3(self, p):
- """ unary_expression : SIZEOF unary_expression
- | SIZEOF LPAREN type_name RPAREN
- """
- p[0] = c_ast.UnaryOp(
- p[1],
- p[2] if len(p) == 3 else p[3],
- self._token_coord(p, 1))
-
- def p_unary_operator(self, p):
- """ unary_operator : AND
- | TIMES
- | PLUS
- | MINUS
- | NOT
- | LNOT
- """
- p[0] = p[1]
-
- def p_postfix_expression_1(self, p):
- """ postfix_expression : primary_expression """
- p[0] = p[1]
-
- def p_postfix_expression_2(self, p):
- """ postfix_expression : postfix_expression LBRACKET expression RBRACKET """
- p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord)
-
- def p_postfix_expression_3(self, p):
- """ postfix_expression : postfix_expression LPAREN argument_expression_list RPAREN
- | postfix_expression LPAREN RPAREN
- """
- p[0] = c_ast.FuncCall(p[1], p[3] if len(p) == 5 else None, p[1].coord)
-
- def p_postfix_expression_4(self, p):
- """ postfix_expression : postfix_expression PERIOD ID
- | postfix_expression PERIOD TYPEID
- | postfix_expression ARROW ID
- | postfix_expression ARROW TYPEID
- """
- field = c_ast.ID(p[3], self._token_coord(p, 3))
- p[0] = c_ast.StructRef(p[1], p[2], field, p[1].coord)
-
- def p_postfix_expression_5(self, p):
- """ postfix_expression : postfix_expression PLUSPLUS
- | postfix_expression MINUSMINUS
- """
- p[0] = c_ast.UnaryOp('p' + p[2], p[1], p[1].coord)
-
- def p_postfix_expression_6(self, p):
- """ postfix_expression : LPAREN type_name RPAREN brace_open initializer_list brace_close
- | LPAREN type_name RPAREN brace_open initializer_list COMMA brace_close
- """
- p[0] = c_ast.CompoundLiteral(p[2], p[5])
-
- def p_primary_expression_1(self, p):
- """ primary_expression : identifier """
- p[0] = p[1]
-
- def p_primary_expression_2(self, p):
- """ primary_expression : constant """
- p[0] = p[1]
-
- def p_primary_expression_3(self, p):
- """ primary_expression : unified_string_literal
- | unified_wstring_literal
- """
- p[0] = p[1]
-
- def p_primary_expression_4(self, p):
- """ primary_expression : LPAREN expression RPAREN """
- p[0] = p[2]
-
- def p_primary_expression_5(self, p):
- """ primary_expression : OFFSETOF LPAREN type_name COMMA offsetof_member_designator RPAREN
- """
- coord = self._token_coord(p, 1)
- p[0] = c_ast.FuncCall(c_ast.ID(p[1], coord),
- c_ast.ExprList([p[3], p[5]], coord),
- coord)
-
- def p_offsetof_member_designator(self, p):
- """ offsetof_member_designator : identifier
- | offsetof_member_designator PERIOD identifier
- | offsetof_member_designator LBRACKET expression RBRACKET
- """
- if len(p) == 2:
- p[0] = p[1]
- elif len(p) == 4:
- field = c_ast.ID(p[3], self._token_coord(p, 3))
- p[0] = c_ast.StructRef(p[1], p[2], field, p[1].coord)
- elif len(p) == 5:
- p[0] = c_ast.ArrayRef(p[1], p[3], p[1].coord)
- else:
- raise NotImplementedError("Unexpected parsing state. len(p): %u" % len(p))
-
- def p_argument_expression_list(self, p):
- """ argument_expression_list : assignment_expression
- | argument_expression_list COMMA assignment_expression
- """
- if len(p) == 2: # single expr
- p[0] = c_ast.ExprList([p[1]], p[1].coord)
- else:
- p[1].exprs.append(p[3])
- p[0] = p[1]
-
- def p_identifier(self, p):
- """ identifier : ID """
- p[0] = c_ast.ID(p[1], self._token_coord(p, 1))
-
- def p_constant_1(self, p):
- """ constant : INT_CONST_DEC
- | INT_CONST_OCT
- | INT_CONST_HEX
- | INT_CONST_BIN
- """
- p[0] = c_ast.Constant(
- 'int', p[1], self._token_coord(p, 1))
-
- def p_constant_2(self, p):
- """ constant : FLOAT_CONST
- | HEX_FLOAT_CONST
- """
- if 'x' in p[1].lower():
- t = 'float'
- else:
- if p[1][-1] in ('f', 'F'):
- t = 'float'
- elif p[1][-1] in ('l', 'L'):
- t = 'long double'
- else:
- t = 'double'
-
- p[0] = c_ast.Constant(
- t, p[1], self._token_coord(p, 1))
-
- def p_constant_3(self, p):
- """ constant : CHAR_CONST
- | WCHAR_CONST
- """
- p[0] = c_ast.Constant(
- 'char', p[1], self._token_coord(p, 1))
-
- # The "unified" string and wstring literal rules are for supporting
- # concatenation of adjacent string literals.
- # I.e. "hello " "world" is seen by the C compiler as a single string literal
- # with the value "hello world"
- #
- def p_unified_string_literal(self, p):
- """ unified_string_literal : STRING_LITERAL
- | unified_string_literal STRING_LITERAL
- """
- if len(p) == 2: # single literal
- p[0] = c_ast.Constant(
- 'string', p[1], self._token_coord(p, 1))
- else:
- p[1].value = p[1].value[:-1] + p[2][1:]
- p[0] = p[1]
-
- def p_unified_wstring_literal(self, p):
- """ unified_wstring_literal : WSTRING_LITERAL
- | unified_wstring_literal WSTRING_LITERAL
- """
- if len(p) == 2: # single literal
- p[0] = c_ast.Constant(
- 'string', p[1], self._token_coord(p, 1))
- else:
- p[1].value = p[1].value.rstrip()[:-1] + p[2][2:]
- p[0] = p[1]
-
- def p_brace_open(self, p):
- """ brace_open : LBRACE
- """
- p[0] = p[1]
- p.set_lineno(0, p.lineno(1))
-
- def p_brace_close(self, p):
- """ brace_close : RBRACE
- """
- p[0] = p[1]
- p.set_lineno(0, p.lineno(1))
-
- def p_empty(self, p):
- 'empty : '
- p[0] = None
-
- def p_error(self, p):
- # If error recovery is added here in the future, make sure
- # _get_yacc_lookahead_token still works!
- #
- if p:
- self._parse_error(
- 'before: %s' % p.value,
- self._coord(lineno=p.lineno,
- column=self.clex.find_tok_column(p)))
- else:
- self._parse_error('At end of input', self.clex.filename)
diff --git a/pycparser/ply/LICENSE b/pycparser/ply/LICENSE
deleted file mode 100644
index bac0d9a..0000000
--- a/pycparser/ply/LICENSE
+++ /dev/null
@@ -1,34 +0,0 @@
-PLY (Python Lex-Yacc) Version 3.10
-
-Copyright (C) 2001-2017
-David M. Beazley (Dabeaz LLC)
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-* Neither the name of the David Beazley or Dabeaz LLC may be used to
- endorse or promote products derived from this software without
- specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-More information about PLY can be obtained on the PLY webpage at:
-
- http://www.dabeaz.com/ply
diff --git a/pycparser/ply/__init__.py b/pycparser/ply/__init__.py
deleted file mode 100644
index 6e53cdd..0000000
--- a/pycparser/ply/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-# PLY package
-# Author: David Beazley (dave@dabeaz.com)
-
-__version__ = '3.9'
-__all__ = ['lex','yacc']
diff --git a/pycparser/ply/cpp.py b/pycparser/ply/cpp.py
deleted file mode 100644
index 86273ea..0000000
--- a/pycparser/ply/cpp.py
+++ /dev/null
@@ -1,905 +0,0 @@
-# -----------------------------------------------------------------------------
-# cpp.py
-#
-# Author: David Beazley (http://www.dabeaz.com)
-# Copyright (C) 2017
-# All rights reserved
-#
-# This module implements an ANSI-C style lexical preprocessor for PLY.
-# -----------------------------------------------------------------------------
-import sys
-
-# Some Python 3 compatibility shims
-if sys.version_info.major < 3:
- STRING_TYPES = (str, unicode)
-else:
- STRING_TYPES = str
- xrange = range
-
-# -----------------------------------------------------------------------------
-# Default preprocessor lexer definitions. These tokens are enough to get
-# a basic preprocessor working. Other modules may import these if they want
-# -----------------------------------------------------------------------------
-
-tokens = (
- 'CPP_ID','CPP_INTEGER', 'CPP_FLOAT', 'CPP_STRING', 'CPP_CHAR', 'CPP_WS', 'CPP_COMMENT1', 'CPP_COMMENT2', 'CPP_POUND','CPP_DPOUND'
-)
-
-literals = "+-*/%|&~^<>=!?()[]{}.,;:\\\'\""
-
-# Whitespace
-def t_CPP_WS(t):
- r'\s+'
- t.lexer.lineno += t.value.count("\n")
- return t
-
-t_CPP_POUND = r'\#'
-t_CPP_DPOUND = r'\#\#'
-
-# Identifier
-t_CPP_ID = r'[A-Za-z_][\w_]*'
-
-# Integer literal
-def CPP_INTEGER(t):
- r'(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)'
- return t
-
-t_CPP_INTEGER = CPP_INTEGER
-
-# Floating literal
-t_CPP_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
-
-# String literal
-def t_CPP_STRING(t):
- r'\"([^\\\n]|(\\(.|\n)))*?\"'
- t.lexer.lineno += t.value.count("\n")
- return t
-
-# Character constant 'c' or L'c'
-def t_CPP_CHAR(t):
- r'(L)?\'([^\\\n]|(\\(.|\n)))*?\''
- t.lexer.lineno += t.value.count("\n")
- return t
-
-# Comment
-def t_CPP_COMMENT1(t):
- r'(/\*(.|\n)*?\*/)'
- ncr = t.value.count("\n")
- t.lexer.lineno += ncr
- # replace with one space or a number of '\n'
- t.type = 'CPP_WS'; t.value = '\n' * ncr if ncr else ' '
- return t
-
-# Line comment
-def t_CPP_COMMENT2(t):
- r'(//.*?(\n|$))'
- # replace with '/n'
- t.type = 'CPP_WS'; t.value = '\n'
- return t
-
-def t_error(t):
- t.type = t.value[0]
- t.value = t.value[0]
- t.lexer.skip(1)
- return t
-
-import re
-import copy
-import time
-import os.path
-
-# -----------------------------------------------------------------------------
-# trigraph()
-#
-# Given an input string, this function replaces all trigraph sequences.
-# The following mapping is used:
-#
-# ??= #
-# ??/ \
-# ??' ^
-# ??( [
-# ??) ]
-# ??! |
-# ??< {
-# ??> }
-# ??- ~
-# -----------------------------------------------------------------------------
-
-_trigraph_pat = re.compile(r'''\?\?[=/\'\(\)\!<>\-]''')
-_trigraph_rep = {
- '=':'#',
- '/':'\\',
- "'":'^',
- '(':'[',
- ')':']',
- '!':'|',
- '<':'{',
- '>':'}',
- '-':'~'
-}
-
-def trigraph(input):
- return _trigraph_pat.sub(lambda g: _trigraph_rep[g.group()[-1]],input)
-
-# ------------------------------------------------------------------
-# Macro object
-#
-# This object holds information about preprocessor macros
-#
-# .name - Macro name (string)
-# .value - Macro value (a list of tokens)
-# .arglist - List of argument names
-# .variadic - Boolean indicating whether or not variadic macro
-# .vararg - Name of the variadic parameter
-#
-# When a macro is created, the macro replacement token sequence is
-# pre-scanned and used to create patch lists that are later used
-# during macro expansion
-# ------------------------------------------------------------------
-
-class Macro(object):
- def __init__(self,name,value,arglist=None,variadic=False):
- self.name = name
- self.value = value
- self.arglist = arglist
- self.variadic = variadic
- if variadic:
- self.vararg = arglist[-1]
- self.source = None
-
-# ------------------------------------------------------------------
-# Preprocessor object
-#
-# Object representing a preprocessor. Contains macro definitions,
-# include directories, and other information
-# ------------------------------------------------------------------
-
-class Preprocessor(object):
- def __init__(self,lexer=None):
- if lexer is None:
- lexer = lex.lexer
- self.lexer = lexer
- self.macros = { }
- self.path = []
- self.temp_path = []
-
- # Probe the lexer for selected tokens
- self.lexprobe()
-
- tm = time.localtime()
- self.define("__DATE__ \"%s\"" % time.strftime("%b %d %Y",tm))
- self.define("__TIME__ \"%s\"" % time.strftime("%H:%M:%S",tm))
- self.parser = None
-
- # -----------------------------------------------------------------------------
- # tokenize()
- #
- # Utility function. Given a string of text, tokenize into a list of tokens
- # -----------------------------------------------------------------------------
-
- def tokenize(self,text):
- tokens = []
- self.lexer.input(text)
- while True:
- tok = self.lexer.token()
- if not tok: break
- tokens.append(tok)
- return tokens
-
- # ---------------------------------------------------------------------
- # error()
- #
- # Report a preprocessor error/warning of some kind
- # ----------------------------------------------------------------------
-
- def error(self,file,line,msg):
- print("%s:%d %s" % (file,line,msg))
-
- # ----------------------------------------------------------------------
- # lexprobe()
- #
- # This method probes the preprocessor lexer object to discover
- # the token types of symbols that are important to the preprocessor.
- # If this works right, the preprocessor will simply "work"
- # with any suitable lexer regardless of how tokens have been named.
- # ----------------------------------------------------------------------
-
- def lexprobe(self):
-
- # Determine the token type for identifiers
- self.lexer.input("identifier")
- tok = self.lexer.token()
- if not tok or tok.value != "identifier":
- print("Couldn't determine identifier type")
- else:
- self.t_ID = tok.type
-
- # Determine the token type for integers
- self.lexer.input("12345")
- tok = self.lexer.token()
- if not tok or int(tok.value) != 12345:
- print("Couldn't determine integer type")
- else:
- self.t_INTEGER = tok.type
- self.t_INTEGER_TYPE = type(tok.value)
-
- # Determine the token type for strings enclosed in double quotes
- self.lexer.input("\"filename\"")
- tok = self.lexer.token()
- if not tok or tok.value != "\"filename\"":
- print("Couldn't determine string type")
- else:
- self.t_STRING = tok.type
-
- # Determine the token type for whitespace--if any
- self.lexer.input(" ")
- tok = self.lexer.token()
- if not tok or tok.value != " ":
- self.t_SPACE = None
- else:
- self.t_SPACE = tok.type
-
- # Determine the token type for newlines
- self.lexer.input("\n")
- tok = self.lexer.token()
- if not tok or tok.value != "\n":
- self.t_NEWLINE = None
- print("Couldn't determine token for newlines")
- else:
- self.t_NEWLINE = tok.type
-
- self.t_WS = (self.t_SPACE, self.t_NEWLINE)
-
- # Check for other characters used by the preprocessor
- chars = [ '<','>','#','##','\\','(',')',',','.']
- for c in chars:
- self.lexer.input(c)
- tok = self.lexer.token()
- if not tok or tok.value != c:
- print("Unable to lex '%s' required for preprocessor" % c)
-
- # ----------------------------------------------------------------------
- # add_path()
- #
- # Adds a search path to the preprocessor.
- # ----------------------------------------------------------------------
-
- def add_path(self,path):
- self.path.append(path)
-
- # ----------------------------------------------------------------------
- # group_lines()
- #
- # Given an input string, this function splits it into lines. Trailing whitespace
- # is removed. Any line ending with \ is grouped with the next line. This
- # function forms the lowest level of the preprocessor---grouping into text into
- # a line-by-line format.
- # ----------------------------------------------------------------------
-
- def group_lines(self,input):
- lex = self.lexer.clone()
- lines = [x.rstrip() for x in input.splitlines()]
- for i in xrange(len(lines)):
- j = i+1
- while lines[i].endswith('\\') and (j < len(lines)):
- lines[i] = lines[i][:-1]+lines[j]
- lines[j] = ""
- j += 1
-
- input = "\n".join(lines)
- lex.input(input)
- lex.lineno = 1
-
- current_line = []
- while True:
- tok = lex.token()
- if not tok:
- break
- current_line.append(tok)
- if tok.type in self.t_WS and '\n' in tok.value:
- yield current_line
- current_line = []
-
- if current_line:
- yield current_line
-
- # ----------------------------------------------------------------------
- # tokenstrip()
- #
- # Remove leading/trailing whitespace tokens from a token list
- # ----------------------------------------------------------------------
-
- def tokenstrip(self,tokens):
- i = 0
- while i < len(tokens) and tokens[i].type in self.t_WS:
- i += 1
- del tokens[:i]
- i = len(tokens)-1
- while i >= 0 and tokens[i].type in self.t_WS:
- i -= 1
- del tokens[i+1:]
- return tokens
-
-
- # ----------------------------------------------------------------------
- # collect_args()
- #
- # Collects comma separated arguments from a list of tokens. The arguments
- # must be enclosed in parenthesis. Returns a tuple (tokencount,args,positions)
- # where tokencount is the number of tokens consumed, args is a list of arguments,
- # and positions is a list of integers containing the starting index of each
- # argument. Each argument is represented by a list of tokens.
- #
- # When collecting arguments, leading and trailing whitespace is removed
- # from each argument.
- #
- # This function properly handles nested parenthesis and commas---these do not
- # define new arguments.
- # ----------------------------------------------------------------------
-
- def collect_args(self,tokenlist):
- args = []
- positions = []
- current_arg = []
- nesting = 1
- tokenlen = len(tokenlist)
-
- # Search for the opening '('.
- i = 0
- while (i < tokenlen) and (tokenlist[i].type in self.t_WS):
- i += 1
-
- if (i < tokenlen) and (tokenlist[i].value == '('):
- positions.append(i+1)
- else:
- self.error(self.source,tokenlist[0].lineno,"Missing '(' in macro arguments")
- return 0, [], []
-
- i += 1
-
- while i < tokenlen:
- t = tokenlist[i]
- if t.value == '(':
- current_arg.append(t)
- nesting += 1
- elif t.value == ')':
- nesting -= 1
- if nesting == 0:
- if current_arg:
- args.append(self.tokenstrip(current_arg))
- positions.append(i)
- return i+1,args,positions
- current_arg.append(t)
- elif t.value == ',' and nesting == 1:
- args.append(self.tokenstrip(current_arg))
- positions.append(i+1)
- current_arg = []
- else:
- current_arg.append(t)
- i += 1
-
- # Missing end argument
- self.error(self.source,tokenlist[-1].lineno,"Missing ')' in macro arguments")
- return 0, [],[]
-
- # ----------------------------------------------------------------------
- # macro_prescan()
- #
- # Examine the macro value (token sequence) and identify patch points
- # This is used to speed up macro expansion later on---we'll know
- # right away where to apply patches to the value to form the expansion
- # ----------------------------------------------------------------------
-
- def macro_prescan(self,macro):
- macro.patch = [] # Standard macro arguments
- macro.str_patch = [] # String conversion expansion
- macro.var_comma_patch = [] # Variadic macro comma patch
- i = 0
- while i < len(macro.value):
- if macro.value[i].type == self.t_ID and macro.value[i].value in macro.arglist:
- argnum = macro.arglist.index(macro.value[i].value)
- # Conversion of argument to a string
- if i > 0 and macro.value[i-1].value == '#':
- macro.value[i] = copy.copy(macro.value[i])
- macro.value[i].type = self.t_STRING
- del macro.value[i-1]
- macro.str_patch.append((argnum,i-1))
- continue
- # Concatenation
- elif (i > 0 and macro.value[i-1].value == '##'):
- macro.patch.append(('c',argnum,i-1))
- del macro.value[i-1]
- continue
- elif ((i+1) < len(macro.value) and macro.value[i+1].value == '##'):
- macro.patch.append(('c',argnum,i))
- i += 1
- continue
- # Standard expansion
- else:
- macro.patch.append(('e',argnum,i))
- elif macro.value[i].value == '##':
- if macro.variadic and (i > 0) and (macro.value[i-1].value == ',') and \
- ((i+1) < len(macro.value)) and (macro.value[i+1].type == self.t_ID) and \
- (macro.value[i+1].value == macro.vararg):
- macro.var_comma_patch.append(i-1)
- i += 1
- macro.patch.sort(key=lambda x: x[2],reverse=True)
-
- # ----------------------------------------------------------------------
- # macro_expand_args()
- #
- # Given a Macro and list of arguments (each a token list), this method
- # returns an expanded version of a macro. The return value is a token sequence
- # representing the replacement macro tokens
- # ----------------------------------------------------------------------
-
- def macro_expand_args(self,macro,args):
- # Make a copy of the macro token sequence
- rep = [copy.copy(_x) for _x in macro.value]
-
- # Make string expansion patches. These do not alter the length of the replacement sequence
-
- str_expansion = {}
- for argnum, i in macro.str_patch:
- if argnum not in str_expansion:
- str_expansion[argnum] = ('"%s"' % "".join([x.value for x in args[argnum]])).replace("\\","\\\\")
- rep[i] = copy.copy(rep[i])
- rep[i].value = str_expansion[argnum]
-
- # Make the variadic macro comma patch. If the variadic macro argument is empty, we get rid
- comma_patch = False
- if macro.variadic and not args[-1]:
- for i in macro.var_comma_patch:
- rep[i] = None
- comma_patch = True
-
- # Make all other patches. The order of these matters. It is assumed that the patch list
- # has been sorted in reverse order of patch location since replacements will cause the
- # size of the replacement sequence to expand from the patch point.
-
- expanded = { }
- for ptype, argnum, i in macro.patch:
- # Concatenation. Argument is left unexpanded
- if ptype == 'c':
- rep[i:i+1] = args[argnum]
- # Normal expansion. Argument is macro expanded first
- elif ptype == 'e':
- if argnum not in expanded:
- expanded[argnum] = self.expand_macros(args[argnum])
- rep[i:i+1] = expanded[argnum]
-
- # Get rid of removed comma if necessary
- if comma_patch:
- rep = [_i for _i in rep if _i]
-
- return rep
-
-
- # ----------------------------------------------------------------------
- # expand_macros()
- #
- # Given a list of tokens, this function performs macro expansion.
- # The expanded argument is a dictionary that contains macros already
- # expanded. This is used to prevent infinite recursion.
- # ----------------------------------------------------------------------
-
- def expand_macros(self,tokens,expanded=None):
- if expanded is None:
- expanded = {}
- i = 0
- while i < len(tokens):
- t = tokens[i]
- if t.type == self.t_ID:
- if t.value in self.macros and t.value not in expanded:
- # Yes, we found a macro match
- expanded[t.value] = True
-
- m = self.macros[t.value]
- if not m.arglist:
- # A simple macro
- ex = self.expand_macros([copy.copy(_x) for _x in m.value],expanded)
- for e in ex:
- e.lineno = t.lineno
- tokens[i:i+1] = ex
- i += len(ex)
- else:
- # A macro with arguments
- j = i + 1
- while j < len(tokens) and tokens[j].type in self.t_WS:
- j += 1
- if tokens[j].value == '(':
- tokcount,args,positions = self.collect_args(tokens[j:])
- if not m.variadic and len(args) != len(m.arglist):
- self.error(self.source,t.lineno,"Macro %s requires %d arguments" % (t.value,len(m.arglist)))
- i = j + tokcount
- elif m.variadic and len(args) < len(m.arglist)-1:
- if len(m.arglist) > 2:
- self.error(self.source,t.lineno,"Macro %s must have at least %d arguments" % (t.value, len(m.arglist)-1))
- else:
- self.error(self.source,t.lineno,"Macro %s must have at least %d argument" % (t.value, len(m.arglist)-1))
- i = j + tokcount
- else:
- if m.variadic:
- if len(args) == len(m.arglist)-1:
- args.append([])
- else:
- args[len(m.arglist)-1] = tokens[j+positions[len(m.arglist)-1]:j+tokcount-1]
- del args[len(m.arglist):]
-
- # Get macro replacement text
- rep = self.macro_expand_args(m,args)
- rep = self.expand_macros(rep,expanded)
- for r in rep:
- r.lineno = t.lineno
- tokens[i:j+tokcount] = rep
- i += len(rep)
- del expanded[t.value]
- continue
- elif t.value == '__LINE__':
- t.type = self.t_INTEGER
- t.value = self.t_INTEGER_TYPE(t.lineno)
-
- i += 1
- return tokens
-
- # ----------------------------------------------------------------------
- # evalexpr()
- #
- # Evaluate an expression token sequence for the purposes of evaluating
- # integral expressions.
- # ----------------------------------------------------------------------
-
- def evalexpr(self,tokens):
- # tokens = tokenize(line)
- # Search for defined macros
- i = 0
- while i < len(tokens):
- if tokens[i].type == self.t_ID and tokens[i].value == 'defined':
- j = i + 1
- needparen = False
- result = "0L"
- while j < len(tokens):
- if tokens[j].type in self.t_WS:
- j += 1
- continue
- elif tokens[j].type == self.t_ID:
- if tokens[j].value in self.macros:
- result = "1L"
- else:
- result = "0L"
- if not needparen: break
- elif tokens[j].value == '(':
- needparen = True
- elif tokens[j].value == ')':
- break
- else:
- self.error(self.source,tokens[i].lineno,"Malformed defined()")
- j += 1
- tokens[i].type = self.t_INTEGER
- tokens[i].value = self.t_INTEGER_TYPE(result)
- del tokens[i+1:j+1]
- i += 1
- tokens = self.expand_macros(tokens)
- for i,t in enumerate(tokens):
- if t.type == self.t_ID:
- tokens[i] = copy.copy(t)
- tokens[i].type = self.t_INTEGER
- tokens[i].value = self.t_INTEGER_TYPE("0L")
- elif t.type == self.t_INTEGER:
- tokens[i] = copy.copy(t)
- # Strip off any trailing suffixes
- tokens[i].value = str(tokens[i].value)
- while tokens[i].value[-1] not in "0123456789abcdefABCDEF":
- tokens[i].value = tokens[i].value[:-1]
-
- expr = "".join([str(x.value) for x in tokens])
- expr = expr.replace("&&"," and ")
- expr = expr.replace("||"," or ")
- expr = expr.replace("!"," not ")
- try:
- result = eval(expr)
- except Exception:
- self.error(self.source,tokens[0].lineno,"Couldn't evaluate expression")
- result = 0
- return result
-
- # ----------------------------------------------------------------------
- # parsegen()
- #
- # Parse an input string/
- # ----------------------------------------------------------------------
- def parsegen(self,input,source=None):
-
- # Replace trigraph sequences
- t = trigraph(input)
- lines = self.group_lines(t)
-
- if not source:
- source = ""
-
- self.define("__FILE__ \"%s\"" % source)
-
- self.source = source
- chunk = []
- enable = True
- iftrigger = False
- ifstack = []
-
- for x in lines:
- for i,tok in enumerate(x):
- if tok.type not in self.t_WS: break
- if tok.value == '#':
- # Preprocessor directive
-
- # insert necessary whitespace instead of eaten tokens
- for tok in x:
- if tok.type in self.t_WS and '\n' in tok.value:
- chunk.append(tok)
-
- dirtokens = self.tokenstrip(x[i+1:])
- if dirtokens:
- name = dirtokens[0].value
- args = self.tokenstrip(dirtokens[1:])
- else:
- name = ""
- args = []
-
- if name == 'define':
- if enable:
- for tok in self.expand_macros(chunk):
- yield tok
- chunk = []
- self.define(args)
- elif name == 'include':
- if enable:
- for tok in self.expand_macros(chunk):
- yield tok
- chunk = []
- oldfile = self.macros['__FILE__']
- for tok in self.include(args):
- yield tok
- self.macros['__FILE__'] = oldfile
- self.source = source
- elif name == 'undef':
- if enable:
- for tok in self.expand_macros(chunk):
- yield tok
- chunk = []
- self.undef(args)
- elif name == 'ifdef':
- ifstack.append((enable,iftrigger))
- if enable:
- if not args[0].value in self.macros:
- enable = False
- iftrigger = False
- else:
- iftrigger = True
- elif name == 'ifndef':
- ifstack.append((enable,iftrigger))
- if enable:
- if args[0].value in self.macros:
- enable = False
- iftrigger = False
- else:
- iftrigger = True
- elif name == 'if':
- ifstack.append((enable,iftrigger))
- if enable:
- result = self.evalexpr(args)
- if not result:
- enable = False
- iftrigger = False
- else:
- iftrigger = True
- elif name == 'elif':
- if ifstack:
- if ifstack[-1][0]: # We only pay attention if outer "if" allows this
- if enable: # If already true, we flip enable False
- enable = False
- elif not iftrigger: # If False, but not triggered yet, we'll check expression
- result = self.evalexpr(args)
- if result:
- enable = True
- iftrigger = True
- else:
- self.error(self.source,dirtokens[0].lineno,"Misplaced #elif")
-
- elif name == 'else':
- if ifstack:
- if ifstack[-1][0]:
- if enable:
- enable = False
- elif not iftrigger:
- enable = True
- iftrigger = True
- else:
- self.error(self.source,dirtokens[0].lineno,"Misplaced #else")
-
- elif name == 'endif':
- if ifstack:
- enable,iftrigger = ifstack.pop()
- else:
- self.error(self.source,dirtokens[0].lineno,"Misplaced #endif")
- else:
- # Unknown preprocessor directive
- pass
-
- else:
- # Normal text
- if enable:
- chunk.extend(x)
-
- for tok in self.expand_macros(chunk):
- yield tok
- chunk = []
-
- # ----------------------------------------------------------------------
- # include()
- #
- # Implementation of file-inclusion
- # ----------------------------------------------------------------------
-
- def include(self,tokens):
- # Try to extract the filename and then process an include file
- if not tokens:
- return
- if tokens:
- if tokens[0].value != '<' and tokens[0].type != self.t_STRING:
- tokens = self.expand_macros(tokens)
-
- if tokens[0].value == '<':
- # Include <...>
- i = 1
- while i < len(tokens):
- if tokens[i].value == '>':
- break
- i += 1
- else:
- print("Malformed #include <...>")
- return
- filename = "".join([x.value for x in tokens[1:i]])
- path = self.path + [""] + self.temp_path
- elif tokens[0].type == self.t_STRING:
- filename = tokens[0].value[1:-1]
- path = self.temp_path + [""] + self.path
- else:
- print("Malformed #include statement")
- return
- for p in path:
- iname = os.path.join(p,filename)
- try:
- data = open(iname,"r").read()
- dname = os.path.dirname(iname)
- if dname:
- self.temp_path.insert(0,dname)
- for tok in self.parsegen(data,filename):
- yield tok
- if dname:
- del self.temp_path[0]
- break
- except IOError:
- pass
- else:
- print("Couldn't find '%s'" % filename)
-
- # ----------------------------------------------------------------------
- # define()
- #
- # Define a new macro
- # ----------------------------------------------------------------------
-
- def define(self,tokens):
- if isinstance(tokens,STRING_TYPES):
- tokens = self.tokenize(tokens)
-
- linetok = tokens
- try:
- name = linetok[0]
- if len(linetok) > 1:
- mtype = linetok[1]
- else:
- mtype = None
- if not mtype:
- m = Macro(name.value,[])
- self.macros[name.value] = m
- elif mtype.type in self.t_WS:
- # A normal macro
- m = Macro(name.value,self.tokenstrip(linetok[2:]))
- self.macros[name.value] = m
- elif mtype.value == '(':
- # A macro with arguments
- tokcount, args, positions = self.collect_args(linetok[1:])
- variadic = False
- for a in args:
- if variadic:
- print("No more arguments may follow a variadic argument")
- break
- astr = "".join([str(_i.value) for _i in a])
- if astr == "...":
- variadic = True
- a[0].type = self.t_ID
- a[0].value = '__VA_ARGS__'
- variadic = True
- del a[1:]
- continue
- elif astr[-3:] == "..." and a[0].type == self.t_ID:
- variadic = True
- del a[1:]
- # If, for some reason, "." is part of the identifier, strip off the name for the purposes
- # of macro expansion
- if a[0].value[-3:] == '...':
- a[0].value = a[0].value[:-3]
- continue
- if len(a) > 1 or a[0].type != self.t_ID:
- print("Invalid macro argument")
- break
- else:
- mvalue = self.tokenstrip(linetok[1+tokcount:])
- i = 0
- while i < len(mvalue):
- if i+1 < len(mvalue):
- if mvalue[i].type in self.t_WS and mvalue[i+1].value == '##':
- del mvalue[i]
- continue
- elif mvalue[i].value == '##' and mvalue[i+1].type in self.t_WS:
- del mvalue[i+1]
- i += 1
- m = Macro(name.value,mvalue,[x[0].value for x in args],variadic)
- self.macro_prescan(m)
- self.macros[name.value] = m
- else:
- print("Bad macro definition")
- except LookupError:
- print("Bad macro definition")
-
- # ----------------------------------------------------------------------
- # undef()
- #
- # Undefine a macro
- # ----------------------------------------------------------------------
-
- def undef(self,tokens):
- id = tokens[0].value
- try:
- del self.macros[id]
- except LookupError:
- pass
-
- # ----------------------------------------------------------------------
- # parse()
- #
- # Parse input text.
- # ----------------------------------------------------------------------
- def parse(self,input,source=None,ignore={}):
- self.ignore = ignore
- self.parser = self.parsegen(input,source)
-
- # ----------------------------------------------------------------------
- # token()
- #
- # Method to return individual tokens
- # ----------------------------------------------------------------------
- def token(self):
- try:
- while True:
- tok = next(self.parser)
- if tok.type not in self.ignore: return tok
- except StopIteration:
- self.parser = None
- return None
-
-if __name__ == '__main__':
- import ply.lex as lex
- lexer = lex.lex()
-
- # Run a preprocessor
- import sys
- f = open(sys.argv[1])
- input = f.read()
-
- p = Preprocessor(lexer)
- p.parse(input,sys.argv[1])
- while True:
- tok = p.token()
- if not tok: break
- print(p.source, tok)
diff --git a/pycparser/ply/ctokens.py b/pycparser/ply/ctokens.py
deleted file mode 100644
index f6f6952..0000000
--- a/pycparser/ply/ctokens.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# ----------------------------------------------------------------------
-# ctokens.py
-#
-# Token specifications for symbols in ANSI C and C++. This file is
-# meant to be used as a library in other tokenizers.
-# ----------------------------------------------------------------------
-
-# Reserved words
-
-tokens = [
- # Literals (identifier, integer constant, float constant, string constant, char const)
- 'ID', 'TYPEID', 'INTEGER', 'FLOAT', 'STRING', 'CHARACTER',
-
- # Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=)
- 'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MODULO',
- 'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
- 'LOR', 'LAND', 'LNOT',
- 'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
-
- # Assignment (=, *=, /=, %=, +=, -=, <<=, >>=, &=, ^=, |=)
- 'EQUALS', 'TIMESEQUAL', 'DIVEQUAL', 'MODEQUAL', 'PLUSEQUAL', 'MINUSEQUAL',
- 'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL',
-
- # Increment/decrement (++,--)
- 'INCREMENT', 'DECREMENT',
-
- # Structure dereference (->)
- 'ARROW',
-
- # Ternary operator (?)
- 'TERNARY',
-
- # Delimeters ( ) [ ] { } , . ; :
- 'LPAREN', 'RPAREN',
- 'LBRACKET', 'RBRACKET',
- 'LBRACE', 'RBRACE',
- 'COMMA', 'PERIOD', 'SEMI', 'COLON',
-
- # Ellipsis (...)
- 'ELLIPSIS',
-]
-
-# Operators
-t_PLUS = r'\+'
-t_MINUS = r'-'
-t_TIMES = r'\*'
-t_DIVIDE = r'/'
-t_MODULO = r'%'
-t_OR = r'\|'
-t_AND = r'&'
-t_NOT = r'~'
-t_XOR = r'\^'
-t_LSHIFT = r'<<'
-t_RSHIFT = r'>>'
-t_LOR = r'\|\|'
-t_LAND = r'&&'
-t_LNOT = r'!'
-t_LT = r'<'
-t_GT = r'>'
-t_LE = r'<='
-t_GE = r'>='
-t_EQ = r'=='
-t_NE = r'!='
-
-# Assignment operators
-
-t_EQUALS = r'='
-t_TIMESEQUAL = r'\*='
-t_DIVEQUAL = r'/='
-t_MODEQUAL = r'%='
-t_PLUSEQUAL = r'\+='
-t_MINUSEQUAL = r'-='
-t_LSHIFTEQUAL = r'<<='
-t_RSHIFTEQUAL = r'>>='
-t_ANDEQUAL = r'&='
-t_OREQUAL = r'\|='
-t_XOREQUAL = r'\^='
-
-# Increment/decrement
-t_INCREMENT = r'\+\+'
-t_DECREMENT = r'--'
-
-# ->
-t_ARROW = r'->'
-
-# ?
-t_TERNARY = r'\?'
-
-# Delimeters
-t_LPAREN = r'\('
-t_RPAREN = r'\)'
-t_LBRACKET = r'\['
-t_RBRACKET = r'\]'
-t_LBRACE = r'\{'
-t_RBRACE = r'\}'
-t_COMMA = r','
-t_PERIOD = r'\.'
-t_SEMI = r';'
-t_COLON = r':'
-t_ELLIPSIS = r'\.\.\.'
-
-# Identifiers
-t_ID = r'[A-Za-z_][A-Za-z0-9_]*'
-
-# Integer literal
-t_INTEGER = r'\d+([uU]|[lL]|[uU][lL]|[lL][uU])?'
-
-# Floating literal
-t_FLOAT = r'((\d+)(\.\d+)(e(\+|-)?(\d+))? | (\d+)e(\+|-)?(\d+))([lL]|[fF])?'
-
-# String literal
-t_STRING = r'\"([^\\\n]|(\\.))*?\"'
-
-# Character constant 'c' or L'c'
-t_CHARACTER = r'(L)?\'([^\\\n]|(\\.))*?\''
-
-# Comment (C-Style)
-def t_COMMENT(t):
- r'/\*(.|\n)*?\*/'
- t.lexer.lineno += t.value.count('\n')
- return t
-
-# Comment (C++-Style)
-def t_CPPCOMMENT(t):
- r'//.*\n'
- t.lexer.lineno += 1
- return t
-
-
-
-
-
-
diff --git a/pycparser/ply/lex.py b/pycparser/ply/lex.py
deleted file mode 100644
index 4bdd76c..0000000
--- a/pycparser/ply/lex.py
+++ /dev/null
@@ -1,1099 +0,0 @@
-# -----------------------------------------------------------------------------
-# ply: lex.py
-#
-# Copyright (C) 2001-2017
-# David M. Beazley (Dabeaz LLC)
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of the David Beazley or Dabeaz LLC may be used to
-# endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# -----------------------------------------------------------------------------
-
-__version__ = '3.10'
-__tabversion__ = '3.10'
-
-import re
-import sys
-import types
-import copy
-import os
-import inspect
-
-# This tuple contains known string types
-try:
- # Python 2.6
- StringTypes = (types.StringType, types.UnicodeType)
-except AttributeError:
- # Python 3.0
- StringTypes = (str, bytes)
-
-# This regular expression is used to match valid token names
-_is_identifier = re.compile(r'^[a-zA-Z0-9_]+$')
-
-# Exception thrown when invalid token encountered and no default error
-# handler is defined.
-class LexError(Exception):
- def __init__(self, message, s):
- self.args = (message,)
- self.text = s
-
-
-# Token class. This class is used to represent the tokens produced.
-class LexToken(object):
- def __str__(self):
- return 'LexToken(%s,%r,%d,%d)' % (self.type, self.value, self.lineno, self.lexpos)
-
- def __repr__(self):
- return str(self)
-
-
-# This object is a stand-in for a logging object created by the
-# logging module.
-
-class PlyLogger(object):
- def __init__(self, f):
- self.f = f
-
- def critical(self, msg, *args, **kwargs):
- self.f.write((msg % args) + '\n')
-
- def warning(self, msg, *args, **kwargs):
- self.f.write('WARNING: ' + (msg % args) + '\n')
-
- def error(self, msg, *args, **kwargs):
- self.f.write('ERROR: ' + (msg % args) + '\n')
-
- info = critical
- debug = critical
-
-
-# Null logger is used when no output is generated. Does nothing.
-class NullLogger(object):
- def __getattribute__(self, name):
- return self
-
- def __call__(self, *args, **kwargs):
- return self
-
-
-# -----------------------------------------------------------------------------
-# === Lexing Engine ===
-#
-# The following Lexer class implements the lexer runtime. There are only
-# a few public methods and attributes:
-#
-# input() - Store a new string in the lexer
-# token() - Get the next token
-# clone() - Clone the lexer
-#
-# lineno - Current line number
-# lexpos - Current position in the input string
-# -----------------------------------------------------------------------------
-
-class Lexer:
- def __init__(self):
- self.lexre = None # Master regular expression. This is a list of
- # tuples (re, findex) where re is a compiled
- # regular expression and findex is a list
- # mapping regex group numbers to rules
- self.lexretext = None # Current regular expression strings
- self.lexstatere = {} # Dictionary mapping lexer states to master regexs
- self.lexstateretext = {} # Dictionary mapping lexer states to regex strings
- self.lexstaterenames = {} # Dictionary mapping lexer states to symbol names
- self.lexstate = 'INITIAL' # Current lexer state
- self.lexstatestack = [] # Stack of lexer states
- self.lexstateinfo = None # State information
- self.lexstateignore = {} # Dictionary of ignored characters for each state
- self.lexstateerrorf = {} # Dictionary of error functions for each state
- self.lexstateeoff = {} # Dictionary of eof functions for each state
- self.lexreflags = 0 # Optional re compile flags
- self.lexdata = None # Actual input data (as a string)
- self.lexpos = 0 # Current position in input text
- self.lexlen = 0 # Length of the input text
- self.lexerrorf = None # Error rule (if any)
- self.lexeoff = None # EOF rule (if any)
- self.lextokens = None # List of valid tokens
- self.lexignore = '' # Ignored characters
- self.lexliterals = '' # Literal characters that can be passed through
- self.lexmodule = None # Module
- self.lineno = 1 # Current line number
- self.lexoptimize = False # Optimized mode
-
- def clone(self, object=None):
- c = copy.copy(self)
-
- # If the object parameter has been supplied, it means we are attaching the
- # lexer to a new object. In this case, we have to rebind all methods in
- # the lexstatere and lexstateerrorf tables.
-
- if object:
- newtab = {}
- for key, ritem in self.lexstatere.items():
- newre = []
- for cre, findex in ritem:
- newfindex = []
- for f in findex:
- if not f or not f[0]:
- newfindex.append(f)
- continue
- newfindex.append((getattr(object, f[0].__name__), f[1]))
- newre.append((cre, newfindex))
- newtab[key] = newre
- c.lexstatere = newtab
- c.lexstateerrorf = {}
- for key, ef in self.lexstateerrorf.items():
- c.lexstateerrorf[key] = getattr(object, ef.__name__)
- c.lexmodule = object
- return c
-
- # ------------------------------------------------------------
- # writetab() - Write lexer information to a table file
- # ------------------------------------------------------------
- def writetab(self, lextab, outputdir=''):
- if isinstance(lextab, types.ModuleType):
- raise IOError("Won't overwrite existing lextab module")
- basetabmodule = lextab.split('.')[-1]
- filename = os.path.join(outputdir, basetabmodule) + '.py'
- with open(filename, 'w') as tf:
- tf.write('# %s.py. This file automatically created by PLY (version %s). Don\'t edit!\n' % (basetabmodule, __version__))
- tf.write('_tabversion = %s\n' % repr(__tabversion__))
- tf.write('_lextokens = set(%s)\n' % repr(tuple(self.lextokens)))
- tf.write('_lexreflags = %s\n' % repr(self.lexreflags))
- tf.write('_lexliterals = %s\n' % repr(self.lexliterals))
- tf.write('_lexstateinfo = %s\n' % repr(self.lexstateinfo))
-
- # Rewrite the lexstatere table, replacing function objects with function names
- tabre = {}
- for statename, lre in self.lexstatere.items():
- titem = []
- for (pat, func), retext, renames in zip(lre, self.lexstateretext[statename], self.lexstaterenames[statename]):
- titem.append((retext, _funcs_to_names(func, renames)))
- tabre[statename] = titem
-
- tf.write('_lexstatere = %s\n' % repr(tabre))
- tf.write('_lexstateignore = %s\n' % repr(self.lexstateignore))
-
- taberr = {}
- for statename, ef in self.lexstateerrorf.items():
- taberr[statename] = ef.__name__ if ef else None
- tf.write('_lexstateerrorf = %s\n' % repr(taberr))
-
- tabeof = {}
- for statename, ef in self.lexstateeoff.items():
- tabeof[statename] = ef.__name__ if ef else None
- tf.write('_lexstateeoff = %s\n' % repr(tabeof))
-
- # ------------------------------------------------------------
- # readtab() - Read lexer information from a tab file
- # ------------------------------------------------------------
- def readtab(self, tabfile, fdict):
- if isinstance(tabfile, types.ModuleType):
- lextab = tabfile
- else:
- exec('import %s' % tabfile)
- lextab = sys.modules[tabfile]
-
- if getattr(lextab, '_tabversion', '0.0') != __tabversion__:
- raise ImportError('Inconsistent PLY version')
-
- self.lextokens = lextab._lextokens
- self.lexreflags = lextab._lexreflags
- self.lexliterals = lextab._lexliterals
- self.lextokens_all = self.lextokens | set(self.lexliterals)
- self.lexstateinfo = lextab._lexstateinfo
- self.lexstateignore = lextab._lexstateignore
- self.lexstatere = {}
- self.lexstateretext = {}
- for statename, lre in lextab._lexstatere.items():
- titem = []
- txtitem = []
- for pat, func_name in lre:
- titem.append((re.compile(pat, lextab._lexreflags), _names_to_funcs(func_name, fdict)))
-
- self.lexstatere[statename] = titem
- self.lexstateretext[statename] = txtitem
-
- self.lexstateerrorf = {}
- for statename, ef in lextab._lexstateerrorf.items():
- self.lexstateerrorf[statename] = fdict[ef]
-
- self.lexstateeoff = {}
- for statename, ef in lextab._lexstateeoff.items():
- self.lexstateeoff[statename] = fdict[ef]
-
- self.begin('INITIAL')
-
- # ------------------------------------------------------------
- # input() - Push a new string into the lexer
- # ------------------------------------------------------------
- def input(self, s):
- # Pull off the first character to see if s looks like a string
- c = s[:1]
- if not isinstance(c, StringTypes):
- raise ValueError('Expected a string')
- self.lexdata = s
- self.lexpos = 0
- self.lexlen = len(s)
-
- # ------------------------------------------------------------
- # begin() - Changes the lexing state
- # ------------------------------------------------------------
- def begin(self, state):
- if state not in self.lexstatere:
- raise ValueError('Undefined state')
- self.lexre = self.lexstatere[state]
- self.lexretext = self.lexstateretext[state]
- self.lexignore = self.lexstateignore.get(state, '')
- self.lexerrorf = self.lexstateerrorf.get(state, None)
- self.lexeoff = self.lexstateeoff.get(state, None)
- self.lexstate = state
-
- # ------------------------------------------------------------
- # push_state() - Changes the lexing state and saves old on stack
- # ------------------------------------------------------------
- def push_state(self, state):
- self.lexstatestack.append(self.lexstate)
- self.begin(state)
-
- # ------------------------------------------------------------
- # pop_state() - Restores the previous state
- # ------------------------------------------------------------
- def pop_state(self):
- self.begin(self.lexstatestack.pop())
-
- # ------------------------------------------------------------
- # current_state() - Returns the current lexing state
- # ------------------------------------------------------------
- def current_state(self):
- return self.lexstate
-
- # ------------------------------------------------------------
- # skip() - Skip ahead n characters
- # ------------------------------------------------------------
- def skip(self, n):
- self.lexpos += n
-
- # ------------------------------------------------------------
- # opttoken() - Return the next token from the Lexer
- #
- # Note: This function has been carefully implemented to be as fast
- # as possible. Don't make changes unless you really know what
- # you are doing
- # ------------------------------------------------------------
- def token(self):
- # Make local copies of frequently referenced attributes
- lexpos = self.lexpos
- lexlen = self.lexlen
- lexignore = self.lexignore
- lexdata = self.lexdata
-
- while lexpos < lexlen:
- # This code provides some short-circuit code for whitespace, tabs, and other ignored characters
- if lexdata[lexpos] in lexignore:
- lexpos += 1
- continue
-
- # Look for a regular expression match
- for lexre, lexindexfunc in self.lexre:
- m = lexre.match(lexdata, lexpos)
- if not m:
- continue
-
- # Create a token for return
- tok = LexToken()
- tok.value = m.group()
- tok.lineno = self.lineno
- tok.lexpos = lexpos
-
- i = m.lastindex
- func, tok.type = lexindexfunc[i]
-
- if not func:
- # If no token type was set, it's an ignored token
- if tok.type:
- self.lexpos = m.end()
- return tok
- else:
- lexpos = m.end()
- break
-
- lexpos = m.end()
-
- # If token is processed by a function, call it
-
- tok.lexer = self # Set additional attributes useful in token rules
- self.lexmatch = m
- self.lexpos = lexpos
-
- newtok = func(tok)
-
- # Every function must return a token, if nothing, we just move to next token
- if not newtok:
- lexpos = self.lexpos # This is here in case user has updated lexpos.
- lexignore = self.lexignore # This is here in case there was a state change
- break
-
- # Verify type of the token. If not in the token map, raise an error
- if not self.lexoptimize:
- if newtok.type not in self.lextokens_all:
- raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % (
- func.__code__.co_filename, func.__code__.co_firstlineno,
- func.__name__, newtok.type), lexdata[lexpos:])
-
- return newtok
- else:
- # No match, see if in literals
- if lexdata[lexpos] in self.lexliterals:
- tok = LexToken()
- tok.value = lexdata[lexpos]
- tok.lineno = self.lineno
- tok.type = tok.value
- tok.lexpos = lexpos
- self.lexpos = lexpos + 1
- return tok
-
- # No match. Call t_error() if defined.
- if self.lexerrorf:
- tok = LexToken()
- tok.value = self.lexdata[lexpos:]
- tok.lineno = self.lineno
- tok.type = 'error'
- tok.lexer = self
- tok.lexpos = lexpos
- self.lexpos = lexpos
- newtok = self.lexerrorf(tok)
- if lexpos == self.lexpos:
- # Error method didn't change text position at all. This is an error.
- raise LexError("Scanning error. Illegal character '%s'" % (lexdata[lexpos]), lexdata[lexpos:])
- lexpos = self.lexpos
- if not newtok:
- continue
- return newtok
-
- self.lexpos = lexpos
- raise LexError("Illegal character '%s' at index %d" % (lexdata[lexpos], lexpos), lexdata[lexpos:])
-
- if self.lexeoff:
- tok = LexToken()
- tok.type = 'eof'
- tok.value = ''
- tok.lineno = self.lineno
- tok.lexpos = lexpos
- tok.lexer = self
- self.lexpos = lexpos
- newtok = self.lexeoff(tok)
- return newtok
-
- self.lexpos = lexpos + 1
- if self.lexdata is None:
- raise RuntimeError('No input string given with input()')
- return None
-
- # Iterator interface
- def __iter__(self):
- return self
-
- def next(self):
- t = self.token()
- if t is None:
- raise StopIteration
- return t
-
- __next__ = next
-
-# -----------------------------------------------------------------------------
-# ==== Lex Builder ===
-#
-# The functions and classes below are used to collect lexing information
-# and build a Lexer object from it.
-# -----------------------------------------------------------------------------
-
-# -----------------------------------------------------------------------------
-# _get_regex(func)
-#
-# Returns the regular expression assigned to a function either as a doc string
-# or as a .regex attribute attached by the @TOKEN decorator.
-# -----------------------------------------------------------------------------
-def _get_regex(func):
- return getattr(func, 'regex', func.__doc__)
-
-# -----------------------------------------------------------------------------
-# get_caller_module_dict()
-#
-# This function returns a dictionary containing all of the symbols defined within
-# a caller further down the call stack. This is used to get the environment
-# associated with the yacc() call if none was provided.
-# -----------------------------------------------------------------------------
-def get_caller_module_dict(levels):
- f = sys._getframe(levels)
- ldict = f.f_globals.copy()
- if f.f_globals != f.f_locals:
- ldict.update(f.f_locals)
- return ldict
-
-# -----------------------------------------------------------------------------
-# _funcs_to_names()
-#
-# Given a list of regular expression functions, this converts it to a list
-# suitable for output to a table file
-# -----------------------------------------------------------------------------
-def _funcs_to_names(funclist, namelist):
- result = []
- for f, name in zip(funclist, namelist):
- if f and f[0]:
- result.append((name, f[1]))
- else:
- result.append(f)
- return result
-
-# -----------------------------------------------------------------------------
-# _names_to_funcs()
-#
-# Given a list of regular expression function names, this converts it back to
-# functions.
-# -----------------------------------------------------------------------------
-def _names_to_funcs(namelist, fdict):
- result = []
- for n in namelist:
- if n and n[0]:
- result.append((fdict[n[0]], n[1]))
- else:
- result.append(n)
- return result
-
-# -----------------------------------------------------------------------------
-# _form_master_re()
-#
-# This function takes a list of all of the regex components and attempts to
-# form the master regular expression. Given limitations in the Python re
-# module, it may be necessary to break the master regex into separate expressions.
-# -----------------------------------------------------------------------------
-def _form_master_re(relist, reflags, ldict, toknames):
- if not relist:
- return []
- regex = '|'.join(relist)
- try:
- lexre = re.compile(regex, reflags)
-
- # Build the index to function map for the matching engine
- lexindexfunc = [None] * (max(lexre.groupindex.values()) + 1)
- lexindexnames = lexindexfunc[:]
-
- for f, i in lexre.groupindex.items():
- handle = ldict.get(f, None)
- if type(handle) in (types.FunctionType, types.MethodType):
- lexindexfunc[i] = (handle, toknames[f])
- lexindexnames[i] = f
- elif handle is not None:
- lexindexnames[i] = f
- if f.find('ignore_') > 0:
- lexindexfunc[i] = (None, None)
- else:
- lexindexfunc[i] = (None, toknames[f])
-
- return [(lexre, lexindexfunc)], [regex], [lexindexnames]
- except Exception:
- m = int(len(relist)/2)
- if m == 0:
- m = 1
- llist, lre, lnames = _form_master_re(relist[:m], reflags, ldict, toknames)
- rlist, rre, rnames = _form_master_re(relist[m:], reflags, ldict, toknames)
- return (llist+rlist), (lre+rre), (lnames+rnames)
-
-# -----------------------------------------------------------------------------
-# def _statetoken(s,names)
-#
-# Given a declaration name s of the form "t_" and a dictionary whose keys are
-# state names, this function returns a tuple (states,tokenname) where states
-# is a tuple of state names and tokenname is the name of the token. For example,
-# calling this with s = "t_foo_bar_SPAM" might return (('foo','bar'),'SPAM')
-# -----------------------------------------------------------------------------
-def _statetoken(s, names):
- nonstate = 1
- parts = s.split('_')
- for i, part in enumerate(parts[1:], 1):
- if part not in names and part != 'ANY':
- break
-
- if i > 1:
- states = tuple(parts[1:i])
- else:
- states = ('INITIAL',)
-
- if 'ANY' in states:
- states = tuple(names)
-
- tokenname = '_'.join(parts[i:])
- return (states, tokenname)
-
-
-# -----------------------------------------------------------------------------
-# LexerReflect()
-#
-# This class represents information needed to build a lexer as extracted from a
-# user's input file.
-# -----------------------------------------------------------------------------
-class LexerReflect(object):
- def __init__(self, ldict, log=None, reflags=0):
- self.ldict = ldict
- self.error_func = None
- self.tokens = []
- self.reflags = reflags
- self.stateinfo = {'INITIAL': 'inclusive'}
- self.modules = set()
- self.error = False
- self.log = PlyLogger(sys.stderr) if log is None else log
-
- # Get all of the basic information
- def get_all(self):
- self.get_tokens()
- self.get_literals()
- self.get_states()
- self.get_rules()
-
- # Validate all of the information
- def validate_all(self):
- self.validate_tokens()
- self.validate_literals()
- self.validate_rules()
- return self.error
-
- # Get the tokens map
- def get_tokens(self):
- tokens = self.ldict.get('tokens', None)
- if not tokens:
- self.log.error('No token list is defined')
- self.error = True
- return
-
- if not isinstance(tokens, (list, tuple)):
- self.log.error('tokens must be a list or tuple')
- self.error = True
- return
-
- if not tokens:
- self.log.error('tokens is empty')
- self.error = True
- return
-
- self.tokens = tokens
-
- # Validate the tokens
- def validate_tokens(self):
- terminals = {}
- for n in self.tokens:
- if not _is_identifier.match(n):
- self.log.error("Bad token name '%s'", n)
- self.error = True
- if n in terminals:
- self.log.warning("Token '%s' multiply defined", n)
- terminals[n] = 1
-
- # Get the literals specifier
- def get_literals(self):
- self.literals = self.ldict.get('literals', '')
- if not self.literals:
- self.literals = ''
-
- # Validate literals
- def validate_literals(self):
- try:
- for c in self.literals:
- if not isinstance(c, StringTypes) or len(c) > 1:
- self.log.error('Invalid literal %s. Must be a single character', repr(c))
- self.error = True
-
- except TypeError:
- self.log.error('Invalid literals specification. literals must be a sequence of characters')
- self.error = True
-
- def get_states(self):
- self.states = self.ldict.get('states', None)
- # Build statemap
- if self.states:
- if not isinstance(self.states, (tuple, list)):
- self.log.error('states must be defined as a tuple or list')
- self.error = True
- else:
- for s in self.states:
- if not isinstance(s, tuple) or len(s) != 2:
- self.log.error("Invalid state specifier %s. Must be a tuple (statename,'exclusive|inclusive')", repr(s))
- self.error = True
- continue
- name, statetype = s
- if not isinstance(name, StringTypes):
- self.log.error('State name %s must be a string', repr(name))
- self.error = True
- continue
- if not (statetype == 'inclusive' or statetype == 'exclusive'):
- self.log.error("State type for state %s must be 'inclusive' or 'exclusive'", name)
- self.error = True
- continue
- if name in self.stateinfo:
- self.log.error("State '%s' already defined", name)
- self.error = True
- continue
- self.stateinfo[name] = statetype
-
- # Get all of the symbols with a t_ prefix and sort them into various
- # categories (functions, strings, error functions, and ignore characters)
-
- def get_rules(self):
- tsymbols = [f for f in self.ldict if f[:2] == 't_']
-
- # Now build up a list of functions and a list of strings
- self.toknames = {} # Mapping of symbols to token names
- self.funcsym = {} # Symbols defined as functions
- self.strsym = {} # Symbols defined as strings
- self.ignore = {} # Ignore strings by state
- self.errorf = {} # Error functions by state
- self.eoff = {} # EOF functions by state
-
- for s in self.stateinfo:
- self.funcsym[s] = []
- self.strsym[s] = []
-
- if len(tsymbols) == 0:
- self.log.error('No rules of the form t_rulename are defined')
- self.error = True
- return
-
- for f in tsymbols:
- t = self.ldict[f]
- states, tokname = _statetoken(f, self.stateinfo)
- self.toknames[f] = tokname
-
- if hasattr(t, '__call__'):
- if tokname == 'error':
- for s in states:
- self.errorf[s] = t
- elif tokname == 'eof':
- for s in states:
- self.eoff[s] = t
- elif tokname == 'ignore':
- line = t.__code__.co_firstlineno
- file = t.__code__.co_filename
- self.log.error("%s:%d: Rule '%s' must be defined as a string", file, line, t.__name__)
- self.error = True
- else:
- for s in states:
- self.funcsym[s].append((f, t))
- elif isinstance(t, StringTypes):
- if tokname == 'ignore':
- for s in states:
- self.ignore[s] = t
- if '\\' in t:
- self.log.warning("%s contains a literal backslash '\\'", f)
-
- elif tokname == 'error':
- self.log.error("Rule '%s' must be defined as a function", f)
- self.error = True
- else:
- for s in states:
- self.strsym[s].append((f, t))
- else:
- self.log.error('%s not defined as a function or string', f)
- self.error = True
-
- # Sort the functions by line number
- for f in self.funcsym.values():
- f.sort(key=lambda x: x[1].__code__.co_firstlineno)
-
- # Sort the strings by regular expression length
- for s in self.strsym.values():
- s.sort(key=lambda x: len(x[1]), reverse=True)
-
- # Validate all of the t_rules collected
- def validate_rules(self):
- for state in self.stateinfo:
- # Validate all rules defined by functions
-
- for fname, f in self.funcsym[state]:
- line = f.__code__.co_firstlineno
- file = f.__code__.co_filename
- module = inspect.getmodule(f)
- self.modules.add(module)
-
- tokname = self.toknames[fname]
- if isinstance(f, types.MethodType):
- reqargs = 2
- else:
- reqargs = 1
- nargs = f.__code__.co_argcount
- if nargs > reqargs:
- self.log.error("%s:%d: Rule '%s' has too many arguments", file, line, f.__name__)
- self.error = True
- continue
-
- if nargs < reqargs:
- self.log.error("%s:%d: Rule '%s' requires an argument", file, line, f.__name__)
- self.error = True
- continue
-
- if not _get_regex(f):
- self.log.error("%s:%d: No regular expression defined for rule '%s'", file, line, f.__name__)
- self.error = True
- continue
-
- try:
- c = re.compile('(?P<%s>%s)' % (fname, _get_regex(f)), self.reflags)
- if c.match(''):
- self.log.error("%s:%d: Regular expression for rule '%s' matches empty string", file, line, f.__name__)
- self.error = True
- except re.error as e:
- self.log.error("%s:%d: Invalid regular expression for rule '%s'. %s", file, line, f.__name__, e)
- if '#' in _get_regex(f):
- self.log.error("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'", file, line, f.__name__)
- self.error = True
-
- # Validate all rules defined by strings
- for name, r in self.strsym[state]:
- tokname = self.toknames[name]
- if tokname == 'error':
- self.log.error("Rule '%s' must be defined as a function", name)
- self.error = True
- continue
-
- if tokname not in self.tokens and tokname.find('ignore_') < 0:
- self.log.error("Rule '%s' defined for an unspecified token %s", name, tokname)
- self.error = True
- continue
-
- try:
- c = re.compile('(?P<%s>%s)' % (name, r), self.reflags)
- if (c.match('')):
- self.log.error("Regular expression for rule '%s' matches empty string", name)
- self.error = True
- except re.error as e:
- self.log.error("Invalid regular expression for rule '%s'. %s", name, e)
- if '#' in r:
- self.log.error("Make sure '#' in rule '%s' is escaped with '\\#'", name)
- self.error = True
-
- if not self.funcsym[state] and not self.strsym[state]:
- self.log.error("No rules defined for state '%s'", state)
- self.error = True
-
- # Validate the error function
- efunc = self.errorf.get(state, None)
- if efunc:
- f = efunc
- line = f.__code__.co_firstlineno
- file = f.__code__.co_filename
- module = inspect.getmodule(f)
- self.modules.add(module)
-
- if isinstance(f, types.MethodType):
- reqargs = 2
- else:
- reqargs = 1
- nargs = f.__code__.co_argcount
- if nargs > reqargs:
- self.log.error("%s:%d: Rule '%s' has too many arguments", file, line, f.__name__)
- self.error = True
-
- if nargs < reqargs:
- self.log.error("%s:%d: Rule '%s' requires an argument", file, line, f.__name__)
- self.error = True
-
- for module in self.modules:
- self.validate_module(module)
-
- # -----------------------------------------------------------------------------
- # validate_module()
- #
- # This checks to see if there are duplicated t_rulename() functions or strings
- # in the parser input file. This is done using a simple regular expression
- # match on each line in the source code of the given module.
- # -----------------------------------------------------------------------------
-
- def validate_module(self, module):
- try:
- lines, linen = inspect.getsourcelines(module)
- except IOError:
- return
-
- fre = re.compile(r'\s*def\s+(t_[a-zA-Z_0-9]*)\(')
- sre = re.compile(r'\s*(t_[a-zA-Z_0-9]*)\s*=')
-
- counthash = {}
- linen += 1
- for line in lines:
- m = fre.match(line)
- if not m:
- m = sre.match(line)
- if m:
- name = m.group(1)
- prev = counthash.get(name)
- if not prev:
- counthash[name] = linen
- else:
- filename = inspect.getsourcefile(module)
- self.log.error('%s:%d: Rule %s redefined. Previously defined on line %d', filename, linen, name, prev)
- self.error = True
- linen += 1
-
-# -----------------------------------------------------------------------------
-# lex(module)
-#
-# Build all of the regular expression rules from definitions in the supplied module
-# -----------------------------------------------------------------------------
-def lex(module=None, object=None, debug=False, optimize=False, lextab='lextab',
- reflags=int(re.VERBOSE), nowarn=False, outputdir=None, debuglog=None, errorlog=None):
-
- if lextab is None:
- lextab = 'lextab'
-
- global lexer
-
- ldict = None
- stateinfo = {'INITIAL': 'inclusive'}
- lexobj = Lexer()
- lexobj.lexoptimize = optimize
- global token, input
-
- if errorlog is None:
- errorlog = PlyLogger(sys.stderr)
-
- if debug:
- if debuglog is None:
- debuglog = PlyLogger(sys.stderr)
-
- # Get the module dictionary used for the lexer
- if object:
- module = object
-
- # Get the module dictionary used for the parser
- if module:
- _items = [(k, getattr(module, k)) for k in dir(module)]
- ldict = dict(_items)
- # If no __file__ attribute is available, try to obtain it from the __module__ instead
- if '__file__' not in ldict:
- ldict['__file__'] = sys.modules[ldict['__module__']].__file__
- else:
- ldict = get_caller_module_dict(2)
-
- # Determine if the module is package of a package or not.
- # If so, fix the tabmodule setting so that tables load correctly
- pkg = ldict.get('__package__')
- if pkg and isinstance(lextab, str):
- if '.' not in lextab:
- lextab = pkg + '.' + lextab
-
- # Collect parser information from the dictionary
- linfo = LexerReflect(ldict, log=errorlog, reflags=reflags)
- linfo.get_all()
- if not optimize:
- if linfo.validate_all():
- raise SyntaxError("Can't build lexer")
-
- if optimize and lextab:
- try:
- lexobj.readtab(lextab, ldict)
- token = lexobj.token
- input = lexobj.input
- lexer = lexobj
- return lexobj
-
- except ImportError:
- pass
-
- # Dump some basic debugging information
- if debug:
- debuglog.info('lex: tokens = %r', linfo.tokens)
- debuglog.info('lex: literals = %r', linfo.literals)
- debuglog.info('lex: states = %r', linfo.stateinfo)
-
- # Build a dictionary of valid token names
- lexobj.lextokens = set()
- for n in linfo.tokens:
- lexobj.lextokens.add(n)
-
- # Get literals specification
- if isinstance(linfo.literals, (list, tuple)):
- lexobj.lexliterals = type(linfo.literals[0])().join(linfo.literals)
- else:
- lexobj.lexliterals = linfo.literals
-
- lexobj.lextokens_all = lexobj.lextokens | set(lexobj.lexliterals)
-
- # Get the stateinfo dictionary
- stateinfo = linfo.stateinfo
-
- regexs = {}
- # Build the master regular expressions
- for state in stateinfo:
- regex_list = []
-
- # Add rules defined by functions first
- for fname, f in linfo.funcsym[state]:
- line = f.__code__.co_firstlineno
- file = f.__code__.co_filename
- regex_list.append('(?P<%s>%s)' % (fname, _get_regex(f)))
- if debug:
- debuglog.info("lex: Adding rule %s -> '%s' (state '%s')", fname, _get_regex(f), state)
-
- # Now add all of the simple rules
- for name, r in linfo.strsym[state]:
- regex_list.append('(?P<%s>%s)' % (name, r))
- if debug:
- debuglog.info("lex: Adding rule %s -> '%s' (state '%s')", name, r, state)
-
- regexs[state] = regex_list
-
- # Build the master regular expressions
-
- if debug:
- debuglog.info('lex: ==== MASTER REGEXS FOLLOW ====')
-
- for state in regexs:
- lexre, re_text, re_names = _form_master_re(regexs[state], reflags, ldict, linfo.toknames)
- lexobj.lexstatere[state] = lexre
- lexobj.lexstateretext[state] = re_text
- lexobj.lexstaterenames[state] = re_names
- if debug:
- for i, text in enumerate(re_text):
- debuglog.info("lex: state '%s' : regex[%d] = '%s'", state, i, text)
-
- # For inclusive states, we need to add the regular expressions from the INITIAL state
- for state, stype in stateinfo.items():
- if state != 'INITIAL' and stype == 'inclusive':
- lexobj.lexstatere[state].extend(lexobj.lexstatere['INITIAL'])
- lexobj.lexstateretext[state].extend(lexobj.lexstateretext['INITIAL'])
- lexobj.lexstaterenames[state].extend(lexobj.lexstaterenames['INITIAL'])
-
- lexobj.lexstateinfo = stateinfo
- lexobj.lexre = lexobj.lexstatere['INITIAL']
- lexobj.lexretext = lexobj.lexstateretext['INITIAL']
- lexobj.lexreflags = reflags
-
- # Set up ignore variables
- lexobj.lexstateignore = linfo.ignore
- lexobj.lexignore = lexobj.lexstateignore.get('INITIAL', '')
-
- # Set up error functions
- lexobj.lexstateerrorf = linfo.errorf
- lexobj.lexerrorf = linfo.errorf.get('INITIAL', None)
- if not lexobj.lexerrorf:
- errorlog.warning('No t_error rule is defined')
-
- # Set up eof functions
- lexobj.lexstateeoff = linfo.eoff
- lexobj.lexeoff = linfo.eoff.get('INITIAL', None)
-
- # Check state information for ignore and error rules
- for s, stype in stateinfo.items():
- if stype == 'exclusive':
- if s not in linfo.errorf:
- errorlog.warning("No error rule is defined for exclusive state '%s'", s)
- if s not in linfo.ignore and lexobj.lexignore:
- errorlog.warning("No ignore rule is defined for exclusive state '%s'", s)
- elif stype == 'inclusive':
- if s not in linfo.errorf:
- linfo.errorf[s] = linfo.errorf.get('INITIAL', None)
- if s not in linfo.ignore:
- linfo.ignore[s] = linfo.ignore.get('INITIAL', '')
-
- # Create global versions of the token() and input() functions
- token = lexobj.token
- input = lexobj.input
- lexer = lexobj
-
- # If in optimize mode, we write the lextab
- if lextab and optimize:
- if outputdir is None:
- # If no output directory is set, the location of the output files
- # is determined according to the following rules:
- # - If lextab specifies a package, files go into that package directory
- # - Otherwise, files go in the same directory as the specifying module
- if isinstance(lextab, types.ModuleType):
- srcfile = lextab.__file__
- else:
- if '.' not in lextab:
- srcfile = ldict['__file__']
- else:
- parts = lextab.split('.')
- pkgname = '.'.join(parts[:-1])
- exec('import %s' % pkgname)
- srcfile = getattr(sys.modules[pkgname], '__file__', '')
- outputdir = os.path.dirname(srcfile)
- try:
- lexobj.writetab(lextab, outputdir)
- except IOError as e:
- errorlog.warning("Couldn't write lextab module %r. %s" % (lextab, e))
-
- return lexobj
-
-# -----------------------------------------------------------------------------
-# runmain()
-#
-# This runs the lexer as a main program
-# -----------------------------------------------------------------------------
-
-def runmain(lexer=None, data=None):
- if not data:
- try:
- filename = sys.argv[1]
- f = open(filename)
- data = f.read()
- f.close()
- except IndexError:
- sys.stdout.write('Reading from standard input (type EOF to end):\n')
- data = sys.stdin.read()
-
- if lexer:
- _input = lexer.input
- else:
- _input = input
- _input(data)
- if lexer:
- _token = lexer.token
- else:
- _token = token
-
- while True:
- tok = _token()
- if not tok:
- break
- sys.stdout.write('(%s,%r,%d,%d)\n' % (tok.type, tok.value, tok.lineno, tok.lexpos))
-
-# -----------------------------------------------------------------------------
-# @TOKEN(regex)
-#
-# This decorator function can be used to set the regex expression on a function
-# when its docstring might need to be set in an alternative way
-# -----------------------------------------------------------------------------
-
-def TOKEN(r):
- def set_regex(f):
- if hasattr(r, '__call__'):
- f.regex = _get_regex(r)
- else:
- f.regex = r
- return f
- return set_regex
-
-# Alternative spelling of the TOKEN decorator
-Token = TOKEN
diff --git a/pycparser/ply/yacc.py b/pycparser/ply/yacc.py
deleted file mode 100644
index 20b4f28..0000000
--- a/pycparser/ply/yacc.py
+++ /dev/null
@@ -1,3494 +0,0 @@
-# -----------------------------------------------------------------------------
-# ply: yacc.py
-#
-# Copyright (C) 2001-2017
-# David M. Beazley (Dabeaz LLC)
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-# * Neither the name of the David Beazley or Dabeaz LLC may be used to
-# endorse or promote products derived from this software without
-# specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# -----------------------------------------------------------------------------
-#
-# This implements an LR parser that is constructed from grammar rules defined
-# as Python functions. The grammer is specified by supplying the BNF inside
-# Python documentation strings. The inspiration for this technique was borrowed
-# from John Aycock's Spark parsing system. PLY might be viewed as cross between
-# Spark and the GNU bison utility.
-#
-# The current implementation is only somewhat object-oriented. The
-# LR parser itself is defined in terms of an object (which allows multiple
-# parsers to co-exist). However, most of the variables used during table
-# construction are defined in terms of global variables. Users shouldn't
-# notice unless they are trying to define multiple parsers at the same
-# time using threads (in which case they should have their head examined).
-#
-# This implementation supports both SLR and LALR(1) parsing. LALR(1)
-# support was originally implemented by Elias Ioup (ezioup@alumni.uchicago.edu),
-# using the algorithm found in Aho, Sethi, and Ullman "Compilers: Principles,
-# Techniques, and Tools" (The Dragon Book). LALR(1) has since been replaced
-# by the more efficient DeRemer and Pennello algorithm.
-#
-# :::::::: WARNING :::::::
-#
-# Construction of LR parsing tables is fairly complicated and expensive.
-# To make this module run fast, a *LOT* of work has been put into
-# optimization---often at the expensive of readability and what might
-# consider to be good Python "coding style." Modify the code at your
-# own risk!
-# ----------------------------------------------------------------------------
-
-import re
-import types
-import sys
-import os.path
-import inspect
-import base64
-import warnings
-
-__version__ = '3.10'
-__tabversion__ = '3.10'
-
-#-----------------------------------------------------------------------------
-# === User configurable parameters ===
-#
-# Change these to modify the default behavior of yacc (if you wish)
-#-----------------------------------------------------------------------------
-
-yaccdebug = True # Debugging mode. If set, yacc generates a
- # a 'parser.out' file in the current directory
-
-debug_file = 'parser.out' # Default name of the debugging file
-tab_module = 'parsetab' # Default name of the table module
-default_lr = 'LALR' # Default LR table generation method
-
-error_count = 3 # Number of symbols that must be shifted to leave recovery mode
-
-yaccdevel = False # Set to True if developing yacc. This turns off optimized
- # implementations of certain functions.
-
-resultlimit = 40 # Size limit of results when running in debug mode.
-
-pickle_protocol = 0 # Protocol to use when writing pickle files
-
-# String type-checking compatibility
-if sys.version_info[0] < 3:
- string_types = basestring
-else:
- string_types = str
-
-MAXINT = sys.maxsize
-
-# This object is a stand-in for a logging object created by the
-# logging module. PLY will use this by default to create things
-# such as the parser.out file. If a user wants more detailed
-# information, they can create their own logging object and pass
-# it into PLY.
-
-class PlyLogger(object):
- def __init__(self, f):
- self.f = f
-
- def debug(self, msg, *args, **kwargs):
- self.f.write((msg % args) + '\n')
-
- info = debug
-
- def warning(self, msg, *args, **kwargs):
- self.f.write('WARNING: ' + (msg % args) + '\n')
-
- def error(self, msg, *args, **kwargs):
- self.f.write('ERROR: ' + (msg % args) + '\n')
-
- critical = debug
-
-# Null logger is used when no output is generated. Does nothing.
-class NullLogger(object):
- def __getattribute__(self, name):
- return self
-
- def __call__(self, *args, **kwargs):
- return self
-
-# Exception raised for yacc-related errors
-class YaccError(Exception):
- pass
-
-# Format the result message that the parser produces when running in debug mode.
-def format_result(r):
- repr_str = repr(r)
- if '\n' in repr_str:
- repr_str = repr(repr_str)
- if len(repr_str) > resultlimit:
- repr_str = repr_str[:resultlimit] + ' ...'
- result = '<%s @ 0x%x> (%s)' % (type(r).__name__, id(r), repr_str)
- return result
-
-# Format stack entries when the parser is running in debug mode
-def format_stack_entry(r):
- repr_str = repr(r)
- if '\n' in repr_str:
- repr_str = repr(repr_str)
- if len(repr_str) < 16:
- return repr_str
- else:
- return '<%s @ 0x%x>' % (type(r).__name__, id(r))
-
-# Panic mode error recovery support. This feature is being reworked--much of the
-# code here is to offer a deprecation/backwards compatible transition
-
-_errok = None
-_token = None
-_restart = None
-_warnmsg = '''PLY: Don't use global functions errok(), token(), and restart() in p_error().
-Instead, invoke the methods on the associated parser instance:
-
- def p_error(p):
- ...
- # Use parser.errok(), parser.token(), parser.restart()
- ...
-
- parser = yacc.yacc()
-'''
-
-def errok():
- warnings.warn(_warnmsg)
- return _errok()
-
-def restart():
- warnings.warn(_warnmsg)
- return _restart()
-
-def token():
- warnings.warn(_warnmsg)
- return _token()
-
-# Utility function to call the p_error() function with some deprecation hacks
-def call_errorfunc(errorfunc, token, parser):
- global _errok, _token, _restart
- _errok = parser.errok
- _token = parser.token
- _restart = parser.restart
- r = errorfunc(token)
- try:
- del _errok, _token, _restart
- except NameError:
- pass
- return r
-
-#-----------------------------------------------------------------------------
-# === LR Parsing Engine ===
-#
-# The following classes are used for the LR parser itself. These are not
-# used during table construction and are independent of the actual LR
-# table generation algorithm
-#-----------------------------------------------------------------------------
-
-# This class is used to hold non-terminal grammar symbols during parsing.
-# It normally has the following attributes set:
-# .type = Grammar symbol type
-# .value = Symbol value
-# .lineno = Starting line number
-# .endlineno = Ending line number (optional, set automatically)
-# .lexpos = Starting lex position
-# .endlexpos = Ending lex position (optional, set automatically)
-
-class YaccSymbol:
- def __str__(self):
- return self.type
-
- def __repr__(self):
- return str(self)
-
-# This class is a wrapper around the objects actually passed to each
-# grammar rule. Index lookup and assignment actually assign the
-# .value attribute of the underlying YaccSymbol object.
-# The lineno() method returns the line number of a given
-# item (or 0 if not defined). The linespan() method returns
-# a tuple of (startline,endline) representing the range of lines
-# for a symbol. The lexspan() method returns a tuple (lexpos,endlexpos)
-# representing the range of positional information for a symbol.
-
-class YaccProduction:
- def __init__(self, s, stack=None):
- self.slice = s
- self.stack = stack
- self.lexer = None
- self.parser = None
-
- def __getitem__(self, n):
- if isinstance(n, slice):
- return [s.value for s in self.slice[n]]
- elif n >= 0:
- return self.slice[n].value
- else:
- return self.stack[n].value
-
- def __setitem__(self, n, v):
- self.slice[n].value = v
-
- def __getslice__(self, i, j):
- return [s.value for s in self.slice[i:j]]
-
- def __len__(self):
- return len(self.slice)
-
- def lineno(self, n):
- return getattr(self.slice[n], 'lineno', 0)
-
- def set_lineno(self, n, lineno):
- self.slice[n].lineno = lineno
-
- def linespan(self, n):
- startline = getattr(self.slice[n], 'lineno', 0)
- endline = getattr(self.slice[n], 'endlineno', startline)
- return startline, endline
-
- def lexpos(self, n):
- return getattr(self.slice[n], 'lexpos', 0)
-
- def lexspan(self, n):
- startpos = getattr(self.slice[n], 'lexpos', 0)
- endpos = getattr(self.slice[n], 'endlexpos', startpos)
- return startpos, endpos
-
- def error(self):
- raise SyntaxError
-
-# -----------------------------------------------------------------------------
-# == LRParser ==
-#
-# The LR Parsing engine.
-# -----------------------------------------------------------------------------
-
-class LRParser:
- def __init__(self, lrtab, errorf):
- self.productions = lrtab.lr_productions
- self.action = lrtab.lr_action
- self.goto = lrtab.lr_goto
- self.errorfunc = errorf
- self.set_defaulted_states()
- self.errorok = True
-
- def errok(self):
- self.errorok = True
-
- def restart(self):
- del self.statestack[:]
- del self.symstack[:]
- sym = YaccSymbol()
- sym.type = '$end'
- self.symstack.append(sym)
- self.statestack.append(0)
-
- # Defaulted state support.
- # This method identifies parser states where there is only one possible reduction action.
- # For such states, the parser can make a choose to make a rule reduction without consuming
- # the next look-ahead token. This delayed invocation of the tokenizer can be useful in
- # certain kinds of advanced parsing situations where the lexer and parser interact with
- # each other or change states (i.e., manipulation of scope, lexer states, etc.).
- #
- # See: https://www.gnu.org/software/bison/manual/html_node/Default-Reductions.html#Default-Reductions
- def set_defaulted_states(self):
- self.defaulted_states = {}
- for state, actions in self.action.items():
- rules = list(actions.values())
- if len(rules) == 1 and rules[0] < 0:
- self.defaulted_states[state] = rules[0]
-
- def disable_defaulted_states(self):
- self.defaulted_states = {}
-
- def parse(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
- if debug or yaccdevel:
- if isinstance(debug, int):
- debug = PlyLogger(sys.stderr)
- return self.parsedebug(input, lexer, debug, tracking, tokenfunc)
- elif tracking:
- return self.parseopt(input, lexer, debug, tracking, tokenfunc)
- else:
- return self.parseopt_notrack(input, lexer, debug, tracking, tokenfunc)
-
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # parsedebug().
- #
- # This is the debugging enabled version of parse(). All changes made to the
- # parsing engine should be made here. Optimized versions of this function
- # are automatically created by the ply/ygen.py script. This script cuts out
- # sections enclosed in markers such as this:
- #
- # #--! DEBUG
- # statements
- # #--! DEBUG
- #
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- def parsedebug(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
- #--! parsedebug-start
- lookahead = None # Current lookahead symbol
- lookaheadstack = [] # Stack of lookahead symbols
- actions = self.action # Local reference to action table (to avoid lookup on self.)
- goto = self.goto # Local reference to goto table (to avoid lookup on self.)
- prod = self.productions # Local reference to production list (to avoid lookup on self.)
- defaulted_states = self.defaulted_states # Local reference to defaulted states
- pslice = YaccProduction(None) # Production object passed to grammar rules
- errorcount = 0 # Used during error recovery
-
- #--! DEBUG
- debug.info('PLY: PARSE DEBUG START')
- #--! DEBUG
-
- # If no lexer was given, we will try to use the lex module
- if not lexer:
- from . import lex
- lexer = lex.lexer
-
- # Set up the lexer and parser objects on pslice
- pslice.lexer = lexer
- pslice.parser = self
-
- # If input was supplied, pass to lexer
- if input is not None:
- lexer.input(input)
-
- if tokenfunc is None:
- # Tokenize function
- get_token = lexer.token
- else:
- get_token = tokenfunc
-
- # Set the parser() token method (sometimes used in error recovery)
- self.token = get_token
-
- # Set up the state and symbol stacks
-
- statestack = [] # Stack of parsing states
- self.statestack = statestack
- symstack = [] # Stack of grammar symbols
- self.symstack = symstack
-
- pslice.stack = symstack # Put in the production
- errtoken = None # Err token
-
- # The start state is assumed to be (0,$end)
-
- statestack.append(0)
- sym = YaccSymbol()
- sym.type = '$end'
- symstack.append(sym)
- state = 0
- while True:
- # Get the next symbol on the input. If a lookahead symbol
- # is already set, we just use that. Otherwise, we'll pull
- # the next token off of the lookaheadstack or from the lexer
-
- #--! DEBUG
- debug.debug('')
- debug.debug('State : %s', state)
- #--! DEBUG
-
- if state not in defaulted_states:
- if not lookahead:
- if not lookaheadstack:
- lookahead = get_token() # Get the next token
- else:
- lookahead = lookaheadstack.pop()
- if not lookahead:
- lookahead = YaccSymbol()
- lookahead.type = '$end'
-
- # Check the action table
- ltype = lookahead.type
- t = actions[state].get(ltype)
- else:
- t = defaulted_states[state]
- #--! DEBUG
- debug.debug('Defaulted state %s: Reduce using %d', state, -t)
- #--! DEBUG
-
- #--! DEBUG
- debug.debug('Stack : %s',
- ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
- #--! DEBUG
-
- if t is not None:
- if t > 0:
- # shift a symbol on the stack
- statestack.append(t)
- state = t
-
- #--! DEBUG
- debug.debug('Action : Shift and goto state %s', t)
- #--! DEBUG
-
- symstack.append(lookahead)
- lookahead = None
-
- # Decrease error count on successful shift
- if errorcount:
- errorcount -= 1
- continue
-
- if t < 0:
- # reduce a symbol on the stack, emit a production
- p = prod[-t]
- pname = p.name
- plen = p.len
-
- # Get production function
- sym = YaccSymbol()
- sym.type = pname # Production name
- sym.value = None
-
- #--! DEBUG
- if plen:
- debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str,
- '['+','.join([format_stack_entry(_v.value) for _v in symstack[-plen:]])+']',
- goto[statestack[-1-plen]][pname])
- else:
- debug.info('Action : Reduce rule [%s] with %s and goto state %d', p.str, [],
- goto[statestack[-1]][pname])
-
- #--! DEBUG
-
- if plen:
- targ = symstack[-plen-1:]
- targ[0] = sym
-
- #--! TRACKING
- if tracking:
- t1 = targ[1]
- sym.lineno = t1.lineno
- sym.lexpos = t1.lexpos
- t1 = targ[-1]
- sym.endlineno = getattr(t1, 'endlineno', t1.lineno)
- sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos)
- #--! TRACKING
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # below as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- del symstack[-plen:]
- self.state = state
- p.callable(pslice)
- del statestack[-plen:]
- #--! DEBUG
- debug.info('Result : %s', format_result(pslice[0]))
- #--! DEBUG
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead) # Save the current lookahead token
- symstack.extend(targ[1:-1]) # Put the production slice back on the stack
- statestack.pop() # Pop back one state (before the reduce)
- state = statestack[-1]
- sym.type = 'error'
- sym.value = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = False
-
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- else:
-
- #--! TRACKING
- if tracking:
- sym.lineno = lexer.lineno
- sym.lexpos = lexer.lexpos
- #--! TRACKING
-
- targ = [sym]
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # above as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- self.state = state
- p.callable(pslice)
- #--! DEBUG
- debug.info('Result : %s', format_result(pslice[0]))
- #--! DEBUG
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead) # Save the current lookahead token
- statestack.pop() # Pop back one state (before the reduce)
- state = statestack[-1]
- sym.type = 'error'
- sym.value = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = False
-
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- if t == 0:
- n = symstack[-1]
- result = getattr(n, 'value', None)
- #--! DEBUG
- debug.info('Done : Returning %s', format_result(result))
- debug.info('PLY: PARSE DEBUG END')
- #--! DEBUG
- return result
-
- if t is None:
-
- #--! DEBUG
- debug.error('Error : %s',
- ('%s . %s' % (' '.join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip())
- #--! DEBUG
-
- # We have some kind of parsing error here. To handle
- # this, we are going to push the current token onto
- # the tokenstack and replace it with an 'error' token.
- # If there are any synchronization rules, they may
- # catch it.
- #
- # In addition to pushing the error token, we call call
- # the user defined p_error() function if this is the
- # first syntax error. This function is only called if
- # errorcount == 0.
- if errorcount == 0 or self.errorok:
- errorcount = error_count
- self.errorok = False
- errtoken = lookahead
- if errtoken.type == '$end':
- errtoken = None # End of file!
- if self.errorfunc:
- if errtoken and not hasattr(errtoken, 'lexer'):
- errtoken.lexer = lexer
- self.state = state
- tok = call_errorfunc(self.errorfunc, errtoken, self)
- if self.errorok:
- # User must have done some kind of panic
- # mode recovery on their own. The
- # returned token is the next lookahead
- lookahead = tok
- errtoken = None
- continue
- else:
- if errtoken:
- if hasattr(errtoken, 'lineno'):
- lineno = lookahead.lineno
- else:
- lineno = 0
- if lineno:
- sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
- else:
- sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
- else:
- sys.stderr.write('yacc: Parse error in input. EOF\n')
- return
-
- else:
- errorcount = error_count
-
- # case 1: the statestack only has 1 entry on it. If we're in this state, the
- # entire parse has been rolled back and we're completely hosed. The token is
- # discarded and we just keep going.
-
- if len(statestack) <= 1 and lookahead.type != '$end':
- lookahead = None
- errtoken = None
- state = 0
- # Nuke the pushback stack
- del lookaheadstack[:]
- continue
-
- # case 2: the statestack has a couple of entries on it, but we're
- # at the end of the file. nuke the top entry and generate an error token
-
- # Start nuking entries on the stack
- if lookahead.type == '$end':
- # Whoa. We're really hosed here. Bail out
- return
-
- if lookahead.type != 'error':
- sym = symstack[-1]
- if sym.type == 'error':
- # Hmmm. Error is on top of stack, we'll just nuke input
- # symbol and continue
- #--! TRACKING
- if tracking:
- sym.endlineno = getattr(lookahead, 'lineno', sym.lineno)
- sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos)
- #--! TRACKING
- lookahead = None
- continue
-
- # Create the error symbol for the first time and make it the new lookahead symbol
- t = YaccSymbol()
- t.type = 'error'
-
- if hasattr(lookahead, 'lineno'):
- t.lineno = t.endlineno = lookahead.lineno
- if hasattr(lookahead, 'lexpos'):
- t.lexpos = t.endlexpos = lookahead.lexpos
- t.value = lookahead
- lookaheadstack.append(lookahead)
- lookahead = t
- else:
- sym = symstack.pop()
- #--! TRACKING
- if tracking:
- lookahead.lineno = sym.lineno
- lookahead.lexpos = sym.lexpos
- #--! TRACKING
- statestack.pop()
- state = statestack[-1]
-
- continue
-
- # Call an error function here
- raise RuntimeError('yacc: internal parser error!!!\n')
-
- #--! parsedebug-end
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # parseopt().
- #
- # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY!
- # This code is automatically generated by the ply/ygen.py script. Make
- # changes to the parsedebug() method instead.
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- def parseopt(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
- #--! parseopt-start
- lookahead = None # Current lookahead symbol
- lookaheadstack = [] # Stack of lookahead symbols
- actions = self.action # Local reference to action table (to avoid lookup on self.)
- goto = self.goto # Local reference to goto table (to avoid lookup on self.)
- prod = self.productions # Local reference to production list (to avoid lookup on self.)
- defaulted_states = self.defaulted_states # Local reference to defaulted states
- pslice = YaccProduction(None) # Production object passed to grammar rules
- errorcount = 0 # Used during error recovery
-
-
- # If no lexer was given, we will try to use the lex module
- if not lexer:
- from . import lex
- lexer = lex.lexer
-
- # Set up the lexer and parser objects on pslice
- pslice.lexer = lexer
- pslice.parser = self
-
- # If input was supplied, pass to lexer
- if input is not None:
- lexer.input(input)
-
- if tokenfunc is None:
- # Tokenize function
- get_token = lexer.token
- else:
- get_token = tokenfunc
-
- # Set the parser() token method (sometimes used in error recovery)
- self.token = get_token
-
- # Set up the state and symbol stacks
-
- statestack = [] # Stack of parsing states
- self.statestack = statestack
- symstack = [] # Stack of grammar symbols
- self.symstack = symstack
-
- pslice.stack = symstack # Put in the production
- errtoken = None # Err token
-
- # The start state is assumed to be (0,$end)
-
- statestack.append(0)
- sym = YaccSymbol()
- sym.type = '$end'
- symstack.append(sym)
- state = 0
- while True:
- # Get the next symbol on the input. If a lookahead symbol
- # is already set, we just use that. Otherwise, we'll pull
- # the next token off of the lookaheadstack or from the lexer
-
-
- if state not in defaulted_states:
- if not lookahead:
- if not lookaheadstack:
- lookahead = get_token() # Get the next token
- else:
- lookahead = lookaheadstack.pop()
- if not lookahead:
- lookahead = YaccSymbol()
- lookahead.type = '$end'
-
- # Check the action table
- ltype = lookahead.type
- t = actions[state].get(ltype)
- else:
- t = defaulted_states[state]
-
-
- if t is not None:
- if t > 0:
- # shift a symbol on the stack
- statestack.append(t)
- state = t
-
-
- symstack.append(lookahead)
- lookahead = None
-
- # Decrease error count on successful shift
- if errorcount:
- errorcount -= 1
- continue
-
- if t < 0:
- # reduce a symbol on the stack, emit a production
- p = prod[-t]
- pname = p.name
- plen = p.len
-
- # Get production function
- sym = YaccSymbol()
- sym.type = pname # Production name
- sym.value = None
-
-
- if plen:
- targ = symstack[-plen-1:]
- targ[0] = sym
-
- #--! TRACKING
- if tracking:
- t1 = targ[1]
- sym.lineno = t1.lineno
- sym.lexpos = t1.lexpos
- t1 = targ[-1]
- sym.endlineno = getattr(t1, 'endlineno', t1.lineno)
- sym.endlexpos = getattr(t1, 'endlexpos', t1.lexpos)
- #--! TRACKING
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # below as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- del symstack[-plen:]
- self.state = state
- p.callable(pslice)
- del statestack[-plen:]
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead) # Save the current lookahead token
- symstack.extend(targ[1:-1]) # Put the production slice back on the stack
- statestack.pop() # Pop back one state (before the reduce)
- state = statestack[-1]
- sym.type = 'error'
- sym.value = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = False
-
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- else:
-
- #--! TRACKING
- if tracking:
- sym.lineno = lexer.lineno
- sym.lexpos = lexer.lexpos
- #--! TRACKING
-
- targ = [sym]
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # above as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- self.state = state
- p.callable(pslice)
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead) # Save the current lookahead token
- statestack.pop() # Pop back one state (before the reduce)
- state = statestack[-1]
- sym.type = 'error'
- sym.value = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = False
-
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- if t == 0:
- n = symstack[-1]
- result = getattr(n, 'value', None)
- return result
-
- if t is None:
-
-
- # We have some kind of parsing error here. To handle
- # this, we are going to push the current token onto
- # the tokenstack and replace it with an 'error' token.
- # If there are any synchronization rules, they may
- # catch it.
- #
- # In addition to pushing the error token, we call call
- # the user defined p_error() function if this is the
- # first syntax error. This function is only called if
- # errorcount == 0.
- if errorcount == 0 or self.errorok:
- errorcount = error_count
- self.errorok = False
- errtoken = lookahead
- if errtoken.type == '$end':
- errtoken = None # End of file!
- if self.errorfunc:
- if errtoken and not hasattr(errtoken, 'lexer'):
- errtoken.lexer = lexer
- self.state = state
- tok = call_errorfunc(self.errorfunc, errtoken, self)
- if self.errorok:
- # User must have done some kind of panic
- # mode recovery on their own. The
- # returned token is the next lookahead
- lookahead = tok
- errtoken = None
- continue
- else:
- if errtoken:
- if hasattr(errtoken, 'lineno'):
- lineno = lookahead.lineno
- else:
- lineno = 0
- if lineno:
- sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
- else:
- sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
- else:
- sys.stderr.write('yacc: Parse error in input. EOF\n')
- return
-
- else:
- errorcount = error_count
-
- # case 1: the statestack only has 1 entry on it. If we're in this state, the
- # entire parse has been rolled back and we're completely hosed. The token is
- # discarded and we just keep going.
-
- if len(statestack) <= 1 and lookahead.type != '$end':
- lookahead = None
- errtoken = None
- state = 0
- # Nuke the pushback stack
- del lookaheadstack[:]
- continue
-
- # case 2: the statestack has a couple of entries on it, but we're
- # at the end of the file. nuke the top entry and generate an error token
-
- # Start nuking entries on the stack
- if lookahead.type == '$end':
- # Whoa. We're really hosed here. Bail out
- return
-
- if lookahead.type != 'error':
- sym = symstack[-1]
- if sym.type == 'error':
- # Hmmm. Error is on top of stack, we'll just nuke input
- # symbol and continue
- #--! TRACKING
- if tracking:
- sym.endlineno = getattr(lookahead, 'lineno', sym.lineno)
- sym.endlexpos = getattr(lookahead, 'lexpos', sym.lexpos)
- #--! TRACKING
- lookahead = None
- continue
-
- # Create the error symbol for the first time and make it the new lookahead symbol
- t = YaccSymbol()
- t.type = 'error'
-
- if hasattr(lookahead, 'lineno'):
- t.lineno = t.endlineno = lookahead.lineno
- if hasattr(lookahead, 'lexpos'):
- t.lexpos = t.endlexpos = lookahead.lexpos
- t.value = lookahead
- lookaheadstack.append(lookahead)
- lookahead = t
- else:
- sym = symstack.pop()
- #--! TRACKING
- if tracking:
- lookahead.lineno = sym.lineno
- lookahead.lexpos = sym.lexpos
- #--! TRACKING
- statestack.pop()
- state = statestack[-1]
-
- continue
-
- # Call an error function here
- raise RuntimeError('yacc: internal parser error!!!\n')
-
- #--! parseopt-end
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # parseopt_notrack().
- #
- # Optimized version of parseopt() with line number tracking removed.
- # DO NOT EDIT THIS CODE DIRECTLY. This code is automatically generated
- # by the ply/ygen.py script. Make changes to the parsedebug() method instead.
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- def parseopt_notrack(self, input=None, lexer=None, debug=False, tracking=False, tokenfunc=None):
- #--! parseopt-notrack-start
- lookahead = None # Current lookahead symbol
- lookaheadstack = [] # Stack of lookahead symbols
- actions = self.action # Local reference to action table (to avoid lookup on self.)
- goto = self.goto # Local reference to goto table (to avoid lookup on self.)
- prod = self.productions # Local reference to production list (to avoid lookup on self.)
- defaulted_states = self.defaulted_states # Local reference to defaulted states
- pslice = YaccProduction(None) # Production object passed to grammar rules
- errorcount = 0 # Used during error recovery
-
-
- # If no lexer was given, we will try to use the lex module
- if not lexer:
- from . import lex
- lexer = lex.lexer
-
- # Set up the lexer and parser objects on pslice
- pslice.lexer = lexer
- pslice.parser = self
-
- # If input was supplied, pass to lexer
- if input is not None:
- lexer.input(input)
-
- if tokenfunc is None:
- # Tokenize function
- get_token = lexer.token
- else:
- get_token = tokenfunc
-
- # Set the parser() token method (sometimes used in error recovery)
- self.token = get_token
-
- # Set up the state and symbol stacks
-
- statestack = [] # Stack of parsing states
- self.statestack = statestack
- symstack = [] # Stack of grammar symbols
- self.symstack = symstack
-
- pslice.stack = symstack # Put in the production
- errtoken = None # Err token
-
- # The start state is assumed to be (0,$end)
-
- statestack.append(0)
- sym = YaccSymbol()
- sym.type = '$end'
- symstack.append(sym)
- state = 0
- while True:
- # Get the next symbol on the input. If a lookahead symbol
- # is already set, we just use that. Otherwise, we'll pull
- # the next token off of the lookaheadstack or from the lexer
-
-
- if state not in defaulted_states:
- if not lookahead:
- if not lookaheadstack:
- lookahead = get_token() # Get the next token
- else:
- lookahead = lookaheadstack.pop()
- if not lookahead:
- lookahead = YaccSymbol()
- lookahead.type = '$end'
-
- # Check the action table
- ltype = lookahead.type
- t = actions[state].get(ltype)
- else:
- t = defaulted_states[state]
-
-
- if t is not None:
- if t > 0:
- # shift a symbol on the stack
- statestack.append(t)
- state = t
-
-
- symstack.append(lookahead)
- lookahead = None
-
- # Decrease error count on successful shift
- if errorcount:
- errorcount -= 1
- continue
-
- if t < 0:
- # reduce a symbol on the stack, emit a production
- p = prod[-t]
- pname = p.name
- plen = p.len
-
- # Get production function
- sym = YaccSymbol()
- sym.type = pname # Production name
- sym.value = None
-
-
- if plen:
- targ = symstack[-plen-1:]
- targ[0] = sym
-
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # below as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- del symstack[-plen:]
- self.state = state
- p.callable(pslice)
- del statestack[-plen:]
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead) # Save the current lookahead token
- symstack.extend(targ[1:-1]) # Put the production slice back on the stack
- statestack.pop() # Pop back one state (before the reduce)
- state = statestack[-1]
- sym.type = 'error'
- sym.value = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = False
-
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- else:
-
-
- targ = [sym]
-
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
- # The code enclosed in this section is duplicated
- # above as a performance optimization. Make sure
- # changes get made in both locations.
-
- pslice.slice = targ
-
- try:
- # Call the grammar rule with our special slice object
- self.state = state
- p.callable(pslice)
- symstack.append(sym)
- state = goto[statestack[-1]][pname]
- statestack.append(state)
- except SyntaxError:
- # If an error was set. Enter error recovery state
- lookaheadstack.append(lookahead) # Save the current lookahead token
- statestack.pop() # Pop back one state (before the reduce)
- state = statestack[-1]
- sym.type = 'error'
- sym.value = 'error'
- lookahead = sym
- errorcount = error_count
- self.errorok = False
-
- continue
- # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-
- if t == 0:
- n = symstack[-1]
- result = getattr(n, 'value', None)
- return result
-
- if t is None:
-
-
- # We have some kind of parsing error here. To handle
- # this, we are going to push the current token onto
- # the tokenstack and replace it with an 'error' token.
- # If there are any synchronization rules, they may
- # catch it.
- #
- # In addition to pushing the error token, we call call
- # the user defined p_error() function if this is the
- # first syntax error. This function is only called if
- # errorcount == 0.
- if errorcount == 0 or self.errorok:
- errorcount = error_count
- self.errorok = False
- errtoken = lookahead
- if errtoken.type == '$end':
- errtoken = None # End of file!
- if self.errorfunc:
- if errtoken and not hasattr(errtoken, 'lexer'):
- errtoken.lexer = lexer
- self.state = state
- tok = call_errorfunc(self.errorfunc, errtoken, self)
- if self.errorok:
- # User must have done some kind of panic
- # mode recovery on their own. The
- # returned token is the next lookahead
- lookahead = tok
- errtoken = None
- continue
- else:
- if errtoken:
- if hasattr(errtoken, 'lineno'):
- lineno = lookahead.lineno
- else:
- lineno = 0
- if lineno:
- sys.stderr.write('yacc: Syntax error at line %d, token=%s\n' % (lineno, errtoken.type))
- else:
- sys.stderr.write('yacc: Syntax error, token=%s' % errtoken.type)
- else:
- sys.stderr.write('yacc: Parse error in input. EOF\n')
- return
-
- else:
- errorcount = error_count
-
- # case 1: the statestack only has 1 entry on it. If we're in this state, the
- # entire parse has been rolled back and we're completely hosed. The token is
- # discarded and we just keep going.
-
- if len(statestack) <= 1 and lookahead.type != '$end':
- lookahead = None
- errtoken = None
- state = 0
- # Nuke the pushback stack
- del lookaheadstack[:]
- continue
-
- # case 2: the statestack has a couple of entries on it, but we're
- # at the end of the file. nuke the top entry and generate an error token
-
- # Start nuking entries on the stack
- if lookahead.type == '$end':
- # Whoa. We're really hosed here. Bail out
- return
-
- if lookahead.type != 'error':
- sym = symstack[-1]
- if sym.type == 'error':
- # Hmmm. Error is on top of stack, we'll just nuke input
- # symbol and continue
- lookahead = None
- continue
-
- # Create the error symbol for the first time and make it the new lookahead symbol
- t = YaccSymbol()
- t.type = 'error'
-
- if hasattr(lookahead, 'lineno'):
- t.lineno = t.endlineno = lookahead.lineno
- if hasattr(lookahead, 'lexpos'):
- t.lexpos = t.endlexpos = lookahead.lexpos
- t.value = lookahead
- lookaheadstack.append(lookahead)
- lookahead = t
- else:
- sym = symstack.pop()
- statestack.pop()
- state = statestack[-1]
-
- continue
-
- # Call an error function here
- raise RuntimeError('yacc: internal parser error!!!\n')
-
- #--! parseopt-notrack-end
-
-# -----------------------------------------------------------------------------
-# === Grammar Representation ===
-#
-# The following functions, classes, and variables are used to represent and
-# manipulate the rules that make up a grammar.
-# -----------------------------------------------------------------------------
-
-# regex matching identifiers
-_is_identifier = re.compile(r'^[a-zA-Z0-9_-]+$')
-
-# -----------------------------------------------------------------------------
-# class Production:
-#
-# This class stores the raw information about a single production or grammar rule.
-# A grammar rule refers to a specification such as this:
-#
-# expr : expr PLUS term
-#
-# Here are the basic attributes defined on all productions
-#
-# name - Name of the production. For example 'expr'
-# prod - A list of symbols on the right side ['expr','PLUS','term']
-# prec - Production precedence level
-# number - Production number.
-# func - Function that executes on reduce
-# file - File where production function is defined
-# lineno - Line number where production function is defined
-#
-# The following attributes are defined or optional.
-#
-# len - Length of the production (number of symbols on right hand side)
-# usyms - Set of unique symbols found in the production
-# -----------------------------------------------------------------------------
-
-class Production(object):
- reduced = 0
- def __init__(self, number, name, prod, precedence=('right', 0), func=None, file='', line=0):
- self.name = name
- self.prod = tuple(prod)
- self.number = number
- self.func = func
- self.callable = None
- self.file = file
- self.line = line
- self.prec = precedence
-
- # Internal settings used during table construction
-
- self.len = len(self.prod) # Length of the production
-
- # Create a list of unique production symbols used in the production
- self.usyms = []
- for s in self.prod:
- if s not in self.usyms:
- self.usyms.append(s)
-
- # List of all LR items for the production
- self.lr_items = []
- self.lr_next = None
-
- # Create a string representation
- if self.prod:
- self.str = '%s -> %s' % (self.name, ' '.join(self.prod))
- else:
- self.str = '%s -> <empty>' % self.name
-
- def __str__(self):
- return self.str
-
- def __repr__(self):
- return 'Production(' + str(self) + ')'
-
- def __len__(self):
- return len(self.prod)
-
- def __nonzero__(self):
- return 1
-
- def __getitem__(self, index):
- return self.prod[index]
-
- # Return the nth lr_item from the production (or None if at the end)
- def lr_item(self, n):
- if n > len(self.prod):
- return None
- p = LRItem(self, n)
- # Precompute the list of productions immediately following.
- try:
- p.lr_after = Prodnames[p.prod[n+1]]
- except (IndexError, KeyError):
- p.lr_after = []
- try:
- p.lr_before = p.prod[n-1]
- except IndexError:
- p.lr_before = None
- return p
-
- # Bind the production function name to a callable
- def bind(self, pdict):
- if self.func:
- self.callable = pdict[self.func]
-
-# This class serves as a minimal standin for Production objects when
-# reading table data from files. It only contains information
-# actually used by the LR parsing engine, plus some additional
-# debugging information.
-class MiniProduction(object):
- def __init__(self, str, name, len, func, file, line):
- self.name = name
- self.len = len
- self.func = func
- self.callable = None
- self.file = file
- self.line = line
- self.str = str
-
- def __str__(self):
- return self.str
-
- def __repr__(self):
- return 'MiniProduction(%s)' % self.str
-
- # Bind the production function name to a callable
- def bind(self, pdict):
- if self.func:
- self.callable = pdict[self.func]
-
-
-# -----------------------------------------------------------------------------
-# class LRItem
-#
-# This class represents a specific stage of parsing a production rule. For
-# example:
-#
-# expr : expr . PLUS term
-#
-# In the above, the "." represents the current location of the parse. Here
-# basic attributes:
-#
-# name - Name of the production. For example 'expr'
-# prod - A list of symbols on the right side ['expr','.', 'PLUS','term']
-# number - Production number.
-#
-# lr_next Next LR item. Example, if we are ' expr -> expr . PLUS term'
-# then lr_next refers to 'expr -> expr PLUS . term'
-# lr_index - LR item index (location of the ".") in the prod list.
-# lookaheads - LALR lookahead symbols for this item
-# len - Length of the production (number of symbols on right hand side)
-# lr_after - List of all productions that immediately follow
-# lr_before - Grammar symbol immediately before
-# -----------------------------------------------------------------------------
-
-class LRItem(object):
- def __init__(self, p, n):
- self.name = p.name
- self.prod = list(p.prod)
- self.number = p.number
- self.lr_index = n
- self.lookaheads = {}
- self.prod.insert(n, '.')
- self.prod = tuple(self.prod)
- self.len = len(self.prod)
- self.usyms = p.usyms
-
- def __str__(self):
- if self.prod:
- s = '%s -> %s' % (self.name, ' '.join(self.prod))
- else:
- s = '%s -> <empty>' % self.name
- return s
-
- def __repr__(self):
- return 'LRItem(' + str(self) + ')'
-
-# -----------------------------------------------------------------------------
-# rightmost_terminal()
-#
-# Return the rightmost terminal from a list of symbols. Used in add_production()
-# -----------------------------------------------------------------------------
-def rightmost_terminal(symbols, terminals):
- i = len(symbols) - 1
- while i >= 0:
- if symbols[i] in terminals:
- return symbols[i]
- i -= 1
- return None
-
-# -----------------------------------------------------------------------------
-# === GRAMMAR CLASS ===
-#
-# The following class represents the contents of the specified grammar along
-# with various computed properties such as first sets, follow sets, LR items, etc.
-# This data is used for critical parts of the table generation process later.
-# -----------------------------------------------------------------------------
-
-class GrammarError(YaccError):
- pass
-
-class Grammar(object):
- def __init__(self, terminals):
- self.Productions = [None] # A list of all of the productions. The first
- # entry is always reserved for the purpose of
- # building an augmented grammar
-
- self.Prodnames = {} # A dictionary mapping the names of nonterminals to a list of all
- # productions of that nonterminal.
-
- self.Prodmap = {} # A dictionary that is only used to detect duplicate
- # productions.
-
- self.Terminals = {} # A dictionary mapping the names of terminal symbols to a
- # list of the rules where they are used.
-
- for term in terminals:
- self.Terminals[term] = []
-
- self.Terminals['error'] = []
-
- self.Nonterminals = {} # A dictionary mapping names of nonterminals to a list
- # of rule numbers where they are used.
-
- self.First = {} # A dictionary of precomputed FIRST(x) symbols
-
- self.Follow = {} # A dictionary of precomputed FOLLOW(x) symbols
-
- self.Precedence = {} # Precedence rules for each terminal. Contains tuples of the
- # form ('right',level) or ('nonassoc', level) or ('left',level)
-
- self.UsedPrecedence = set() # Precedence rules that were actually used by the grammer.
- # This is only used to provide error checking and to generate
- # a warning about unused precedence rules.
-
- self.Start = None # Starting symbol for the grammar
-
-
- def __len__(self):
- return len(self.Productions)
-
- def __getitem__(self, index):
- return self.Productions[index]
-
- # -----------------------------------------------------------------------------
- # set_precedence()
- #
- # Sets the precedence for a given terminal. assoc is the associativity such as
- # 'left','right', or 'nonassoc'. level is a numeric level.
- #
- # -----------------------------------------------------------------------------
-
- def set_precedence(self, term, assoc, level):
- assert self.Productions == [None], 'Must call set_precedence() before add_production()'
- if term in self.Precedence:
- raise GrammarError('Precedence already specified for terminal %r' % term)
- if assoc not in ['left', 'right', 'nonassoc']:
- raise GrammarError("Associativity must be one of 'left','right', or 'nonassoc'")
- self.Precedence[term] = (assoc, level)
-
- # -----------------------------------------------------------------------------
- # add_production()
- #
- # Given an action function, this function assembles a production rule and
- # computes its precedence level.
- #
- # The production rule is supplied as a list of symbols. For example,
- # a rule such as 'expr : expr PLUS term' has a production name of 'expr' and
- # symbols ['expr','PLUS','term'].
- #
- # Precedence is determined by the precedence of the right-most non-terminal
- # or the precedence of a terminal specified by %prec.
- #
- # A variety of error checks are performed to make sure production symbols
- # are valid and that %prec is used correctly.
- # -----------------------------------------------------------------------------
-
- def add_production(self, prodname, syms, func=None, file='', line=0):
-
- if prodname in self.Terminals:
- raise GrammarError('%s:%d: Illegal rule name %r. Already defined as a token' % (file, line, prodname))
- if prodname == 'error':
- raise GrammarError('%s:%d: Illegal rule name %r. error is a reserved word' % (file, line, prodname))
- if not _is_identifier.match(prodname):
- raise GrammarError('%s:%d: Illegal rule name %r' % (file, line, prodname))
-
- # Look for literal tokens
- for n, s in enumerate(syms):
- if s[0] in "'\"":
- try:
- c = eval(s)
- if (len(c) > 1):
- raise GrammarError('%s:%d: Literal token %s in rule %r may only be a single character' %
- (file, line, s, prodname))
- if c not in self.Terminals:
- self.Terminals[c] = []
- syms[n] = c
- continue
- except SyntaxError:
- pass
- if not _is_identifier.match(s) and s != '%prec':
- raise GrammarError('%s:%d: Illegal name %r in rule %r' % (file, line, s, prodname))
-
- # Determine the precedence level
- if '%prec' in syms:
- if syms[-1] == '%prec':
- raise GrammarError('%s:%d: Syntax error. Nothing follows %%prec' % (file, line))
- if syms[-2] != '%prec':
- raise GrammarError('%s:%d: Syntax error. %%prec can only appear at the end of a grammar rule' %
- (file, line))
- precname = syms[-1]
- prodprec = self.Precedence.get(precname)
- if not prodprec:
- raise GrammarError('%s:%d: Nothing known about the precedence of %r' % (file, line, precname))
- else:
- self.UsedPrecedence.add(precname)
- del syms[-2:] # Drop %prec from the rule
- else:
- # If no %prec, precedence is determined by the rightmost terminal symbol
- precname = rightmost_terminal(syms, self.Terminals)
- prodprec = self.Precedence.get(precname, ('right', 0))
-
- # See if the rule is already in the rulemap
- map = '%s -> %s' % (prodname, syms)
- if map in self.Prodmap:
- m = self.Prodmap[map]
- raise GrammarError('%s:%d: Duplicate rule %s. ' % (file, line, m) +
- 'Previous definition at %s:%d' % (m.file, m.line))
-
- # From this point on, everything is valid. Create a new Production instance
- pnumber = len(self.Productions)
- if prodname not in self.Nonterminals:
- self.Nonterminals[prodname] = []
-
- # Add the production number to Terminals and Nonterminals
- for t in syms:
- if t in self.Terminals:
- self.Terminals[t].append(pnumber)
- else:
- if t not in self.Nonterminals:
- self.Nonterminals[t] = []
- self.Nonterminals[t].append(pnumber)
-
- # Create a production and add it to the list of productions
- p = Production(pnumber, prodname, syms, prodprec, func, file, line)
- self.Productions.append(p)
- self.Prodmap[map] = p
-
- # Add to the global productions list
- try:
- self.Prodnames[prodname].append(p)
- except KeyError:
- self.Prodnames[prodname] = [p]
-
- # -----------------------------------------------------------------------------
- # set_start()
- #
- # Sets the starting symbol and creates the augmented grammar. Production
- # rule 0 is S' -> start where start is the start symbol.
- # -----------------------------------------------------------------------------
-
- def set_start(self, start=None):
- if not start:
- start = self.Productions[1].name
- if start not in self.Nonterminals:
- raise GrammarError('start symbol %s undefined' % start)
- self.Productions[0] = Production(0, "S'", [start])
- self.Nonterminals[start].append(0)
- self.Start = start
-
- # -----------------------------------------------------------------------------
- # find_unreachable()
- #
- # Find all of the nonterminal symbols that can't be reached from the starting
- # symbol. Returns a list of nonterminals that can't be reached.
- # -----------------------------------------------------------------------------
-
- def find_unreachable(self):
-
- # Mark all symbols that are reachable from a symbol s
- def mark_reachable_from(s):
- if s in reachable:
- return
- reachable.add(s)
- for p in self.Prodnames.get(s, []):
- for r in p.prod:
- mark_reachable_from(r)
-
- reachable = set()
- mark_reachable_from(self.Productions[0].prod[0])
- return [s for s in self.Nonterminals if s not in reachable]
-
- # -----------------------------------------------------------------------------
- # infinite_cycles()
- #
- # This function looks at the various parsing rules and tries to detect
- # infinite recursion cycles (grammar rules where there is no possible way
- # to derive a string of only terminals).
- # -----------------------------------------------------------------------------
-
- def infinite_cycles(self):
- terminates = {}
-
- # Terminals:
- for t in self.Terminals:
- terminates[t] = True
-
- terminates['$end'] = True
-
- # Nonterminals:
-
- # Initialize to false:
- for n in self.Nonterminals:
- terminates[n] = False
-
- # Then propagate termination until no change:
- while True:
- some_change = False
- for (n, pl) in self.Prodnames.items():
- # Nonterminal n terminates iff any of its productions terminates.
- for p in pl:
- # Production p terminates iff all of its rhs symbols terminate.
- for s in p.prod:
- if not terminates[s]:
- # The symbol s does not terminate,
- # so production p does not terminate.
- p_terminates = False
- break
- else:
- # didn't break from the loop,
- # so every symbol s terminates
- # so production p terminates.
- p_terminates = True
-
- if p_terminates:
- # symbol n terminates!
- if not terminates[n]:
- terminates[n] = True
- some_change = True
- # Don't need to consider any more productions for this n.
- break
-
- if not some_change:
- break
-
- infinite = []
- for (s, term) in terminates.items():
- if not term:
- if s not in self.Prodnames and s not in self.Terminals and s != 'error':
- # s is used-but-not-defined, and we've already warned of that,
- # so it would be overkill to say that it's also non-terminating.
- pass
- else:
- infinite.append(s)
-
- return infinite
-
- # -----------------------------------------------------------------------------
- # undefined_symbols()
- #
- # Find all symbols that were used the grammar, but not defined as tokens or
- # grammar rules. Returns a list of tuples (sym, prod) where sym in the symbol
- # and prod is the production where the symbol was used.
- # -----------------------------------------------------------------------------
- def undefined_symbols(self):
- result = []
- for p in self.Productions:
- if not p:
- continue
-
- for s in p.prod:
- if s not in self.Prodnames and s not in self.Terminals and s != 'error':
- result.append((s, p))
- return result
-
- # -----------------------------------------------------------------------------
- # unused_terminals()
- #
- # Find all terminals that were defined, but not used by the grammar. Returns
- # a list of all symbols.
- # -----------------------------------------------------------------------------
- def unused_terminals(self):
- unused_tok = []
- for s, v in self.Terminals.items():
- if s != 'error' and not v:
- unused_tok.append(s)
-
- return unused_tok
-
- # ------------------------------------------------------------------------------
- # unused_rules()
- #
- # Find all grammar rules that were defined, but not used (maybe not reachable)
- # Returns a list of productions.
- # ------------------------------------------------------------------------------
-
- def unused_rules(self):
- unused_prod = []
- for s, v in self.Nonterminals.items():
- if not v:
- p = self.Prodnames[s][0]
- unused_prod.append(p)
- return unused_prod
-
- # -----------------------------------------------------------------------------
- # unused_precedence()
- #
- # Returns a list of tuples (term,precedence) corresponding to precedence
- # rules that were never used by the grammar. term is the name of the terminal
- # on which precedence was applied and precedence is a string such as 'left' or
- # 'right' corresponding to the type of precedence.
- # -----------------------------------------------------------------------------
-
- def unused_precedence(self):
- unused = []
- for termname in self.Precedence:
- if not (termname in self.Terminals or termname in self.UsedPrecedence):
- unused.append((termname, self.Precedence[termname][0]))
-
- return unused
-
- # -------------------------------------------------------------------------
- # _first()
- #
- # Compute the value of FIRST1(beta) where beta is a tuple of symbols.
- #
- # During execution of compute_first1, the result may be incomplete.
- # Afterward (e.g., when called from compute_follow()), it will be complete.
- # -------------------------------------------------------------------------
- def _first(self, beta):
-
- # We are computing First(x1,x2,x3,...,xn)
- result = []
- for x in beta:
- x_produces_empty = False
-
- # Add all the non-<empty> symbols of First[x] to the result.
- for f in self.First[x]:
- if f == '<empty>':
- x_produces_empty = True
- else:
- if f not in result:
- result.append(f)
-
- if x_produces_empty:
- # We have to consider the next x in beta,
- # i.e. stay in the loop.
- pass
- else:
- # We don't have to consider any further symbols in beta.
- break
- else:
- # There was no 'break' from the loop,
- # so x_produces_empty was true for all x in beta,
- # so beta produces empty as well.
- result.append('<empty>')
-
- return result
-
- # -------------------------------------------------------------------------
- # compute_first()
- #
- # Compute the value of FIRST1(X) for all symbols
- # -------------------------------------------------------------------------
- def compute_first(self):
- if self.First:
- return self.First
-
- # Terminals:
- for t in self.Terminals:
- self.First[t] = [t]
-
- self.First['$end'] = ['$end']
-
- # Nonterminals:
-
- # Initialize to the empty set:
- for n in self.Nonterminals:
- self.First[n] = []
-
- # Then propagate symbols until no change:
- while True:
- some_change = False
- for n in self.Nonterminals:
- for p in self.Prodnames[n]:
- for f in self._first(p.prod):
- if f not in self.First[n]:
- self.First[n].append(f)
- some_change = True
- if not some_change:
- break
-
- return self.First
-
- # ---------------------------------------------------------------------
- # compute_follow()
- #
- # Computes all of the follow sets for every non-terminal symbol. The
- # follow set is the set of all symbols that might follow a given
- # non-terminal. See the Dragon book, 2nd Ed. p. 189.
- # ---------------------------------------------------------------------
- def compute_follow(self, start=None):
- # If already computed, return the result
- if self.Follow:
- return self.Follow
-
- # If first sets not computed yet, do that first.
- if not self.First:
- self.compute_first()
-
- # Add '$end' to the follow list of the start symbol
- for k in self.Nonterminals:
- self.Follow[k] = []
-
- if not start:
- start = self.Productions[1].name
-
- self.Follow[start] = ['$end']
-
- while True:
- didadd = False
- for p in self.Productions[1:]:
- # Here is the production set
- for i, B in enumerate(p.prod):
- if B in self.Nonterminals:
- # Okay. We got a non-terminal in a production
- fst = self._first(p.prod[i+1:])
- hasempty = False
- for f in fst:
- if f != '<empty>' and f not in self.Follow[B]:
- self.Follow[B].append(f)
- didadd = True
- if f == '<empty>':
- hasempty = True
- if hasempty or i == (len(p.prod)-1):
- # Add elements of follow(a) to follow(b)
- for f in self.Follow[p.name]:
- if f not in self.Follow[B]:
- self.Follow[B].append(f)
- didadd = True
- if not didadd:
- break
- return self.Follow
-
-
- # -----------------------------------------------------------------------------
- # build_lritems()
- #
- # This function walks the list of productions and builds a complete set of the
- # LR items. The LR items are stored in two ways: First, they are uniquely
- # numbered and placed in the list _lritems. Second, a linked list of LR items
- # is built for each production. For example:
- #
- # E -> E PLUS E
- #
- # Creates the list
- #
- # [E -> . E PLUS E, E -> E . PLUS E, E -> E PLUS . E, E -> E PLUS E . ]
- # -----------------------------------------------------------------------------
-
- def build_lritems(self):
- for p in self.Productions:
- lastlri = p
- i = 0
- lr_items = []
- while True:
- if i > len(p):
- lri = None
- else:
- lri = LRItem(p, i)
- # Precompute the list of productions immediately following
- try:
- lri.lr_after = self.Prodnames[lri.prod[i+1]]
- except (IndexError, KeyError):
- lri.lr_after = []
- try:
- lri.lr_before = lri.prod[i-1]
- except IndexError:
- lri.lr_before = None
-
- lastlri.lr_next = lri
- if not lri:
- break
- lr_items.append(lri)
- lastlri = lri
- i += 1
- p.lr_items = lr_items
-
-# -----------------------------------------------------------------------------
-# == Class LRTable ==
-#
-# This basic class represents a basic table of LR parsing information.
-# Methods for generating the tables are not defined here. They are defined
-# in the derived class LRGeneratedTable.
-# -----------------------------------------------------------------------------
-
-class VersionError(YaccError):
- pass
-
-class LRTable(object):
- def __init__(self):
- self.lr_action = None
- self.lr_goto = None
- self.lr_productions = None
- self.lr_method = None
-
- def read_table(self, module):
- if isinstance(module, types.ModuleType):
- parsetab = module
- else:
- exec('import %s' % module)
- parsetab = sys.modules[module]
-
- if parsetab._tabversion != __tabversion__:
- raise VersionError('yacc table file version is out of date')
-
- self.lr_action = parsetab._lr_action
- self.lr_goto = parsetab._lr_goto
-
- self.lr_productions = []
- for p in parsetab._lr_productions:
- self.lr_productions.append(MiniProduction(*p))
-
- self.lr_method = parsetab._lr_method
- return parsetab._lr_signature
-
- def read_pickle(self, filename):
- try:
- import cPickle as pickle
- except ImportError:
- import pickle
-
- if not os.path.exists(filename):
- raise ImportError
-
- in_f = open(filename, 'rb')
-
- tabversion = pickle.load(in_f)
- if tabversion != __tabversion__:
- raise VersionError('yacc table file version is out of date')
- self.lr_method = pickle.load(in_f)
- signature = pickle.load(in_f)
- self.lr_action = pickle.load(in_f)
- self.lr_goto = pickle.load(in_f)
- productions = pickle.load(in_f)
-
- self.lr_productions = []
- for p in productions:
- self.lr_productions.append(MiniProduction(*p))
-
- in_f.close()
- return signature
-
- # Bind all production function names to callable objects in pdict
- def bind_callables(self, pdict):
- for p in self.lr_productions:
- p.bind(pdict)
-
-
-# -----------------------------------------------------------------------------
-# === LR Generator ===
-#
-# The following classes and functions are used to generate LR parsing tables on
-# a grammar.
-# -----------------------------------------------------------------------------
-
-# -----------------------------------------------------------------------------
-# digraph()
-# traverse()
-#
-# The following two functions are used to compute set valued functions
-# of the form:
-#
-# F(x) = F'(x) U U{F(y) | x R y}
-#
-# This is used to compute the values of Read() sets as well as FOLLOW sets
-# in LALR(1) generation.
-#
-# Inputs: X - An input set
-# R - A relation
-# FP - Set-valued function
-# ------------------------------------------------------------------------------
-
-def digraph(X, R, FP):
- N = {}
- for x in X:
- N[x] = 0
- stack = []
- F = {}
- for x in X:
- if N[x] == 0:
- traverse(x, N, stack, F, X, R, FP)
- return F
-
-def traverse(x, N, stack, F, X, R, FP):
- stack.append(x)
- d = len(stack)
- N[x] = d
- F[x] = FP(x) # F(X) <- F'(x)
-
- rel = R(x) # Get y's related to x
- for y in rel:
- if N[y] == 0:
- traverse(y, N, stack, F, X, R, FP)
- N[x] = min(N[x], N[y])
- for a in F.get(y, []):
- if a not in F[x]:
- F[x].append(a)
- if N[x] == d:
- N[stack[-1]] = MAXINT
- F[stack[-1]] = F[x]
- element = stack.pop()
- while element != x:
- N[stack[-1]] = MAXINT
- F[stack[-1]] = F[x]
- element = stack.pop()
-
-class LALRError(YaccError):
- pass
-
-# -----------------------------------------------------------------------------
-# == LRGeneratedTable ==
-#
-# This class implements the LR table generation algorithm. There are no
-# public methods except for write()
-# -----------------------------------------------------------------------------
-
-class LRGeneratedTable(LRTable):
- def __init__(self, grammar, method='LALR', log=None):
- if method not in ['SLR', 'LALR']:
- raise LALRError('Unsupported method %s' % method)
-
- self.grammar = grammar
- self.lr_method = method
-
- # Set up the logger
- if not log:
- log = NullLogger()
- self.log = log
-
- # Internal attributes
- self.lr_action = {} # Action table
- self.lr_goto = {} # Goto table
- self.lr_productions = grammar.Productions # Copy of grammar Production array
- self.lr_goto_cache = {} # Cache of computed gotos
- self.lr0_cidhash = {} # Cache of closures
-
- self._add_count = 0 # Internal counter used to detect cycles
-
- # Diagonistic information filled in by the table generator
- self.sr_conflict = 0
- self.rr_conflict = 0
- self.conflicts = [] # List of conflicts
-
- self.sr_conflicts = []
- self.rr_conflicts = []
-
- # Build the tables
- self.grammar.build_lritems()
- self.grammar.compute_first()
- self.grammar.compute_follow()
- self.lr_parse_table()
-
- # Compute the LR(0) closure operation on I, where I is a set of LR(0) items.
-
- def lr0_closure(self, I):
- self._add_count += 1
-
- # Add everything in I to J
- J = I[:]
- didadd = True
- while didadd:
- didadd = False
- for j in J:
- for x in j.lr_after:
- if getattr(x, 'lr0_added', 0) == self._add_count:
- continue
- # Add B --> .G to J
- J.append(x.lr_next)
- x.lr0_added = self._add_count
- didadd = True
-
- return J
-
- # Compute the LR(0) goto function goto(I,X) where I is a set
- # of LR(0) items and X is a grammar symbol. This function is written
- # in a way that guarantees uniqueness of the generated goto sets
- # (i.e. the same goto set will never be returned as two different Python
- # objects). With uniqueness, we can later do fast set comparisons using
- # id(obj) instead of element-wise comparison.
-
- def lr0_goto(self, I, x):
- # First we look for a previously cached entry
- g = self.lr_goto_cache.get((id(I), x))
- if g:
- return g
-
- # Now we generate the goto set in a way that guarantees uniqueness
- # of the result
-
- s = self.lr_goto_cache.get(x)
- if not s:
- s = {}
- self.lr_goto_cache[x] = s
-
- gs = []
- for p in I:
- n = p.lr_next
- if n and n.lr_before == x:
- s1 = s.get(id(n))
- if not s1:
- s1 = {}
- s[id(n)] = s1
- gs.append(n)
- s = s1
- g = s.get('$end')
- if not g:
- if gs:
- g = self.lr0_closure(gs)
- s['$end'] = g
- else:
- s['$end'] = gs
- self.lr_goto_cache[(id(I), x)] = g
- return g
-
- # Compute the LR(0) sets of item function
- def lr0_items(self):
- C = [self.lr0_closure([self.grammar.Productions[0].lr_next])]
- i = 0
- for I in C:
- self.lr0_cidhash[id(I)] = i
- i += 1
-
- # Loop over the items in C and each grammar symbols
- i = 0
- while i < len(C):
- I = C[i]
- i += 1
-
- # Collect all of the symbols that could possibly be in the goto(I,X) sets
- asyms = {}
- for ii in I:
- for s in ii.usyms:
- asyms[s] = None
-
- for x in asyms:
- g = self.lr0_goto(I, x)
- if not g or id(g) in self.lr0_cidhash:
- continue
- self.lr0_cidhash[id(g)] = len(C)
- C.append(g)
-
- return C
-
- # -----------------------------------------------------------------------------
- # ==== LALR(1) Parsing ====
- #
- # LALR(1) parsing is almost exactly the same as SLR except that instead of
- # relying upon Follow() sets when performing reductions, a more selective
- # lookahead set that incorporates the state of the LR(0) machine is utilized.
- # Thus, we mainly just have to focus on calculating the lookahead sets.
- #
- # The method used here is due to DeRemer and Pennelo (1982).
- #
- # DeRemer, F. L., and T. J. Pennelo: "Efficient Computation of LALR(1)
- # Lookahead Sets", ACM Transactions on Programming Languages and Systems,
- # Vol. 4, No. 4, Oct. 1982, pp. 615-649
- #
- # Further details can also be found in:
- #
- # J. Tremblay and P. Sorenson, "The Theory and Practice of Compiler Writing",
- # McGraw-Hill Book Company, (1985).
- #
- # -----------------------------------------------------------------------------
-
- # -----------------------------------------------------------------------------
- # compute_nullable_nonterminals()
- #
- # Creates a dictionary containing all of the non-terminals that might produce
- # an empty production.
- # -----------------------------------------------------------------------------
-
- def compute_nullable_nonterminals(self):
- nullable = set()
- num_nullable = 0
- while True:
- for p in self.grammar.Productions[1:]:
- if p.len == 0:
- nullable.add(p.name)
- continue
- for t in p.prod:
- if t not in nullable:
- break
- else:
- nullable.add(p.name)
- if len(nullable) == num_nullable:
- break
- num_nullable = len(nullable)
- return nullable
-
- # -----------------------------------------------------------------------------
- # find_nonterminal_trans(C)
- #
- # Given a set of LR(0) items, this functions finds all of the non-terminal
- # transitions. These are transitions in which a dot appears immediately before
- # a non-terminal. Returns a list of tuples of the form (state,N) where state
- # is the state number and N is the nonterminal symbol.
- #
- # The input C is the set of LR(0) items.
- # -----------------------------------------------------------------------------
-
- def find_nonterminal_transitions(self, C):
- trans = []
- for stateno, state in enumerate(C):
- for p in state:
- if p.lr_index < p.len - 1:
- t = (stateno, p.prod[p.lr_index+1])
- if t[1] in self.grammar.Nonterminals:
- if t not in trans:
- trans.append(t)
- return trans
-
- # -----------------------------------------------------------------------------
- # dr_relation()
- #
- # Computes the DR(p,A) relationships for non-terminal transitions. The input
- # is a tuple (state,N) where state is a number and N is a nonterminal symbol.
- #
- # Returns a list of terminals.
- # -----------------------------------------------------------------------------
-
- def dr_relation(self, C, trans, nullable):
- dr_set = {}
- state, N = trans
- terms = []
-
- g = self.lr0_goto(C[state], N)
- for p in g:
- if p.lr_index < p.len - 1:
- a = p.prod[p.lr_index+1]
- if a in self.grammar.Terminals:
- if a not in terms:
- terms.append(a)
-
- # This extra bit is to handle the start state
- if state == 0 and N == self.grammar.Productions[0].prod[0]:
- terms.append('$end')
-
- return terms
-
- # -----------------------------------------------------------------------------
- # reads_relation()
- #
- # Computes the READS() relation (p,A) READS (t,C).
- # -----------------------------------------------------------------------------
-
- def reads_relation(self, C, trans, empty):
- # Look for empty transitions
- rel = []
- state, N = trans
-
- g = self.lr0_goto(C[state], N)
- j = self.lr0_cidhash.get(id(g), -1)
- for p in g:
- if p.lr_index < p.len - 1:
- a = p.prod[p.lr_index + 1]
- if a in empty:
- rel.append((j, a))
-
- return rel
-
- # -----------------------------------------------------------------------------
- # compute_lookback_includes()
- #
- # Determines the lookback and includes relations
- #
- # LOOKBACK:
- #
- # This relation is determined by running the LR(0) state machine forward.
- # For example, starting with a production "N : . A B C", we run it forward
- # to obtain "N : A B C ." We then build a relationship between this final
- # state and the starting state. These relationships are stored in a dictionary
- # lookdict.
- #
- # INCLUDES:
- #
- # Computes the INCLUDE() relation (p,A) INCLUDES (p',B).
- #
- # This relation is used to determine non-terminal transitions that occur
- # inside of other non-terminal transition states. (p,A) INCLUDES (p', B)
- # if the following holds:
- #
- # B -> LAT, where T -> epsilon and p' -L-> p
- #
- # L is essentially a prefix (which may be empty), T is a suffix that must be
- # able to derive an empty string. State p' must lead to state p with the string L.
- #
- # -----------------------------------------------------------------------------
-
- def compute_lookback_includes(self, C, trans, nullable):
- lookdict = {} # Dictionary of lookback relations
- includedict = {} # Dictionary of include relations
-
- # Make a dictionary of non-terminal transitions
- dtrans = {}
- for t in trans:
- dtrans[t] = 1
-
- # Loop over all transitions and compute lookbacks and includes
- for state, N in trans:
- lookb = []
- includes = []
- for p in C[state]:
- if p.name != N:
- continue
-
- # Okay, we have a name match. We now follow the production all the way
- # through the state machine until we get the . on the right hand side
-
- lr_index = p.lr_index
- j = state
- while lr_index < p.len - 1:
- lr_index = lr_index + 1
- t = p.prod[lr_index]
-
- # Check to see if this symbol and state are a non-terminal transition
- if (j, t) in dtrans:
- # Yes. Okay, there is some chance that this is an includes relation
- # the only way to know for certain is whether the rest of the
- # production derives empty
-
- li = lr_index + 1
- while li < p.len:
- if p.prod[li] in self.grammar.Terminals:
- break # No forget it
- if p.prod[li] not in nullable:
- break
- li = li + 1
- else:
- # Appears to be a relation between (j,t) and (state,N)
- includes.append((j, t))
-
- g = self.lr0_goto(C[j], t) # Go to next set
- j = self.lr0_cidhash.get(id(g), -1) # Go to next state
-
- # When we get here, j is the final state, now we have to locate the production
- for r in C[j]:
- if r.name != p.name:
- continue
- if r.len != p.len:
- continue
- i = 0
- # This look is comparing a production ". A B C" with "A B C ."
- while i < r.lr_index:
- if r.prod[i] != p.prod[i+1]:
- break
- i = i + 1
- else:
- lookb.append((j, r))
- for i in includes:
- if i not in includedict:
- includedict[i] = []
- includedict[i].append((state, N))
- lookdict[(state, N)] = lookb
-
- return lookdict, includedict
-
- # -----------------------------------------------------------------------------
- # compute_read_sets()
- #
- # Given a set of LR(0) items, this function computes the read sets.
- #
- # Inputs: C = Set of LR(0) items
- # ntrans = Set of nonterminal transitions
- # nullable = Set of empty transitions
- #
- # Returns a set containing the read sets
- # -----------------------------------------------------------------------------
-
- def compute_read_sets(self, C, ntrans, nullable):
- FP = lambda x: self.dr_relation(C, x, nullable)
- R = lambda x: self.reads_relation(C, x, nullable)
- F = digraph(ntrans, R, FP)
- return F
-
- # -----------------------------------------------------------------------------
- # compute_follow_sets()
- #
- # Given a set of LR(0) items, a set of non-terminal transitions, a readset,
- # and an include set, this function computes the follow sets
- #
- # Follow(p,A) = Read(p,A) U U {Follow(p',B) | (p,A) INCLUDES (p',B)}
- #
- # Inputs:
- # ntrans = Set of nonterminal transitions
- # readsets = Readset (previously computed)
- # inclsets = Include sets (previously computed)
- #
- # Returns a set containing the follow sets
- # -----------------------------------------------------------------------------
-
- def compute_follow_sets(self, ntrans, readsets, inclsets):
- FP = lambda x: readsets[x]
- R = lambda x: inclsets.get(x, [])
- F = digraph(ntrans, R, FP)
- return F
-
- # -----------------------------------------------------------------------------
- # add_lookaheads()
- #
- # Attaches the lookahead symbols to grammar rules.
- #
- # Inputs: lookbacks - Set of lookback relations
- # followset - Computed follow set
- #
- # This function directly attaches the lookaheads to productions contained
- # in the lookbacks set
- # -----------------------------------------------------------------------------
-
- def add_lookaheads(self, lookbacks, followset):
- for trans, lb in lookbacks.items():
- # Loop over productions in lookback
- for state, p in lb:
- if state not in p.lookaheads:
- p.lookaheads[state] = []
- f = followset.get(trans, [])
- for a in f:
- if a not in p.lookaheads[state]:
- p.lookaheads[state].append(a)
-
- # -----------------------------------------------------------------------------
- # add_lalr_lookaheads()
- #
- # This function does all of the work of adding lookahead information for use
- # with LALR parsing
- # -----------------------------------------------------------------------------
-
- def add_lalr_lookaheads(self, C):
- # Determine all of the nullable nonterminals
- nullable = self.compute_nullable_nonterminals()
-
- # Find all non-terminal transitions
- trans = self.find_nonterminal_transitions(C)
-
- # Compute read sets
- readsets = self.compute_read_sets(C, trans, nullable)
-
- # Compute lookback/includes relations
- lookd, included = self.compute_lookback_includes(C, trans, nullable)
-
- # Compute LALR FOLLOW sets
- followsets = self.compute_follow_sets(trans, readsets, included)
-
- # Add all of the lookaheads
- self.add_lookaheads(lookd, followsets)
-
- # -----------------------------------------------------------------------------
- # lr_parse_table()
- #
- # This function constructs the parse tables for SLR or LALR
- # -----------------------------------------------------------------------------
- def lr_parse_table(self):
- Productions = self.grammar.Productions
- Precedence = self.grammar.Precedence
- goto = self.lr_goto # Goto array
- action = self.lr_action # Action array
- log = self.log # Logger for output
-
- actionp = {} # Action production array (temporary)
-
- log.info('Parsing method: %s', self.lr_method)
-
- # Step 1: Construct C = { I0, I1, ... IN}, collection of LR(0) items
- # This determines the number of states
-
- C = self.lr0_items()
-
- if self.lr_method == 'LALR':
- self.add_lalr_lookaheads(C)
-
- # Build the parser table, state by state
- st = 0
- for I in C:
- # Loop over each production in I
- actlist = [] # List of actions
- st_action = {}
- st_actionp = {}
- st_goto = {}
- log.info('')
- log.info('state %d', st)
- log.info('')
- for p in I:
- log.info(' (%d) %s', p.number, p)
- log.info('')
-
- for p in I:
- if p.len == p.lr_index + 1:
- if p.name == "S'":
- # Start symbol. Accept!
- st_action['$end'] = 0
- st_actionp['$end'] = p
- else:
- # We are at the end of a production. Reduce!
- if self.lr_method == 'LALR':
- laheads = p.lookaheads[st]
- else:
- laheads = self.grammar.Follow[p.name]
- for a in laheads:
- actlist.append((a, p, 'reduce using rule %d (%s)' % (p.number, p)))
- r = st_action.get(a)
- if r is not None:
- # Whoa. Have a shift/reduce or reduce/reduce conflict
- if r > 0:
- # Need to decide on shift or reduce here
- # By default we favor shifting. Need to add
- # some precedence rules here.
-
- # Shift precedence comes from the token
- sprec, slevel = Precedence.get(a, ('right', 0))
-
- # Reduce precedence comes from rule being reduced (p)
- rprec, rlevel = Productions[p.number].prec
-
- if (slevel < rlevel) or ((slevel == rlevel) and (rprec == 'left')):
- # We really need to reduce here.
- st_action[a] = -p.number
- st_actionp[a] = p
- if not slevel and not rlevel:
- log.info(' ! shift/reduce conflict for %s resolved as reduce', a)
- self.sr_conflicts.append((st, a, 'reduce'))
- Productions[p.number].reduced += 1
- elif (slevel == rlevel) and (rprec == 'nonassoc'):
- st_action[a] = None
- else:
- # Hmmm. Guess we'll keep the shift
- if not rlevel:
- log.info(' ! shift/reduce conflict for %s resolved as shift', a)
- self.sr_conflicts.append((st, a, 'shift'))
- elif r < 0:
- # Reduce/reduce conflict. In this case, we favor the rule
- # that was defined first in the grammar file
- oldp = Productions[-r]
- pp = Productions[p.number]
- if oldp.line > pp.line:
- st_action[a] = -p.number
- st_actionp[a] = p
- chosenp, rejectp = pp, oldp
- Productions[p.number].reduced += 1
- Productions[oldp.number].reduced -= 1
- else:
- chosenp, rejectp = oldp, pp
- self.rr_conflicts.append((st, chosenp, rejectp))
- log.info(' ! reduce/reduce conflict for %s resolved using rule %d (%s)',
- a, st_actionp[a].number, st_actionp[a])
- else:
- raise LALRError('Unknown conflict in state %d' % st)
- else:
- st_action[a] = -p.number
- st_actionp[a] = p
- Productions[p.number].reduced += 1
- else:
- i = p.lr_index
- a = p.prod[i+1] # Get symbol right after the "."
- if a in self.grammar.Terminals:
- g = self.lr0_goto(I, a)
- j = self.lr0_cidhash.get(id(g), -1)
- if j >= 0:
- # We are in a shift state
- actlist.append((a, p, 'shift and go to state %d' % j))
- r = st_action.get(a)
- if r is not None:
- # Whoa have a shift/reduce or shift/shift conflict
- if r > 0:
- if r != j:
- raise LALRError('Shift/shift conflict in state %d' % st)
- elif r < 0:
- # Do a precedence check.
- # - if precedence of reduce rule is higher, we reduce.
- # - if precedence of reduce is same and left assoc, we reduce.
- # - otherwise we shift
-
- # Shift precedence comes from the token
- sprec, slevel = Precedence.get(a, ('right', 0))
-
- # Reduce precedence comes from the rule that could have been reduced
- rprec, rlevel = Productions[st_actionp[a].number].prec
-
- if (slevel > rlevel) or ((slevel == rlevel) and (rprec == 'right')):
- # We decide to shift here... highest precedence to shift
- Productions[st_actionp[a].number].reduced -= 1
- st_action[a] = j
- st_actionp[a] = p
- if not rlevel:
- log.info(' ! shift/reduce conflict for %s resolved as shift', a)
- self.sr_conflicts.append((st, a, 'shift'))
- elif (slevel == rlevel) and (rprec == 'nonassoc'):
- st_action[a] = None
- else:
- # Hmmm. Guess we'll keep the reduce
- if not slevel and not rlevel:
- log.info(' ! shift/reduce conflict for %s resolved as reduce', a)
- self.sr_conflicts.append((st, a, 'reduce'))
-
- else:
- raise LALRError('Unknown conflict in state %d' % st)
- else:
- st_action[a] = j
- st_actionp[a] = p
-
- # Print the actions associated with each terminal
- _actprint = {}
- for a, p, m in actlist:
- if a in st_action:
- if p is st_actionp[a]:
- log.info(' %-15s %s', a, m)
- _actprint[(a, m)] = 1
- log.info('')
- # Print the actions that were not used. (debugging)
- not_used = 0
- for a, p, m in actlist:
- if a in st_action:
- if p is not st_actionp[a]:
- if not (a, m) in _actprint:
- log.debug(' ! %-15s [ %s ]', a, m)
- not_used = 1
- _actprint[(a, m)] = 1
- if not_used:
- log.debug('')
-
- # Construct the goto table for this state
-
- nkeys = {}
- for ii in I:
- for s in ii.usyms:
- if s in self.grammar.Nonterminals:
- nkeys[s] = None
- for n in nkeys:
- g = self.lr0_goto(I, n)
- j = self.lr0_cidhash.get(id(g), -1)
- if j >= 0:
- st_goto[n] = j
- log.info(' %-30s shift and go to state %d', n, j)
-
- action[st] = st_action
- actionp[st] = st_actionp
- goto[st] = st_goto
- st += 1
-
- # -----------------------------------------------------------------------------
- # write()
- #
- # This function writes the LR parsing tables to a file
- # -----------------------------------------------------------------------------
-
- def write_table(self, tabmodule, outputdir='', signature=''):
- if isinstance(tabmodule, types.ModuleType):
- raise IOError("Won't overwrite existing tabmodule")
-
- basemodulename = tabmodule.split('.')[-1]
- filename = os.path.join(outputdir, basemodulename) + '.py'
- try:
- f = open(filename, 'w')
-
- f.write('''
-# %s
-# This file is automatically generated. Do not edit.
-_tabversion = %r
-
-_lr_method = %r
-
-_lr_signature = %r
- ''' % (os.path.basename(filename), __tabversion__, self.lr_method, signature))
-
- # Change smaller to 0 to go back to original tables
- smaller = 1
-
- # Factor out names to try and make smaller
- if smaller:
- items = {}
-
- for s, nd in self.lr_action.items():
- for name, v in nd.items():
- i = items.get(name)
- if not i:
- i = ([], [])
- items[name] = i
- i[0].append(s)
- i[1].append(v)
-
- f.write('\n_lr_action_items = {')
- for k, v in items.items():
- f.write('%r:([' % k)
- for i in v[0]:
- f.write('%r,' % i)
- f.write('],[')
- for i in v[1]:
- f.write('%r,' % i)
-
- f.write(']),')
- f.write('}\n')
-
- f.write('''
-_lr_action = {}
-for _k, _v in _lr_action_items.items():
- for _x,_y in zip(_v[0],_v[1]):
- if not _x in _lr_action: _lr_action[_x] = {}
- _lr_action[_x][_k] = _y
-del _lr_action_items
-''')
-
- else:
- f.write('\n_lr_action = { ')
- for k, v in self.lr_action.items():
- f.write('(%r,%r):%r,' % (k[0], k[1], v))
- f.write('}\n')
-
- if smaller:
- # Factor out names to try and make smaller
- items = {}
-
- for s, nd in self.lr_goto.items():
- for name, v in nd.items():
- i = items.get(name)
- if not i:
- i = ([], [])
- items[name] = i
- i[0].append(s)
- i[1].append(v)
-
- f.write('\n_lr_goto_items = {')
- for k, v in items.items():
- f.write('%r:([' % k)
- for i in v[0]:
- f.write('%r,' % i)
- f.write('],[')
- for i in v[1]:
- f.write('%r,' % i)
-
- f.write(']),')
- f.write('}\n')
-
- f.write('''
-_lr_goto = {}
-for _k, _v in _lr_goto_items.items():
- for _x, _y in zip(_v[0], _v[1]):
- if not _x in _lr_goto: _lr_goto[_x] = {}
- _lr_goto[_x][_k] = _y
-del _lr_goto_items
-''')
- else:
- f.write('\n_lr_goto = { ')
- for k, v in self.lr_goto.items():
- f.write('(%r,%r):%r,' % (k[0], k[1], v))
- f.write('}\n')
-
- # Write production table
- f.write('_lr_productions = [\n')
- for p in self.lr_productions:
- if p.func:
- f.write(' (%r,%r,%d,%r,%r,%d),\n' % (p.str, p.name, p.len,
- p.func, os.path.basename(p.file), p.line))
- else:
- f.write(' (%r,%r,%d,None,None,None),\n' % (str(p), p.name, p.len))
- f.write(']\n')
- f.close()
-
- except IOError as e:
- raise
-
-
- # -----------------------------------------------------------------------------
- # pickle_table()
- #
- # This function pickles the LR parsing tables to a supplied file object
- # -----------------------------------------------------------------------------
-
- def pickle_table(self, filename, signature=''):
- try:
- import cPickle as pickle
- except ImportError:
- import pickle
- with open(filename, 'wb') as outf:
- pickle.dump(__tabversion__, outf, pickle_protocol)
- pickle.dump(self.lr_method, outf, pickle_protocol)
- pickle.dump(signature, outf, pickle_protocol)
- pickle.dump(self.lr_action, outf, pickle_protocol)
- pickle.dump(self.lr_goto, outf, pickle_protocol)
-
- outp = []
- for p in self.lr_productions:
- if p.func:
- outp.append((p.str, p.name, p.len, p.func, os.path.basename(p.file), p.line))
- else:
- outp.append((str(p), p.name, p.len, None, None, None))
- pickle.dump(outp, outf, pickle_protocol)
-
-# -----------------------------------------------------------------------------
-# === INTROSPECTION ===
-#
-# The following functions and classes are used to implement the PLY
-# introspection features followed by the yacc() function itself.
-# -----------------------------------------------------------------------------
-
-# -----------------------------------------------------------------------------
-# get_caller_module_dict()
-#
-# This function returns a dictionary containing all of the symbols defined within
-# a caller further down the call stack. This is used to get the environment
-# associated with the yacc() call if none was provided.
-# -----------------------------------------------------------------------------
-
-def get_caller_module_dict(levels):
- f = sys._getframe(levels)
- ldict = f.f_globals.copy()
- if f.f_globals != f.f_locals:
- ldict.update(f.f_locals)
- return ldict
-
-# -----------------------------------------------------------------------------
-# parse_grammar()
-#
-# This takes a raw grammar rule string and parses it into production data
-# -----------------------------------------------------------------------------
-def parse_grammar(doc, file, line):
- grammar = []
- # Split the doc string into lines
- pstrings = doc.splitlines()
- lastp = None
- dline = line
- for ps in pstrings:
- dline += 1
- p = ps.split()
- if not p:
- continue
- try:
- if p[0] == '|':
- # This is a continuation of a previous rule
- if not lastp:
- raise SyntaxError("%s:%d: Misplaced '|'" % (file, dline))
- prodname = lastp
- syms = p[1:]
- else:
- prodname = p[0]
- lastp = prodname
- syms = p[2:]
- assign = p[1]
- if assign != ':' and assign != '::=':
- raise SyntaxError("%s:%d: Syntax error. Expected ':'" % (file, dline))
-
- grammar.append((file, dline, prodname, syms))
- except SyntaxError:
- raise
- except Exception:
- raise SyntaxError('%s:%d: Syntax error in rule %r' % (file, dline, ps.strip()))
-
- return grammar
-
-# -----------------------------------------------------------------------------
-# ParserReflect()
-#
-# This class represents information extracted for building a parser including
-# start symbol, error function, tokens, precedence list, action functions,
-# etc.
-# -----------------------------------------------------------------------------
-class ParserReflect(object):
- def __init__(self, pdict, log=None):
- self.pdict = pdict
- self.start = None
- self.error_func = None
- self.tokens = None
- self.modules = set()
- self.grammar = []
- self.error = False
-
- if log is None:
- self.log = PlyLogger(sys.stderr)
- else:
- self.log = log
-
- # Get all of the basic information
- def get_all(self):
- self.get_start()
- self.get_error_func()
- self.get_tokens()
- self.get_precedence()
- self.get_pfunctions()
-
- # Validate all of the information
- def validate_all(self):
- self.validate_start()
- self.validate_error_func()
- self.validate_tokens()
- self.validate_precedence()
- self.validate_pfunctions()
- self.validate_modules()
- return self.error
-
- # Compute a signature over the grammar
- def signature(self):
- parts = []
- try:
- if self.start:
- parts.append(self.start)
- if self.prec:
- parts.append(''.join([''.join(p) for p in self.prec]))
- if self.tokens:
- parts.append(' '.join(self.tokens))
- for f in self.pfuncs:
- if f[3]:
- parts.append(f[3])
- except (TypeError, ValueError):
- pass
- return ''.join(parts)
-
- # -----------------------------------------------------------------------------
- # validate_modules()
- #
- # This method checks to see if there are duplicated p_rulename() functions
- # in the parser module file. Without this function, it is really easy for
- # users to make mistakes by cutting and pasting code fragments (and it's a real
- # bugger to try and figure out why the resulting parser doesn't work). Therefore,
- # we just do a little regular expression pattern matching of def statements
- # to try and detect duplicates.
- # -----------------------------------------------------------------------------
-
- def validate_modules(self):
- # Match def p_funcname(
- fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(')
-
- for module in self.modules:
- try:
- lines, linen = inspect.getsourcelines(module)
- except IOError:
- continue
-
- counthash = {}
- for linen, line in enumerate(lines):
- linen += 1
- m = fre.match(line)
- if m:
- name = m.group(1)
- prev = counthash.get(name)
- if not prev:
- counthash[name] = linen
- else:
- filename = inspect.getsourcefile(module)
- self.log.warning('%s:%d: Function %s redefined. Previously defined on line %d',
- filename, linen, name, prev)
-
- # Get the start symbol
- def get_start(self):
- self.start = self.pdict.get('start')
-
- # Validate the start symbol
- def validate_start(self):
- if self.start is not None:
- if not isinstance(self.start, string_types):
- self.log.error("'start' must be a string")
-
- # Look for error handler
- def get_error_func(self):
- self.error_func = self.pdict.get('p_error')
-
- # Validate the error function
- def validate_error_func(self):
- if self.error_func:
- if isinstance(self.error_func, types.FunctionType):
- ismethod = 0
- elif isinstance(self.error_func, types.MethodType):
- ismethod = 1
- else:
- self.log.error("'p_error' defined, but is not a function or method")
- self.error = True
- return
-
- eline = self.error_func.__code__.co_firstlineno
- efile = self.error_func.__code__.co_filename
- module = inspect.getmodule(self.error_func)
- self.modules.add(module)
-
- argcount = self.error_func.__code__.co_argcount - ismethod
- if argcount != 1:
- self.log.error('%s:%d: p_error() requires 1 argument', efile, eline)
- self.error = True
-
- # Get the tokens map
- def get_tokens(self):
- tokens = self.pdict.get('tokens')
- if not tokens:
- self.log.error('No token list is defined')
- self.error = True
- return
-
- if not isinstance(tokens, (list, tuple)):
- self.log.error('tokens must be a list or tuple')
- self.error = True
- return
-
- if not tokens:
- self.log.error('tokens is empty')
- self.error = True
- return
-
- self.tokens = tokens
-
- # Validate the tokens
- def validate_tokens(self):
- # Validate the tokens.
- if 'error' in self.tokens:
- self.log.error("Illegal token name 'error'. Is a reserved word")
- self.error = True
- return
-
- terminals = set()
- for n in self.tokens:
- if n in terminals:
- self.log.warning('Token %r multiply defined', n)
- terminals.add(n)
-
- # Get the precedence map (if any)
- def get_precedence(self):
- self.prec = self.pdict.get('precedence')
-
- # Validate and parse the precedence map
- def validate_precedence(self):
- preclist = []
- if self.prec:
- if not isinstance(self.prec, (list, tuple)):
- self.log.error('precedence must be a list or tuple')
- self.error = True
- return
- for level, p in enumerate(self.prec):
- if not isinstance(p, (list, tuple)):
- self.log.error('Bad precedence table')
- self.error = True
- return
-
- if len(p) < 2:
- self.log.error('Malformed precedence entry %s. Must be (assoc, term, ..., term)', p)
- self.error = True
- return
- assoc = p[0]
- if not isinstance(assoc, string_types):
- self.log.error('precedence associativity must be a string')
- self.error = True
- return
- for term in p[1:]:
- if not isinstance(term, string_types):
- self.log.error('precedence items must be strings')
- self.error = True
- return
- preclist.append((term, assoc, level+1))
- self.preclist = preclist
-
- # Get all p_functions from the grammar
- def get_pfunctions(self):
- p_functions = []
- for name, item in self.pdict.items():
- if not name.startswith('p_') or name == 'p_error':
- continue
- if isinstance(item, (types.FunctionType, types.MethodType)):
- line = getattr(item, 'co_firstlineno', item.__code__.co_firstlineno)
- module = inspect.getmodule(item)
- p_functions.append((line, module, name, item.__doc__))
-
- # Sort all of the actions by line number; make sure to stringify
- # modules to make them sortable, since `line` may not uniquely sort all
- # p functions
- p_functions.sort(key=lambda p_function: (
- p_function[0],
- str(p_function[1]),
- p_function[2],
- p_function[3]))
- self.pfuncs = p_functions
-
- # Validate all of the p_functions
- def validate_pfunctions(self):
- grammar = []
- # Check for non-empty symbols
- if len(self.pfuncs) == 0:
- self.log.error('no rules of the form p_rulename are defined')
- self.error = True
- return
-
- for line, module, name, doc in self.pfuncs:
- file = inspect.getsourcefile(module)
- func = self.pdict[name]
- if isinstance(func, types.MethodType):
- reqargs = 2
- else:
- reqargs = 1
- if func.__code__.co_argcount > reqargs:
- self.log.error('%s:%d: Rule %r has too many arguments', file, line, func.__name__)
- self.error = True
- elif func.__code__.co_argcount < reqargs:
- self.log.error('%s:%d: Rule %r requires an argument', file, line, func.__name__)
- self.error = True
- elif not func.__doc__:
- self.log.warning('%s:%d: No documentation string specified in function %r (ignored)',
- file, line, func.__name__)
- else:
- try:
- parsed_g = parse_grammar(doc, file, line)
- for g in parsed_g:
- grammar.append((name, g))
- except SyntaxError as e:
- self.log.error(str(e))
- self.error = True
-
- # Looks like a valid grammar rule
- # Mark the file in which defined.
- self.modules.add(module)
-
- # Secondary validation step that looks for p_ definitions that are not functions
- # or functions that look like they might be grammar rules.
-
- for n, v in self.pdict.items():
- if n.startswith('p_') and isinstance(v, (types.FunctionType, types.MethodType)):
- continue
- if n.startswith('t_'):
- continue
- if n.startswith('p_') and n != 'p_error':
- self.log.warning('%r not defined as a function', n)
- if ((isinstance(v, types.FunctionType) and v.__code__.co_argcount == 1) or
- (isinstance(v, types.MethodType) and v.__func__.__code__.co_argcount == 2)):
- if v.__doc__:
- try:
- doc = v.__doc__.split(' ')
- if doc[1] == ':':
- self.log.warning('%s:%d: Possible grammar rule %r defined without p_ prefix',
- v.__code__.co_filename, v.__code__.co_firstlineno, n)
- except IndexError:
- pass
-
- self.grammar = grammar
-
-# -----------------------------------------------------------------------------
-# yacc(module)
-#
-# Build a parser
-# -----------------------------------------------------------------------------
-
-def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None,
- check_recursion=True, optimize=False, write_tables=True, debugfile=debug_file,
- outputdir=None, debuglog=None, errorlog=None, picklefile=None):
-
- if tabmodule is None:
- tabmodule = tab_module
-
- # Reference to the parsing method of the last built parser
- global parse
-
- # If pickling is enabled, table files are not created
- if picklefile:
- write_tables = 0
-
- if errorlog is None:
- errorlog = PlyLogger(sys.stderr)
-
- # Get the module dictionary used for the parser
- if module:
- _items = [(k, getattr(module, k)) for k in dir(module)]
- pdict = dict(_items)
- # If no __file__ attribute is available, try to obtain it from the __module__ instead
- if '__file__' not in pdict:
- pdict['__file__'] = sys.modules[pdict['__module__']].__file__
- else:
- pdict = get_caller_module_dict(2)
-
- if outputdir is None:
- # If no output directory is set, the location of the output files
- # is determined according to the following rules:
- # - If tabmodule specifies a package, files go into that package directory
- # - Otherwise, files go in the same directory as the specifying module
- if isinstance(tabmodule, types.ModuleType):
- srcfile = tabmodule.__file__
- else:
- if '.' not in tabmodule:
- srcfile = pdict['__file__']
- else:
- parts = tabmodule.split('.')
- pkgname = '.'.join(parts[:-1])
- exec('import %s' % pkgname)
- srcfile = getattr(sys.modules[pkgname], '__file__', '')
- outputdir = os.path.dirname(srcfile)
-
- # Determine if the module is package of a package or not.
- # If so, fix the tabmodule setting so that tables load correctly
- pkg = pdict.get('__package__')
- if pkg and isinstance(tabmodule, str):
- if '.' not in tabmodule:
- tabmodule = pkg + '.' + tabmodule
-
-
-
- # Set start symbol if it's specified directly using an argument
- if start is not None:
- pdict['start'] = start
-
- # Collect parser information from the dictionary
- pinfo = ParserReflect(pdict, log=errorlog)
- pinfo.get_all()
-
- if pinfo.error:
- raise YaccError('Unable to build parser')
-
- # Check signature against table files (if any)
- signature = pinfo.signature()
-
- # Read the tables
- try:
- lr = LRTable()
- if picklefile:
- read_signature = lr.read_pickle(picklefile)
- else:
- read_signature = lr.read_table(tabmodule)
- if optimize or (read_signature == signature):
- try:
- lr.bind_callables(pinfo.pdict)
- parser = LRParser(lr, pinfo.error_func)
- parse = parser.parse
- return parser
- except Exception as e:
- errorlog.warning('There was a problem loading the table file: %r', e)
- except VersionError as e:
- errorlog.warning(str(e))
- except ImportError:
- pass
-
- if debuglog is None:
- if debug:
- try:
- debuglog = PlyLogger(open(os.path.join(outputdir, debugfile), 'w'))
- except IOError as e:
- errorlog.warning("Couldn't open %r. %s" % (debugfile, e))
- debuglog = NullLogger()
- else:
- debuglog = NullLogger()
-
- debuglog.info('Created by PLY version %s (http://www.dabeaz.com/ply)', __version__)
-
- errors = False
-
- # Validate the parser information
- if pinfo.validate_all():
- raise YaccError('Unable to build parser')
-
- if not pinfo.error_func:
- errorlog.warning('no p_error() function is defined')
-
- # Create a grammar object
- grammar = Grammar(pinfo.tokens)
-
- # Set precedence level for terminals
- for term, assoc, level in pinfo.preclist:
- try:
- grammar.set_precedence(term, assoc, level)
- except GrammarError as e:
- errorlog.warning('%s', e)
-
- # Add productions to the grammar
- for funcname, gram in pinfo.grammar:
- file, line, prodname, syms = gram
- try:
- grammar.add_production(prodname, syms, funcname, file, line)
- except GrammarError as e:
- errorlog.error('%s', e)
- errors = True
-
- # Set the grammar start symbols
- try:
- if start is None:
- grammar.set_start(pinfo.start)
- else:
- grammar.set_start(start)
- except GrammarError as e:
- errorlog.error(str(e))
- errors = True
-
- if errors:
- raise YaccError('Unable to build parser')
-
- # Verify the grammar structure
- undefined_symbols = grammar.undefined_symbols()
- for sym, prod in undefined_symbols:
- errorlog.error('%s:%d: Symbol %r used, but not defined as a token or a rule', prod.file, prod.line, sym)
- errors = True
-
- unused_terminals = grammar.unused_terminals()
- if unused_terminals:
- debuglog.info('')
- debuglog.info('Unused terminals:')
- debuglog.info('')
- for term in unused_terminals:
- errorlog.warning('Token %r defined, but not used', term)
- debuglog.info(' %s', term)
-
- # Print out all productions to the debug log
- if debug:
- debuglog.info('')
- debuglog.info('Grammar')
- debuglog.info('')
- for n, p in enumerate(grammar.Productions):
- debuglog.info('Rule %-5d %s', n, p)
-
- # Find unused non-terminals
- unused_rules = grammar.unused_rules()
- for prod in unused_rules:
- errorlog.warning('%s:%d: Rule %r defined, but not used', prod.file, prod.line, prod.name)
-
- if len(unused_terminals) == 1:
- errorlog.warning('There is 1 unused token')
- if len(unused_terminals) > 1:
- errorlog.warning('There are %d unused tokens', len(unused_terminals))
-
- if len(unused_rules) == 1:
- errorlog.warning('There is 1 unused rule')
- if len(unused_rules) > 1:
- errorlog.warning('There are %d unused rules', len(unused_rules))
-
- if debug:
- debuglog.info('')
- debuglog.info('Terminals, with rules where they appear')
- debuglog.info('')
- terms = list(grammar.Terminals)
- terms.sort()
- for term in terms:
- debuglog.info('%-20s : %s', term, ' '.join([str(s) for s in grammar.Terminals[term]]))
-
- debuglog.info('')
- debuglog.info('Nonterminals, with rules where they appear')
- debuglog.info('')
- nonterms = list(grammar.Nonterminals)
- nonterms.sort()
- for nonterm in nonterms:
- debuglog.info('%-20s : %s', nonterm, ' '.join([str(s) for s in grammar.Nonterminals[nonterm]]))
- debuglog.info('')
-
- if check_recursion:
- unreachable = grammar.find_unreachable()
- for u in unreachable:
- errorlog.warning('Symbol %r is unreachable', u)
-
- infinite = grammar.infinite_cycles()
- for inf in infinite:
- errorlog.error('Infinite recursion detected for symbol %r', inf)
- errors = True
-
- unused_prec = grammar.unused_precedence()
- for term, assoc in unused_prec:
- errorlog.error('Precedence rule %r defined for unknown symbol %r', assoc, term)
- errors = True
-
- if errors:
- raise YaccError('Unable to build parser')
-
- # Run the LRGeneratedTable on the grammar
- if debug:
- errorlog.debug('Generating %s tables', method)
-
- lr = LRGeneratedTable(grammar, method, debuglog)
-
- if debug:
- num_sr = len(lr.sr_conflicts)
-
- # Report shift/reduce and reduce/reduce conflicts
- if num_sr == 1:
- errorlog.warning('1 shift/reduce conflict')
- elif num_sr > 1:
- errorlog.warning('%d shift/reduce conflicts', num_sr)
-
- num_rr = len(lr.rr_conflicts)
- if num_rr == 1:
- errorlog.warning('1 reduce/reduce conflict')
- elif num_rr > 1:
- errorlog.warning('%d reduce/reduce conflicts', num_rr)
-
- # Write out conflicts to the output file
- if debug and (lr.sr_conflicts or lr.rr_conflicts):
- debuglog.warning('')
- debuglog.warning('Conflicts:')
- debuglog.warning('')
-
- for state, tok, resolution in lr.sr_conflicts:
- debuglog.warning('shift/reduce conflict for %s in state %d resolved as %s', tok, state, resolution)
-
- already_reported = set()
- for state, rule, rejected in lr.rr_conflicts:
- if (state, id(rule), id(rejected)) in already_reported:
- continue
- debuglog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule)
- debuglog.warning('rejected rule (%s) in state %d', rejected, state)
- errorlog.warning('reduce/reduce conflict in state %d resolved using rule (%s)', state, rule)
- errorlog.warning('rejected rule (%s) in state %d', rejected, state)
- already_reported.add((state, id(rule), id(rejected)))
-
- warned_never = []
- for state, rule, rejected in lr.rr_conflicts:
- if not rejected.reduced and (rejected not in warned_never):
- debuglog.warning('Rule (%s) is never reduced', rejected)
- errorlog.warning('Rule (%s) is never reduced', rejected)
- warned_never.append(rejected)
-
- # Write the table file if requested
- if write_tables:
- try:
- lr.write_table(tabmodule, outputdir, signature)
- except IOError as e:
- errorlog.warning("Couldn't create %r. %s" % (tabmodule, e))
-
- # Write a pickled version of the tables
- if picklefile:
- try:
- lr.pickle_table(picklefile, signature)
- except IOError as e:
- errorlog.warning("Couldn't create %r. %s" % (picklefile, e))
-
- # Build the parser
- lr.bind_callables(pinfo.pdict)
- parser = LRParser(lr, pinfo.error_func)
-
- parse = parser.parse
- return parser
diff --git a/pycparser/ply/ygen.py b/pycparser/ply/ygen.py
deleted file mode 100644
index acf5ca1..0000000
--- a/pycparser/ply/ygen.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# ply: ygen.py
-#
-# This is a support program that auto-generates different versions of the YACC parsing
-# function with different features removed for the purposes of performance.
-#
-# Users should edit the method LParser.parsedebug() in yacc.py. The source code
-# for that method is then used to create the other methods. See the comments in
-# yacc.py for further details.
-
-import os.path
-import shutil
-
-def get_source_range(lines, tag):
- srclines = enumerate(lines)
- start_tag = '#--! %s-start' % tag
- end_tag = '#--! %s-end' % tag
-
- for start_index, line in srclines:
- if line.strip().startswith(start_tag):
- break
-
- for end_index, line in srclines:
- if line.strip().endswith(end_tag):
- break
-
- return (start_index + 1, end_index)
-
-def filter_section(lines, tag):
- filtered_lines = []
- include = True
- tag_text = '#--! %s' % tag
- for line in lines:
- if line.strip().startswith(tag_text):
- include = not include
- elif include:
- filtered_lines.append(line)
- return filtered_lines
-
-def main():
- dirname = os.path.dirname(__file__)
- shutil.copy2(os.path.join(dirname, 'yacc.py'), os.path.join(dirname, 'yacc.py.bak'))
- with open(os.path.join(dirname, 'yacc.py'), 'r') as f:
- lines = f.readlines()
-
- parse_start, parse_end = get_source_range(lines, 'parsedebug')
- parseopt_start, parseopt_end = get_source_range(lines, 'parseopt')
- parseopt_notrack_start, parseopt_notrack_end = get_source_range(lines, 'parseopt-notrack')
-
- # Get the original source
- orig_lines = lines[parse_start:parse_end]
-
- # Filter the DEBUG sections out
- parseopt_lines = filter_section(orig_lines, 'DEBUG')
-
- # Filter the TRACKING sections out
- parseopt_notrack_lines = filter_section(parseopt_lines, 'TRACKING')
-
- # Replace the parser source sections with updated versions
- lines[parseopt_notrack_start:parseopt_notrack_end] = parseopt_notrack_lines
- lines[parseopt_start:parseopt_end] = parseopt_lines
-
- lines = [line.rstrip()+'\n' for line in lines]
- with open(os.path.join(dirname, 'yacc.py'), 'w') as f:
- f.writelines(lines)
-
- print('Updated yacc.py')
-
-if __name__ == '__main__':
- main()
-
-
-
-
-
diff --git a/pycparser/plyparser.py b/pycparser/plyparser.py
deleted file mode 100644
index 6222c0e..0000000
--- a/pycparser/plyparser.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#-----------------------------------------------------------------
-# plyparser.py
-#
-# PLYParser class and other utilites for simplifying programming
-# parsers with PLY
-#
-# Eli Bendersky [https://eli.thegreenplace.net/]
-# License: BSD
-#-----------------------------------------------------------------
-
-import warnings
-
-class Coord(object):
- """ Coordinates of a syntactic element. Consists of:
- - File name
- - Line number
- - (optional) column number, for the Lexer
- """
- __slots__ = ('file', 'line', 'column', '__weakref__')
- def __init__(self, file, line, column=None):
- self.file = file
- self.line = line
- self.column = column
-
- def __str__(self):
- str = "%s:%s" % (self.file, self.line)
- if self.column: str += ":%s" % self.column
- return str
-
-
-class ParseError(Exception): pass
-
-
-class PLYParser(object):
- def _create_opt_rule(self, rulename):
- """ Given a rule name, creates an optional ply.yacc rule
- for it. The name of the optional rule is
- <rulename>_opt
- """
- optname = rulename + '_opt'
-
- def optrule(self, p):
- p[0] = p[1]
-
- optrule.__doc__ = '%s : empty\n| %s' % (optname, rulename)
- optrule.__name__ = 'p_%s' % optname
- setattr(self.__class__, optrule.__name__, optrule)
-
- def _coord(self, lineno, column=None):
- return Coord(
- file=self.clex.filename,
- line=lineno,
- column=column)
-
- def _token_coord(self, p, token_idx):
- """ Returns the coordinates for the YaccProduction objet 'p' indexed
- with 'token_idx'. The coordinate includes the 'lineno' and
- 'column'. Both follow the lex semantic, starting from 1.
- """
- last_cr = p.lexer.lexer.lexdata.rfind('\n', 0, p.lexpos(token_idx))
- if last_cr < 0:
- last_cr = -1
- column = (p.lexpos(token_idx) - (last_cr))
- return self._coord(p.lineno(token_idx), column)
-
- def _parse_error(self, msg, coord):
- raise ParseError("%s: %s" % (coord, msg))
-
-
-def parameterized(*params):
- """ Decorator to create parameterized rules.
-
- Parameterized rule methods must be named starting with 'p_' and contain
- 'xxx', and their docstrings may contain 'xxx' and 'yyy'. These will be
- replaced by the given parameter tuples. For example, ``p_xxx_rule()`` with
- docstring 'xxx_rule : yyy' when decorated with
- ``@parameterized(('id', 'ID'))`` produces ``p_id_rule()`` with the docstring
- 'id_rule : ID'. Using multiple tuples produces multiple rules.
- """
- def decorate(rule_func):
- rule_func._params = params
- return rule_func
- return decorate
-
-
-def template(cls):
- """ Class decorator to generate rules from parameterized rule templates.
-
- See `parameterized` for more information on parameterized rules.
- """
- issued_nodoc_warning = False
- for attr_name in dir(cls):
- if attr_name.startswith('p_'):
- method = getattr(cls, attr_name)
- if hasattr(method, '_params'):
- # Remove the template method
- delattr(cls, attr_name)
- # Create parameterized rules from this method; only run this if
- # the method has a docstring. This is to address an issue when
- # pycparser's users are installed in -OO mode which strips
- # docstrings away.
- # See: https://github.com/eliben/pycparser/pull/198/ and
- # https://github.com/eliben/pycparser/issues/197
- # for discussion.
- if method.__doc__ is not None:
- _create_param_rules(cls, method)
- elif not issued_nodoc_warning:
- warnings.warn(
- 'parsing methods must have __doc__ for pycparser to work properly',
- RuntimeWarning,
- stacklevel=2)
- issued_nodoc_warning = True
- return cls
-
-
-def _create_param_rules(cls, func):
- """ Create ply.yacc rules based on a parameterized rule function
-
- Generates new methods (one per each pair of parameters) based on the
- template rule function `func`, and attaches them to `cls`. The rule
- function's parameters must be accessible via its `_params` attribute.
- """
- for xxx, yyy in func._params:
- # Use the template method's body for each new method
- def param_rule(self, p):
- func(self, p)
-
- # Substitute in the params for the grammar rule and function name
- param_rule.__doc__ = func.__doc__.replace('xxx', xxx).replace('yyy', yyy)
- param_rule.__name__ = func.__name__.replace('xxx', xxx)
-
- # Attach the new method to the class
- setattr(cls, param_rule.__name__, param_rule)
diff --git a/setup.cfg b/setup.cfg
deleted file mode 100644
index ed8a958..0000000
--- a/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[bdist_wheel]
-universal = 1
-
-[metadata]
-license_file = LICENSE
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 62eddc2..0000000
--- a/setup.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import os, sys
-try:
- from setuptools import setup
- from setuptools.command.install import install as _install
- from setuptools.command.sdist import sdist as _sdist
-except ImportError:
- from distutils.core import setup
- from distutils.command.install import install as _install
- from distutils.command.sdist import sdist as _sdist
-
-
-def _run_build_tables(dir):
- from subprocess import check_call
- # This is run inside the install staging directory (that had no .pyc files)
- # We don't want to generate any.
- # https://github.com/eliben/pycparser/pull/135
- check_call([sys.executable, '-B', '_build_tables.py'],
- cwd=os.path.join(dir, 'pycparser'))
-
-
-class install(_install):
- def run(self):
- _install.run(self)
- self.execute(_run_build_tables, (self.install_lib,),
- msg="Build the lexing/parsing tables")
-
-
-class sdist(_sdist):
- def make_release_tree(self, basedir, files):
- _sdist.make_release_tree(self, basedir, files)
- self.execute(_run_build_tables, (basedir,),
- msg="Build the lexing/parsing tables")
-
-
-setup(
- # metadata
- name='pycparser',
- description='C parser in Python',
- long_description="""
- pycparser is a complete parser of the C language, written in
- pure Python using the PLY parsing library.
- It parses C code into an AST and can serve as a front-end for
- C compilers or analysis tools.
- """,
- license='BSD',
- version='2.19',
- author='Eli Bendersky',
- maintainer='Eli Bendersky',
- author_email='eliben@gmail.com',
- url='https://github.com/eliben/pycparser',
- platforms='Cross Platform',
- classifiers = [
- 'Development Status :: 5 - Production/Stable',
- 'License :: OSI Approved :: BSD License',
- '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',
- ],
- python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
- packages=['pycparser', 'pycparser.ply'],
- package_data={'pycparser': ['*.cfg']},
- cmdclass={'install': install, 'sdist': sdist},
-)
diff --git a/tests/README.txt b/tests/README.txt
deleted file mode 100644
index 5196024..0000000
--- a/tests/README.txt
+++ /dev/null
@@ -1 +0,0 @@
-Run 'python tests/all_tests.py' from the root pycparser directory
diff --git a/tests/all_tests.py b/tests/all_tests.py
deleted file mode 100755
index 74761b6..0000000
--- a/tests/all_tests.py
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-import sys
-sys.path[0:0] = ['.', '..']
-
-import unittest
-
-
-suite = unittest.TestLoader().loadTestsFromNames(
- [
- 'test_c_lexer',
- 'test_c_ast',
- 'test_general',
- 'test_c_parser',
- 'test_c_generator',
- ]
-)
-
-testresult = unittest.TextTestRunner(verbosity=1).run(suite)
-sys.exit(0 if testresult.wasSuccessful() else 1)
diff --git a/tests/c_files/cppd_with_stdio_h.c b/tests/c_files/cppd_with_stdio_h.c
deleted file mode 100644
index ab1426a..0000000
--- a/tests/c_files/cppd_with_stdio_h.c
+++ /dev/null
@@ -1,5038 +0,0 @@
-#line 1 "example_c_file.c"
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-#line 19 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-#line 25 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-#line 11 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/newlib.h"
-
-#line 3 "D:\eli\cpp_stuff\libc_include/newlib.h"
-#line 16 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-
-
-
-#line 52 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-
-
-#line 58 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 83 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-#line 86 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-#line 89 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-
-#line 95 "D:\eli\cpp_stuff\libc_include/machine/ieeefp.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 5 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-#line 11 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 143 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 157 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 195 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-#line 207 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-#line 17 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-#line 21 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 30 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 19 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 26 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 30 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 35 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 39 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 42 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-#line 53 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 56 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-#line 67 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-#line 76 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 98 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-#line 108 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 126 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-#line 131 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 170 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef long unsigned int size_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 243 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 246 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 290 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-#line 302 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-#line 310 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 361 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-#line 365 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 418 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 422 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-#line 427 "D:\eli\cpp_stuff\libc_include/stddef.h"
-#line 35 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-#line 19 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-#line 26 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-#line 30 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef char* __builtin_va_list;
-typedef __builtin_va_list __gnuc_va_list;
-
-
-
-#line 50 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-
-
-
-
-
-
-
-
-
-
-#line 66 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-
-
-
-
-
-
-
-
-
-#line 80 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 98 "D:\eli\cpp_stuff\libc_include/stdarg.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 38 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-#line 44 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-#line 6 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-#line 11 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-
-
-
-
-
-
-#line 21 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 14 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-
-#line 8 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/machine/_types.h"
-
-#line 4 "D:\eli\cpp_stuff\libc_include/machine/_types.h"
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/machine/_default_types.h"
-
-#line 4 "D:\eli\cpp_stuff\libc_include/machine/_default_types.h"
-
-
-
-
-
-
-
-
-
-#line 15 "D:\eli\cpp_stuff\libc_include/machine/_default_types.h"
-
-#line 17 "D:\eli\cpp_stuff\libc_include/machine/_default_types.h"
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/limits.h"
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/newlib.h"
-
-#line 3 "D:\eli\cpp_stuff\libc_include/newlib.h"
-#line 5 "D:\eli\cpp_stuff\libc_include/limits.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 19 "D:\eli\cpp_stuff\libc_include/limits.h"
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-#line 11 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 143 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 157 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 195 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-
-
-
-
-#line 207 "D:\eli\cpp_stuff\libc_include/sys/config.h"
-
-
-
-
-
-
-
-#line 25 "D:\eli\cpp_stuff\libc_include/limits.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 79 "D:\eli\cpp_stuff\libc_include/limits.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 23 "D:\eli\cpp_stuff\libc_include/machine/_default_types.h"
-
-
-
-typedef signed char __int8_t ;
-typedef unsigned char __uint8_t ;
-
-
-
-
-
-
-
-
-typedef signed short __int16_t;
-typedef unsigned short __uint16_t;
-
-
-
-
-
-
-
-
-typedef __int16_t __int_least16_t;
-typedef __uint16_t __uint_least16_t;
-
-
-
-
-
-
-
-
-
-
-typedef signed int __int32_t;
-typedef unsigned int __uint32_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef __int32_t __int_least32_t;
-typedef __uint32_t __uint_least32_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 8 "D:\eli\cpp_stuff\libc_include/machine/_types.h"
-
-#line 13 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/lock.h"
-
-
-
-
-
-typedef int _LOCK_T;
-typedef int _LOCK_RECURSIVE_T;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 14 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-typedef long _off_t;
-
-
-
-
-
-
-
-typedef short __dev_t;
-
-
-
-
-typedef unsigned short __uid_t;
-
-
-typedef unsigned short __gid_t;
-
-
-
- typedef long long _off64_t;
-
-
-
-#line 43 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-typedef long _fpos_t;
-
-
-
-
-
-
-
-
-
-
-
-typedef int _ssize_t;
-
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 19 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 26 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 30 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 35 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 39 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 42 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-#line 53 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 56 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-#line 67 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-#line 76 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 98 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-#line 108 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 126 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-#line 131 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 170 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 243 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 246 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 290 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-#line 302 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-#line 310 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef unsigned int wint_t;
-
-
-
-
-
-#line 361 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-#line 365 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 418 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 422 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-#line 427 "D:\eli\cpp_stuff\libc_include/stddef.h"
-#line 64 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-
-typedef struct
-{
- int __count;
- union
- {
- wint_t __wch;
- unsigned char __wchb[4];
- } __value;
-} _mbstate_t;
-
-
-
-typedef _LOCK_RECURSIVE_T _flock_t;
-
-
-
-
-typedef void *_iconv_t;
-
-
-
-#line 15 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-typedef unsigned long __ULong;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-struct _reent;
-
-
-#line 43 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-struct _Bigint
-{
- struct _Bigint *_next;
- int _k, _maxwds, _sign, _wds;
- __ULong _x[1];
-};
-
-
-struct __tm
-{
- int __tm_sec;
- int __tm_min;
- int __tm_hour;
- int __tm_mday;
- int __tm_mon;
- int __tm_year;
- int __tm_wday;
- int __tm_yday;
- int __tm_isdst;
-};
-
-
-#line 68 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-struct _on_exit_args {
- void * _fnargs[32];
- void * _dso_handle[32];
-
- __ULong _fntypes;
-#line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
- __ULong _is_cxa;
-};
-
-
-
-
-
-
-
-
-
-struct _atexit {
- struct _atexit *_next;
- int _ind;
-
- void (*_fns[32])(void);
- struct _on_exit_args _on_exit_args;
-};
-
-
-
-#line 104 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-struct __sbuf {
- unsigned char *_base;
- int _size;
-};
-
-
-#line 134 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-#line 141 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-struct __sFILE {
- unsigned char *_p;
- int _r;
- int _w;
- short _flags;
- short _file;
- struct __sbuf _bf;
- int _lbfsize;
-
-
-
-
-
-
- char * _cookie;
-
- int(*_read)();
-#line 176 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
- int(*_write)();
-#line 178 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
- _fpos_t(*_seek)();
- int(*_close)();
-
-
- struct __sbuf _ub;
- unsigned char *_up;
- int _ur;
-
-
- unsigned char _ubuf[3];
- unsigned char _nbuf[1];
-
-
- struct __sbuf _lb;
-
-
- int _blksize;
- int _offset;
-
-
- struct _reent *_data;
-
-
-
- _flock_t _lock;
-
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef struct __sFILE __FILE;
-
-
-
-struct _glue
-{
- struct _glue *_next;
- int _niobs;
- __FILE *_iobs;
-};
-
-
-#line 284 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-struct _rand48 {
- unsigned short _seed[3];
- unsigned short _mult[3];
- unsigned short _add;
-
-
-
-
-};
-
-
-
-
-
-
-
-#line 313 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 344 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-#line 350 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 420 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 452 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 474 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 478 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 482 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-#line 494 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-#line 496 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 503 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-#line 505 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 508 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 531 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-#line 533 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 536 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-struct _reent
-{
- int _errno;
-
-
-#line 571 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
- __FILE *_stdin, *_stdout, *_stderr;
-
- int _inc;
- char _emergency[25];
-
- int _current_category;
- char *_current_locale;
-
- int __sdidinit;
-
- void(*__cleanup)();
-
-
- struct _Bigint *_result;
- int _result_k;
- struct _Bigint *_p5s;
- struct _Bigint **_freelist;
-
-
- int _cvtlen;
- char *_cvtbuf;
-
- union
- {
- struct
- {
- unsigned int _unused_rand;
- char * _strtok_last;
- char _asctime_buf[26];
- struct __tm _localtime_buf;
- int _gamma_signgam;
- unsigned long long _rand_next;
- struct _rand48 _r48;
- _mbstate_t _mblen_state;
- _mbstate_t _mbtowc_state;
- _mbstate_t _wctomb_state;
- char _l64a_buf[8];
- char _signal_buf[24];
- int _getdate_err;
- _mbstate_t _mbrlen_state;
- _mbstate_t _mbrtowc_state;
- _mbstate_t _mbsrtowcs_state;
- _mbstate_t _wcrtomb_state;
- _mbstate_t _wcsrtombs_state;
- } _reent;
-
-#line 619 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
- struct
- {
-
- unsigned char * _nextf[30];
- unsigned int _nmalloc[30];
- } _unused;
- } _new;
-
-
- struct _atexit *_atexit;
- struct _atexit _atexit0;
-
-
- void (**(_sig_func))(int);
-
-
-#line 637 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
- struct _glue __sglue;
- __FILE __sf[3];
-};
-
-
-#line 689 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 751 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 791 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-extern struct _reent *_impure_ptr;
-extern struct _reent * _global_impure_ptr;
-
-void _reclaim_reent();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 46 "D:\eli\cpp_stuff\libc_include/stdio.h"
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-#line 17 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-#line 11 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-
-
-
-
-
-
-#line 21 "D:\eli\cpp_stuff\libc_include/_ansi.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 21 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/machine/_types.h"
-
-#line 4 "D:\eli\cpp_stuff\libc_include/machine/_types.h"
-
-
-
-
-
-#line 26 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-#line 33 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-
-#line 8 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 43 "D:\eli\cpp_stuff\libc_include/sys/_types.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 62 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 19 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 26 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 30 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 35 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 39 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 42 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-#line 53 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 56 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-#line 67 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-#line 76 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 98 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-#line 108 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 126 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-#line 131 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef long int ptrdiff_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 170 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 243 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-#line 246 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 290 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-#line 302 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-#line 310 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef int wchar_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 361 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-#line 365 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 418 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-#line 422 "D:\eli\cpp_stuff\libc_include/stddef.h"
-
-
-
-
-#line 427 "D:\eli\cpp_stuff\libc_include/stddef.h"
-#line 70 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-#line 1 "D:\eli\cpp_stuff\libc_include/machine/types.h"
-
-
-
-
-#line 9 "D:\eli\cpp_stuff\libc_include/machine/types.h"
-
-
-
-
-
-
-
-
-
-
-typedef long int __off_t;
-typedef int __pid_t;
-
-
-
-typedef long int __loff_t;
-
-
-
-
-
-
-#line 71 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-#line 79 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef unsigned char u_char;
-typedef unsigned short u_short;
-typedef unsigned int u_int;
-typedef unsigned long u_long;
-
-
-
-typedef unsigned short ushort;
-typedef unsigned int uint;
-
-
-
-typedef unsigned long clock_t;
-
-
-
-
-typedef long time_t;
-
-
-
-
-struct timespec {
- time_t tv_sec;
- long tv_nsec;
-};
-
-struct itimerspec {
- struct timespec it_interval;
- struct timespec it_value;
-};
-
-
-typedef long daddr_t;
-typedef char * caddr_t;
-
-
-
-#line 131 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-typedef unsigned short ino_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 160 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-typedef _off_t off_t;
-typedef __dev_t dev_t;
-typedef __uid_t uid_t;
-typedef __gid_t gid_t;
-
-
-typedef int pid_t;
-
-typedef long key_t;
-
-typedef _ssize_t ssize_t;
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef unsigned int mode_t;
-
-
-
-
-typedef unsigned short nlink_t;
-
-
-#line 200 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-#line 209 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-typedef long fd_mask;
-
-
-
-
-
-
-#line 221 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-typedef struct _types_fd_set {
- fd_mask fds_bits[(((64)+(((sizeof (fd_mask) * 8))-1))/((sizeof (fd_mask) * 8)))];
-} _types_fd_set;
-
-
-
-
-
-
-
-#line 236 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-
-
-
-
-typedef unsigned long clockid_t;
-
-
-
-
-typedef unsigned long timer_t;
-
-
-
-typedef unsigned long useconds_t;
-typedef long suseconds_t;
-
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/features.h"
-
-#line 20 "D:\eli\cpp_stuff\libc_include/sys/features.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 257 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-#line 266 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-
-#line 273 "D:\eli\cpp_stuff\libc_include/sys/types.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 47 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-typedef __FILE FILE;
-
-
-
-
-
-
-
-
-typedef _fpos_t fpos_t;
-
-
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/stdio.h"
-
-
-
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/lock.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 5 "D:\eli\cpp_stuff\libc_include/sys/stdio.h"
-#line 1 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-#line 6 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 43 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 68 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-#line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 104 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-#line 134 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-#line 141 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 284 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 313 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 344 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-#line 350 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 420 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 452 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 474 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 478 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 482 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-#line 494 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-#line 496 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 503 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-#line 505 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 508 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 531 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-#line 533 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 536 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 571 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 619 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 637 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-#line 689 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-#line 751 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 791 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 6 "D:\eli\cpp_stuff\libc_include/sys/stdio.h"
-
-
-#line 11 "D:\eli\cpp_stuff\libc_include/sys/stdio.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 66 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 96 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 163 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-FILE * tmpfile();
-char * tmpnam();
-int fclose();
-int fflush();
-FILE * freopen();
-void setbuf();
-int setvbuf();
-int fprintf();
-#line 179 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int fscanf();
-#line 181 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int printf();
-#line 183 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int scanf();
-#line 185 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int sscanf();
-#line 187 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vfprintf();
-#line 189 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vprintf();
-#line 191 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vsprintf();
-#line 193 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int fgetc();
-char * fgets();
-int fputc();
-int fputs();
-int getc();
-int getchar();
-char * gets();
-int putc();
-int putchar();
-int puts();
-int ungetc();
-size_t fread();
-size_t fwrite();
-
-
-
-int fgetpos();
-
-int fseek();
-
-
-
-int fsetpos();
-
-long ftell();
-void rewind();
-void clearerr();
-int feof();
-int ferror();
-void perror();
-
-FILE * fopen();
-int sprintf();
-#line 227 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int remove();
-int rename();
-
-
-
-
-
-
-int fseeko();
-off_t ftello();
-
-
-int asiprintf();
-#line 241 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * asniprintf();
-#line 243 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * asnprintf();
-#line 245 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int asprintf();
-#line 247 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-int diprintf();
-#line 250 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-int fcloseall();
-int fiprintf();
-#line 254 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int fiscanf();
-#line 256 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int iprintf();
-#line 258 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int iscanf();
-#line 260 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int siprintf();
-#line 262 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int siscanf();
-#line 264 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int snprintf();
-#line 266 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int sniprintf();
-#line 268 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * tempnam();
-int vasiprintf();
-#line 271 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * vasniprintf();
-#line 273 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * vasnprintf();
-#line 275 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vasprintf();
-#line 277 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vdiprintf();
-#line 279 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vfiprintf();
-#line 281 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vfiscanf();
-#line 283 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vfscanf();
-#line 285 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int viprintf();
-#line 287 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int viscanf();
-#line 289 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vscanf();
-#line 291 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vsiprintf();
-#line 293 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vsiscanf();
-#line 295 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vsniprintf();
-#line 297 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vsnprintf();
-#line 299 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int vsscanf();
-#line 301 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-#line 307 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-FILE * fdopen();
-
-int fileno();
-int getw();
-int pclose();
-FILE * popen();
-int putw();
-void setbuffer();
-int setlinebuf();
-int getc_unlocked();
-int getchar_unlocked();
-void flockfile();
-int ftrylockfile();
-void funlockfile();
-int putc_unlocked();
-int putchar_unlocked();
-
-
-
-#line 331 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-int dprintf();
-#line 337 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-FILE * fmemopen();
-
-
-FILE * open_memstream();
-
-int vdprintf();
-#line 345 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-#line 351 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-int _asiprintf_r();
-#line 354 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * _asniprintf_r();
-#line 356 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * _asnprintf_r();
-#line 358 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _asprintf_r();
-#line 360 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _diprintf_r();
-#line 362 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _dprintf_r();
-#line 364 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _fclose_r();
-int _fcloseall_r();
-FILE * _fdopen_r();
-int _fflush_r();
-char * _fgets_r();
-int _fiprintf_r();
-#line 371 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _fiscanf_r();
-#line 373 "D:\eli\cpp_stuff\libc_include/stdio.h"
-FILE * _fmemopen_r();
-FILE * _fopen_r();
-int _fprintf_r();
-#line 377 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _fputc_r();
-int _fputs_r();
-size_t _fread_r();
-int _fscanf_r();
-#line 382 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _fseek_r();
-long _ftell_r();
-size_t _fwrite_r();
-int _getc_r();
-int _getc_unlocked_r();
-int _getchar_r();
-int _getchar_unlocked_r();
-char * _gets_r();
-int _iprintf_r();
-#line 392 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _iscanf_r();
-#line 394 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _mkstemp_r();
-char * _mktemp_r();
-FILE * _open_memstream_r();
-void _perror_r();
-int _printf_r();
-#line 400 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _putc_r();
-int _putc_unlocked_r();
-int _putchar_unlocked_r();
-int _putchar_r();
-int _puts_r();
-int _remove_r();
-int _rename_r();
-#line 408 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _scanf_r();
-#line 410 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _siprintf_r();
-#line 412 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _siscanf_r();
-#line 414 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _sniprintf_r();
-#line 416 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _snprintf_r();
-#line 418 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _sprintf_r();
-#line 420 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _sscanf_r();
-#line 422 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * _tempnam_r();
-FILE * _tmpfile_r();
-char * _tmpnam_r();
-int _ungetc_r();
-int _vasiprintf_r();
-#line 428 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * _vasniprintf_r();
-#line 430 "D:\eli\cpp_stuff\libc_include/stdio.h"
-char * _vasnprintf_r();
-#line 432 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vasprintf_r();
-#line 434 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vdiprintf_r();
-#line 436 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vdprintf_r();
-#line 438 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vfiprintf_r();
-#line 440 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vfiscanf_r();
-#line 442 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vfprintf_r();
-#line 444 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vfscanf_r();
-#line 446 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _viprintf_r();
-#line 448 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _viscanf_r();
-#line 450 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vprintf_r();
-#line 452 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vscanf_r();
-#line 454 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vsiprintf_r();
-#line 456 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vsiscanf_r();
-#line 458 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vsniprintf_r();
-#line 460 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vsnprintf_r();
-#line 462 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vsprintf_r();
-#line 464 "D:\eli\cpp_stuff\libc_include/stdio.h"
-int _vsscanf_r();
-#line 466 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-ssize_t __getdelim();
-ssize_t __getline();
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 493 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-int __srget_r();
-int __swbuf_r();
-
-
-#line 500 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-
-FILE * funopen();
-#line 514 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-#line 518 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-#line 520 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-typedef ssize_t cookie_read_function_t(void *__cookie, char *__buf, size_t __n);
-typedef ssize_t cookie_write_function_t(void *__cookie, const char *__buf,
- size_t __n);
-
-
-
-
-typedef int cookie_seek_function_t(void *__cookie, off_t *__off, int __whence);
-
-typedef int cookie_close_function_t(void *__cookie);
-typedef struct
-{
-
-#line 535 "D:\eli\cpp_stuff\libc_include/stdio.h"
- cookie_read_function_t *read;
- cookie_write_function_t *write;
- cookie_seek_function_t *seek;
- cookie_close_function_t *close;
-} cookie_io_functions_t;
-FILE * fopencookie();
-#line 542 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-#line 549 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-#line 574 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-#line 580 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 603 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-#line 613 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-#line 621 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-#line 626 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 657 "D:\eli\cpp_stuff\libc_include/stdio.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#line 4 "example_c_file.c"
-
-#line 8 "example_c_file.c"
-
-char tav = 'b';
-char maav = L"'guruguru\n";
-char* moral = "ain't I \\\"\\\t\" a nice string?\"\"";
-char* comment_inside = "but you will /* see it */!!!!";
-char* i_have_newlines = "line one\nline two\nline three";
-
-int main()
-{
- auto char* multi = "a multi";
-}
-
-
-
-
-
diff --git a/tests/c_files/empty.h b/tests/c_files/empty.h
deleted file mode 100644
index 635750a..0000000
--- a/tests/c_files/empty.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#define PERFECTLY
-#define NORMAL
-#define TO
-#define HAVE
-#define HEADER
-#define WITH
-#define ONLY
-#define DEFINES
diff --git a/tests/c_files/example_c_file.c b/tests/c_files/example_c_file.c
deleted file mode 100644
index 17b2ac4..0000000
--- a/tests/c_files/example_c_file.c
+++ /dev/null
@@ -1,12 +0,0 @@
-char tav = 'b';
-char* moral = "ain't I \\\"\\\t\" a nice string?\"\"";
-char* comment_inside = "but you will /* see it */!!!!";
-char* i_have_newlines = "line one\nline two\nline three";
-
-int main()
-{
- auto char* multi = "a multi";
-}
-
-
-
diff --git a/tests/c_files/hdir/9/inc.h b/tests/c_files/hdir/9/inc.h
deleted file mode 100644
index 0c96cbd..0000000
--- a/tests/c_files/hdir/9/inc.h
+++ /dev/null
@@ -1 +0,0 @@
-extern int ie;
diff --git a/tests/c_files/memmgr.c b/tests/c_files/memmgr.c
deleted file mode 100644
index 6036ec6..0000000
--- a/tests/c_files/memmgr.c
+++ /dev/null
@@ -1,206 +0,0 @@
-//----------------------------------------------------------------
-// Statically-allocated memory manager
-//
-// by Eli Bendersky (eliben@gmail.com)
-//
-// This code is in the public domain.
-//----------------------------------------------------------------
-#include "memmgr.h"
-
-typedef ulong Align;
-
-union mem_header_union
-{
- struct
- {
- // Pointer to the next block in the free list
- //
- union mem_header_union* next;
-
- // Size of the block (in quantas of sizeof(mem_header_t))
- //
- ulong size;
- } s;
-
- // Used to align headers in memory to a boundary
- //
- Align align_dummy;
-};
-
-typedef union mem_header_union mem_header_t;
-
-// Initial empty list
-//
-static mem_header_t base;
-
-// Start of free list
-//
-static mem_header_t* freep = 0;
-
-// Static pool for new allocations
-//
-static byte pool[POOL_SIZE] = {0};
-static ulong pool_free_pos = 0;
-
-
-void memmgr_init()
-{
- base.s.next = 0;
- base.s.size = 0;
- freep = 0;
- pool_free_pos = 0;
-}
-
-
-static mem_header_t* get_mem_from_pool(ulong nquantas)
-{
- ulong total_req_size;
-
- mem_header_t* h;
-
- if (nquantas < MIN_POOL_ALLOC_QUANTAS)
- nquantas = MIN_POOL_ALLOC_QUANTAS;
-
- total_req_size = nquantas * sizeof(mem_header_t);
-
- if (pool_free_pos + total_req_size <= POOL_SIZE)
- {
- h = (mem_header_t*) (pool + pool_free_pos);
- h->s.size = nquantas;
- memmgr_free((void*) (h + 1));
- pool_free_pos += total_req_size;
- }
- else
- {
- return 0;
- }
-
- return freep;
-}
-
-
-// Allocations are done in 'quantas' of header size.
-// The search for a free block of adequate size begins at the point 'freep'
-// where the last block was found.
-// If a too-big block is found, it is split and the tail is returned (this
-// way the header of the original needs only to have its size adjusted).
-// The pointer returned to the user points to the free space within the block,
-// which begins one quanta after the header.
-//
-void* memmgr_alloc(ulong nbytes)
-{
- mem_header_t* p;
- mem_header_t* prevp;
-
- // Calculate how many quantas are required: we need enough to house all
- // the requested bytes, plus the header. The -1 and +1 are there to make sure
- // that if nbytes is a multiple of nquantas, we don't allocate too much
- //
- ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;
-
- // First alloc call, and no free list yet ? Use 'base' for an initial
- // denegerate block of size 0, which points to itself
- //
- if ((prevp = freep) == 0)
- {
- base.s.next = freep = prevp = &base;
- base.s.size = 0;
- }
-
- for (p = prevp->s.next; ; prevp = p, p = p->s.next)
- {
- // big enough ?
- if (p->s.size >= nquantas)
- {
- // exactly ?
- if (p->s.size == nquantas)
- {
- // just eliminate this block from the free list by pointing
- // its prev's next to its next
- //
- prevp->s.next = p->s.next;
- }
- else // too big
- {
- p->s.size -= nquantas;
- p += p->s.size;
- p->s.size = nquantas;
- }
-
- freep = prevp;
- return (void*) (p + 1);
- }
- // Reached end of free list ?
- // Try to allocate the block from the pool. If that succeeds,
- // get_mem_from_pool adds the new block to the free list and
- // it will be found in the following iterations. If the call
- // to get_mem_from_pool doesn't succeed, we've run out of
- // memory
- //
- else if (p == freep)
- {
- if ((p = get_mem_from_pool(nquantas)) == 0)
- {
- #ifdef DEBUG_MEMMGR_FATAL
- printf("!! Memory allocation failed !!\n");
- #endif
- return 0;
- }
- }
- }
-}
-
-
-// Scans the free list, starting at freep, looking the the place to insert the
-// free block. This is either between two existing blocks or at the end of the
-// list. In any case, if the block being freed is adjacent to either neighbor,
-// the adjacent blocks are combined.
-//
-void memmgr_free(void* ap)
-{
- mem_header_t* block;
- mem_header_t* p;
-
- // acquire pointer to block header
- block = ((mem_header_t*) ap) - 1;
-
- // Find the correct place to place the block in (the free list is sorted by
- // address, increasing order)
- //
- for (p = freep; !(block > p && block < p->s.next); p = p->s.next)
- {
- // Since the free list is circular, there is one link where a
- // higher-addressed block points to a lower-addressed block.
- // This condition checks if the block should be actually
- // inserted between them
- //
- if (p >= p->s.next && (block > p || block < p->s.next))
- break;
- }
-
- // Try to combine with the higher neighbor
- //
- if (block + block->s.size == p->s.next)
- {
- block->s.size += p->s.next->s.size;
- block->s.next = p->s.next->s.next;
- }
- else
- {
- block->s.next = p->s.next;
- }
-
- // Try to combine with the lower neighbor
- //
- if (p + p->s.size == block)
- {
- p->s.size += block->s.size;
- p->s.next = block->s.next;
- }
- else
- {
- p->s.next = block;
- }
-
- freep = p;
-}
diff --git a/tests/c_files/memmgr.h b/tests/c_files/memmgr.h
deleted file mode 100644
index ae8212d..0000000
--- a/tests/c_files/memmgr.h
+++ /dev/null
@@ -1,96 +0,0 @@
-//----------------------------------------------------------------
-// Statically-allocated memory manager
-//
-// by Eli Bendersky (eliben@gmail.com)
-//
-// This code is in the public domain.
-//----------------------------------------------------------------
-#ifndef MEMMGR_H
-#define MEMMGR_H
-
-//
-// Memory manager: dynamically allocates memory from
-// a fixed pool that is allocated statically at link-time.
-//
-// Usage: after calling memmgr_init() in your
-// initialization routine, just use memmgr_alloc() instead
-// of malloc() and memmgr_free() instead of free().
-// Naturally, you can use the preprocessor to define
-// malloc() and free() as aliases to memmgr_alloc() and
-// memmgr_free(). This way the manager will be a drop-in
-// replacement for the standard C library allocators, and can
-// be useful for debugging memory allocation problems and
-// leaks.
-//
-// Preprocessor flags you can define to customize the
-// memory manager:
-//
-// DEBUG_MEMMGR_FATAL
-// Allow printing out a message when allocations fail
-//
-// DEBUG_MEMMGR_SUPPORT_STATS
-// Allow printing out of stats in function
-// memmgr_print_stats When this is disabled,
-// memmgr_print_stats does nothing.
-//
-// Note that in production code on an embedded system
-// you'll probably want to keep those undefined, because
-// they cause printf to be called.
-//
-// POOL_SIZE
-// Size of the pool for new allocations. This is
-// effectively the heap size of the application, and can
-// be changed in accordance with the available memory
-// resources.
-//
-// MIN_POOL_ALLOC_QUANTAS
-// Internally, the memory manager allocates memory in
-// quantas roughly the size of two ulong objects. To
-// minimize pool fragmentation in case of multiple allocations
-// and deallocations, it is advisable to not allocate
-// blocks that are too small.
-// This flag sets the minimal ammount of quantas for
-// an allocation. If the size of a ulong is 4 and you
-// set this flag to 16, the minimal size of an allocation
-// will be 4 * 2 * 16 = 128 bytes
-// If you have a lot of small allocations, keep this value
-// low to conserve memory. If you have mostly large
-// allocations, it is best to make it higher, to avoid
-// fragmentation.
-//
-// Notes:
-// 1. This memory manager is *not thread safe*. Use it only
-// for single thread/task applications.
-//
-
-#define DEBUG_MEMMGR_SUPPORT_STATS 1
-
-#define POOL_SIZE 8 * 1024
-#define MIN_POOL_ALLOC_QUANTAS 16
-
-
-typedef unsigned char byte;
-typedef unsigned long ulong;
-
-
-
-// Initialize the memory manager. This function should be called
-// only once in the beginning of the program.
-//
-void memmgr_init();
-
-// 'malloc' clone
-//
-void* memmgr_alloc(ulong nbytes);
-
-// 'free' clone
-//
-void memmgr_free(void* ap);
-
-// Prints statistics about the current state of the memory
-// manager
-//
-void memmgr_print_stats();
-
-
-#endif // MEMMGR_H
diff --git a/tests/c_files/memmgr_with_h.c b/tests/c_files/memmgr_with_h.c
deleted file mode 100644
index 8ea6ff6..0000000
--- a/tests/c_files/memmgr_with_h.c
+++ /dev/null
@@ -1,350 +0,0 @@
-#line 1 "memmgr.c"
-
-
-
-
-
-
-
-#line 1 "./memmgr.h"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-typedef unsigned char byte;
-typedef unsigned long ulong;
-
-
-
-
-
-
-void memmgr_init();
-
-
-
-void* memmgr_alloc(ulong nbytes);
-
-
-
-void memmgr_free(void* ap);
-
-
-
-
-void memmgr_print_stats();
-
-
-
-#line 9 "memmgr.c"
-
-typedef ulong Align;
-
-union mem_header_union
-{
- struct
- {
-
-
- union mem_header_union* next;
-
-
-
- ulong size;
- } s;
-
-
-
- Align align_dummy;
-};
-
-typedef union mem_header_union mem_header_t;
-
-
-
-static mem_header_t base;
-
-
-
-static mem_header_t* freep = 0;
-
-
-
-static byte pool[8 * 1024] = {0};
-static ulong pool_free_pos = 0;
-
-
-void memmgr_init()
-{
- base.s.next = 0;
- base.s.size = 0;
- freep = 0;
- pool_free_pos = 0;
-}
-
-
-void memmgr_print_stats()
-{
-
- mem_header_t* p;
-
- printf("------ Memory manager stats ------\n\n");
- printf( "Pool: free_pos = %lu (%lu bytes left)\n\n",
- pool_free_pos,8 * 1024 - pool_free_pos);
-
- p = (mem_header_t*) pool;
-
- while (p < (mem_header_t*) (pool + pool_free_pos))
- {
- printf( " * Addr: 0x%8lu; Size: %8lu\n",
- p, p->s.size);
-
- p += p->s.size;
- }
-
- printf("\nFree list:\n\n");
-
- if (freep)
- {
- p = freep;
-
- while (1)
- {
- printf( " * Addr: 0x%8lu; Size: %8lu; Next: 0x%8lu\n",
- p, p->s.size, p->s.next);
-
- p = p->s.next;
-
- if (p == freep)
- break;
- }
- }
- else
- {
- printf("Empty\n");
- }
-
- printf("\n");
-
-}
-
-
-static mem_header_t* get_mem_from_pool(ulong nquantas)
-{
- ulong total_req_size;
-
- mem_header_t* h;
-
- if (nquantas < 16)
- nquantas = 16;
-
- total_req_size = nquantas * sizeof(mem_header_t);
-
- if (pool_free_pos + total_req_size <= 8 * 1024)
- {
- h = (mem_header_t*) (pool + pool_free_pos);
- h->s.size = nquantas;
- memmgr_free((void*) (h + 1));
- pool_free_pos += total_req_size;
- }
- else
- {
- return 0;
- }
-
- return freep;
-}
-
-
-
-
-
-
-
-
-
-
-void* memmgr_alloc(ulong nbytes)
-{
- mem_header_t* p;
- mem_header_t* prevp;
-
-
-
-
-
- ulong nquantas = (nbytes + sizeof(mem_header_t) - 1) / sizeof(mem_header_t) + 1;
-
-
-
-
- if ((prevp = freep) == 0)
- {
- base.s.next = freep = prevp = &base;
- base.s.size = 0;
- }
-
- for (p = prevp->s.next; ; prevp = p, p = p->s.next)
- {
-
- if (p->s.size >= nquantas)
- {
-
- if (p->s.size == nquantas)
- {
-
-
-
- prevp->s.next = p->s.next;
- }
- else
- {
- p->s.size -= nquantas;
- p += p->s.size;
- p->s.size = nquantas;
- }
-
- freep = prevp;
- return (void*) (p + 1);
- }
-
-
-
-
-
-
-
- else if (p == freep)
- {
- if ((p = get_mem_from_pool(nquantas)) == 0)
- {
-
-
-
- return 0;
- }
- }
- }
-}
-
-
-
-
-
-
-
-void memmgr_free(void* ap)
-{
- mem_header_t* block;
- mem_header_t* p;
-
-
- block = ((mem_header_t*) ap) - 1;
-
-
-
-
- for (p = freep; !(block > p && block < p->s.next); p = p->s.next)
- {
-
-
-
-
-
- if (p >= p->s.next && (block > p || block < p->s.next))
- break;
- }
-
-
-
- if (block + block->s.size == p->s.next)
- {
- block->s.size += p->s.next->s.size;
- block->s.next = p->s.next->s.next;
- }
- else
- {
- block->s.next = p->s.next;
- }
-
-
-
- if (p + p->s.size == block)
- {
- p->s.size += block->s.size;
- p->s.next = block->s.next;
- }
- else
- {
- p->s.next = block;
- }
-
- freep = p;
-}
diff --git a/tests/c_files/simplemain.c b/tests/c_files/simplemain.c
deleted file mode 100644
index abbe5d8..0000000
--- a/tests/c_files/simplemain.c
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "hdir\emptydir\..\9\inc.h"
-
-int main() {
- return 0;
-}
diff --git a/tests/c_files/year.c b/tests/c_files/year.c
deleted file mode 100644
index 11d9475..0000000
--- a/tests/c_files/year.c
+++ /dev/null
@@ -1,60 +0,0 @@
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
-/* C99 bools */
-_Bool just_a_flag = false;
-bool another_flag = true;
-
-void convert(int thousands, int hundreds, int tens, int ones)
-{
-char *num[] = {"", "One", "Two", "Three", "Four", "Five", "Six",
- "Seven", "Eight", "Nine"};
-
-char *for_ten[] = {"", "", "Twenty", "Thirty", "Fourty", "Fifty", "Sixty",
- "Seventy", "Eighty", "Ninty"};
-
-char *af_ten[] = {"Ten", "Eleven", "Twelve", "Thirteen", "Fourteen",
- "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Ninteen"};
-
- printf("\nThe year in words is:\n");
-
- printf("%s thousand", num[thousands]);
- if (hundreds != 0)
- printf(" %s hundred", num[hundreds]);
-
- if (tens != 1)
- printf(" %s %s", for_ten[tens], num[ones]);
- else
- printf(" %s", af_ten[ones]);
-
- va_list jajaja;
-}
-
-
-int main()
-{
-int year;
-int n1000, n100, n10, n1;
-
- printf("\nEnter the year (4 digits): ");
- scanf("%d", &year);
-
- if (year > 9999 || year < 1000)
- {
- printf("\nError !! The year must contain 4 digits.");
- exit(EXIT_FAILURE);
- }
-
- n1000 = year/1000;
- n100 = ((year)%1000)/100;
- n10 = (year%100)/10;
- n1 = ((year%10)%10);
-
- convert(n1000, n100, n10, n1);
-
-return 0;
-}
-
-
diff --git a/tests/test_c_ast.py b/tests/test_c_ast.py
deleted file mode 100644
index 6ea3ceb..0000000
--- a/tests/test_c_ast.py
+++ /dev/null
@@ -1,150 +0,0 @@
-import pprint
-import re
-import sys
-import unittest
-import weakref
-
-sys.path.insert(0, '..')
-import pycparser.c_ast as c_ast
-import pycparser.plyparser as plyparser
-
-
-class Test_c_ast(unittest.TestCase):
- def test_BinaryOp(self):
- b1 = c_ast.BinaryOp(
- op='+',
- left=c_ast.Constant(type='int', value='6'),
- right=c_ast.ID(name='joe'))
-
- self.assertIsInstance(b1.left, c_ast.Constant)
- self.assertEqual(b1.left.type, 'int')
- self.assertEqual(b1.left.value, '6')
-
- self.assertIsInstance(b1.right, c_ast.ID)
- self.assertEqual(b1.right.name, 'joe')
-
- def test_weakref_works_on_nodes(self):
- c1 = c_ast.Constant(type='float', value='3.14')
- wr = weakref.ref(c1)
- cref = wr()
- self.assertEqual(cref.type, 'float')
- self.assertEqual(weakref.getweakrefcount(c1), 1)
-
- def test_weakref_works_on_coord(self):
- coord = plyparser.Coord(file='a', line=2)
- wr = weakref.ref(coord)
- cref = wr()
- self.assertEqual(cref.line, 2)
- self.assertEqual(weakref.getweakrefcount(coord), 1)
-
-
-class TestNodeVisitor(unittest.TestCase):
- class ConstantVisitor(c_ast.NodeVisitor):
- def __init__(self):
- self.values = []
-
- def visit_Constant(self, node):
- self.values.append(node.value)
-
- def test_scalar_children(self):
- b1 = c_ast.BinaryOp(
- op='+',
- left=c_ast.Constant(type='int', value='6'),
- right=c_ast.ID(name='joe'))
-
- cv = self.ConstantVisitor()
- cv.visit(b1)
-
- self.assertEqual(cv.values, ['6'])
-
- b2 = c_ast.BinaryOp(
- op='*',
- left=c_ast.Constant(type='int', value='111'),
- right=b1)
-
- b3 = c_ast.BinaryOp(
- op='^',
- left=b2,
- right=b1)
-
- cv = self.ConstantVisitor()
- cv.visit(b3)
-
- self.assertEqual(cv.values, ['111', '6', '6'])
-
- def tests_list_children(self):
- c1 = c_ast.Constant(type='float', value='5.6')
- c2 = c_ast.Constant(type='char', value='t')
-
- b1 = c_ast.BinaryOp(
- op='+',
- left=c1,
- right=c2)
-
- b2 = c_ast.BinaryOp(
- op='-',
- left=b1,
- right=c2)
-
- comp = c_ast.Compound(
- block_items=[b1, b2, c1, c2])
-
- cv = self.ConstantVisitor()
- cv.visit(comp)
-
- self.assertEqual(cv.values,
- ['5.6', 't', '5.6', 't', 't', '5.6', 't'])
-
- def test_repr(self):
- c1 = c_ast.Constant(type='float', value='5.6')
- c2 = c_ast.Constant(type='char', value='t')
-
- b1 = c_ast.BinaryOp(
- op='+',
- left=c1,
- right=c2)
-
- b2 = c_ast.BinaryOp(
- op='-',
- left=b1,
- right=c2)
-
- comp = c_ast.Compound(
- block_items=[b1, b2, c1, c2])
-
- expected = ("Compound(block_items=[BinaryOp(op='+',\n"
- " left=Constant(type='float',\n"
- " value='5.6'\n"
- " ),\n"
- " right=Constant(type='char',\n"
- " value='t'\n"
- " )\n"
- " ),\n"
- " BinaryOp(op='-',\n"
- " left=BinaryOp(op='+',\n"
- " left=Constant(type='float',\n"
- " value='5.6'\n"
- " ),\n"
- " right=Constant(type='char',\n"
- " value='t'\n"
- " )\n"
- " ),\n"
- " right=Constant(type='char',\n"
- " value='t'\n"
- " )\n"
- " ),\n"
- " Constant(type='float',\n"
- " value='5.6'\n"
- " ),\n"
- " Constant(type='char',\n"
- " value='t'\n"
- " )\n"
- " ]\n"
- " )")
-
- self.assertEqual(repr(comp),
- expected)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tests/test_c_generator.py b/tests/test_c_generator.py
deleted file mode 100644
index 3727f91..0000000
--- a/tests/test_c_generator.py
+++ /dev/null
@@ -1,337 +0,0 @@
-import sys
-import textwrap
-import unittest
-
-# Run from the root dir
-sys.path.insert(0, '.')
-
-from pycparser import c_parser, c_generator, c_ast
-
-_c_parser = c_parser.CParser(
- lex_optimize=False,
- yacc_debug=True,
- yacc_optimize=False,
- yacctab='yacctab')
-
-
-def compare_asts(ast1, ast2):
- if type(ast1) != type(ast2):
- return False
- if isinstance(ast1, tuple) and isinstance(ast2, tuple):
- if ast1[0] != ast2[0]:
- return False
- ast1 = ast1[1]
- ast2 = ast2[1]
- return compare_asts(ast1, ast2)
- for attr in ast1.attr_names:
- if getattr(ast1, attr) != getattr(ast2, attr):
- return False
- for i, c1 in enumerate(ast1.children()):
- if compare_asts(c1, ast2.children()[i]) == False:
- return False
- return True
-
-
-def parse_to_ast(src):
- return _c_parser.parse(src)
-
-
-class TestFunctionDeclGeneration(unittest.TestCase):
- class _FuncDeclVisitor(c_ast.NodeVisitor):
- def __init__(self):
- self.stubs = []
-
- def visit_FuncDecl(self, node):
- gen = c_generator.CGenerator()
- self.stubs.append(gen.visit(node))
-
- def test_partial_funcdecl_generation(self):
- src = r'''
- void noop(void);
- void *something(void *thing);
- int add(int x, int y);'''
- ast = parse_to_ast(src)
- v = TestFunctionDeclGeneration._FuncDeclVisitor()
- v.visit(ast)
- self.assertEqual(len(v.stubs), 3)
- self.assertTrue(r'void noop(void)' in v.stubs)
- self.assertTrue(r'void *something(void *thing)' in v.stubs)
- self.assertTrue(r'int add(int x, int y)' in v.stubs)
-
-
-class TestCtoC(unittest.TestCase):
- def _run_c_to_c(self, src):
- ast = parse_to_ast(src)
- generator = c_generator.CGenerator()
- return generator.visit(ast)
-
- def _assert_ctoc_correct(self, src):
- """ Checks that the c2c translation was correct by parsing the code
- generated by c2c for src and comparing the AST with the original
- AST.
- """
- src2 = self._run_c_to_c(src)
- self.assertTrue(compare_asts(parse_to_ast(src), parse_to_ast(src2)),
- src2)
-
- def test_trivial_decls(self):
- self._assert_ctoc_correct('int a;')
- self._assert_ctoc_correct('int b, a;')
- self._assert_ctoc_correct('int c, b, a;')
-
- def test_complex_decls(self):
- self._assert_ctoc_correct('int** (*a)(void);')
- self._assert_ctoc_correct('int** (*a)(void*, int);')
- self._assert_ctoc_correct('int (*b)(char * restrict k, float);')
- self._assert_ctoc_correct('int test(const char* const* arg);')
- self._assert_ctoc_correct('int test(const char** const arg);')
-
- #s = 'int test(const char* const* arg);'
- #parse_to_ast(s).show()
-
- def test_ternary(self):
- self._assert_ctoc_correct('''
- int main(void)
- {
- int a, b;
- (a == 0) ? (b = 1) : (b = 2);
- }''')
-
- def test_casts(self):
- self._assert_ctoc_correct(r'''
- int main() {
- int b = (int) f;
- int c = (int*) f;
- }''')
- self._assert_ctoc_correct(r'''
- int main() {
- int a = (int) b + 8;
- int t = (int) c;
- }
- ''')
-
- def test_initlist(self):
- self._assert_ctoc_correct('int arr[] = {1, 2, 3};')
-
- def test_exprs(self):
- self._assert_ctoc_correct('''
- int main(void)
- {
- int a;
- int b = a++;
- int c = ++a;
- int d = a--;
- int e = --a;
- }''')
-
- def test_statements(self):
- # note two minuses here
- self._assert_ctoc_correct(r'''
- int main() {
- int a;
- a = 5;
- ;
- b = - - a;
- return a;
- }''')
-
- def test_struct_decl(self):
- self._assert_ctoc_correct(r'''
- typedef struct node_t {
- struct node_t* next;
- int data;
- } node;
- ''')
-
- def test_krstyle(self):
- self._assert_ctoc_correct(r'''
- int main(argc, argv)
- int argc;
- char** argv;
- {
- return 0;
- }
- ''')
-
- def test_switchcase(self):
- self._assert_ctoc_correct(r'''
- int main() {
- switch (myvar) {
- case 10:
- {
- k = 10;
- p = k + 1;
- break;
- }
- case 20:
- case 30:
- return 20;
- default:
- break;
- }
- }
- ''')
-
- def test_nest_initializer_list(self):
- self._assert_ctoc_correct(r'''
- int main()
- {
- int i[1][1] = { { 1 } };
- }''')
-
- def test_nest_named_initializer(self):
- self._assert_ctoc_correct(r'''struct test
- {
- int i;
- struct test_i_t
- {
- int k;
- } test_i;
- int j;
- };
- struct test test_var = {.i = 0, .test_i = {.k = 1}, .j = 2};
- ''')
-
- def test_expr_list_in_initializer_list(self):
- self._assert_ctoc_correct(r'''
- int main()
- {
- int i[1] = { (1, 2) };
- }''')
-
- def test_issue36(self):
- self._assert_ctoc_correct(r'''
- int main() {
- }''')
-
- def test_issue37(self):
- self._assert_ctoc_correct(r'''
- int main(void)
- {
- unsigned size;
- size = sizeof(size);
- return 0;
- }''')
-
- def test_issue66(self):
- # A non-existing body must not be generated
- # (previous valid behavior, still working)
- self._assert_ctoc_correct(r'''
- struct foo;
- ''')
- # An empty body must be generated
- # (added behavior)
- self._assert_ctoc_correct(r'''
- struct foo {};
- ''')
-
- def test_issue83(self):
- self._assert_ctoc_correct(r'''
- void x(void) {
- int i = (9, k);
- }
- ''')
-
- def test_issue84(self):
- self._assert_ctoc_correct(r'''
- void x(void) {
- for (int i = 0;;)
- i;
- }
- ''')
-
- def test_issue246(self):
- self._assert_ctoc_correct(r'''
- int array[3] = {[0] = 0, [1] = 1, [1+1] = 2};
- ''')
-
- def test_exprlist_with_semi(self):
- self._assert_ctoc_correct(r'''
- void x() {
- if (i < j)
- tmp = C[i], C[i] = C[j], C[j] = tmp;
- if (i <= j)
- i++, j--;
- }
- ''')
-
- def test_exprlist_with_subexprlist(self):
- self._assert_ctoc_correct(r'''
- void x() {
- (a = b, (b = c, c = a));
- }
- ''')
-
- def test_comma_operator_funcarg(self):
- self._assert_ctoc_correct(r'''
- void f(int x) { return x; }
- int main(void) { f((1, 2)); return 0; }
- ''')
-
- def test_comma_op_in_ternary(self):
- self._assert_ctoc_correct(r'''
- void f() {
- (0, 0) ? (0, 0) : (0, 0);
- }
- ''')
-
- def test_comma_op_assignment(self):
- self._assert_ctoc_correct(r'''
- void f() {
- i = (a, b, c);
- }
- ''')
-
- def test_pragma(self):
- self._assert_ctoc_correct(r'''
- #pragma foo
- void f() {
- #pragma bar
- i = (a, b, c);
- }
- typedef struct s {
- #pragma baz
- } s;
- ''')
-
- def test_compound_literal(self):
- self._assert_ctoc_correct('char **foo = (char *[]){ "x", "y", "z" };')
- self._assert_ctoc_correct('int i = ++(int){ 1 };')
- self._assert_ctoc_correct('struct foo_s foo = (struct foo_s){ 1, 2 };')
-
- def test_enum(self):
- self._assert_ctoc_correct(r'''
- enum e
- {
- a,
- b = 2,
- c = 3
- };
- ''')
- self._assert_ctoc_correct(r'''
- enum f
- {
- g = 4,
- h,
- i
- };
- ''')
-
- def test_enum_typedef(self):
- self._assert_ctoc_correct('typedef enum EnumName EnumTypedefName;')
-
- def test_generate_struct_union_enum_exception(self):
- generator = c_generator.CGenerator()
- self.assertRaises(
- AssertionError,
- generator._generate_struct_union_enum,
- n=c_ast.Struct(
- name='TestStruct',
- decls=[],
- ),
- name='',
- )
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/tests/test_c_lexer.py b/tests/test_c_lexer.py
deleted file mode 100644
index 11c7b26..0000000
--- a/tests/test_c_lexer.py
+++ /dev/null
@@ -1,447 +0,0 @@
-import re
-import sys
-import unittest
-
-sys.path.insert(0, '..')
-from pycparser.c_lexer import CLexer
-
-
-def token_list(clex):
- return list(iter(clex.token, None))
-
-
-def token_types(clex):
- return [i.type for i in token_list(clex)]
-
-
-class TestCLexerNoErrors(unittest.TestCase):
- """ Test lexing of strings that are not supposed to cause
- errors. Therefore, the error_func passed to the lexer
- raises an exception.
- """
- def error_func(self, msg, line, column):
- self.fail(msg)
-
- def on_lbrace_func(self):
- pass
-
- def on_rbrace_func(self):
- pass
-
- def type_lookup_func(self, typ):
- if typ.startswith('mytype'):
- return True
- else:
- return False
-
- def setUp(self):
- self.clex = CLexer(self.error_func, lambda: None, lambda: None,
- self.type_lookup_func)
- self.clex.build(optimize=False)
-
- def assertTokensTypes(self, str, types):
- self.clex.input(str)
- self.assertEqual(token_types(self.clex), types)
-
- def test_trivial_tokens(self):
- self.assertTokensTypes('1', ['INT_CONST_DEC'])
- self.assertTokensTypes('-', ['MINUS'])
- self.assertTokensTypes('volatile', ['VOLATILE'])
- self.assertTokensTypes('...', ['ELLIPSIS'])
- self.assertTokensTypes('++', ['PLUSPLUS'])
- self.assertTokensTypes('case int', ['CASE', 'INT'])
- self.assertTokensTypes('caseint', ['ID'])
- self.assertTokensTypes('$dollar cent$', ['ID', 'ID'])
- self.assertTokensTypes('i ^= 1;', ['ID', 'XOREQUAL', 'INT_CONST_DEC', 'SEMI'])
-
- def test_id_typeid(self):
- self.assertTokensTypes('myt', ['ID'])
- self.assertTokensTypes('mytype', ['TYPEID'])
- self.assertTokensTypes('mytype6 var', ['TYPEID', 'ID'])
-
- def test_integer_constants(self):
- self.assertTokensTypes('12', ['INT_CONST_DEC'])
- self.assertTokensTypes('12u', ['INT_CONST_DEC'])
- self.assertTokensTypes('12l', ['INT_CONST_DEC'])
- self.assertTokensTypes('199872Ul', ['INT_CONST_DEC'])
- self.assertTokensTypes('199872lU', ['INT_CONST_DEC'])
- self.assertTokensTypes('199872LL', ['INT_CONST_DEC'])
- self.assertTokensTypes('199872ull', ['INT_CONST_DEC'])
- self.assertTokensTypes('199872llu', ['INT_CONST_DEC'])
- self.assertTokensTypes('1009843200000uLL', ['INT_CONST_DEC'])
- self.assertTokensTypes('1009843200000LLu', ['INT_CONST_DEC'])
-
- self.assertTokensTypes('077', ['INT_CONST_OCT'])
- self.assertTokensTypes('0123456L', ['INT_CONST_OCT'])
-
- self.assertTokensTypes('0xf7', ['INT_CONST_HEX'])
- self.assertTokensTypes('0b110', ['INT_CONST_BIN'])
- self.assertTokensTypes('0x01202AAbbf7Ul', ['INT_CONST_HEX'])
-
- # no 0 before x, so ID catches it
- self.assertTokensTypes('xf7', ['ID'])
-
- # - is MINUS, the rest a constnant
- self.assertTokensTypes('-1', ['MINUS', 'INT_CONST_DEC'])
-
- def test_special_names(self):
- self.assertTokensTypes('sizeof offsetof', ['SIZEOF', 'OFFSETOF'])
-
- def test_floating_constants(self):
- self.assertTokensTypes('1.5f', ['FLOAT_CONST'])
- self.assertTokensTypes('01.5', ['FLOAT_CONST'])
- self.assertTokensTypes('.15L', ['FLOAT_CONST'])
- self.assertTokensTypes('0.', ['FLOAT_CONST'])
-
- # but just a period is a period
- self.assertTokensTypes('.', ['PERIOD'])
-
- self.assertTokensTypes('3.3e-3', ['FLOAT_CONST'])
- self.assertTokensTypes('.7e25L', ['FLOAT_CONST'])
- self.assertTokensTypes('6.e+125f', ['FLOAT_CONST'])
- self.assertTokensTypes('666e666', ['FLOAT_CONST'])
- self.assertTokensTypes('00666e+3', ['FLOAT_CONST'])
-
- # but this is a hex integer + 3
- self.assertTokensTypes('0x0666e+3', ['INT_CONST_HEX', 'PLUS', 'INT_CONST_DEC'])
-
- def test_hexadecimal_floating_constants(self):
- self.assertTokensTypes('0xDE.488641p0', ['HEX_FLOAT_CONST'])
- self.assertTokensTypes('0x.488641p0', ['HEX_FLOAT_CONST'])
- self.assertTokensTypes('0X12.P0', ['HEX_FLOAT_CONST'])
-
- def test_char_constants(self):
- self.assertTokensTypes(r"""'x'""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""L'x'""", ['WCHAR_CONST'])
- self.assertTokensTypes(r"""'\t'""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""'\''""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""'\?'""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""'\012'""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""'\x2f'""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""'\x2f12'""", ['CHAR_CONST'])
- self.assertTokensTypes(r"""L'\xaf'""", ['WCHAR_CONST'])
-
- def test_on_rbrace_lbrace(self):
- braces = []
- def on_lbrace():
- braces.append('{')
- def on_rbrace():
- braces.append('}')
- clex = CLexer(self.error_func, on_lbrace, on_rbrace,
- self.type_lookup_func)
- clex.build(optimize=False)
- clex.input('hello { there } } and again }}{')
- token_list(clex)
- self.assertEqual(braces, ['{', '}', '}', '}', '}', '{'])
-
- def test_string_literal(self):
- self.assertTokensTypes('"a string"', ['STRING_LITERAL'])
- self.assertTokensTypes('L"ing"', ['WSTRING_LITERAL'])
- self.assertTokensTypes(
- '"i am a string too \t"',
- ['STRING_LITERAL'])
- self.assertTokensTypes(
- r'''"esc\ape \"\'\? \0234 chars \rule"''',
- ['STRING_LITERAL'])
- self.assertTokensTypes(
- r'''"hello 'joe' wanna give it a \"go\"?"''',
- ['STRING_LITERAL'])
- self.assertTokensTypes(
- '"\123\123\123\123\123\123\123\123\123\123\123\123\123\123\123\123"',
- ['STRING_LITERAL'])
-
- def test_mess(self):
- self.assertTokensTypes(
- r'[{}]()',
- ['LBRACKET',
- 'LBRACE', 'RBRACE',
- 'RBRACKET',
- 'LPAREN', 'RPAREN'])
-
- self.assertTokensTypes(
- r'()||!C&~Z?J',
- ['LPAREN', 'RPAREN',
- 'LOR',
- 'LNOT', 'ID',
- 'AND',
- 'NOT', 'ID',
- 'CONDOP', 'ID'])
-
- self.assertTokensTypes(
- r'+-*/%|||&&&^><>=<===!=',
- ['PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
- 'LOR', 'OR',
- 'LAND', 'AND',
- 'XOR',
- 'GT', 'LT', 'GE', 'LE', 'EQ', 'NE'])
-
- self.assertTokensTypes(
- r'++--->?.,;:',
- ['PLUSPLUS', 'MINUSMINUS',
- 'ARROW', 'CONDOP',
- 'PERIOD', 'COMMA', 'SEMI', 'COLON'])
-
- def test_exprs(self):
- self.assertTokensTypes(
- 'bb-cc',
- ['ID', 'MINUS', 'ID'])
-
- self.assertTokensTypes(
- 'foo & 0xFF',
- ['ID', 'AND', 'INT_CONST_HEX'])
-
- self.assertTokensTypes(
- '(2+k) * 62',
- ['LPAREN', 'INT_CONST_DEC', 'PLUS', 'ID',
- 'RPAREN', 'TIMES', 'INT_CONST_DEC'],)
-
- self.assertTokensTypes(
- 'x | y >> z',
- ['ID', 'OR', 'ID', 'RSHIFT', 'ID'])
-
- self.assertTokensTypes(
- 'x <<= z << 5',
- ['ID', 'LSHIFTEQUAL', 'ID', 'LSHIFT', 'INT_CONST_DEC'])
-
- self.assertTokensTypes(
- 'x = y > 0 ? y : -6',
- ['ID', 'EQUALS',
- 'ID', 'GT', 'INT_CONST_OCT',
- 'CONDOP',
- 'ID',
- 'COLON',
- 'MINUS', 'INT_CONST_DEC'])
-
- self.assertTokensTypes(
- 'a+++b',
- ['ID', 'PLUSPLUS', 'PLUS', 'ID'])
-
- def test_statements(self):
- self.assertTokensTypes(
- 'for (int i = 0; i < n; ++i)',
- ['FOR', 'LPAREN',
- 'INT', 'ID', 'EQUALS', 'INT_CONST_OCT', 'SEMI',
- 'ID', 'LT', 'ID', 'SEMI',
- 'PLUSPLUS', 'ID',
- 'RPAREN'])
-
- self.assertTokensTypes(
- 'self: goto self;',
- ['ID', 'COLON', 'GOTO', 'ID', 'SEMI'])
-
- self.assertTokensTypes(
- """ switch (typ)
- {
- case TYPE_ID:
- m = 5;
- break;
- default:
- m = 8;
- }""",
- ['SWITCH', 'LPAREN', 'ID', 'RPAREN',
- 'LBRACE',
- 'CASE', 'ID', 'COLON',
- 'ID', 'EQUALS', 'INT_CONST_DEC', 'SEMI',
- 'BREAK', 'SEMI',
- 'DEFAULT', 'COLON',
- 'ID', 'EQUALS', 'INT_CONST_DEC', 'SEMI',
- 'RBRACE'])
-
- def test_preprocessor_line(self):
- self.assertTokensTypes('#abracadabra', ['PPHASH', 'ID'])
-
- str = r"""
- 546
- #line 66 "kwas\df.h"
- id 4
- dsf
- # 9
- armo
- #line 10 "..\~..\test.h"
- tok1
- #line 99999 "include/me.h"
- tok2
- """
-
- #~ self.clex.filename
- self.clex.input(str)
- self.clex.reset_lineno()
-
- t1 = self.clex.token()
- self.assertEqual(t1.type, 'INT_CONST_DEC')
- self.assertEqual(t1.lineno, 2)
-
- t2 = self.clex.token()
- self.assertEqual(t2.type, 'ID')
- self.assertEqual(t2.value, 'id')
- self.assertEqual(t2.lineno, 66)
- self.assertEqual(self.clex.filename, r'kwas\df.h')
-
- for i in range(3):
- t = self.clex.token()
-
- self.assertEqual(t.type, 'ID')
- self.assertEqual(t.value, 'armo')
- self.assertEqual(t.lineno, 9)
- self.assertEqual(self.clex.filename, r'kwas\df.h')
-
- t4 = self.clex.token()
- self.assertEqual(t4.type, 'ID')
- self.assertEqual(t4.value, 'tok1')
- self.assertEqual(t4.lineno, 10)
- self.assertEqual(self.clex.filename, r'..\~..\test.h')
-
- t5 = self.clex.token()
- self.assertEqual(t5.type, 'ID')
- self.assertEqual(t5.value, 'tok2')
- self.assertEqual(t5.lineno, 99999)
- self.assertEqual(self.clex.filename, r'include/me.h')
-
- def test_preprocessor_line_funny(self):
- str = r'''
- #line 10 "..\6\joe.h"
- 10
- '''
- self.clex.input(str)
- self.clex.reset_lineno()
-
- t1 = self.clex.token()
- self.assertEqual(t1.type, 'INT_CONST_DEC')
- self.assertEqual(t1.lineno, 10)
- self.assertEqual(self.clex.filename, r'..\6\joe.h')
-
-
- def test_preprocessor_pragma(self):
- str = '''
- 42
- #pragma
- #pragma helo me
- #pragma once
- # pragma omp parallel private(th_id)
- #\tpragma {pack: 2, smack: 3}
- #pragma <includeme.h> "nowit.h"
- #pragma "string"
- #pragma somestring="some_other_string"
- #pragma id 124124 and numbers 0235495
- 59
- '''
- # Check that pragmas are tokenized, including trailing string
- self.clex.input(str)
- self.clex.reset_lineno()
-
- t1 = self.clex.token()
- self.assertEqual(t1.type, 'INT_CONST_DEC')
-
- t2 = self.clex.token()
- self.assertEqual(t2.type, 'PPPRAGMA')
-
- t3 = self.clex.token()
- self.assertEqual(t3.type, 'PPPRAGMA')
-
- t4 = self.clex.token()
- self.assertEqual(t4.type, 'PPPRAGMASTR')
- self.assertEqual(t4.value, 'helo me')
-
- for i in range(3):
- t = self.clex.token()
-
- t5 = self.clex.token()
- self.assertEqual(t5.type, 'PPPRAGMASTR')
- self.assertEqual(t5.value, 'omp parallel private(th_id)')
-
- for i in range(5):
- ta = self.clex.token()
- self.assertEqual(ta.type, 'PPPRAGMA')
- tb = self.clex.token()
- self.assertEqual(tb.type, 'PPPRAGMASTR')
-
- t6 = self.clex.token()
- self.assertEqual(t6.type, 'INT_CONST_DEC')
- self.assertEqual(t6.lineno, 12)
-
-
-
-# Keeps all the errors the lexer spits in one place, to allow
-# easier modification if the error syntax changes.
-#
-ERR_ILLEGAL_CHAR = 'Illegal character'
-ERR_OCTAL = 'Invalid octal constant'
-ERR_UNMATCHED_QUOTE = 'Unmatched \''
-ERR_INVALID_CCONST = 'Invalid char constant'
-ERR_STRING_ESCAPE = 'String contains invalid escape'
-
-ERR_FILENAME_BEFORE_LINE = 'filename before line'
-ERR_LINENUM_MISSING = 'line number missing'
-ERR_INVALID_LINE_DIRECTIVE = 'invalid #line directive'
-
-
-class TestCLexerErrors(unittest.TestCase):
- """ Test lexing of erroneous strings.
- Works by passing an error functions that saves the error
- in an attribute for later perusal.
- """
- def error_func(self, msg, line, column):
- self.error = msg
-
- def on_lbrace_func(self):
- pass
-
- def on_rbrace_func(self):
- pass
-
- def type_lookup_func(self, typ):
- return False
-
- def setUp(self):
- self.clex = CLexer(self.error_func, self.on_lbrace_func,
- self.on_rbrace_func, self.type_lookup_func)
- self.clex.build(optimize=False)
- self.error = ""
-
- def assertLexerError(self, str, error_like):
- # feed the string to the lexer
- self.clex.input(str)
-
- # Pulls all tokens from the string. Errors will
- # be written into self.error by the error_func
- # callback
- #
- token_types(self.clex)
-
- # compare the error to the expected
- self.assertTrue(re.search(error_like, self.error),
- "\nExpected error matching: %s\nGot: %s" %
- (error_like, self.error))
-
- # clear last error, for the sake of subsequent invocations
- self.error = ""
-
- def test_trivial_tokens(self):
- self.assertLexerError('@', ERR_ILLEGAL_CHAR)
- self.assertLexerError('`', ERR_ILLEGAL_CHAR)
- self.assertLexerError('\\', ERR_ILLEGAL_CHAR)
-
- def test_integer_constants(self):
- self.assertLexerError('029', ERR_OCTAL)
- self.assertLexerError('012345678', ERR_OCTAL)
-
- def test_char_constants(self):
- self.assertLexerError("'", ERR_UNMATCHED_QUOTE)
- self.assertLexerError("'b\n", ERR_UNMATCHED_QUOTE)
-
- self.assertLexerError("'jx'", ERR_INVALID_CCONST)
- self.assertLexerError(r"'\*'", ERR_INVALID_CCONST)
-
- def test_string_literals(self):
- self.assertLexerError(r'"jx\9"', ERR_STRING_ESCAPE)
- self.assertLexerError(r'"hekllo\* on ix"', ERR_STRING_ESCAPE)
- self.assertLexerError(r'L"hekllo\* on ix"', ERR_STRING_ESCAPE)
-
- def test_preprocessor(self):
- self.assertLexerError('#line "ka"', ERR_FILENAME_BEFORE_LINE)
- self.assertLexerError('#line df', ERR_INVALID_LINE_DIRECTIVE)
- self.assertLexerError('#line \n', ERR_LINENUM_MISSING)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tests/test_c_parser.py b/tests/test_c_parser.py
deleted file mode 100755
index a48f1c6..0000000
--- a/tests/test_c_parser.py
+++ /dev/null
@@ -1,2132 +0,0 @@
-#!/usr/bin/env python
-
-import pprint
-import re
-import os, sys
-import io
-import unittest
-
-sys.path[0:0] = ['.', '..']
-
-from pycparser import c_parser
-from pycparser.c_ast import *
-from pycparser.c_parser import CParser, Coord, ParseError
-
-_c_parser = c_parser.CParser(
- lex_optimize=False,
- yacc_debug=True,
- yacc_optimize=False,
- yacctab='yacctab')
-
-
-def expand_decl(decl):
- """ Converts the declaration into a nested list.
- """
- typ = type(decl)
-
- if typ == TypeDecl:
- return ['TypeDecl', expand_decl(decl.type)]
- elif typ == IdentifierType:
- return ['IdentifierType', decl.names]
- elif typ == ID:
- return ['ID', decl.name]
- elif typ in [Struct, Union]:
- decls = [expand_decl(d) for d in decl.decls or []]
- return [typ.__name__, decl.name, decls]
- else:
- nested = expand_decl(decl.type)
-
- if typ == Decl:
- if decl.quals:
- return ['Decl', decl.quals, decl.name, nested]
- else:
- return ['Decl', decl.name, nested]
- elif typ == Typename: # for function parameters
- if decl.quals:
- return ['Typename', decl.quals, nested]
- else:
- return ['Typename', nested]
- elif typ == ArrayDecl:
- dimval = decl.dim.value if decl.dim else ''
- return ['ArrayDecl', dimval, decl.dim_quals, nested]
- elif typ == PtrDecl:
- if decl.quals:
- return ['PtrDecl', decl.quals, nested]
- else:
- return ['PtrDecl', nested]
- elif typ == Typedef:
- return ['Typedef', decl.name, nested]
- elif typ == FuncDecl:
- if decl.args:
- params = [expand_decl(param) for param in decl.args.params]
- else:
- params = []
- return ['FuncDecl', params, nested]
-
-
-def expand_init(init):
- """ Converts an initialization into a nested list
- """
- typ = type(init)
-
- if typ == NamedInitializer:
- des = [expand_init(dp) for dp in init.name]
- return (des, expand_init(init.expr))
- elif typ in (InitList, ExprList):
- return [expand_init(expr) for expr in init.exprs]
- elif typ == Constant:
- return ['Constant', init.type, init.value]
- elif typ == ID:
- return ['ID', init.name]
- elif typ == UnaryOp:
- return ['UnaryOp', init.op, expand_decl(init.expr)]
-
-
-class TestCParser_base(unittest.TestCase):
- def parse(self, txt, filename=''):
- return self.cparser.parse(txt, filename)
-
- def setUp(self):
- self.cparser = _c_parser
-
- def assert_coord(self, node, line, column=None, file=None):
- self.assertEqual(node.coord.line, line)
- if column is not None:
- self.assertEqual(node.coord.column, column)
- if file:
- self.assertEqual(node.coord.file, file)
-
-
-
-class TestCParser_fundamentals(TestCParser_base):
- def get_decl(self, txt, index=0):
- """ Given a source and an index returns the expanded
- declaration at that index.
-
- FileAST holds a list of 'external declarations'.
- index is the offset of the desired declaration in that
- list.
- """
- t = self.parse(txt).ext[index]
- return expand_decl(t)
-
- def get_decl_init(self, txt, index=0):
- """ Returns the expanded initializer of the declaration
- at index.
- """
- t = self.parse(txt).ext[index]
- return expand_init(t.init)
-
- def test_FileAST(self):
- t = self.parse('int a; char c;')
- self.assertIsInstance(t, FileAST)
- self.assertEqual(len(t.ext), 2)
-
- # empty file
- t2 = self.parse('')
- self.assertIsInstance(t2, FileAST)
- self.assertEqual(len(t2.ext), 0)
-
- def test_empty_toplevel_decl(self):
- code = 'int foo;;'
- t = self.parse(code)
- self.assertIsInstance(t, FileAST)
- self.assertEqual(len(t.ext), 1)
- self.assertEqual(self.get_decl(code),
- ['Decl', 'foo',
- ['TypeDecl', ['IdentifierType', ['int']]]])
-
- def test_coords(self):
- """ Tests the "coordinates" of parsed elements - file
- name, line and column numbers, with modification
- insterted by #line directives.
- """
- self.assert_coord(self.parse('int a;').ext[0], 1, 5)
-
- t1 = """
- int a;
- int b;\n\n
- int c;
- """
- f1 = self.parse(t1, filename='test.c')
- self.assert_coord(f1.ext[0], 2, 13, 'test.c')
- self.assert_coord(f1.ext[1], 3, 13, 'test.c')
- self.assert_coord(f1.ext[2], 6, 13, 'test.c')
-
- t1_1 = '''
- int main() {
- k = p;
- printf("%d", b);
- return 0;
- }'''
- f1_1 = self.parse(t1_1, filename='test.c')
- self.assert_coord(f1_1.ext[0].body.block_items[0], 3, 13, 'test.c')
- self.assert_coord(f1_1.ext[0].body.block_items[1], 4, 13, 'test.c')
-
- t1_2 = '''
- int main () {
- int p = (int) k;
- }'''
- f1_2 = self.parse(t1_2, filename='test.c')
- # make sure that the Cast has a coord (issue 23)
- self.assert_coord(f1_2.ext[0].body.block_items[0].init, 3, 21, file='test.c')
-
- t2 = """
- #line 99
- int c;
- """
- self.assert_coord(self.parse(t2).ext[0], 99, 13)
-
- t3 = """
- int dsf;
- char p;
- #line 3000 "in.h"
- char d;
- """
- f3 = self.parse(t3, filename='test.c')
- self.assert_coord(f3.ext[0], 2, 13, 'test.c')
- self.assert_coord(f3.ext[1], 3, 14, 'test.c')
- self.assert_coord(f3.ext[2], 3000, 14, 'in.h')
-
- t4 = """
- #line 20 "restore.h"
- int maydler(char);
-
- #line 30 "includes/daween.ph"
- long j, k;
-
- #line 50000
- char* ro;
- """
- f4 = self.parse(t4, filename='myb.c')
- self.assert_coord(f4.ext[0], 20, 13, 'restore.h')
- self.assert_coord(f4.ext[1], 30, 14, 'includes/daween.ph')
- self.assert_coord(f4.ext[2], 30, 17, 'includes/daween.ph')
- self.assert_coord(f4.ext[3], 50000, 13, 'includes/daween.ph')
-
- t5 = """
- int
- #line 99
- c;
- """
- self.assert_coord(self.parse(t5).ext[0], 99, 9)
-
- # coord for ellipsis
- t6 = """
- int foo(int j,
- ...) {
- }"""
- f6 = self.parse(t6, filename='z.c')
- self.assert_coord(self.parse(t6).ext[0].decl.type.args.params[1], 3, 17)
-
- def test_forloop_coord(self):
- t = '''\
- void foo() {
- for(int z=0; z<4;
- z++){}
- }
- '''
- s = self.parse(t, filename='f.c')
- forloop = s.ext[0].body.block_items[0]
- self.assert_coord(forloop.init, 2, 13, 'f.c')
- self.assert_coord(forloop.cond, 2, 26, 'f.c')
- self.assert_coord(forloop.next, 3, 17, 'f.c')
-
- def test_simple_decls(self):
- self.assertEqual(self.get_decl('int a;'),
- ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
-
- self.assertEqual(self.get_decl('unsigned int a;'),
- ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]])
-
- self.assertEqual(self.get_decl('_Bool a;'),
- ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['_Bool']]]])
-
- self.assertEqual(self.get_decl('float _Complex fcc;'),
- ['Decl', 'fcc', ['TypeDecl', ['IdentifierType', ['float', '_Complex']]]])
-
- self.assertEqual(self.get_decl('char* string;'),
- ['Decl', 'string',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]])
-
- self.assertEqual(self.get_decl('long ar[15];'),
- ['Decl', 'ar',
- ['ArrayDecl', '15', [],
- ['TypeDecl', ['IdentifierType', ['long']]]]])
-
- self.assertEqual(self.get_decl('long long ar[15];'),
- ['Decl', 'ar',
- ['ArrayDecl', '15', [],
- ['TypeDecl', ['IdentifierType', ['long', 'long']]]]])
-
- self.assertEqual(self.get_decl('unsigned ar[];'),
- ['Decl', 'ar',
- ['ArrayDecl', '', [],
- ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
-
- self.assertEqual(self.get_decl('int strlen(char* s);'),
- ['Decl', 'strlen',
- ['FuncDecl',
- [['Decl', 's',
- ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- self.assertEqual(self.get_decl('int strcmp(char* s1, char* s2);'),
- ['Decl', 'strcmp',
- ['FuncDecl',
- [ ['Decl', 's1',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
- ['Decl', 's2',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]
- ],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- # function return values and parameters may not have type information
- self.assertEqual(self.get_decl('extern foobar(foo, bar);'),
- ['Decl', 'foobar',
- ['FuncDecl',
- [ ['ID', 'foo'],
- ['ID', 'bar']
- ],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- def test_int128(self):
- self.assertEqual(self.get_decl('__int128 a;'),
- ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['__int128']]]])
-
-
- def test_nested_decls(self): # the fun begins
- self.assertEqual(self.get_decl('char** ar2D;'),
- ['Decl', 'ar2D',
- ['PtrDecl', ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]]])
-
- self.assertEqual(self.get_decl('int (*a)[1][2];'),
- ['Decl', 'a',
- ['PtrDecl',
- ['ArrayDecl', '1', [],
- ['ArrayDecl', '2', [],
- ['TypeDecl', ['IdentifierType', ['int']]]]]]])
-
- self.assertEqual(self.get_decl('int *a[1][2];'),
- ['Decl', 'a',
- ['ArrayDecl', '1', [],
- ['ArrayDecl', '2', [],
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]]])
-
- self.assertEqual(self.get_decl('char* const* p;'),
- ['Decl', 'p',
- ['PtrDecl', ['PtrDecl', ['const'],
- ['TypeDecl', ['IdentifierType', ['char']]]]]])
-
- self.assertEqual(self.get_decl('char* * const p;'),
- ['Decl', 'p',
- ['PtrDecl', ['const'], ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]]])
-
- self.assertEqual(self.get_decl('char ***ar3D[40];'),
- ['Decl', 'ar3D',
- ['ArrayDecl', '40', [],
- ['PtrDecl', ['PtrDecl', ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
-
- self.assertEqual(self.get_decl('char (***ar3D)[40];'),
- ['Decl', 'ar3D',
- ['PtrDecl', ['PtrDecl', ['PtrDecl',
- ['ArrayDecl', '40', [], ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
-
- self.assertEqual(self.get_decl('int (*x[4])(char, int);'),
- ['Decl', 'x',
- ['ArrayDecl', '4', [],
- ['PtrDecl',
- ['FuncDecl',
- [ ['Typename', ['TypeDecl', ['IdentifierType', ['char']]]],
- ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]]])
-
- self.assertEqual(self.get_decl('char *(*(**foo [][8])())[];'),
- ['Decl', 'foo',
- ['ArrayDecl', '', [],
- ['ArrayDecl', '8', [],
- ['PtrDecl', ['PtrDecl',
- ['FuncDecl',
- [],
- ['PtrDecl',
- ['ArrayDecl', '', [],
- ['PtrDecl',
- ['TypeDecl',
- ['IdentifierType', ['char']]]]]]]]]]]])
-
- # explore named and unnamed function pointer parameters,
- # with and without qualifiers
-
- # unnamed w/o quals
- self.assertEqual(self.get_decl('int (*k)(int);'),
- ['Decl', 'k',
- ['PtrDecl',
- ['FuncDecl',
- [['Typename', ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- # unnamed w/ quals
- self.assertEqual(self.get_decl('int (*k)(const int);'),
- ['Decl', 'k',
- ['PtrDecl',
- ['FuncDecl',
- [['Typename', ['const'], ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- # named w/o quals
- self.assertEqual(self.get_decl('int (*k)(int q);'),
- ['Decl', 'k',
- ['PtrDecl',
- ['FuncDecl',
- [['Decl', 'q', ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- # named w/ quals
- self.assertEqual(self.get_decl('int (*k)(const volatile int q);'),
- ['Decl', 'k',
- ['PtrDecl',
- ['FuncDecl',
- [['Decl', ['const', 'volatile'], 'q',
- ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- self.assertEqual(self.get_decl('int (*k)(const volatile int* q);'),
- ['Decl', 'k',
- ['PtrDecl',
- ['FuncDecl',
- [['Decl', ['const', 'volatile'], 'q',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['int']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- # restrict qualifier
- self.assertEqual(self.get_decl('int (*k)(restrict int* q);'),
- ['Decl', 'k',
- ['PtrDecl',
- ['FuncDecl',
- [['Decl', ['restrict'], 'q',
- ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['int']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- def test_func_decls_with_array_dim_qualifiers(self):
- self.assertEqual(self.get_decl('int zz(int p[static 10]);'),
- ['Decl', 'zz',
- ['FuncDecl',
- [['Decl', 'p', ['ArrayDecl', '10', ['static'],
- ['TypeDecl', ['IdentifierType', ['int']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- self.assertEqual(self.get_decl('int zz(int p[const 10]);'),
- ['Decl', 'zz',
- ['FuncDecl',
- [['Decl', 'p', ['ArrayDecl', '10', ['const'],
- ['TypeDecl', ['IdentifierType', ['int']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- self.assertEqual(self.get_decl('int zz(int p[restrict][5]);'),
- ['Decl', 'zz',
- ['FuncDecl',
- [['Decl', 'p', ['ArrayDecl', '', ['restrict'],
- ['ArrayDecl', '5', [],
- ['TypeDecl', ['IdentifierType', ['int']]]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- self.assertEqual(self.get_decl('int zz(int p[const restrict static 10][5]);'),
- ['Decl', 'zz',
- ['FuncDecl',
- [['Decl', 'p', ['ArrayDecl', '10', ['const', 'restrict', 'static'],
- ['ArrayDecl', '5', [],
- ['TypeDecl', ['IdentifierType', ['int']]]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- def test_qualifiers_storage_specifiers(self):
- def assert_qs(txt, index, quals, storage):
- d = self.parse(txt).ext[index]
- self.assertEqual(d.quals, quals)
- self.assertEqual(d.storage, storage)
-
- assert_qs("extern int p;", 0, [], ['extern'])
- assert_qs("const long p = 6;", 0, ['const'], [])
-
- d1 = "static const int p, q, r;"
- for i in range(3):
- assert_qs(d1, i, ['const'], ['static'])
-
- d2 = "static char * const p;"
- assert_qs(d2, 0, [], ['static'])
- pdecl = self.parse(d2).ext[0].type
- self.assertIsInstance(pdecl, PtrDecl)
- self.assertEqual(pdecl.quals, ['const'])
-
- def test_sizeof(self):
- e = """
- void foo()
- {
- int a = sizeof k;
- int b = sizeof(int);
- int c = sizeof(int**);;
-
- char* p = "just to make sure this parses w/o error...";
- int d = sizeof(int());
- }
- """
- compound = self.parse(e).ext[0].body
-
- s1 = compound.block_items[0].init
- self.assertIsInstance(s1, UnaryOp)
- self.assertEqual(s1.op, 'sizeof')
- self.assertIsInstance(s1.expr, ID)
- self.assertEqual(s1.expr.name, 'k')
-
- s2 = compound.block_items[1].init
- self.assertEqual(expand_decl(s2.expr),
- ['Typename', ['TypeDecl', ['IdentifierType', ['int']]]])
-
- s3 = compound.block_items[2].init
- self.assertEqual(expand_decl(s3.expr),
- ['Typename',
- ['PtrDecl',
- ['PtrDecl',
- ['TypeDecl',
- ['IdentifierType', ['int']]]]]])
-
- def test_offsetof(self):
- e = """
- void foo() {
- int a = offsetof(struct S, p);
- a.b = offsetof(struct sockaddr, sp) + strlen(bar);
- int a = offsetof(struct S, p.q.r);
- int a = offsetof(struct S, p[5].q[4][5]);
- }
- """
- compound = self.parse(e).ext[0].body
- s1 = compound.block_items[0].init
- self.assertIsInstance(s1, FuncCall)
- self.assertIsInstance(s1.name, ID)
- self.assertEqual(s1.name.name, 'offsetof')
- self.assertIsInstance(s1.args.exprs[0], Typename)
- self.assertIsInstance(s1.args.exprs[1], ID)
- s3 = compound.block_items[2].init
- self.assertIsInstance(s3.args.exprs[1], StructRef)
- s4 = compound.block_items[3].init
- self.assertIsInstance(s4.args.exprs[1], ArrayRef)
-
- def test_compound_statement(self):
- e = """
- void foo() {
- }
- """
- compound = self.parse(e).ext[0].body
- self.assertIsInstance(compound, Compound)
- self.assert_coord(compound, 2)
-
- # The C99 compound literal feature
- #
- def test_compound_literals(self):
- ps1 = self.parse(r'''
- void foo() {
- p = (long long){k};
- tc = (struct jk){.a = {1, 2}, .b[0] = t};
- }''')
-
- compound = ps1.ext[0].body.block_items[0].rvalue
- self.assertEqual(expand_decl(compound.type),
- ['Typename', ['TypeDecl', ['IdentifierType', ['long', 'long']]]])
- self.assertEqual(expand_init(compound.init),
- [['ID', 'k']])
-
- compound = ps1.ext[0].body.block_items[1].rvalue
- self.assertEqual(expand_decl(compound.type),
- ['Typename', ['TypeDecl', ['Struct', 'jk', []]]])
- self.assertEqual(expand_init(compound.init),
- [
- ([['ID', 'a']], [['Constant', 'int', '1'], ['Constant', 'int', '2']]),
- ([['ID', 'b'], ['Constant', 'int', '0']], ['ID', 't'])])
-
- def test_enums(self):
- e1 = "enum mycolor op;"
- e1_type = self.parse(e1).ext[0].type.type
-
- self.assertIsInstance(e1_type, Enum)
- self.assertEqual(e1_type.name, 'mycolor')
- self.assertEqual(e1_type.values, None)
-
- e2 = "enum mysize {large=20, small, medium} shoes;"
- e2_type = self.parse(e2).ext[0].type.type
-
- self.assertIsInstance(e2_type, Enum)
- self.assertEqual(e2_type.name, 'mysize')
-
- e2_elist = e2_type.values
- self.assertIsInstance(e2_elist, EnumeratorList)
-
- for e2_eval in e2_elist.enumerators:
- self.assertIsInstance(e2_eval, Enumerator)
-
- self.assertEqual(e2_elist.enumerators[0].name, 'large')
- self.assertEqual(e2_elist.enumerators[0].value.value, '20')
- self.assertEqual(e2_elist.enumerators[2].name, 'medium')
- self.assertEqual(e2_elist.enumerators[2].value, None)
-
- # enum with trailing comma (C99 feature)
- e3 = """
- enum
- {
- red,
- blue,
- green,
- } color;
- """
-
- e3_type = self.parse(e3).ext[0].type.type
- self.assertIsInstance(e3_type, Enum)
- e3_elist = e3_type.values
- self.assertIsInstance(e3_elist, EnumeratorList)
-
- for e3_eval in e3_elist.enumerators:
- self.assertIsInstance(e3_eval, Enumerator)
-
- self.assertEqual(e3_elist.enumerators[0].name, 'red')
- self.assertEqual(e3_elist.enumerators[0].value, None)
- self.assertEqual(e3_elist.enumerators[1].name, 'blue')
- self.assertEqual(e3_elist.enumerators[2].name, 'green')
-
- def test_typedef(self):
- # without typedef, error
- s1 = """
- node k;
- """
- self.assertRaises(ParseError, self.parse, s1)
-
- # now with typedef, works
- s2 = """
- typedef void* node;
- node k;
- """
- ps2 = self.parse(s2)
- self.assertEqual(expand_decl(ps2.ext[0]),
- ['Typedef', 'node',
- ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['void']]]]])
-
- self.assertEqual(expand_decl(ps2.ext[1]),
- ['Decl', 'k',
- ['TypeDecl', ['IdentifierType', ['node']]]])
-
- s3 = """
- typedef int T;
- typedef T *pT;
-
- pT aa, bb;
- """
- ps3 = self.parse(s3)
- self.assertEqual(expand_decl(ps3.ext[3]),
- ['Decl', 'bb',
- ['TypeDecl', ['IdentifierType', ['pT']]]])
-
- s4 = '''
- typedef char* __builtin_va_list;
- typedef __builtin_va_list __gnuc_va_list;
- '''
- ps4 = self.parse(s4)
- self.assertEqual(expand_decl(ps4.ext[1]),
- ['Typedef', '__gnuc_va_list',
- ['TypeDecl',
- ['IdentifierType', ['__builtin_va_list']]]])
-
- s5 = '''typedef struct tagHash Hash;'''
- ps5 = self.parse(s5)
- self.assertEqual(expand_decl(ps5.ext[0]),
- ['Typedef', 'Hash', ['TypeDecl', ['Struct', 'tagHash', []]]])
-
- def test_struct_union(self):
- s1 = """
- struct {
- int id;
- char* name;
- } joe;
- """
-
- self.assertEqual(expand_decl(self.parse(s1).ext[0]),
- ['Decl', 'joe',
- ['TypeDecl', ['Struct', None,
- [ ['Decl', 'id',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', 'name',
- ['PtrDecl',
- ['TypeDecl',
- ['IdentifierType', ['char']]]]]]]]])
-
- s2 = """
- struct node p;
- """
- self.assertEqual(expand_decl(self.parse(s2).ext[0]),
- ['Decl', 'p',
- ['TypeDecl', ['Struct', 'node', []]]])
-
- s21 = """
- union pri ra;
- """
- self.assertEqual(expand_decl(self.parse(s21).ext[0]),
- ['Decl', 'ra',
- ['TypeDecl', ['Union', 'pri', []]]])
-
- s3 = """
- struct node* p;
- """
- self.assertEqual(expand_decl(self.parse(s3).ext[0]),
- ['Decl', 'p',
- ['PtrDecl',
- ['TypeDecl', ['Struct', 'node', []]]]])
-
- s4 = """
- struct node;
- """
- self.assertEqual(expand_decl(self.parse(s4).ext[0]),
- ['Decl', None,
- ['Struct', 'node', []]])
-
- s5 = """
- union
- {
- struct
- {
- int type;
- } n;
-
- struct
- {
- int type;
- int intnode;
- } ni;
- } u;
- """
- self.assertEqual(expand_decl(self.parse(s5).ext[0]),
- ['Decl', 'u',
- ['TypeDecl',
- ['Union', None,
- [['Decl', 'n',
- ['TypeDecl',
- ['Struct', None,
- [['Decl', 'type',
- ['TypeDecl', ['IdentifierType', ['int']]]]]]]],
- ['Decl', 'ni',
- ['TypeDecl',
- ['Struct', None,
- [['Decl', 'type',
- ['TypeDecl', ['IdentifierType', ['int']]]],
- ['Decl', 'intnode',
- ['TypeDecl', ['IdentifierType', ['int']]]]]]]]]]]])
-
- s6 = """
- typedef struct foo_tag
- {
- void* data;
- } foo, *pfoo;
- """
- s6_ast = self.parse(s6)
-
- self.assertEqual(expand_decl(s6_ast.ext[0]),
- ['Typedef', 'foo',
- ['TypeDecl',
- ['Struct', 'foo_tag',
- [['Decl', 'data',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]])
-
- self.assertEqual(expand_decl(s6_ast.ext[1]),
- ['Typedef', 'pfoo',
- ['PtrDecl',
- ['TypeDecl',
- ['Struct', 'foo_tag',
- [['Decl', 'data',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['void']]]]]]]]]])
-
- s7 = r"""
- struct _on_exit_args {
- void * _fnargs[32];
- void * _dso_handle[32];
-
- long _fntypes;
- #line 77 "D:\eli\cpp_stuff\libc_include/sys/reent.h"
-
- long _is_cxa;
- };
- """
-
- s7_ast = self.parse(s7, filename='test.c')
- self.assert_coord(s7_ast.ext[0].type.decls[2], 6, 22, 'test.c')
- self.assert_coord(s7_ast.ext[0].type.decls[3], 78, 22,
- r'D:\eli\cpp_stuff\libc_include/sys/reent.h')
-
- s8 = """
- typedef enum tagReturnCode {SUCCESS, FAIL} ReturnCode;
-
- typedef struct tagEntry
- {
- char* key;
- char* value;
- } Entry;
-
-
- typedef struct tagNode
- {
- Entry* entry;
-
- struct tagNode* next;
- } Node;
-
- typedef struct tagHash
- {
- unsigned int table_size;
-
- Node** heads;
-
- } Hash;
- """
- s8_ast = self.parse(s8)
- self.assertEqual(expand_decl(s8_ast.ext[3]),
- ['Typedef', 'Hash',
- ['TypeDecl', ['Struct', 'tagHash',
- [['Decl', 'table_size',
- ['TypeDecl', ['IdentifierType', ['unsigned', 'int']]]],
- ['Decl', 'heads',
- ['PtrDecl', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['Node']]]]]]]]]])
-
- def test_struct_with_extra_semis_inside(self):
- s1 = """
- struct {
- int a;;
- } foo;
- """
- s1_ast = self.parse(s1)
- self.assertEqual(expand_decl(s1_ast.ext[0]),
- ['Decl', 'foo',
- ['TypeDecl', ['Struct', None,
- [['Decl', 'a',
- ['TypeDecl', ['IdentifierType', ['int']]]]]]]])
-
- s2 = """
- struct {
- int a;;;;
- float b, c;
- ;;
- char d;
- } foo;
- """
- s2_ast = self.parse(s2)
- self.assertEqual(expand_decl(s2_ast.ext[0]),
- ['Decl', 'foo',
- ['TypeDecl', ['Struct', None,
- [['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]],
- ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['float']]]],
- ['Decl', 'c', ['TypeDecl', ['IdentifierType', ['float']]]],
- ['Decl', 'd',
- ['TypeDecl', ['IdentifierType', ['char']]]]]]]])
-
- def test_anonymous_struct_union(self):
- s1 = """
- union
- {
- union
- {
- int i;
- long l;
- };
-
- struct
- {
- int type;
- int intnode;
- };
- } u;
- """
-
- self.assertEqual(expand_decl(self.parse(s1).ext[0]),
- ['Decl', 'u',
- ['TypeDecl',
- ['Union', None,
- [['Decl', None,
- ['Union', None,
- [['Decl', 'i',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', 'l',
- ['TypeDecl',
- ['IdentifierType', ['long']]]]]]],
- ['Decl', None,
- ['Struct', None,
- [['Decl', 'type',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', 'intnode',
- ['TypeDecl',
- ['IdentifierType', ['int']]]]]]]]]]])
-
- s2 = """
- struct
- {
- int i;
- union
- {
- int id;
- char* name;
- };
- float f;
- } joe;
- """
-
- self.assertEqual(expand_decl(self.parse(s2).ext[0]),
- ['Decl', 'joe',
- ['TypeDecl',
- ['Struct', None,
- [['Decl', 'i',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', None,
- ['Union', None,
- [['Decl', 'id',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', 'name',
- ['PtrDecl',
- ['TypeDecl',
- ['IdentifierType', ['char']]]]]]]],
- ['Decl', 'f',
- ['TypeDecl',
- ['IdentifierType', ['float']]]]]]]])
-
- # ISO/IEC 9899:201x Commitee Draft 2010-11-16, N1539
- # section 6.7.2.1, par. 19, example 1
- s3 = """
- struct v {
- union {
- struct { int i, j; };
- struct { long k, l; } w;
- };
- int m;
- } v1;
- """
-
- self.assertEqual(expand_decl(self.parse(s3).ext[0]),
- ['Decl', 'v1',
- ['TypeDecl',
- ['Struct', 'v',
- [['Decl', None,
- ['Union', None,
- [['Decl', None,
- ['Struct', None,
- [['Decl', 'i',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', 'j',
- ['TypeDecl',
- ['IdentifierType', ['int']]]]]]],
- ['Decl', 'w',
- ['TypeDecl',
- ['Struct', None,
- [['Decl', 'k',
- ['TypeDecl',
- ['IdentifierType', ['long']]]],
- ['Decl', 'l',
- ['TypeDecl',
- ['IdentifierType', ['long']]]]]]]]]]],
- ['Decl', 'm',
- ['TypeDecl',
- ['IdentifierType', ['int']]]]]]]])
-
- s4 = """
- struct v {
- int i;
- float;
- } v2;"""
- # just make sure this doesn't raise ParseError
- self.parse(s4)
-
- def test_struct_members_namespace(self):
- """ Tests that structure/union member names reside in a separate
- namespace and can be named after existing types.
- """
- s1 = """
- typedef int Name;
- typedef Name NameArray[10];
-
- struct {
- Name Name;
- Name NameArray[3];
- } sye;
-
- void main(void)
- {
- sye.Name = 1;
- }
- """
-
- s1_ast = self.parse(s1)
- self.assertEqual(expand_decl(s1_ast.ext[2]),
- ['Decl', 'sye',
- ['TypeDecl', ['Struct', None,
- [ ['Decl', 'Name',
- ['TypeDecl',
- ['IdentifierType', ['Name']]]],
- ['Decl', 'NameArray',
- ['ArrayDecl', '3', [],
- ['TypeDecl', ['IdentifierType', ['Name']]]]]]]]])
- self.assertEqual(s1_ast.ext[3].body.block_items[0].lvalue.field.name, 'Name')
-
- def test_struct_bitfields(self):
- # a struct with two bitfields, one unnamed
- s1 = """
- struct {
- int k:6;
- int :2;
- } joe;
- """
-
- parsed_struct = self.parse(s1).ext[0]
-
- # We can see here the name of the decl for the unnamed bitfield is
- # None, but expand_decl doesn't show bitfield widths
- # ...
- self.assertEqual(expand_decl(parsed_struct),
- ['Decl', 'joe',
- ['TypeDecl', ['Struct', None,
- [ ['Decl', 'k',
- ['TypeDecl',
- ['IdentifierType', ['int']]]],
- ['Decl', None,
- ['TypeDecl',
- ['IdentifierType', ['int']]]]]]]])
-
- # ...
- # so we test them manually
- self.assertEqual(parsed_struct.type.type.decls[0].bitsize.value, '6')
- self.assertEqual(parsed_struct.type.type.decls[1].bitsize.value, '2')
-
- def test_struct_empty(self):
- """
- Tests that parsing an empty struct works.
-
- Empty structs do NOT follow C99 (See 6.2.5-20 of the C99 standard).
- This is nevertheless supported by some compilers (clang, gcc),
- especially when using FORTIFY code.
- Some compilers (visual) will fail to compile with an error.
- """
- # an empty struct. This is NOT C99 compliant
- s1 = """
- struct foo { };
- """
-
- parsed_struct = self.parse(s1).ext[0]
- self.assertEqual(expand_decl(parsed_struct),
- ['Decl', None, ['Struct', 'foo', []]])
-
- s2 = """struct { } foo;"""
- parsed_struct = self.parse(s2).ext[0]
- self.assertEqual(expand_decl(parsed_struct),
- ['Decl', 'foo', ['TypeDecl', ['Struct', None, []]]])
-
- s3 = """union { } foo;"""
- parsed_struct = self.parse(s3).ext[0]
- self.assertEqual(expand_decl(parsed_struct),
- ['Decl', 'foo', ['TypeDecl', ['Union', None, []]]])
-
- def test_tags_namespace(self):
- """ Tests that the tags of structs/unions/enums reside in a separate namespace and
- can be named after existing types.
- """
- s1 = """
- typedef int tagEntry;
-
- struct tagEntry
- {
- char* key;
- char* value;
- } Entry;
- """
-
- s1_ast = self.parse(s1)
- self.assertEqual(expand_decl(s1_ast.ext[1]),
- ['Decl', 'Entry',
- ['TypeDecl', ['Struct', 'tagEntry',
- [['Decl', 'key',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
- ['Decl', 'value',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
-
- s2 = """
- struct tagEntry;
-
- typedef struct tagEntry tagEntry;
-
- struct tagEntry
- {
- char* key;
- char* value;
- } Entry;
- """
-
- s2_ast = self.parse(s2)
- self.assertEqual(expand_decl(s2_ast.ext[2]),
- ['Decl', 'Entry',
- ['TypeDecl', ['Struct', 'tagEntry',
- [['Decl', 'key',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]],
- ['Decl', 'value',
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]]]]])
-
- s3 = """
- typedef int mytag;
-
- enum mytag {ABC, CDE};
- enum mytag joe;
- """
-
- s3_type = self.parse(s3).ext[1].type
-
- self.assertIsInstance(s3_type, Enum)
- self.assertEqual(s3_type.name, 'mytag')
-
- def test_multi_decls(self):
- d1 = 'int a, b;'
-
- self.assertEqual(self.get_decl(d1, 0),
- ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
- self.assertEqual(self.get_decl(d1, 1),
- ['Decl', 'b', ['TypeDecl', ['IdentifierType', ['int']]]])
-
- d2 = 'char* p, notp, ar[4];'
- self.assertEqual(self.get_decl(d2, 0),
- ['Decl', 'p',
- ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]])
- self.assertEqual(self.get_decl(d2, 1),
- ['Decl', 'notp', ['TypeDecl', ['IdentifierType', ['char']]]])
- self.assertEqual(self.get_decl(d2, 2),
- ['Decl', 'ar',
- ['ArrayDecl', '4', [],
- ['TypeDecl', ['IdentifierType', ['char']]]]])
-
- def test_invalid_multiple_types_error(self):
- bad = [
- 'int enum {ab, cd} fubr;',
- 'enum kid char brbr;']
-
- for b in bad:
- self.assertRaises(ParseError, self.parse, b)
-
- def test_duplicate_typedef(self):
- """ Tests that redeclarations of existing types are parsed correctly.
- This is non-standard, but allowed by many compilers.
- """
- d1 = '''
- typedef int numbertype;
- typedef int numbertype;
- '''
-
- self.assertEqual(self.get_decl(d1, 0),
- ['Typedef', 'numbertype',
- ['TypeDecl', ['IdentifierType', ['int']]]])
- self.assertEqual(self.get_decl(d1, 1),
- ['Typedef', 'numbertype',
- ['TypeDecl', ['IdentifierType', ['int']]]])
-
- d2 = '''
- typedef int (*funcptr)(int x);
- typedef int (*funcptr)(int x);
- '''
- self.assertEqual(self.get_decl(d2, 0),
- ['Typedef', 'funcptr',
- ['PtrDecl', ['FuncDecl',
- [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
- self.assertEqual(self.get_decl(d2, 1),
- ['Typedef', 'funcptr',
- ['PtrDecl', ['FuncDecl',
- [['Decl', 'x', ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]]])
-
- d3 = '''
- typedef int numberarray[5];
- typedef int numberarray[5];
- '''
- self.assertEqual(self.get_decl(d3, 0),
- ['Typedef', 'numberarray',
- ['ArrayDecl', '5', [],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
- self.assertEqual(self.get_decl(d3, 1),
- ['Typedef', 'numberarray',
- ['ArrayDecl', '5', [],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- def test_decl_inits(self):
- d1 = 'int a = 16;'
- #~ self.parse(d1).show()
- self.assertEqual(self.get_decl(d1),
- ['Decl', 'a', ['TypeDecl', ['IdentifierType', ['int']]]])
- self.assertEqual(self.get_decl_init(d1),
- ['Constant', 'int', '16'])
-
- d1_1 = 'float f = 0xEF.56p1;'
- self.assertEqual(self.get_decl_init(d1_1),
- ['Constant', 'float', '0xEF.56p1'])
-
- d1_2 = 'int bitmask = 0b1001010;'
- self.assertEqual(self.get_decl_init(d1_2),
- ['Constant', 'int', '0b1001010'])
-
- d2 = 'long ar[] = {7, 8, 9};'
- self.assertEqual(self.get_decl(d2),
- ['Decl', 'ar',
- ['ArrayDecl', '', [],
- ['TypeDecl', ['IdentifierType', ['long']]]]])
- self.assertEqual(self.get_decl_init(d2),
- [ ['Constant', 'int', '7'],
- ['Constant', 'int', '8'],
- ['Constant', 'int', '9']])
-
- d21 = 'long ar[4] = {};'
- self.assertEqual(self.get_decl_init(d21), [])
-
- d3 = 'char p = j;'
- self.assertEqual(self.get_decl(d3),
- ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['char']]]])
- self.assertEqual(self.get_decl_init(d3),
- ['ID', 'j'])
-
- d4 = "char x = 'c', *p = {0, 1, 2, {4, 5}, 6};"
- self.assertEqual(self.get_decl(d4, 0),
- ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['char']]]])
- self.assertEqual(self.get_decl_init(d4, 0),
- ['Constant', 'char', "'c'"])
- self.assertEqual(self.get_decl(d4, 1),
- ['Decl', 'p',
- ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]])
-
- self.assertEqual(self.get_decl_init(d4, 1),
- [ ['Constant', 'int', '0'],
- ['Constant', 'int', '1'],
- ['Constant', 'int', '2'],
- [['Constant', 'int', '4'],
- ['Constant', 'int', '5']],
- ['Constant', 'int', '6']])
-
- d5 = 'float d = 1.0;'
- self.assertEqual(self.get_decl_init(d5),
- ['Constant', 'double', '1.0'])
-
- d51 = 'float ld = 1.0l;'
- self.assertEqual(self.get_decl_init(d51),
- ['Constant', 'long double', '1.0l'])
-
- d52 = 'float ld = 1.0L;'
- self.assertEqual(self.get_decl_init(d52),
- ['Constant', 'long double', '1.0L'])
-
- d53 = 'float ld = 1.0f;'
- self.assertEqual(self.get_decl_init(d53),
- ['Constant', 'float', '1.0f'])
-
- d54 = 'float ld = 1.0F;'
- self.assertEqual(self.get_decl_init(d54),
- ['Constant', 'float', '1.0F'])
-
- d55 = 'float ld = 0xDE.38p0;'
- self.assertEqual(self.get_decl_init(d55),
- ['Constant', 'float', '0xDE.38p0'])
-
- def test_decl_named_inits(self):
- d1 = 'int a = {.k = 16};'
- self.assertEqual(self.get_decl_init(d1),
- [( [['ID', 'k']],
- ['Constant', 'int', '16'])])
-
- d2 = 'int a = { [0].a = {1}, [1].a[0] = 2 };'
- self.assertEqual(self.get_decl_init(d2),
- [
- ([['Constant', 'int', '0'], ['ID', 'a']],
- [['Constant', 'int', '1']]),
- ([['Constant', 'int', '1'], ['ID', 'a'], ['Constant', 'int', '0']],
- ['Constant', 'int', '2'])])
-
- d3 = 'int a = { .a = 1, .c = 3, 4, .b = 5};'
- self.assertEqual(self.get_decl_init(d3),
- [
- ([['ID', 'a']], ['Constant', 'int', '1']),
- ([['ID', 'c']], ['Constant', 'int', '3']),
- ['Constant', 'int', '4'],
- ([['ID', 'b']], ['Constant', 'int', '5'])])
-
- def test_function_definitions(self):
- def parse_fdef(str):
- return self.parse(str).ext[0]
-
- def fdef_decl(fdef):
- return expand_decl(fdef.decl)
-
- f1 = parse_fdef('''
- int factorial(int p)
- {
- return 3;
- }
- ''')
-
- self.assertEqual(fdef_decl(f1),
- ['Decl', 'factorial',
- ['FuncDecl',
- [['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- self.assertEqual(type(f1.body.block_items[0]), Return)
-
- f2 = parse_fdef('''
- char* zzz(int p, char* c)
- {
- int a;
- char b;
-
- a = b + 2;
- return 3;
- }
- ''')
-
- self.assertEqual(fdef_decl(f2),
- ['Decl', 'zzz',
- ['FuncDecl',
- [ ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['int']]]],
- ['Decl', 'c', ['PtrDecl',
- ['TypeDecl', ['IdentifierType', ['char']]]]]],
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
-
- self.assertEqual(list(map(type, f2.body.block_items)),
- [Decl, Decl, Assignment, Return])
-
- f3 = parse_fdef('''
- char* zzz(p, c)
- long p, *c;
- {
- int a;
- char b;
-
- a = b + 2;
- return 3;
- }
- ''')
-
- self.assertEqual(fdef_decl(f3),
- ['Decl', 'zzz',
- ['FuncDecl',
- [ ['ID', 'p'],
- ['ID', 'c']],
- ['PtrDecl', ['TypeDecl', ['IdentifierType', ['char']]]]]])
-
- self.assertEqual(list(map(type, f3.body.block_items)),
- [Decl, Decl, Assignment, Return])
-
- self.assertEqual(expand_decl(f3.param_decls[0]),
- ['Decl', 'p', ['TypeDecl', ['IdentifierType', ['long']]]])
- self.assertEqual(expand_decl(f3.param_decls[1]),
- ['Decl', 'c', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['long']]]]])
-
- # function return values and parameters may not have type information
- f4 = parse_fdef('''
- que(p)
- {
- return 3;
- }
- ''')
-
- self.assertEqual(fdef_decl(f4),
- ['Decl', 'que',
- ['FuncDecl',
- [['ID', 'p']],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- def test_unified_string_literals(self):
- # simple string, for reference
- d1 = self.get_decl_init('char* s = "hello";')
- self.assertEqual(d1, ['Constant', 'string', '"hello"'])
-
- d2 = self.get_decl_init('char* s = "hello" " world";')
- self.assertEqual(d2, ['Constant', 'string', '"hello world"'])
-
- # the test case from issue 6
- d3 = self.parse(r'''
- int main() {
- fprintf(stderr,
- "Wrong Params?\n"
- "Usage:\n"
- "%s <binary_file_path>\n",
- argv[0]
- );
- }
- ''')
-
- self.assertEqual(
- d3.ext[0].body.block_items[0].args.exprs[1].value,
- r'"Wrong Params?\nUsage:\n%s <binary_file_path>\n"')
-
- d4 = self.get_decl_init('char* s = "" "foobar";')
- self.assertEqual(d4, ['Constant', 'string', '"foobar"'])
-
- d5 = self.get_decl_init(r'char* s = "foo\"" "bar";')
- self.assertEqual(d5, ['Constant', 'string', r'"foo\"bar"'])
-
- def test_unified_wstring_literals(self):
- d1 = self.get_decl_init('char* s = L"hello" L"world";')
- self.assertEqual(d1, ['Constant', 'string', 'L"helloworld"'])
-
- d2 = self.get_decl_init('char* s = L"hello " L"world" L" and I";')
- self.assertEqual(d2, ['Constant', 'string', 'L"hello world and I"'])
-
- def test_inline_specifier(self):
- ps2 = self.parse('static inline void inlinefoo(void);')
- self.assertEqual(ps2.ext[0].funcspec, ['inline'])
-
- # variable length array
- def test_vla(self):
- ps2 = self.parse(r'''
- int main() {
- int size;
- int var[size = 5];
-
- int var2[*];
- }
- ''')
- self.assertIsInstance(ps2.ext[0].body.block_items[1].type.dim, Assignment)
- self.assertIsInstance(ps2.ext[0].body.block_items[2].type.dim, ID)
-
- def test_pragma(self):
- s1 = r'''
- #pragma bar
- void main() {
- #pragma foo
- for(;;) {}
- #pragma
- }
- struct s {
- #pragma baz
- } s;
- '''
- s1_ast = self.parse(s1)
- self.assertIsInstance(s1_ast.ext[0], Pragma)
- self.assertEqual(s1_ast.ext[0].string, 'bar')
- self.assertEqual(s1_ast.ext[0].coord.line, 2)
-
- self.assertIsInstance(s1_ast.ext[1].body.block_items[0], Pragma)
- self.assertEqual(s1_ast.ext[1].body.block_items[0].string, 'foo')
- self.assertEqual(s1_ast.ext[1].body.block_items[0].coord.line, 4)
-
- self.assertIsInstance(s1_ast.ext[1].body.block_items[2], Pragma)
- self.assertEqual(s1_ast.ext[1].body.block_items[2].string, '')
- self.assertEqual(s1_ast.ext[1].body.block_items[2].coord.line, 6)
-
- self.assertIsInstance(s1_ast.ext[2].type.type.decls[0], Pragma)
- self.assertEqual(s1_ast.ext[2].type.type.decls[0].string, 'baz')
- self.assertEqual(s1_ast.ext[2].type.type.decls[0].coord.line, 9)
-
- def test_pragmacomp_or_statement(self):
- s1 = r'''
- void main() {
- int sum = 0;
- for (int i; i < 3; i++)
- #pragma omp critical
- sum += 1;
-
- while(sum < 10)
- #pragma omp critical
- sum += 1;
-
- mylabel:
- #pragma foo
- sum += 10;
-
- if (sum > 10)
- #pragma bar
- sum = 10;
-
- switch (sum)
- case 10:
- #pragma foo
- sum = 20;
- }
- '''
- s1_ast = self.parse(s1)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[1], For)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt, Compound)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[0], Pragma)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[1].stmt.block_items[1], Assignment)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[2], While)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt, Compound)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[0], Pragma)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[2].stmt.block_items[1], Assignment)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[3], Label)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt, Compound)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[0], Pragma)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[3].stmt.block_items[1], Assignment)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[4], If)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue, Compound)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[0], Pragma)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[4].iftrue.block_items[1], Assignment)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[5], Switch)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0], Compound)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[0], Pragma)
- self.assertIsInstance(s1_ast.ext[0].body.block_items[5].stmt.stmts[0].block_items[1], Assignment)
-
-
-class TestCParser_whole_code(TestCParser_base):
- """ Testing of parsing whole chunks of code.
-
- Since I don't want to rely on the structure of ASTs too
- much, most of these tests are implemented with visitors.
- """
- # A simple helper visitor that lists the values of all the
- # Constant nodes it sees.
- #
- class ConstantVisitor(NodeVisitor):
- def __init__(self):
- self.values = []
-
- def visit_Constant(self, node):
- self.values.append(node.value)
-
- # This visitor counts the amount of references to the ID
- # with the name provided to it in the constructor.
- #
- class IDNameCounter(NodeVisitor):
- def __init__(self, name):
- self.name = name
- self.nrefs = 0
-
- def visit_ID(self, node):
- if node.name == self.name:
- self.nrefs += 1
-
- # Counts the amount of nodes of a given class
- #
- class NodeKlassCounter(NodeVisitor):
- def __init__(self, node_klass):
- self.klass = node_klass
- self.n = 0
-
- def generic_visit(self, node):
- if node.__class__ == self.klass:
- self.n += 1
-
- NodeVisitor.generic_visit(self, node)
-
- def assert_all_Constants(self, code, constants):
- """ Asserts that the list of all Constant values (by
- 'preorder' appearance) in the chunk of code is as
- given.
- """
- if isinstance(code, str):
- parsed = self.parse(code)
- else:
- parsed = code
-
- cv = self.ConstantVisitor()
- cv.visit(parsed)
- self.assertEqual(cv.values, constants)
-
- def assert_num_ID_refs(self, code, name, num):
- """ Asserts the number of references to the ID with
- the given name.
- """
- if isinstance(code, str):
- parsed = self.parse(code)
- else:
- parsed = code
-
- iv = self.IDNameCounter(name)
- iv.visit(parsed)
- self.assertEqual(iv.nrefs, num)
-
- def assert_num_klass_nodes(self, code, klass, num):
- """ Asserts the amount of klass nodes in the code.
- """
- if isinstance(code, str):
- parsed = self.parse(code)
- else:
- parsed = code
-
- cv = self.NodeKlassCounter(klass)
- cv.visit(parsed)
- self.assertEqual(cv.n, num)
-
- def test_expressions(self):
- e1 = '''int k = (r + 10.0) >> 6 + 8 << (3 & 0x14);'''
- self.assert_all_Constants(e1, ['10.0', '6', '8', '3', '0x14'])
-
- e2 = r'''char n = '\n', *prefix = "st_";'''
- self.assert_all_Constants(e2, [r"'\n'", '"st_"'])
-
- s1 = r'''int main() {
- int i = 5, j = 6, k = 1;
- if ((i=j && k == 1) || k > j)
- printf("Hello, world\n");
- return 0;
- }'''
- ps1 = self.parse(s1)
- self.assert_all_Constants(ps1,
- ['5', '6', '1', '1', '"Hello, world\\n"', '0'])
- self.assert_num_ID_refs(ps1, 'i', 1)
- self.assert_num_ID_refs(ps1, 'j', 2)
-
-
- def test_statements(self):
- s1 = r'''
- void foo(){
- if (sp == 1)
- if (optind >= argc ||
- argv[optind][0] != '-' || argv[optind][1] == '\0')
- return -1;
- else if (strcmp(argv[optind], "--") == 0) {
- optind++;
- return -1;
- }
- }
- '''
-
- self.assert_all_Constants(s1,
- ['1', '0', r"'-'", '1', r"'\0'", '1', r'"--"', '0', '1'])
-
- ps1 = self.parse(s1)
- self.assert_num_ID_refs(ps1, 'argv', 3)
- self.assert_num_ID_refs(ps1, 'optind', 5)
-
- self.assert_num_klass_nodes(ps1, If, 3)
- self.assert_num_klass_nodes(ps1, Return, 2)
- self.assert_num_klass_nodes(ps1, FuncCall, 1) # strcmp
- self.assert_num_klass_nodes(ps1, BinaryOp, 7)
-
- # In the following code, Hash and Node were defined as
- # int to pacify the parser that sees they're used as
- # types
- #
- s2 = r'''
- typedef int Hash, Node;
-
- void HashDestroy(Hash* hash)
- {
- unsigned int i;
-
- if (hash == NULL)
- return;
-
- for (i = 0; i < hash->table_size; ++i)
- {
- Node* temp = hash->heads[i];
-
- while (temp != NULL)
- {
- Node* temp2 = temp;
-
- free(temp->entry->key);
- free(temp->entry->value);
- free(temp->entry);
-
- temp = temp->next;
-
- free(temp2);
- }
- }
-
- free(hash->heads);
- hash->heads = NULL;
-
- free(hash);
- }
- '''
-
- ps2 = self.parse(s2)
- self.assert_num_klass_nodes(ps2, FuncCall, 6)
- self.assert_num_klass_nodes(ps2, FuncDef, 1)
- self.assert_num_klass_nodes(ps2, For, 1)
- self.assert_num_klass_nodes(ps2, While, 1)
- self.assert_num_klass_nodes(ps2, StructRef, 10)
-
- # declarations don't count
- self.assert_num_ID_refs(ps2, 'hash', 6)
- self.assert_num_ID_refs(ps2, 'i', 4)
-
- s3 = r'''
- void x(void) {
- int a, b;
- if (a < b)
- do {
- a = 0;
- } while (0);
- else if (a == b) {
- a = 1;
- }
- }
- '''
-
- ps3 = self.parse(s3)
- self.assert_num_klass_nodes(ps3, DoWhile, 1)
- self.assert_num_ID_refs(ps3, 'a', 4)
- self.assert_all_Constants(ps3, ['0', '0', '1'])
-
- def test_empty_statements(self):
- s1 = r'''
- void foo(void){
- ;
- return;;
-
- ;
- }
- '''
- ps1 = self.parse(s1)
- self.assert_num_klass_nodes(ps1, EmptyStatement, 3)
- self.assert_num_klass_nodes(ps1, Return, 1)
- self.assert_coord(ps1.ext[0].body.block_items[0], 3)
- self.assert_coord(ps1.ext[0].body.block_items[1], 4)
- self.assert_coord(ps1.ext[0].body.block_items[2], 4)
- self.assert_coord(ps1.ext[0].body.block_items[3], 6)
-
- def test_switch_statement(self):
- def assert_case_node(node, const_value):
- self.assertIsInstance(node, Case)
- self.assertIsInstance(node.expr, Constant)
- self.assertEqual(node.expr.value, const_value)
-
- def assert_default_node(node):
- self.assertIsInstance(node, Default)
-
- s1 = r'''
- int foo(void) {
- switch (myvar) {
- case 10:
- k = 10;
- p = k + 1;
- return 10;
- case 20:
- case 30:
- return 20;
- default:
- break;
- }
- return 0;
- }
- '''
- ps1 = self.parse(s1)
- switch = ps1.ext[0].body.block_items[0]
-
- block = switch.stmt.block_items
- assert_case_node(block[0], '10')
- self.assertEqual(len(block[0].stmts), 3)
- assert_case_node(block[1], '20')
- self.assertEqual(len(block[1].stmts), 0)
- assert_case_node(block[2], '30')
- self.assertEqual(len(block[2].stmts), 1)
- assert_default_node(block[3])
-
- s2 = r'''
- int foo(void) {
- switch (myvar) {
- default:
- joe = moe;
- return 10;
- case 10:
- case 20:
- case 30:
- case 40:
- break;
- }
- return 0;
- }
- '''
- ps2 = self.parse(s2)
- switch = ps2.ext[0].body.block_items[0]
-
- block = switch.stmt.block_items
- assert_default_node(block[0])
- self.assertEqual(len(block[0].stmts), 2)
- assert_case_node(block[1], '10')
- self.assertEqual(len(block[1].stmts), 0)
- assert_case_node(block[2], '20')
- self.assertEqual(len(block[1].stmts), 0)
- assert_case_node(block[3], '30')
- self.assertEqual(len(block[1].stmts), 0)
- assert_case_node(block[4], '40')
- self.assertEqual(len(block[4].stmts), 1)
-
- def test_for_statement(self):
- s2 = r'''
- void x(void)
- {
- int i;
- for (i = 0; i < 5; ++i) {
- x = 50;
- }
- }
- '''
- ps2 = self.parse(s2)
- self.assert_num_klass_nodes(ps2, For, 1)
- # here there are 3 refs to 'i' since the declaration doesn't count as
- # a ref in the visitor
- #
- self.assert_num_ID_refs(ps2, 'i', 3)
-
- s3 = r'''
- void x(void)
- {
- for (int i = 0; i < 5; ++i) {
- x = 50;
- }
- }
- '''
- ps3 = self.parse(s3)
- self.assert_num_klass_nodes(ps3, For, 1)
- # here there are 2 refs to 'i' since the declaration doesn't count as
- # a ref in the visitor
- #
- self.assert_num_ID_refs(ps3, 'i', 2)
-
- s4 = r'''
- void x(void) {
- for (int i = 0;;)
- i;
- }
- '''
- ps4 = self.parse(s4)
- self.assert_num_ID_refs(ps4, 'i', 1)
-
- def _open_c_file(self, name):
- """ Find a c file by name, taking into account the current dir can be
- in a couple of typical places
- """
- testdir = os.path.dirname(__file__)
- name = os.path.join(testdir, 'c_files', name)
- assert os.path.exists(name)
- return io.open(name)
-
- def test_whole_file(self):
- # See how pycparser handles a whole, real C file.
- #
- with self._open_c_file('memmgr_with_h.c') as f:
- code = f.read()
- p = self.parse(code)
-
- self.assert_num_klass_nodes(p, FuncDef, 5)
-
- # each FuncDef also has a FuncDecl. 4 declarations
- # + 5 definitions, overall 9
- self.assert_num_klass_nodes(p, FuncDecl, 9)
-
- self.assert_num_klass_nodes(p, Typedef, 4)
-
- self.assertEqual(p.ext[4].coord.line, 88)
- self.assertEqual(p.ext[4].coord.file, "./memmgr.h")
-
- self.assertEqual(p.ext[6].coord.line, 10)
- self.assertEqual(p.ext[6].coord.file, "memmgr.c")
-
- def test_whole_file_with_stdio(self):
- # Parse a whole file with stdio.h included by cpp
- #
- with self._open_c_file('cppd_with_stdio_h.c') as f:
- code = f.read()
- p = self.parse(code)
-
- self.assertIsInstance(p.ext[0], Typedef)
- self.assertEqual(p.ext[0].coord.line, 213)
- self.assertEqual(p.ext[0].coord.file, r"D:\eli\cpp_stuff\libc_include/stddef.h")
-
- self.assertIsInstance(p.ext[-1], FuncDef)
- self.assertEqual(p.ext[-1].coord.line, 15)
- self.assertEqual(p.ext[-1].coord.file, "example_c_file.c")
-
- self.assertIsInstance(p.ext[-8], Typedef)
- self.assertIsInstance(p.ext[-8].type, TypeDecl)
- self.assertEqual(p.ext[-8].name, 'cookie_io_functions_t')
-
-
-class TestCParser_typenames(TestCParser_base):
- """ Test issues related to the typedef-name problem.
- """
- def test_innerscope_typedef(self):
- # should fail since TT is not a type in bar
- s1 = r'''
- void foo() {
- typedef char TT;
- TT x;
- }
- void bar() {
- TT y;
- }
- '''
- self.assertRaises(ParseError, self.parse, s1)
-
- # should succeed since TT is not a type in bar
- s2 = r'''
- void foo() {
- typedef char TT;
- TT x;
- }
- void bar() {
- unsigned TT;
- }
- '''
- self.assertIsInstance(self.parse(s2), FileAST)
-
- def test_ambiguous_parameters(self):
- # From ISO/IEC 9899:TC2, 6.7.5.3.11:
- # "If, in a parameter declaration, an identifier can be treated either
- # as a typedef name or as a parameter name, it shall be taken as a
- # typedef name."
-
- # foo takes an int named aa
- # bar takes a function taking a TT
- s1 = r'''
- typedef char TT;
- int foo(int (aa));
- int bar(int (TT));
- '''
- s1_ast = self.parse(s1)
- self.assertEqual(expand_decl(s1_ast.ext[1].type.args.params[0]),
- ['Decl', 'aa', ['TypeDecl', ['IdentifierType', ['int']]]])
- self.assertEqual(expand_decl(s1_ast.ext[2].type.args.params[0]),
- ['Typename', ['FuncDecl',
- [['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- # foo takes a function taking a char
- # bar takes a function taking a function taking a char
- s2 = r'''
- typedef char TT;
- int foo(int (aa (char)));
- int bar(int (TT (char)));
- '''
- s2_ast = self.parse(s2)
- self.assertEqual(expand_decl(s2_ast.ext[1].type.args.params[0]),
- ['Decl', 'aa', ['FuncDecl',
- [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
- self.assertEqual(expand_decl(s2_ast.ext[2].type.args.params[0]),
- ['Typename', ['FuncDecl',
- [['Typename', ['FuncDecl',
- [['Typename', ['TypeDecl', ['IdentifierType', ['char']]]]],
- ['TypeDecl', ['IdentifierType', ['TT']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
-
- # foo takes an int array named aa
- # bar takes a function taking a TT array
- s3 = r'''
- typedef char TT;
- int foo(int (aa[]));
- int bar(int (TT[]));
- '''
- s3_ast = self.parse(s3)
- self.assertEqual(expand_decl(s3_ast.ext[1].type.args.params[0]),
- ['Decl', 'aa', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['int']]]]])
- self.assertEqual(expand_decl(s3_ast.ext[2].type.args.params[0]),
- ['Typename', ['FuncDecl',
- [['Typename', ['ArrayDecl', '', [], ['TypeDecl', ['IdentifierType', ['TT']]]]]],
- ['TypeDecl', ['IdentifierType', ['int']]]]])
-
- def test_innerscope_reuse_typedef_name(self):
- # identifiers can be reused in inner scopes; the original should be
- # restored at the end of the block
- s1 = r'''
- typedef char TT;
- void foo(void) {
- unsigned TT;
- TT = 10;
- }
- TT x = 5;
- '''
- s1_ast = self.parse(s1)
- self.assertEqual(expand_decl(s1_ast.ext[1].body.block_items[0]),
- ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
- self.assertEqual(expand_decl(s1_ast.ext[2]),
- ['Decl', 'x', ['TypeDecl', ['IdentifierType', ['TT']]]])
-
- # this should be recognized even with an initializer
- s2 = r'''
- typedef char TT;
- void foo(void) {
- unsigned TT = 10;
- }
- '''
- s2_ast = self.parse(s2)
- self.assertEqual(expand_decl(s2_ast.ext[1].body.block_items[0]),
- ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
-
- # before the second local variable, TT is a type; after, it's a
- # variable
- s3 = r'''
- typedef char TT;
- void foo(void) {
- TT tt = sizeof(TT);
- unsigned TT = 10;
- }
- '''
- s3_ast = self.parse(s3)
- self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[0]),
- ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['TT']]]])
- self.assertEqual(expand_decl(s3_ast.ext[1].body.block_items[1]),
- ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
-
- # a variable and its type can even share the same name
- s4 = r'''
- typedef char TT;
- void foo(void) {
- TT TT = sizeof(TT);
- unsigned uu = TT * 2;
- }
- '''
- s4_ast = self.parse(s4)
- self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[0]),
- ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['TT']]]])
- self.assertEqual(expand_decl(s4_ast.ext[1].body.block_items[1]),
- ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
-
- # ensure an error is raised if a type, redeclared as a variable, is
- # used as a type
- s5 = r'''
- typedef char TT;
- void foo(void) {
- unsigned TT = 10;
- TT erroneous = 20;
- }
- '''
- self.assertRaises(ParseError, self.parse, s5)
-
- # reusing a type name should work with multiple declarators
- s6 = r'''
- typedef char TT;
- void foo(void) {
- unsigned TT, uu;
- }
- '''
- s6_ast = self.parse(s6)
- items = s6_ast.ext[1].body.block_items
- self.assertEqual(expand_decl(items[0]),
- ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
- self.assertEqual(expand_decl(items[1]),
- ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['unsigned']]]])
-
- # reusing a type name should work after a pointer
- s7 = r'''
- typedef char TT;
- void foo(void) {
- unsigned * TT;
- }
- '''
- s7_ast = self.parse(s7)
- items = s7_ast.ext[1].body.block_items
- self.assertEqual(expand_decl(items[0]),
- ['Decl', 'TT', ['PtrDecl', ['TypeDecl', ['IdentifierType', ['unsigned']]]]])
-
- # redefine a name in the middle of a multi-declarator declaration
- s8 = r'''
- typedef char TT;
- void foo(void) {
- int tt = sizeof(TT), TT, uu = sizeof(TT);
- int uu = sizeof(tt);
- }
- '''
- s8_ast = self.parse(s8)
- items = s8_ast.ext[1].body.block_items
- self.assertEqual(expand_decl(items[0]),
- ['Decl', 'tt', ['TypeDecl', ['IdentifierType', ['int']]]])
- self.assertEqual(expand_decl(items[1]),
- ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['int']]]])
- self.assertEqual(expand_decl(items[2]),
- ['Decl', 'uu', ['TypeDecl', ['IdentifierType', ['int']]]])
-
- # Don't test this until we have support for it
- # self.assertEqual(expand_init(items[0].init),
- # ['UnaryOp', 'sizeof', ['Typename', ['TypeDecl', ['IdentifierType', ['TT']]]]])
- # self.assertEqual(expand_init(items[2].init),
- # ['UnaryOp', 'sizeof', ['ID', 'TT']])
-
- def test_parameter_reuse_typedef_name(self):
- # identifiers can be reused as parameter names; parameter name scope
- # begins and ends with the function body; it's important that TT is
- # used immediately before the LBRACE or after the RBRACE, to test
- # a corner case
- s1 = r'''
- typedef char TT;
- void foo(unsigned TT, TT bar) {
- TT = 10;
- }
- TT x = 5;
- '''
- s1_ast = self.parse(s1)
- self.assertEqual(expand_decl(s1_ast.ext[1].decl),
- ['Decl', 'foo',
- ['FuncDecl',
- [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
- ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
- ['TypeDecl', ['IdentifierType', ['void']]]]])
-
- # the scope of a parameter name in a function declaration ends at the
- # end of the declaration...so it is effectively never used; it's
- # important that TT is used immediately after the declaration, to
- # test a corner case
- s2 = r'''
- typedef char TT;
- void foo(unsigned TT, TT bar);
- TT x = 5;
- '''
- s2_ast = self.parse(s2)
- self.assertEqual(expand_decl(s2_ast.ext[1]),
- ['Decl', 'foo',
- ['FuncDecl',
- [ ['Decl', 'TT', ['TypeDecl', ['IdentifierType', ['unsigned']]]],
- ['Decl', 'bar', ['TypeDecl', ['IdentifierType', ['TT']]]]],
- ['TypeDecl', ['IdentifierType', ['void']]]]])
-
- # ensure an error is raised if a type, redeclared as a parameter, is
- # used as a type
- s3 = r'''
- typedef char TT;
- void foo(unsigned TT, TT bar) {
- TT erroneous = 20;
- }
- '''
- self.assertRaises(ParseError, self.parse, s3)
-
- def test_nested_function_decls(self):
- # parameter names of nested function declarations must not escape into
- # the top-level function _definition's_ scope; the following must
- # succeed because TT is still a typedef inside foo's body
- s1 = r'''
- typedef char TT;
- void foo(unsigned bar(int TT)) {
- TT x = 10;
- }
- '''
- self.assertIsInstance(self.parse(s1), FileAST)
-
- def test_samescope_reuse_name(self):
- # a typedef name cannot be reused as an object name in the same scope
- s1 = r'''
- typedef char TT;
- char TT = 5;
- '''
- self.assertRaises(ParseError, self.parse, s1)
-
- # ...and vice-versa
- s2 = r'''
- char TT = 5;
- typedef char TT;
- '''
- self.assertRaises(ParseError, self.parse, s2)
-
-
-if __name__ == '__main__':
- #~ suite = unittest.TestLoader().loadTestsFromNames(
- #~ ['test_c_parser.TestCParser_fundamentals.test_typedef'])
-
- #~ unittest.TextTestRunner(verbosity=2).run(suite)
- unittest.main()
diff --git a/tests/test_general.py b/tests/test_general.py
deleted file mode 100644
index 18e388c..0000000
--- a/tests/test_general.py
+++ /dev/null
@@ -1,67 +0,0 @@
-import os
-import platform
-import sys
-import unittest
-
-sys.path.insert(0, '..')
-from pycparser import parse_file, c_ast
-
-CPPPATH = 'cpp'
-
-
-# Test successful parsing
-#
-class TestParsing(unittest.TestCase):
- def _find_file(self, name):
- """ Find a c file by name, taking into account the current dir can be
- in a couple of typical places
- """
- testdir = os.path.dirname(__file__)
- name = os.path.join(testdir, 'c_files', name)
- assert os.path.exists(name)
- return name
-
- def test_without_cpp(self):
- ast = parse_file(self._find_file('example_c_file.c'))
- self.assertIsInstance(ast, c_ast.FileAST)
-
- @unittest.skipUnless(platform.system() == 'Linux',
- 'cpp only works on Linux')
- def test_with_cpp(self):
- memmgr_path = self._find_file('memmgr.c')
- c_files_path = os.path.dirname(memmgr_path)
- ast = parse_file(memmgr_path, use_cpp=True,
- cpp_path=CPPPATH,
- cpp_args='-I%s' % c_files_path)
- self.assertIsInstance(ast, c_ast.FileAST)
-
- fake_libc = os.path.join(c_files_path, '..', '..',
- 'utils', 'fake_libc_include')
- ast2 = parse_file(self._find_file('year.c'), use_cpp=True,
- cpp_path=CPPPATH,
- cpp_args=[r'-I%s' % fake_libc])
-
- self.assertIsInstance(ast2, c_ast.FileAST)
-
- @unittest.skipUnless(platform.system() == 'Linux',
- 'cpp only works on Linux')
- def test_cpp_funkydir(self):
- # This test contains Windows specific path escapes
- if sys.platform != 'win32':
- return
-
- c_files_path = os.path.join('tests', 'c_files')
- ast = parse_file(self._find_file('simplemain.c'), use_cpp=True,
- cpp_path=CPPPATH, cpp_args='-I%s' % c_files_path)
- self.assertIsInstance(ast, c_ast.FileAST)
-
- @unittest.skipUnless(platform.system() == 'Linux',
- 'cpp only works on Linux')
- def test_no_real_content_after_cpp(self):
- ast = parse_file(self._find_file('empty.h'), use_cpp=True,
- cpp_path=CPPPATH)
- self.assertIsInstance(ast, c_ast.FileAST)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index 02bd1e2..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[tox]
-envlist = py27,py34,py35,py36
-
-[testenv]
-commands =
- python tests/all_tests.py
diff --git a/utils/fake_libc_include/X11/Intrinsic.h b/utils/fake_libc_include/X11/Intrinsic.h
deleted file mode 100644
index ab7ebb3..0000000
--- a/utils/fake_libc_include/X11/Intrinsic.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
-#include "_X11_fake_defines.h"
-#include "_X11_fake_typedefs.h"
diff --git a/utils/fake_libc_include/X11/Xlib.h b/utils/fake_libc_include/X11/Xlib.h
deleted file mode 100644
index ab7ebb3..0000000
--- a/utils/fake_libc_include/X11/Xlib.h
+++ /dev/null
@@ -1,4 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
-#include "_X11_fake_defines.h"
-#include "_X11_fake_typedefs.h"
diff --git a/utils/fake_libc_include/X11/_X11_fake_defines.h b/utils/fake_libc_include/X11/_X11_fake_defines.h
deleted file mode 100644
index c88774b..0000000
--- a/utils/fake_libc_include/X11/_X11_fake_defines.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _X11_FAKE_DEFINES_H
-#define _X11_FAKE_DEFINES_H
-
-#define Atom CARD32
-#define Bool int
-#define KeySym CARD32
-#define Pixmap CARD32
-#define Time CARD32
-#define _XFUNCPROTOBEGIN
-#define _XFUNCPROTOEND
-#define _Xconst const
-
-#define _X_RESTRICT_KYWD
-#define Cardinal unsigned int
-#define Boolean int
-#endif
diff --git a/utils/fake_libc_include/X11/_X11_fake_typedefs.h b/utils/fake_libc_include/X11/_X11_fake_typedefs.h
deleted file mode 100644
index 3901142..0000000
--- a/utils/fake_libc_include/X11/_X11_fake_typedefs.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef _X11_FAKE_TYPEDEFS_H
-#define _X11_FAKE_TYPEDEFS_H
-
-typedef char* XPointer;
-typedef unsigned char KeyCode;
-typedef unsigned int CARD32;
-typedef unsigned long VisualID;
-typedef unsigned long XIMResetState;
-typedef unsigned long XID;
-typedef XID Window;
-typedef XID Colormap;
-typedef XID Cursor;
-typedef XID Drawable;
-typedef void* XtPointer;
-typedef XtPointer XtRequestId;
-typedef struct Display Display;
-typedef struct Screen Screen;
-typedef struct Status Status;
-typedef struct Visual Visual;
-typedef struct Widget *Widget;
-typedef struct XColor XColor;
-typedef struct XClassHint XClassHint;
-typedef struct XEvent XEvent;
-typedef struct XFontStruct XFontStruct;
-typedef struct XGCValues XGCValues;
-typedef struct XKeyEvent XKeyEvent;
-typedef struct XKeyPressedEvent XKeyPressedEvent;
-typedef struct XPoint XPoint;
-typedef struct XRectangle XRectangle;
-typedef struct XSelectionRequestEvent XSelectionRequestEvent;
-typedef struct XWindowChanges XWindowChanges;
-typedef struct _XGC _XCG;
-typedef struct _XGC *GC;
-typedef struct _XIC *XIC;
-typedef struct _XIM *XIM;
-typedef struct _XImage XImage;
-
-#endif
diff --git a/utils/fake_libc_include/_ansi.h b/utils/fake_libc_include/_ansi.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/_ansi.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/_fake_defines.h b/utils/fake_libc_include/_fake_defines.h
deleted file mode 100644
index 35bd4ad..0000000
--- a/utils/fake_libc_include/_fake_defines.h
+++ /dev/null
@@ -1,201 +0,0 @@
-#ifndef _FAKE_DEFINES_H
-#define _FAKE_DEFINES_H
-
-#define NULL 0
-#define BUFSIZ 1024
-#define FOPEN_MAX 20
-#define FILENAME_MAX 1024
-
-#ifndef SEEK_SET
-#define SEEK_SET 0 /* set file offset to offset */
-#endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1 /* set file offset to current plus offset */
-#endif
-#ifndef SEEK_END
-#define SEEK_END 2 /* set file offset to EOF plus offset */
-#endif
-
-#define __LITTLE_ENDIAN 1234
-#define LITTLE_ENDIAN __LITTLE_ENDIAN
-#define __BIG_ENDIAN 4321
-#define BIG_ENDIAN __BIG_ENDIAN
-#define __BYTE_ORDER __LITTLE_ENDIAN
-#define BYTE_ORDER __BYTE_ORDER
-
-#define EXIT_FAILURE 1
-#define EXIT_SUCCESS 0
-
-#define UCHAR_MAX 255
-#define USHRT_MAX 65535
-#define UINT_MAX 4294967295U
-#define RAND_MAX 32767
-#define INT_MAX 32767
-
-/* C99 inttypes.h defines */
-#define PRId8 "d"
-#define PRIi8 "i"
-#define PRIo8 "o"
-#define PRIu8 "u"
-#define PRIx8 "x"
-#define PRIX8 "X"
-#define PRId16 "d"
-#define PRIi16 "i"
-#define PRIo16 "o"
-#define PRIu16 "u"
-#define PRIx16 "x"
-#define PRIX16 "X"
-#define PRId32 "d"
-#define PRIi32 "i"
-#define PRIo32 "o"
-#define PRIu32 "u"
-#define PRIx32 "x"
-#define PRIX32 "X"
-#define PRId64 "d"
-#define PRIi64 "i"
-#define PRIo64 "o"
-#define PRIu64 "u"
-#define PRIx64 "x"
-#define PRIX64 "X"
-#define PRIdLEAST8 "d"
-#define PRIiLEAST8 "i"
-#define PRIoLEAST8 "o"
-#define PRIuLEAST8 "u"
-#define PRIxLEAST8 "x"
-#define PRIXLEAST8 "X"
-#define PRIdLEAST16 "d"
-#define PRIiLEAST16 "i"
-#define PRIoLEAST16 "o"
-#define PRIuLEAST16 "u"
-#define PRIxLEAST16 "x"
-#define PRIXLEAST16 "X"
-#define PRIdLEAST32 "d"
-#define PRIiLEAST32 "i"
-#define PRIoLEAST32 "o"
-#define PRIuLEAST32 "u"
-#define PRIxLEAST32 "x"
-#define PRIXLEAST32 "X"
-#define PRIdLEAST64 "d"
-#define PRIiLEAST64 "i"
-#define PRIoLEAST64 "o"
-#define PRIuLEAST64 "u"
-#define PRIxLEAST64 "x"
-#define PRIXLEAST64 "X"
-#define PRIdFAST8 "d"
-#define PRIiFAST8 "i"
-#define PRIoFAST8 "o"
-#define PRIuFAST8 "u"
-#define PRIxFAST8 "x"
-#define PRIXFAST8 "X"
-#define PRIdFAST16 "d"
-#define PRIiFAST16 "i"
-#define PRIoFAST16 "o"
-#define PRIuFAST16 "u"
-#define PRIxFAST16 "x"
-#define PRIXFAST16 "X"
-#define PRIdFAST32 "d"
-#define PRIiFAST32 "i"
-#define PRIoFAST32 "o"
-#define PRIuFAST32 "u"
-#define PRIxFAST32 "x"
-#define PRIXFAST32 "X"
-#define PRIdFAST64 "d"
-#define PRIiFAST64 "i"
-#define PRIoFAST64 "o"
-#define PRIuFAST64 "u"
-#define PRIxFAST64 "x"
-#define PRIXFAST64 "X"
-#define PRIdPTR "d"
-#define PRIiPTR "i"
-#define PRIoPTR "o"
-#define PRIuPTR "u"
-#define PRIxPTR "x"
-#define PRIXPTR "X"
-#define PRIdMAX "d"
-#define PRIiMAX "i"
-#define PRIoMAX "o"
-#define PRIuMAX "u"
-#define PRIxMAX "x"
-#define PRIXMAX "X"
-#define SCNd8 "d"
-#define SCNi8 "i"
-#define SCNo8 "o"
-#define SCNu8 "u"
-#define SCNx8 "x"
-#define SCNd16 "d"
-#define SCNi16 "i"
-#define SCNo16 "o"
-#define SCNu16 "u"
-#define SCNx16 "x"
-#define SCNd32 "d"
-#define SCNi32 "i"
-#define SCNo32 "o"
-#define SCNu32 "u"
-#define SCNx32 "x"
-#define SCNd64 "d"
-#define SCNi64 "i"
-#define SCNo64 "o"
-#define SCNu64 "u"
-#define SCNx64 "x"
-#define SCNdLEAST8 "d"
-#define SCNiLEAST8 "i"
-#define SCNoLEAST8 "o"
-#define SCNuLEAST8 "u"
-#define SCNxLEAST8 "x"
-#define SCNdLEAST16 "d"
-#define SCNiLEAST16 "i"
-#define SCNoLEAST16 "o"
-#define SCNuLEAST16 "u"
-#define SCNxLEAST16 "x"
-#define SCNdLEAST32 "d"
-#define SCNiLEAST32 "i"
-#define SCNoLEAST32 "o"
-#define SCNuLEAST32 "u"
-#define SCNxLEAST32 "x"
-#define SCNdLEAST64 "d"
-#define SCNiLEAST64 "i"
-#define SCNoLEAST64 "o"
-#define SCNuLEAST64 "u"
-#define SCNxLEAST64 "x"
-#define SCNdFAST8 "d"
-#define SCNiFAST8 "i"
-#define SCNoFAST8 "o"
-#define SCNuFAST8 "u"
-#define SCNxFAST8 "x"
-#define SCNdFAST16 "d"
-#define SCNiFAST16 "i"
-#define SCNoFAST16 "o"
-#define SCNuFAST16 "u"
-#define SCNxFAST16 "x"
-#define SCNdFAST32 "d"
-#define SCNiFAST32 "i"
-#define SCNoFAST32 "o"
-#define SCNuFAST32 "u"
-#define SCNxFAST32 "x"
-#define SCNdFAST64 "d"
-#define SCNiFAST64 "i"
-#define SCNoFAST64 "o"
-#define SCNuFAST64 "u"
-#define SCNxFAST64 "x"
-#define SCNdPTR "d"
-#define SCNiPTR "i"
-#define SCNoPTR "o"
-#define SCNuPTR "u"
-#define SCNxPTR "x"
-#define SCNdMAX "d"
-#define SCNiMAX "i"
-#define SCNoMAX "o"
-#define SCNuMAX "u"
-#define SCNxMAX "x"
-
-/* C99 stdbool.h defines */
-#define __bool_true_false_are_defined 1
-#define false 0
-#define true 1
-
-/* va_arg macros and type*/
-#define va_start(_ap, _type) __builtin_va_start((_ap))
-#define va_arg(_ap, _type) __builtin_va_arg((_ap))
-#define va_end(_list)
-
-#endif
diff --git a/utils/fake_libc_include/_fake_typedefs.h b/utils/fake_libc_include/_fake_typedefs.h
deleted file mode 100644
index dfcc653..0000000
--- a/utils/fake_libc_include/_fake_typedefs.h
+++ /dev/null
@@ -1,172 +0,0 @@
-#ifndef _FAKE_TYPEDEFS_H
-#define _FAKE_TYPEDEFS_H
-
-typedef int size_t;
-typedef int __builtin_va_list;
-typedef int __gnuc_va_list;
-typedef int va_list;
-typedef int __int8_t;
-typedef int __uint8_t;
-typedef int __int16_t;
-typedef int __uint16_t;
-typedef int __int_least16_t;
-typedef int __uint_least16_t;
-typedef int __int32_t;
-typedef int __uint32_t;
-typedef int __int64_t;
-typedef int __uint64_t;
-typedef int __int_least32_t;
-typedef int __uint_least32_t;
-typedef int __s8;
-typedef int __u8;
-typedef int __s16;
-typedef int __u16;
-typedef int __s32;
-typedef int __u32;
-typedef int __s64;
-typedef int __u64;
-typedef int _LOCK_T;
-typedef int _LOCK_RECURSIVE_T;
-typedef int _off_t;
-typedef int __dev_t;
-typedef int __uid_t;
-typedef int __gid_t;
-typedef int _off64_t;
-typedef int _fpos_t;
-typedef int _ssize_t;
-typedef int wint_t;
-typedef int _mbstate_t;
-typedef int _flock_t;
-typedef int _iconv_t;
-typedef int __ULong;
-typedef int __FILE;
-typedef int ptrdiff_t;
-typedef int wchar_t;
-typedef int __off_t;
-typedef int __pid_t;
-typedef int __loff_t;
-typedef int u_char;
-typedef int u_short;
-typedef int u_int;
-typedef int u_long;
-typedef int ushort;
-typedef int uint;
-typedef int clock_t;
-typedef int time_t;
-typedef int daddr_t;
-typedef int caddr_t;
-typedef int ino_t;
-typedef int off_t;
-typedef int dev_t;
-typedef int uid_t;
-typedef int gid_t;
-typedef int pid_t;
-typedef int key_t;
-typedef int ssize_t;
-typedef int mode_t;
-typedef int nlink_t;
-typedef int fd_mask;
-typedef int _types_fd_set;
-typedef int clockid_t;
-typedef int timer_t;
-typedef int useconds_t;
-typedef int suseconds_t;
-typedef int FILE;
-typedef int fpos_t;
-typedef int cookie_read_function_t;
-typedef int cookie_write_function_t;
-typedef int cookie_seek_function_t;
-typedef int cookie_close_function_t;
-typedef int cookie_io_functions_t;
-typedef int div_t;
-typedef int ldiv_t;
-typedef int lldiv_t;
-typedef int sigset_t;
-typedef int __sigset_t;
-typedef int _sig_func_ptr;
-typedef int sig_atomic_t;
-typedef int __tzrule_type;
-typedef int __tzinfo_type;
-typedef int mbstate_t;
-typedef int sem_t;
-typedef int pthread_t;
-typedef int pthread_attr_t;
-typedef int pthread_mutex_t;
-typedef int pthread_mutexattr_t;
-typedef int pthread_cond_t;
-typedef int pthread_condattr_t;
-typedef int pthread_key_t;
-typedef int pthread_once_t;
-typedef int pthread_rwlock_t;
-typedef int pthread_rwlockattr_t;
-typedef int pthread_spinlock_t;
-typedef int pthread_barrier_t;
-typedef int pthread_barrierattr_t;
-typedef int jmp_buf;
-typedef int rlim_t;
-typedef int sa_family_t;
-typedef int sigjmp_buf;
-typedef int stack_t;
-typedef int siginfo_t;
-typedef int z_stream;
-
-/* C99 exact-width integer types */
-typedef int int8_t;
-typedef int uint8_t;
-typedef int int16_t;
-typedef int uint16_t;
-typedef int int32_t;
-typedef int uint32_t;
-typedef int int64_t;
-typedef int uint64_t;
-
-/* C99 minimum-width integer types */
-typedef int int_least8_t;
-typedef int uint_least8_t;
-typedef int int_least16_t;
-typedef int uint_least16_t;
-typedef int int_least32_t;
-typedef int uint_least32_t;
-typedef int int_least64_t;
-typedef int uint_least64_t;
-
-/* C99 fastest minimum-width integer types */
-typedef int int_fast8_t;
-typedef int uint_fast8_t;
-typedef int int_fast16_t;
-typedef int uint_fast16_t;
-typedef int int_fast32_t;
-typedef int uint_fast32_t;
-typedef int int_fast64_t;
-typedef int uint_fast64_t;
-
-/* C99 integer types capable of holding object pointers */
-typedef int intptr_t;
-typedef int uintptr_t;
-
-/* C99 greatest-width integer types */
-typedef int intmax_t;
-typedef int uintmax_t;
-
-/* C99 stdbool.h bool type. _Bool is built-in in C99 */
-typedef _Bool bool;
-
-/* Mir typedefs */
-typedef void* MirEGLNativeWindowType;
-typedef void* MirEGLNativeDisplayType;
-typedef struct MirConnection MirConnection;
-typedef struct MirSurface MirSurface;
-typedef struct MirSurfaceSpec MirSurfaceSpec;
-typedef struct MirScreencast MirScreencast;
-typedef struct MirPromptSession MirPromptSession;
-typedef struct MirBufferStream MirBufferStream;
-typedef struct MirPersistentId MirPersistentId;
-typedef struct MirBlob MirBlob;
-typedef struct MirDisplayConfig MirDisplayConfig;
-
-/* xcb typedefs */
-typedef struct xcb_connection_t xcb_connection_t;
-typedef uint32_t xcb_window_t;
-typedef uint32_t xcb_visualid_t;
-
-#endif
diff --git a/utils/fake_libc_include/_syslist.h b/utils/fake_libc_include/_syslist.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/_syslist.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/aio.h b/utils/fake_libc_include/aio.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/aio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/alloca.h b/utils/fake_libc_include/alloca.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/alloca.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/ar.h b/utils/fake_libc_include/ar.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/ar.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/argz.h b/utils/fake_libc_include/argz.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/argz.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/arpa/inet.h b/utils/fake_libc_include/arpa/inet.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/arpa/inet.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/asm-generic/int-ll64.h b/utils/fake_libc_include/asm-generic/int-ll64.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/asm-generic/int-ll64.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/assert.h b/utils/fake_libc_include/assert.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/assert.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/complex.h b/utils/fake_libc_include/complex.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/complex.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/cpio.h b/utils/fake_libc_include/cpio.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/cpio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/ctype.h b/utils/fake_libc_include/ctype.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/ctype.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/dirent.h b/utils/fake_libc_include/dirent.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/dirent.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/dlfcn.h b/utils/fake_libc_include/dlfcn.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/dlfcn.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/endian.h b/utils/fake_libc_include/endian.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/endian.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/envz.h b/utils/fake_libc_include/envz.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/envz.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/errno.h b/utils/fake_libc_include/errno.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/errno.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/fastmath.h b/utils/fake_libc_include/fastmath.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/fastmath.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/fcntl.h b/utils/fake_libc_include/fcntl.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/fcntl.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/features.h b/utils/fake_libc_include/features.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/features.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/fenv.h b/utils/fake_libc_include/fenv.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/fenv.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/float.h b/utils/fake_libc_include/float.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/float.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/fmtmsg.h b/utils/fake_libc_include/fmtmsg.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/fmtmsg.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/fnmatch.h b/utils/fake_libc_include/fnmatch.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/fnmatch.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/ftw.h b/utils/fake_libc_include/ftw.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/ftw.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/getopt.h b/utils/fake_libc_include/getopt.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/getopt.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/glob.h b/utils/fake_libc_include/glob.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/glob.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/grp.h b/utils/fake_libc_include/grp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/grp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/iconv.h b/utils/fake_libc_include/iconv.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/iconv.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/ieeefp.h b/utils/fake_libc_include/ieeefp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/ieeefp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/inttypes.h b/utils/fake_libc_include/inttypes.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/inttypes.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/iso646.h b/utils/fake_libc_include/iso646.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/iso646.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/langinfo.h b/utils/fake_libc_include/langinfo.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/langinfo.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/libgen.h b/utils/fake_libc_include/libgen.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/libgen.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/libintl.h b/utils/fake_libc_include/libintl.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/libintl.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/limits.h b/utils/fake_libc_include/limits.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/limits.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/linux/socket.h b/utils/fake_libc_include/linux/socket.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/linux/socket.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/linux/version.h b/utils/fake_libc_include/linux/version.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/linux/version.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/locale.h b/utils/fake_libc_include/locale.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/locale.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/malloc.h b/utils/fake_libc_include/malloc.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/malloc.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/math.h b/utils/fake_libc_include/math.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/math.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/mir_toolkit/client_types.h b/utils/fake_libc_include/mir_toolkit/client_types.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/mir_toolkit/client_types.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/monetary.h b/utils/fake_libc_include/monetary.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/monetary.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/mqueue.h b/utils/fake_libc_include/mqueue.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/mqueue.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/ndbm.h b/utils/fake_libc_include/ndbm.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/ndbm.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/net/if.h b/utils/fake_libc_include/net/if.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/net/if.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/netdb.h b/utils/fake_libc_include/netdb.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/netdb.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/netinet/in.h b/utils/fake_libc_include/netinet/in.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/netinet/in.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/netinet/tcp.h b/utils/fake_libc_include/netinet/tcp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/netinet/tcp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/newlib.h b/utils/fake_libc_include/newlib.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/newlib.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/nl_types.h b/utils/fake_libc_include/nl_types.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/nl_types.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/openssl/err.h b/utils/fake_libc_include/openssl/err.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/openssl/err.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/openssl/evp.h b/utils/fake_libc_include/openssl/evp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/openssl/evp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/openssl/hmac.h b/utils/fake_libc_include/openssl/hmac.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/openssl/hmac.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/openssl/ssl.h b/utils/fake_libc_include/openssl/ssl.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/openssl/ssl.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/openssl/x509v3.h b/utils/fake_libc_include/openssl/x509v3.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/openssl/x509v3.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/paths.h b/utils/fake_libc_include/paths.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/paths.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/poll.h b/utils/fake_libc_include/poll.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/poll.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/process.h b/utils/fake_libc_include/process.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/process.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/pthread.h b/utils/fake_libc_include/pthread.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/pthread.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/pwd.h b/utils/fake_libc_include/pwd.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/pwd.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/reent.h b/utils/fake_libc_include/reent.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/reent.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/regdef.h b/utils/fake_libc_include/regdef.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/regdef.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/regex.h b/utils/fake_libc_include/regex.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/regex.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sched.h b/utils/fake_libc_include/sched.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sched.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/search.h b/utils/fake_libc_include/search.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/search.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/semaphore.h b/utils/fake_libc_include/semaphore.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/semaphore.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/setjmp.h b/utils/fake_libc_include/setjmp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/setjmp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/signal.h b/utils/fake_libc_include/signal.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/signal.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/spawn.h b/utils/fake_libc_include/spawn.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/spawn.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stdarg.h b/utils/fake_libc_include/stdarg.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stdarg.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stdbool.h b/utils/fake_libc_include/stdbool.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stdbool.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stddef.h b/utils/fake_libc_include/stddef.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stddef.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stdint.h b/utils/fake_libc_include/stdint.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stdint.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stdio.h b/utils/fake_libc_include/stdio.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stdio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stdlib.h b/utils/fake_libc_include/stdlib.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stdlib.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/string.h b/utils/fake_libc_include/string.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/string.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/strings.h b/utils/fake_libc_include/strings.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/strings.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/stropts.h b/utils/fake_libc_include/stropts.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/stropts.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/ioctl.h b/utils/fake_libc_include/sys/ioctl.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/ioctl.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/ipc.h b/utils/fake_libc_include/sys/ipc.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/ipc.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/mman.h b/utils/fake_libc_include/sys/mman.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/mman.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/msg.h b/utils/fake_libc_include/sys/msg.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/msg.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/poll.h b/utils/fake_libc_include/sys/poll.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/poll.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/resource.h b/utils/fake_libc_include/sys/resource.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/resource.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/select.h b/utils/fake_libc_include/sys/select.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/select.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/sem.h b/utils/fake_libc_include/sys/sem.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/sem.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/shm.h b/utils/fake_libc_include/sys/shm.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/shm.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/socket.h b/utils/fake_libc_include/sys/socket.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/socket.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/stat.h b/utils/fake_libc_include/sys/stat.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/stat.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/statvfs.h b/utils/fake_libc_include/sys/statvfs.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/statvfs.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/sysctl.h b/utils/fake_libc_include/sys/sysctl.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/sysctl.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/time.h b/utils/fake_libc_include/sys/time.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/time.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/times.h b/utils/fake_libc_include/sys/times.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/times.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/types.h b/utils/fake_libc_include/sys/types.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/types.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/uio.h b/utils/fake_libc_include/sys/uio.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/uio.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/un.h b/utils/fake_libc_include/sys/un.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/un.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/utsname.h b/utils/fake_libc_include/sys/utsname.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/utsname.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/sys/wait.h b/utils/fake_libc_include/sys/wait.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/sys/wait.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/syslog.h b/utils/fake_libc_include/syslog.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/syslog.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/tar.h b/utils/fake_libc_include/tar.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/tar.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/termios.h b/utils/fake_libc_include/termios.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/termios.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/tgmath.h b/utils/fake_libc_include/tgmath.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/tgmath.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/time.h b/utils/fake_libc_include/time.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/time.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/trace.h b/utils/fake_libc_include/trace.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/trace.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/ulimit.h b/utils/fake_libc_include/ulimit.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/ulimit.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/unctrl.h b/utils/fake_libc_include/unctrl.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/unctrl.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/unistd.h b/utils/fake_libc_include/unistd.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/unistd.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/utime.h b/utils/fake_libc_include/utime.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/utime.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/utmp.h b/utils/fake_libc_include/utmp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/utmp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/utmpx.h b/utils/fake_libc_include/utmpx.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/utmpx.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/wchar.h b/utils/fake_libc_include/wchar.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/wchar.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/wctype.h b/utils/fake_libc_include/wctype.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/wctype.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/wordexp.h b/utils/fake_libc_include/wordexp.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/wordexp.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/xcb/xcb.h b/utils/fake_libc_include/xcb/xcb.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/xcb/xcb.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/fake_libc_include/zlib.h b/utils/fake_libc_include/zlib.h
deleted file mode 100644
index f952c1d..0000000
--- a/utils/fake_libc_include/zlib.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "_fake_defines.h"
-#include "_fake_typedefs.h"
diff --git a/utils/internal/constptr.c b/utils/internal/constptr.c
deleted file mode 100644
index 2fe14bf..0000000
--- a/utils/internal/constptr.c
+++ /dev/null
@@ -1,9 +0,0 @@
-void foo(char * const * arg) {
- arg += 1;
- (*arg) += 1;
-}
-
-void foo2(char ** const arg) {
- arg += 1;
- (*arg) += 1;
-}
diff --git a/utils/internal/cppify.bat b/utils/internal/cppify.bat
deleted file mode 100644
index af69f5f..0000000
--- a/utils/internal/cppify.bat
+++ /dev/null
@@ -1,3 +0,0 @@
-REM ~ ..\cpp -D__i386__ -I"D:\eli\cpp_stuff\libc_include" -D__extension__ example_c_file.c > example_c_file_pp.c
-REM ~ ..\cpp -D__i386__ -I"D:\eli\c_analyzing\pycparser-trunk\utils\fake_libc_include" example_c_file.c > example_c_file_pp.c
-..\cpp -D__i386__ -I"D:\eli\c_analyzing\pycparser-trunk\utils\fake_libc_include" zc.c > zc_pp.c
diff --git a/utils/internal/example_c_file.c b/utils/internal/example_c_file.c
deleted file mode 100644
index 35da01d..0000000
--- a/utils/internal/example_c_file.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/* a comment / */
-/* "not a string" */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <ctype.h>
-#include <signal.h>
-#include <time.h>
-#include <wchar.h>
-
-/*
- multiline comment
- comment
-*/
-
-int main()
-{
- auto char* multi = "a multi"; /* and a comment !*/
-}
-
-/* A final comment for good measure /* /* /* */
-
-
-
diff --git a/utils/internal/fake_includes.py b/utils/internal/fake_includes.py
deleted file mode 100644
index 1ce69fa..0000000
--- a/utils/internal/fake_includes.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import os.path
-
-for cur_path, dirs, files in os.walk('.'):
- if cur_path == '.':
- for f in files:
- if f.endswith('.h'):
- print f
- fo = open(f, 'w')
- fo.write('#include "_fake_defines.h"\n')
- fo.write('#include "_fake_typedefs.h"\n')
- fo.close()
-
-
diff --git a/utils/internal/make_fake_typedefs.py b/utils/internal/make_fake_typedefs.py
deleted file mode 100644
index b82e92f..0000000
--- a/utils/internal/make_fake_typedefs.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import sys
-sys.path.insert(0, '../..')
-
-from pycparser import c_parser, c_ast, parse_file
-
-
-class MyVisitor(c_ast.NodeVisitor):
- def visit_Typedef(self, node):
- print 'typedef int %s;' % node.name
-
-
-
-def generate_fake_typedefs(filename):
- ast = parse_file(filename, use_cpp=True, cpp_path="../cpp.exe")
- v = MyVisitor()
- v.visit(ast)
-
-
-if __name__ == "__main__":
- generate_fake_typedefs('example_c_file_pp.c')
-
diff --git a/utils/internal/memprofiling.py b/utils/internal/memprofiling.py
deleted file mode 100644
index 5b25120..0000000
--- a/utils/internal/memprofiling.py
+++ /dev/null
@@ -1,121 +0,0 @@
-import sys
-from pycparser import parse_file
-from pycparser.c_ast import *
-from pycparser.c_parser import CParser, Coord, ParseError
-from pycparser.c_lexer import CLexer
-
-
-def expand_decl(decl):
- """ Converts the declaration into a nested list.
- """
- typ = type(decl)
-
- if typ == TypeDecl:
- return ['TypeDecl', expand_decl(decl.type)]
- elif typ == IdentifierType:
- return ['IdentifierType', decl.names]
- elif typ == ID:
- return ['ID', decl.name]
- elif typ in [Struct, Union]:
- decls = [expand_decl(d) for d in decl.decls or []]
- return [typ.__name__, decl.name, decls]
- else:
- nested = expand_decl(decl.type)
-
- if typ == Decl:
- if decl.quals:
- return ['Decl', decl.quals, decl.name, nested]
- else:
- return ['Decl', decl.name, nested]
- elif typ == Typename: # for function parameters
- if decl.quals:
- return ['Typename', decl.quals, nested]
- else:
- return ['Typename', nested]
- elif typ == ArrayDecl:
- dimval = decl.dim.value if decl.dim else ''
- return ['ArrayDecl', dimval, nested]
- elif typ == PtrDecl:
- return ['PtrDecl', nested]
- elif typ == Typedef:
- return ['Typedef', decl.name, nested]
- elif typ == FuncDecl:
- if decl.args:
- params = [expand_decl(param) for param in decl.args.params]
- else:
- params = []
- return ['FuncDecl', params, nested]
-
-#-----------------------------------------------------------------
-class NodeVisitor(object):
- def __init__(self):
- self.current_parent = None
-
- def visit(self, node):
- """ Visit a node.
- """
- method = 'visit_' + node.__class__.__name__
- visitor = getattr(self, method, self.generic_visit)
- return visitor(node)
-
- def visit_FuncCall(self, node):
- print("Visiting FuncCall")
- print(node.show())
- print('---- parent ----')
- print(self.current_parent.show())
-
- def generic_visit(self, node):
- """ Called if no explicit visitor function exists for a
- node. Implements preorder visiting of the node.
- """
- oldparent = self.current_parent
- self.current_parent = node
- for c in node.children():
- self.visit(c)
- self.current_parent = oldparent
-
-
-def heapyprofile():
- # pip install guppy
- # [works on python 2.7, AFAIK]
- from guppy import hpy
- import gc
-
- hp = hpy()
- ast = parse_file('/tmp/197.c')
- gc.collect()
- h = hp.heap()
- print(h)
-
-
-def memprofile():
- import resource
- import tracemalloc
-
- tracemalloc.start()
-
- ast = parse_file('/tmp/197.c')
-
- print('Memory usage: %s (kb)' %
- resource.getrusage(resource.RUSAGE_SELF).ru_maxrss)
-
- snapshot = tracemalloc.take_snapshot()
- print("[ tracemalloc stats ]")
- for stat in snapshot.statistics('lineno')[:20]:
- print(stat)
-
-
-if __name__ == "__main__":
- source_code = r'''void foo() {
- L"hi" L"there";
-}
- '''
-
- memprofile()
- #heapyprofile()
-
- #parser = CParser()
- #ast = parser.parse(source_code, filename='zz')
- #ast.show(showcoord=True, attrnames=True, nodenames=True)
-
-
diff --git a/utils/internal/zc.c b/utils/internal/zc.c
deleted file mode 100644
index 5e56974..0000000
--- a/utils/internal/zc.c
+++ /dev/null
@@ -1,107 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-
-#define PACKAGE "wgram"
-#define VERSION "0.0.4"
-#define MAXLINE 1024
-#define MAXGRAM 32
-
-/* status epilepticus .. print help */
-void print_help(int exval);
-
-int main (int argc, char *argv[]) {
- /* word delimeter for strtok() */
- char delim[] = ".,:;`/\"+-_(){}[]<>*&^%$#@!?~/|\\=1234567890 \t\n";
- char line[MAXLINE]; /* input buff, fgets() */
- char *stray = NULL; /* returned value by strtok() */
- char **strarray = NULL; /* array to hold all entrys */
- int i = 0; /* general counter */
- int strcount = 0; /* number of entrys in pointer array */
- int N = 3, pos = 0; /* ngram size, 3 in this case */
- int opt = 0; /* holds command line opt nr.. */
- int word_flag = 0; /* print only the `raw' words */
- FILE *fp = stdin; /* read input from `FILE', default is stdin */
-
- while((opt = getopt(argc, argv, "hvn:wf:")) != -1) {
- switch(opt) {
- case 'h':
- print_help(0);
- break;
- case 'v':
- exit(0);
- break;
- case 'n':
- N = atoi(optarg);
- if(N > MAXGRAM || N < 2) {
- fprintf(stderr, "%s: Error - Ngram length `%d' out of range `0-%d'\n",
- PACKAGE, N, MAXGRAM);
- return 1;
- }
- break;
- case 'w':
- word_flag = 1;
- break;
- case 'f':
- if(freopen(optarg, "r", fp) == NULL) {
- fprintf(stderr, "%s: Error - opening `%s'\n", PACKAGE, optarg);
- return 1;
- }
- break;
- case '?':
- fprintf(stderr, "%s: Error - No such option: `%c'\n\n", PACKAGE, optopt);
- print_help(1);
- } /* switch */
- } /* while */
-
- /* start reading lines from file pointer, add all entrys to **strarray */
- while((fgets(line, MAXLINE, fp)) != NULL) {
- if(strlen(line) < 2)
- continue;
-
- stray = strtok(line, delim);
- while(stray != NULL) {
- strarray = (char **)realloc(strarray, (strcount + 1) * sizeof(char *));
- strarray[strcount++] = strdup(stray);
- stray = strtok(NULL, delim);
- }
- }
-
- if(word_flag == 0) {
- /*
- // print the array of strings, jumping back each time
- // (N - 1) positions if a whole ngram of words has been printed
- */
- for(i = 0, pos = N; i < strcount; i++, pos--) {
- if(pos == 0) pos = N, i -= (N - 1), printf("\n");
- printf("%s ", strarray[i]);
- }
- printf("\n");
- } else {
- /* print raw words */
- for(i = 0; i < strcount; i++)
- printf("%s\n", strarray[i]);
- }
-
- /* free the string array */
- for(i = 0; i < strcount; i++)
- free(strarray[i]);
-
- free(strarray);
- return 0;
-}
-
-/* status epilepticus .. print help */
-void print_help(int exval) {
- printf("%s,%s extract N-grams from text data\n", PACKAGE, VERSION);
- printf("Usage: %s [-h] [-v] [-n INT] [-w] [-f FILE]\n\n", PACKAGE);
-
- printf(" -h print this help and exit\n");
- printf(" -v print version and exit\n\n");
-
- printf(" -n INT set ngram length (default=3)\n");
- printf(" -w print only the extracted words\n");
- printf(" -f FILE read input from `FILE' (default=stdin)\n\n");
- exit(exval);
-}
diff --git a/utils/internal/zz_parse.py b/utils/internal/zz_parse.py
deleted file mode 100644
index 39978d1..0000000
--- a/utils/internal/zz_parse.py
+++ /dev/null
@@ -1,21 +0,0 @@
-from __future__ import print_function
-
-import sys
-from pycparser import c_parser, c_generator, c_ast, parse_file
-
-
-if __name__ == "__main__":
- parser = c_parser.CParser()
- code = r'''
- void* ptr = (int[ ]){0};
- '''
-
- print(code)
- ast = parser.parse(code)
- ast.show(attrnames=True, nodenames=True)
- print(ast.ext[0].__slots__)
- print(dir(ast.ext[0]))
-
- print("==== From C generator:")
- generator = c_generator.CGenerator()
- print(generator.visit(ast))