update windows build to Python 3.7
This commit is contained in:
parent
73105fa71e
commit
ddc59ab92d
5761 changed files with 750298 additions and 213405 deletions
|
|
@ -4,13 +4,14 @@
|
|||
# This package file exports some convenience functions for
|
||||
# interacting with pycparser
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
__all__ = ['c_lexer', 'c_parser', 'c_ast']
|
||||
__version__ = '2.14'
|
||||
__version__ = '2.19'
|
||||
|
||||
from subprocess import Popen, PIPE
|
||||
import io
|
||||
from subprocess import check_output
|
||||
from .c_parser import CParser
|
||||
|
||||
|
||||
|
|
@ -38,11 +39,7 @@ def preprocess_file(filename, cpp_path='cpp', cpp_args=''):
|
|||
try:
|
||||
# Note the use of universal_newlines to treat all newlines
|
||||
# as \n for Python's purpose
|
||||
#
|
||||
pipe = Popen( path_list,
|
||||
stdout=PIPE,
|
||||
universal_newlines=True)
|
||||
text = pipe.communicate()[0]
|
||||
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' +
|
||||
|
|
@ -85,7 +82,7 @@ def parse_file(filename, use_cpp=False, cpp_path='cpp', cpp_args='',
|
|||
if use_cpp:
|
||||
text = preprocess_file(filename, cpp_path, cpp_args)
|
||||
else:
|
||||
with open(filename, 'rU') as f:
|
||||
with io.open(filename) as f:
|
||||
text = f.read()
|
||||
|
||||
if parser is None:
|
||||
|
|
|
|||
BIN
Lib/site-packages/pycparser/__pycache__/__init__.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/__init__.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/_ast_gen.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/_ast_gen.cpython-37.pyc
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/c_ast.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/c_ast.cpython-37.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/c_lexer.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/c_lexer.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/c_parser.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/c_parser.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/lextab.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/lextab.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/plyparser.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/plyparser.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/__pycache__/yacctab.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/__pycache__/yacctab.cpython-37.pyc
Normal file
Binary file not shown.
|
|
@ -7,7 +7,7 @@
|
|||
# The design of this module was inspired by astgen.py from the
|
||||
# Python 2.5 code-base.
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
import pprint
|
||||
|
|
@ -63,6 +63,7 @@ class NodeCfg(object):
|
|||
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 = []
|
||||
|
|
@ -84,6 +85,8 @@ class NodeCfg(object):
|
|||
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
|
||||
|
||||
|
|
@ -131,6 +134,33 @@ class NodeCfg(object):
|
|||
|
||||
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
|
||||
|
|
@ -150,7 +180,7 @@ r'''#-----------------------------------------------------------------
|
|||
#
|
||||
# AST Node classes.
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
|
@ -159,11 +189,38 @@ r'''#-----------------------------------------------------------------
|
|||
_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
|
||||
"""
|
||||
|
|
@ -253,26 +310,29 @@ class NodeVisitor(object):
|
|||
* 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.
|
||||
"""
|
||||
method = 'visit_' + node.__class__.__name__
|
||||
visitor = getattr(self, method, self.generic_visit)
|
||||
|
||||
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_name, c in node.children():
|
||||
for c in node:
|
||||
self.visit(c)
|
||||
|
||||
|
||||
'''
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
ast_gen = ASTCodeGenerator('_c_ast.cfg')
|
||||
ast_gen.generate(open('c_ast.py', 'w'))
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
# Also generates AST code from the configuration file.
|
||||
# Should be called from the pycparser directory.
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
# <name>** - a sequence of child nodes
|
||||
# <name> - an attribute
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
|
|
@ -187,3 +187,5 @@ UnaryOp: [op, expr*]
|
|||
Union: [name, decls**]
|
||||
|
||||
While: [cond*, stmt*]
|
||||
|
||||
Pragma: [string]
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# Some utilities used by the parser to create a friendlier AST.
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
|
|
@ -43,7 +43,7 @@ def fix_switch_cases(switch_node):
|
|||
Default:
|
||||
break
|
||||
|
||||
The goal of this transform it to fix this mess, turning it into the
|
||||
The goal of this transform is to fix this mess, turning it into the
|
||||
following:
|
||||
|
||||
Switch
|
||||
|
|
|
|||
|
|
@ -11,18 +11,45 @@
|
|||
#
|
||||
# AST Node classes.
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# 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
|
||||
"""
|
||||
|
|
@ -112,21 +139,31 @@ class NodeVisitor(object):
|
|||
* 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.
|
||||
"""
|
||||
method = 'visit_' + node.__class__.__name__
|
||||
visitor = getattr(self, method, self.generic_visit)
|
||||
|
||||
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_name, c in node.children():
|
||||
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):
|
||||
|
|
@ -141,6 +178,12 @@ class ArrayDecl(Node):
|
|||
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):
|
||||
|
|
@ -156,6 +199,12 @@ class ArrayRef(Node):
|
|||
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):
|
||||
|
|
@ -172,6 +221,12 @@ class Assignment(Node):
|
|||
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):
|
||||
|
|
@ -188,6 +243,12 @@ class BinaryOp(Node):
|
|||
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):
|
||||
|
|
@ -198,6 +259,10 @@ class Break(Node):
|
|||
def children(self):
|
||||
return ()
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ()
|
||||
|
||||
class Case(Node):
|
||||
|
|
@ -214,6 +279,12 @@ class Case(Node):
|
|||
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):
|
||||
|
|
@ -229,6 +300,12 @@ class Cast(Node):
|
|||
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):
|
||||
|
|
@ -243,6 +320,10 @@ class Compound(Node):
|
|||
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):
|
||||
|
|
@ -258,6 +339,12 @@ class CompoundLiteral(Node):
|
|||
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):
|
||||
|
|
@ -271,6 +358,10 @@ class Constant(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ('type', 'value', )
|
||||
|
||||
class Continue(Node):
|
||||
|
|
@ -281,6 +372,10 @@ class Continue(Node):
|
|||
def children(self):
|
||||
return ()
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ()
|
||||
|
||||
class Decl(Node):
|
||||
|
|
@ -302,6 +397,14 @@ class Decl(Node):
|
|||
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):
|
||||
|
|
@ -316,6 +419,10 @@ class DeclList(Node):
|
|||
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):
|
||||
|
|
@ -330,6 +437,10 @@ class Default(Node):
|
|||
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):
|
||||
|
|
@ -345,6 +456,12 @@ class DoWhile(Node):
|
|||
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):
|
||||
|
|
@ -355,6 +472,10 @@ class EllipsisParam(Node):
|
|||
def children(self):
|
||||
return ()
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ()
|
||||
|
||||
class EmptyStatement(Node):
|
||||
|
|
@ -365,6 +486,10 @@ class EmptyStatement(Node):
|
|||
def children(self):
|
||||
return ()
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ()
|
||||
|
||||
class Enum(Node):
|
||||
|
|
@ -379,6 +504,10 @@ class Enum(Node):
|
|||
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):
|
||||
|
|
@ -393,6 +522,10 @@ class Enumerator(Node):
|
|||
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):
|
||||
|
|
@ -407,6 +540,10 @@ class EnumeratorList(Node):
|
|||
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):
|
||||
|
|
@ -421,6 +558,10 @@ class ExprList(Node):
|
|||
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):
|
||||
|
|
@ -435,6 +576,10 @@ class FileAST(Node):
|
|||
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):
|
||||
|
|
@ -454,6 +599,16 @@ class For(Node):
|
|||
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):
|
||||
|
|
@ -469,6 +624,12 @@ class FuncCall(Node):
|
|||
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):
|
||||
|
|
@ -484,6 +645,12 @@ class FuncDecl(Node):
|
|||
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):
|
||||
|
|
@ -502,6 +669,14 @@ class FuncDef(Node):
|
|||
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):
|
||||
|
|
@ -514,6 +689,10 @@ class Goto(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ('name', )
|
||||
|
||||
class ID(Node):
|
||||
|
|
@ -526,6 +705,10 @@ class ID(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ('name', )
|
||||
|
||||
class IdentifierType(Node):
|
||||
|
|
@ -538,6 +721,10 @@ class IdentifierType(Node):
|
|||
nodelist = []
|
||||
return tuple(nodelist)
|
||||
|
||||
def __iter__(self):
|
||||
return
|
||||
yield
|
||||
|
||||
attr_names = ('names', )
|
||||
|
||||
class If(Node):
|
||||
|
|
@ -555,6 +742,14 @@ class If(Node):
|
|||
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):
|
||||
|
|
@ -569,6 +764,10 @@ class InitList(Node):
|
|||
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):
|
||||
|
|
@ -583,6 +782,10 @@ class Label(Node):
|
|||
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):
|
||||
|
|
@ -599,6 +802,12 @@ class NamedInitializer(Node):
|
|||
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):
|
||||
|
|
@ -613,6 +822,10 @@ class ParamList(Node):
|
|||
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):
|
||||
|
|
@ -627,6 +840,10 @@ class PtrDecl(Node):
|
|||
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):
|
||||
|
|
@ -640,6 +857,10 @@ class Return(Node):
|
|||
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):
|
||||
|
|
@ -655,6 +876,10 @@ class Struct(Node):
|
|||
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):
|
||||
|
|
@ -671,6 +896,12 @@ class StructRef(Node):
|
|||
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):
|
||||
|
|
@ -686,6 +917,12 @@ class Switch(Node):
|
|||
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):
|
||||
|
|
@ -703,6 +940,14 @@ class TernaryOp(Node):
|
|||
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):
|
||||
|
|
@ -718,6 +963,10 @@ class TypeDecl(Node):
|
|||
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):
|
||||
|
|
@ -734,6 +983,10 @@ class Typedef(Node):
|
|||
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):
|
||||
|
|
@ -749,6 +1002,10 @@ class Typename(Node):
|
|||
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):
|
||||
|
|
@ -763,6 +1020,10 @@ class UnaryOp(Node):
|
|||
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):
|
||||
|
|
@ -778,6 +1039,10 @@ class Union(Node):
|
|||
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):
|
||||
|
|
@ -793,5 +1058,27 @@ class While(Node):
|
|||
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', )
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# C code generator from pycparser AST nodes.
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
from . import c_ast
|
||||
|
|
@ -40,6 +40,12 @@ class CGenerator(object):
|
|||
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) + ']'
|
||||
|
|
@ -129,18 +135,20 @@ class CGenerator(object):
|
|||
return ', '.join(visited_subexprs)
|
||||
|
||||
def visit_Enum(self, n):
|
||||
s = 'enum'
|
||||
if n.name: s += ' ' + n.name
|
||||
if n.values:
|
||||
s += ' {'
|
||||
for i, enumerator in enumerate(n.values.enumerators):
|
||||
s += enumerator.name
|
||||
if enumerator.value:
|
||||
s += ' = ' + self.visit(enumerator.value)
|
||||
if i != len(n.values.enumerators) - 1:
|
||||
s += ', '
|
||||
s += '}'
|
||||
return s
|
||||
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)
|
||||
|
|
@ -157,6 +165,8 @@ class CGenerator(object):
|
|||
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
|
||||
|
|
@ -170,6 +180,10 @@ class CGenerator(object):
|
|||
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 ';'
|
||||
|
||||
|
|
@ -188,9 +202,9 @@ class CGenerator(object):
|
|||
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)
|
||||
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):
|
||||
|
|
@ -256,43 +270,58 @@ class CGenerator(object):
|
|||
return '...'
|
||||
|
||||
def visit_Struct(self, n):
|
||||
return self._generate_struct_union(n, 'struct')
|
||||
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(n, 'union')
|
||||
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
|
||||
elif isinstance(name, c_ast.Constant):
|
||||
s += '[' + name.value + ']'
|
||||
s += ' = ' + self.visit(n.expr)
|
||||
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(self, n, name):
|
||||
""" Generates code for structs and unions. name should be either
|
||||
'struct' or union.
|
||||
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 n.decls:
|
||||
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'
|
||||
for decl in n.decls:
|
||||
s += self._generate_stmt(decl)
|
||||
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
|
||||
|
|
@ -395,5 +424,5 @@ class CGenerator(object):
|
|||
""" 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))
|
||||
return isinstance(n, (c_ast.Constant, c_ast.ID, c_ast.ArrayRef,
|
||||
c_ast.StructRef, c_ast.FuncCall))
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# CLexer class: lexer for the C language
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#------------------------------------------------------------------------------
|
||||
import re
|
||||
|
|
@ -52,8 +52,8 @@ class CLexer(object):
|
|||
# Allow either "# line" or "# <num>" to support GCC's
|
||||
# cpp output
|
||||
#
|
||||
self.line_pattern = re.compile('([ \t]*line\W)|([ \t]*\d+)')
|
||||
self.pragma_pattern = re.compile('[ \t]*pragma\W')
|
||||
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
|
||||
|
|
@ -102,11 +102,11 @@ class CLexer(object):
|
|||
keywords = (
|
||||
'_BOOL', '_COMPLEX', 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST',
|
||||
'CONTINUE', 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN',
|
||||
'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG',
|
||||
'FLOAT', 'FOR', 'GOTO', 'IF', 'INLINE', 'INT', 'LONG',
|
||||
'REGISTER', 'OFFSETOF',
|
||||
'RESTRICT', 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT',
|
||||
'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID',
|
||||
'VOLATILE', 'WHILE',
|
||||
'VOLATILE', 'WHILE', '__INT128',
|
||||
)
|
||||
|
||||
keyword_map = {}
|
||||
|
|
@ -171,7 +171,9 @@ class CLexer(object):
|
|||
'ELLIPSIS',
|
||||
|
||||
# pre-processor
|
||||
'PPHASH', # '#'
|
||||
'PPHASH', # '#'
|
||||
'PPPRAGMA', # 'pragma'
|
||||
'PPPRAGMASTR',
|
||||
)
|
||||
|
||||
##
|
||||
|
|
@ -219,7 +221,7 @@ class CLexer(object):
|
|||
string_char = r"""([^"\\\n]|"""+escape_sequence+')'
|
||||
string_literal = '"'+string_char+'*"'
|
||||
wstring_literal = 'L'+string_literal
|
||||
bad_string_literal = '"'+string_char+'*'+bad_escape+string_char+'*"'
|
||||
bad_string_literal = '"'+string_char+'*?'+bad_escape+string_char+'*"'
|
||||
|
||||
# floating constants (K&R2: A.2.5.3)
|
||||
exponent_part = r"""([eE][-+]?[0-9]+)"""
|
||||
|
|
@ -274,7 +276,6 @@ class CLexer(object):
|
|||
|
||||
def t_ppline_NEWLINE(self, t):
|
||||
r'\n'
|
||||
|
||||
if self.pp_line is None:
|
||||
self._error('line number missing in #line', t)
|
||||
else:
|
||||
|
|
@ -304,15 +305,14 @@ class CLexer(object):
|
|||
|
||||
def t_pppragma_PPPRAGMA(self, t):
|
||||
r'pragma'
|
||||
pass
|
||||
return t
|
||||
|
||||
t_pppragma_ignore = ' \t<>.-{}();=+-*/$%@&^~!?:,0123456789'
|
||||
t_pppragma_ignore = ' \t'
|
||||
|
||||
@TOKEN(string_literal)
|
||||
def t_pppragma_STR(self, t): pass
|
||||
|
||||
@TOKEN(identifier)
|
||||
def t_pppragma_ID(self, t): pass
|
||||
def t_pppragma_STR(self, t):
|
||||
'.+'
|
||||
t.type = 'PPPRAGMASTR'
|
||||
return t
|
||||
|
||||
def t_pppragma_error(self, t):
|
||||
self._error('invalid #pragma directive', t)
|
||||
|
|
@ -482,4 +482,3 @@ class CLexer(object):
|
|||
def t_error(self, t):
|
||||
msg = 'Illegal character %s' % repr(t.value[0])
|
||||
self._error(msg, t)
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,5 @@
|
|||
# PLY package
|
||||
# Author: David Beazley (dave@dabeaz.com)
|
||||
|
||||
__version__ = '3.9'
|
||||
__all__ = ['lex','yacc']
|
||||
|
|
|
|||
Binary file not shown.
BIN
Lib/site-packages/pycparser/ply/__pycache__/cpp.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/ply/__pycache__/cpp.cpython-37.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
Lib/site-packages/pycparser/ply/__pycache__/lex.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/ply/__pycache__/lex.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/ply/__pycache__/yacc.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/ply/__pycache__/yacc.cpython-37.pyc
Normal file
Binary file not shown.
BIN
Lib/site-packages/pycparser/ply/__pycache__/ygen.cpython-37.pyc
Normal file
BIN
Lib/site-packages/pycparser/ply/__pycache__/ygen.cpython-37.pyc
Normal file
Binary file not shown.
|
|
@ -2,12 +2,19 @@
|
|||
# cpp.py
|
||||
#
|
||||
# Author: David Beazley (http://www.dabeaz.com)
|
||||
# Copyright (C) 2007
|
||||
# Copyright (C) 2017
|
||||
# All rights reserved
|
||||
#
|
||||
# This module implements an ANSI-C style lexical preprocessor for PLY.
|
||||
# This module implements an ANSI-C style lexical preprocessor for PLY.
|
||||
# -----------------------------------------------------------------------------
|
||||
from __future__ import generators
|
||||
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
|
||||
|
|
@ -15,7 +22,7 @@ from __future__ import generators
|
|||
# -----------------------------------------------------------------------------
|
||||
|
||||
tokens = (
|
||||
'CPP_ID','CPP_INTEGER', 'CPP_FLOAT', 'CPP_STRING', 'CPP_CHAR', 'CPP_WS', 'CPP_COMMENT', 'CPP_POUND','CPP_DPOUND'
|
||||
'CPP_ID','CPP_INTEGER', 'CPP_FLOAT', 'CPP_STRING', 'CPP_CHAR', 'CPP_WS', 'CPP_COMMENT1', 'CPP_COMMENT2', 'CPP_POUND','CPP_DPOUND'
|
||||
)
|
||||
|
||||
literals = "+-*/%|&~^<>=!?()[]{}.,;:\\\'\""
|
||||
|
|
@ -34,7 +41,7 @@ t_CPP_ID = r'[A-Za-z_][\w_]*'
|
|||
|
||||
# Integer literal
|
||||
def CPP_INTEGER(t):
|
||||
r'(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU]|[lL]|[uU][lL]|[lL][uU])?)'
|
||||
r'(((((0x)|(0X))[0-9a-fA-F]+)|(\d+))([uU][lL]|[lL][uU]|[uU]|[lL])?)'
|
||||
return t
|
||||
|
||||
t_CPP_INTEGER = CPP_INTEGER
|
||||
|
|
@ -55,11 +62,21 @@ def t_CPP_CHAR(t):
|
|||
return t
|
||||
|
||||
# Comment
|
||||
def t_CPP_COMMENT(t):
|
||||
r'(/\*(.|\n)*?\*/)|(//.*?\n)'
|
||||
t.lexer.lineno += t.value.count("\n")
|
||||
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]
|
||||
|
|
@ -73,8 +90,8 @@ import os.path
|
|||
|
||||
# -----------------------------------------------------------------------------
|
||||
# trigraph()
|
||||
#
|
||||
# Given an input string, this function replaces all trigraph sequences.
|
||||
#
|
||||
# Given an input string, this function replaces all trigraph sequences.
|
||||
# The following mapping is used:
|
||||
#
|
||||
# ??= #
|
||||
|
|
@ -244,7 +261,7 @@ class Preprocessor(object):
|
|||
# ----------------------------------------------------------------------
|
||||
# add_path()
|
||||
#
|
||||
# Adds a search path to the preprocessor.
|
||||
# Adds a search path to the preprocessor.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
def add_path(self,path):
|
||||
|
|
@ -288,7 +305,7 @@ class Preprocessor(object):
|
|||
|
||||
# ----------------------------------------------------------------------
|
||||
# tokenstrip()
|
||||
#
|
||||
#
|
||||
# Remove leading/trailing whitespace tokens from a token list
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
|
|
@ -314,7 +331,7 @@ class Preprocessor(object):
|
|||
# argument. Each argument is represented by a list of tokens.
|
||||
#
|
||||
# When collecting arguments, leading and trailing whitespace is removed
|
||||
# from each argument.
|
||||
# from each argument.
|
||||
#
|
||||
# This function properly handles nested parenthesis and commas---these do not
|
||||
# define new arguments.
|
||||
|
|
@ -326,7 +343,7 @@ class Preprocessor(object):
|
|||
current_arg = []
|
||||
nesting = 1
|
||||
tokenlen = len(tokenlist)
|
||||
|
||||
|
||||
# Search for the opening '('.
|
||||
i = 0
|
||||
while (i < tokenlen) and (tokenlist[i].type in self.t_WS):
|
||||
|
|
@ -360,7 +377,7 @@ class Preprocessor(object):
|
|||
else:
|
||||
current_arg.append(t)
|
||||
i += 1
|
||||
|
||||
|
||||
# Missing end argument
|
||||
self.error(self.source,tokenlist[-1].lineno,"Missing ')' in macro arguments")
|
||||
return 0, [],[]
|
||||
|
|
@ -372,9 +389,9 @@ class Preprocessor(object):
|
|||
# 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.patch = [] # Standard macro arguments
|
||||
macro.str_patch = [] # String conversion expansion
|
||||
macro.var_comma_patch = [] # Variadic macro comma patch
|
||||
i = 0
|
||||
|
|
@ -421,7 +438,7 @@ class Preprocessor(object):
|
|||
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:
|
||||
|
|
@ -439,7 +456,7 @@ class Preprocessor(object):
|
|||
# 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
|
||||
|
|
@ -476,7 +493,7 @@ class Preprocessor(object):
|
|||
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
|
||||
|
|
@ -508,7 +525,7 @@ class Preprocessor(object):
|
|||
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)
|
||||
|
|
@ -521,13 +538,13 @@ class Preprocessor(object):
|
|||
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.
|
||||
# ----------------------------------------------------------------------
|
||||
|
|
@ -574,14 +591,14 @@ class Preprocessor(object):
|
|||
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 StandardError:
|
||||
except Exception:
|
||||
self.error(self.source,tokens[0].lineno,"Couldn't evaluate expression")
|
||||
result = 0
|
||||
return result
|
||||
|
|
@ -599,7 +616,7 @@ class Preprocessor(object):
|
|||
|
||||
if not source:
|
||||
source = ""
|
||||
|
||||
|
||||
self.define("__FILE__ \"%s\"" % source)
|
||||
|
||||
self.source = source
|
||||
|
|
@ -614,10 +631,11 @@ class Preprocessor(object):
|
|||
if tok.value == '#':
|
||||
# Preprocessor directive
|
||||
|
||||
# insert necessary whitespace instead of eaten tokens
|
||||
for tok in x:
|
||||
if tok in self.t_WS and '\n' in tok.value:
|
||||
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
|
||||
|
|
@ -625,7 +643,7 @@ class Preprocessor(object):
|
|||
else:
|
||||
name = ""
|
||||
args = []
|
||||
|
||||
|
||||
if name == 'define':
|
||||
if enable:
|
||||
for tok in self.expand_macros(chunk):
|
||||
|
|
@ -685,7 +703,7 @@ class Preprocessor(object):
|
|||
iftrigger = True
|
||||
else:
|
||||
self.error(self.source,dirtokens[0].lineno,"Misplaced #elif")
|
||||
|
||||
|
||||
elif name == 'else':
|
||||
if ifstack:
|
||||
if ifstack[-1][0]:
|
||||
|
|
@ -771,7 +789,7 @@ class Preprocessor(object):
|
|||
# ----------------------------------------------------------------------
|
||||
|
||||
def define(self,tokens):
|
||||
if isinstance(tokens,(str,unicode)):
|
||||
if isinstance(tokens,STRING_TYPES):
|
||||
tokens = self.tokenize(tokens)
|
||||
|
||||
linetok = tokens
|
||||
|
|
@ -855,7 +873,7 @@ class Preprocessor(object):
|
|||
def parse(self,input,source=None,ignore={}):
|
||||
self.ignore = ignore
|
||||
self.parser = self.parsegen(input,source)
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# token()
|
||||
#
|
||||
|
|
@ -885,14 +903,3 @@ if __name__ == '__main__':
|
|||
tok = p.token()
|
||||
if not tok: break
|
||||
print(p.source, tok)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
tokens = [
|
||||
# Literals (identifier, integer constant, float constant, string constant, char const)
|
||||
'ID', 'TYPEID', 'ICONST', 'FCONST', 'SCONST', 'CCONST',
|
||||
'ID', 'TYPEID', 'INTEGER', 'FLOAT', 'STRING', 'CHARACTER',
|
||||
|
||||
# Operators (+,-,*,/,%,|,&,~,^,<<,>>, ||, &&, !, <, <=, >, >=, ==, !=)
|
||||
'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MOD',
|
||||
'PLUS', 'MINUS', 'TIMES', 'DIVIDE', 'MODULO',
|
||||
'OR', 'AND', 'NOT', 'XOR', 'LSHIFT', 'RSHIFT',
|
||||
'LOR', 'LAND', 'LNOT',
|
||||
'LT', 'LE', 'GT', 'GE', 'EQ', 'NE',
|
||||
|
|
@ -22,7 +22,7 @@ tokens = [
|
|||
'LSHIFTEQUAL','RSHIFTEQUAL', 'ANDEQUAL', 'XOREQUAL', 'OREQUAL',
|
||||
|
||||
# Increment/decrement (++,--)
|
||||
'PLUSPLUS', 'MINUSMINUS',
|
||||
'INCREMENT', 'DECREMENT',
|
||||
|
||||
# Structure dereference (->)
|
||||
'ARROW',
|
||||
|
|
@ -74,7 +74,7 @@ t_LSHIFTEQUAL = r'<<='
|
|||
t_RSHIFTEQUAL = r'>>='
|
||||
t_ANDEQUAL = r'&='
|
||||
t_OREQUAL = r'\|='
|
||||
t_XOREQUAL = r'^='
|
||||
t_XOREQUAL = r'\^='
|
||||
|
||||
# Increment/decrement
|
||||
t_INCREMENT = r'\+\+'
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
74
Lib/site-packages/pycparser/ply/ygen.py
Normal file
74
Lib/site-packages/pycparser/ply/ygen.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# 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()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -4,10 +4,11 @@
|
|||
# PLYParser class and other utilites for simplifying programming
|
||||
# parsers with PLY
|
||||
#
|
||||
# Copyright (C) 2008-2015, Eli Bendersky
|
||||
# Eli Bendersky [https://eli.thegreenplace.net/]
|
||||
# License: BSD
|
||||
#-----------------------------------------------------------------
|
||||
|
||||
import warnings
|
||||
|
||||
class Coord(object):
|
||||
""" Coordinates of a syntactic element. Consists of:
|
||||
|
|
@ -51,5 +52,82 @@ class PLYParser(object):
|
|||
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)
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
Loading…
Add table
Add a link
Reference in a new issue