diff --git a/README.creole b/README.creole index d460d89..7d207b8 100644 --- a/README.creole +++ b/README.creole @@ -14,7 +14,13 @@ * Easy plugin development with automatic reloading and a simple hooking API. ==Requirements== -Skybot runs on Python 2.6. Many of the plugins require [[http://codespeak.net/lxml/|lxml]]. It is developed on Ubuntu 9.10 with Python 2.6.4. +To install dependencies, run: + + pip install -r requirements.txt + +Skybot runs on Python 2.7. ==License== Skybot is public domain. If you find a way to make money using it, I'll be very impressed. + +See LICENSE for precise terms. diff --git a/plugins/pycparser/__init__.py b/plugins/pycparser/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/plugins/pycparser/cdecl.py b/plugins/pycparser/cdecl.py deleted file mode 100644 index 77ef479..0000000 --- a/plugins/pycparser/cdecl.py +++ /dev/null @@ -1,98 +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. All the types used in it must be defined with typedef, -# or parsing will fail. The definition can be arbitrary, it isn't -# really used - by pycparser must know which tokens are types. -# -# For example: -# -# 'typedef int Node; const Node* (*ar)[10];' -# => -# ar is a pointer to array[10] of pointer to const Node -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- -import sys - -from pycparser import c_parser, c_ast - - -def explain_c_declaration(c_decl): - """ 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. - """ - parser = c_parser.CParser() - - node = parser.parse(c_decl, filename='') - - if ( not isinstance(node, c_ast.FileAST) or - not isinstance(node.ext[-1], c_ast.Decl)): - return "Last external node is invalid type" - - return _explain_decl_node(node.ext[-1]) - - -def _explain_decl_node(decl_node): - """ Receives a c_ast.Decl note and returns its explanation in - English. - """ - #~ print decl_node.show() - 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)) - - -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 - print "\n", explain_c_declaration(c_decl) diff --git a/plugins/pycparser/lextab.py b/plugins/pycparser/lextab.py deleted file mode 100644 index f33ce0c..0000000 --- a/plugins/pycparser/lextab.py +++ /dev/null @@ -1,9 +0,0 @@ -# pycparser.lextab.py. This file automatically created by PLY (version 3.3). Don't edit! -_tabversion = '3.3' -_lextokens = {'VOID': 1, 'LBRACKET': 1, 'WCHAR_CONST': 1, 'FLOAT_CONST': 1, 'MINUS': 1, 'RPAREN': 1, 'LONG': 1, 'PLUS': 1, 'ELLIPSIS': 1, 'GT': 1, 'GOTO': 1, 'ENUM': 1, 'PERIOD': 1, 'GE': 1, 'INT_CONST_DEC': 1, 'ARROW': 1, 'DOUBLE': 1, 'MINUSEQUAL': 1, 'INT_CONST_OCT': 1, 'TIMESEQUAL': 1, 'OR': 1, 'SHORT': 1, 'RETURN': 1, 'RSHIFTEQUAL': 1, 'STATIC': 1, 'SIZEOF': 1, 'UNSIGNED': 1, 'UNION': 1, 'COLON': 1, 'WSTRING_LITERAL': 1, 'DIVIDE': 1, 'FOR': 1, 'PLUSPLUS': 1, 'EQUALS': 1, 'ELSE': 1, 'EQ': 1, 'AND': 1, 'TYPEID': 1, 'LBRACE': 1, 'PPHASH': 1, 'INT': 1, 'SIGNED': 1, 'CONTINUE': 1, 'NOT': 1, 'OREQUAL': 1, 'MOD': 1, 'RSHIFT': 1, 'DEFAULT': 1, 'CHAR': 1, 'WHILE': 1, 'DIVEQUAL': 1, 'EXTERN': 1, 'CASE': 1, 'LAND': 1, 'REGISTER': 1, 'MODEQUAL': 1, 'NE': 1, 'SWITCH': 1, 'INT_CONST_HEX': 1, 'PLUSEQUAL': 1, 'STRUCT': 1, 'CONDOP': 1, 'BREAK': 1, 'VOLATILE': 1, 'ANDEQUAL': 1, 'DO': 1, 'LNOT': 1, 'CONST': 1, 'LOR': 1, 'CHAR_CONST': 1, 'LSHIFT': 1, 'RBRACE': 1, 'LE': 1, 'SEMI': 1, 'LT': 1, 'COMMA': 1, 'TYPEDEF': 1, 'XOR': 1, 'AUTO': 1, 'TIMES': 1, 'LPAREN': 1, 'MINUSMINUS': 1, 'ID': 1, 'IF': 1, 'STRING_LITERAL': 1, 'FLOAT': 1, 'XOREQUAL': 1, 'LSHIFTEQUAL': 1, 'RBRACKET': 1} -_lexreflags = 0 -_lexliterals = '' -_lexstateinfo = {'ppline': 'exclusive', 'INITIAL': 'inclusive'} -_lexstatere = {'ppline': [('(?P"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")|(?P(0(([uU][lL])|([lL][uU])|[uU]|[lL])?)|([1-9][0-9]*(([uU][lL])|([lL][uU])|[uU]|[lL])?))|(?P\\n)|(?Pline)', [None, ('t_ppline_FILENAME', 'FILENAME'), None, None, None, None, None, None, ('t_ppline_LINE_NUMBER', 'LINE_NUMBER'), None, None, None, None, None, None, None, None, ('t_ppline_NEWLINE', 'NEWLINE'), ('t_ppline_PPLINE', 'PPLINE')])], 'INITIAL': [('(?P[ \\t]*\\#)|(?P\\n+)|(?P((((([0-9]*\\.[0-9]+)|([0-9]+\\.))([eE][-+]?[0-9]+)?)|([0-9]+([eE][-+]?[0-9]+)))[FfLl]?))|(?P0[xX][0-9a-fA-F]+(([uU][lL])|([lL][uU])|[uU]|[lL])?)|(?P0[0-7]*[89])|(?P0[0-7]*(([uU][lL])|([lL][uU])|[uU]|[lL])?)|(?P(0(([uU][lL])|([lL][uU])|[uU]|[lL])?)|([1-9][0-9]*(([uU][lL])|([lL][uU])|[uU]|[lL])?))|(?P\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))\')|(?PL\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))\')|(?P(\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*\\n)|(\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*$))|(?P(\'([^\'\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))[^\'\n]+\')|(\'\')|(\'([\\\\][^a-zA-Z\\\\?\'"x0-7])[^\'\\n]*\'))|(?PL"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")|(?P"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*([\\\\][^a-zA-Z\\\\?\'"x0-7])([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")|(?P[a-zA-Z_][0-9a-zA-Z_]*)|(?P"([^"\\\\\\n]|(\\\\(([a-zA-Z\\\\?\'"])|([0-7]{1,3})|(x[0-9a-fA-F]+))))*")', [None, ('t_PPHASH', 'PPHASH'), ('t_NEWLINE', 'NEWLINE'), ('t_FLOAT_CONST', 'FLOAT_CONST'), None, None, None, None, None, None, None, None, None, ('t_INT_CONST_HEX', 'INT_CONST_HEX'), None, None, None, ('t_BAD_CONST_OCT', 'BAD_CONST_OCT'), ('t_INT_CONST_OCT', 'INT_CONST_OCT'), None, None, None, ('t_INT_CONST_DEC', 'INT_CONST_DEC'), None, None, None, None, None, None, None, None, ('t_CHAR_CONST', 'CHAR_CONST'), None, None, None, None, None, None, ('t_WCHAR_CONST', 'WCHAR_CONST'), None, None, None, None, None, None, ('t_UNMATCHED_QUOTE', 'UNMATCHED_QUOTE'), None, None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_BAD_CHAR_CONST', 'BAD_CHAR_CONST'), None, None, None, None, None, None, None, None, None, None, ('t_WSTRING_LITERAL', 'WSTRING_LITERAL'), None, None, None, None, None, None, ('t_BAD_STRING_LITERAL', 'BAD_STRING_LITERAL'), None, None, None, None, None, None, None, None, None, None, None, None, None, ('t_ID', 'ID'), (None, 'STRING_LITERAL')]), ('(?P\\.\\.\\.)|(?P\\+\\+)|(?P\\|\\|)|(?P\\|=)|(?P<<=)|(?P>>=)|(?P\\*=)|(?P\\+=)|(?P^=)|(?P\\+)|(?P%=)|(?P\\{)|(?P/=)|(?P\\])|(?P\\?)', [None, (None, 'ELLIPSIS'), (None, 'PLUSPLUS'), (None, 'LOR'), (None, 'OREQUAL'), (None, 'LSHIFTEQUAL'), (None, 'RSHIFTEQUAL'), (None, 'TIMESEQUAL'), (None, 'PLUSEQUAL'), (None, 'XOREQUAL'), (None, 'PLUS'), (None, 'MODEQUAL'), (None, 'LBRACE'), (None, 'DIVEQUAL'), (None, 'RBRACKET'), (None, 'CONDOP')]), ('(?P\\^)|(?P<<)|(?P<=)|(?P\\()|(?P->)|(?P==)|(?P\\})|(?P!=)|(?P--)|(?P\\|)|(?P\\*)|(?P\\[)|(?P>=)|(?P\\))|(?P&&)|(?P>>)|(?P&=)|(?P-=)|(?P\\.)|(?P=)|(?P<)|(?P,)|(?P/)|(?P&)|(?P%)|(?P;)|(?P-)|(?P>)|(?P:)|(?P~)|(?P!)', [None, (None, 'XOR'), (None, 'LSHIFT'), (None, 'LE'), (None, 'LPAREN'), (None, 'ARROW'), (None, 'EQ'), (None, 'RBRACE'), (None, 'NE'), (None, 'MINUSMINUS'), (None, 'OR'), (None, 'TIMES'), (None, 'LBRACKET'), (None, 'GE'), (None, 'RPAREN'), (None, 'LAND'), (None, 'RSHIFT'), (None, 'ANDEQUAL'), (None, 'MINUSEQUAL'), (None, 'PERIOD'), (None, 'EQUALS'), (None, 'LT'), (None, 'COMMA'), (None, 'DIVIDE'), (None, 'AND'), (None, 'MOD'), (None, 'SEMI'), (None, 'MINUS'), (None, 'GT'), (None, 'COLON'), (None, 'NOT'), (None, 'LNOT')])]} -_lexstateignore = {'ppline': ' \t', 'INITIAL': ' \t'} -_lexstateerrorf = {'ppline': 't_ppline_error', 'INITIAL': 't_error'} diff --git a/plugins/pycparser/pycparser/__init__.py b/plugins/pycparser/pycparser/__init__.py deleted file mode 100644 index f04359d..0000000 --- a/plugins/pycparser/pycparser/__init__.py +++ /dev/null @@ -1,75 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: __init__.py -# -# This package file exports some convenience functions for -# interacting with pycparser -# -# Copyright (C) 2008-2009, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -__all__ = ['c_lexer', 'c_parser', 'c_ast'] -__version__ = '1.05' - -from subprocess import Popen, PIPE -from types import ListType - -from c_parser import CParser - - -def parse_file( filename, use_cpp=False, - cpp_path='cpp', cpp_args=''): - """ 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. - - 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: - path_list = [cpp_path] - if isinstance(cpp_args, ListType): - path_list += cpp_args - elif cpp_args != '': - path_list += [cpp_args] - path_list += [filename] - - # 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] - else: - text = open(filename).read() - - parser = CParser() - return parser.parse(text, filename) - - -if __name__ == "__main__": - pass - - diff --git a/plugins/pycparser/pycparser/c_ast.py b/plugins/pycparser/pycparser/c_ast.py deleted file mode 100644 index e0ebab8..0000000 --- a/plugins/pycparser/pycparser/c_ast.py +++ /dev/null @@ -1,1163 +0,0 @@ -#----------------------------------------------------------------- -# ** ATTENTION ** -# This code was automatically generated from the file: -# _c_ast.yaml -# -# Do not modify it directly. Modify the configuration file and -# run the generator again. -# ** ** *** ** ** -# -# pycparser: c_ast.py -# -# AST Node classes. -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - - -import sys - - -class Node(object): - """ Abstract base class for AST nodes. - """ - def children(self): - """ A sequence of all children that are Nodes - """ - pass - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - """ Pretty print the Node and all its attributes and - children (recursively) to a buffer. - - file: - 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. - - showcoord: - Do you want the coordinates of each Node to be - displayed. - """ - pass - - -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) - """ - def visit(self, node): - """ Visit a node. - """ - method = 'visit_' + node.__class__.__name__ - visitor = getattr(self, method, self.generic_visit) - 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.children(): - self.visit(c) - - -class Typedef(Node): - 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(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Typedef: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name)), ("quals", repr(self.quals)), ("storage", repr(self.storage))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name, self.quals, self.storage]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Struct(Node): - def __init__(self, name, decls, coord=None): - self.name = name - self.decls = decls - self.coord = coord - - def children(self): - nodelist = [] - if self.decls is not None: nodelist.extend(self.decls) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Struct: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FuncCall(Node): - 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(self.name) - if self.args is not None: nodelist.append(self.args) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FuncCall: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class UnaryOp(Node): - 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(self.expr) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'UnaryOp: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("op", repr(self.op))]) - else: - attrstr = ', '.join('%s' % v for v in [self.op]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Union(Node): - def __init__(self, name, decls, coord=None): - self.name = name - self.decls = decls - self.coord = coord - - def children(self): - nodelist = [] - if self.decls is not None: nodelist.extend(self.decls) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Union: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class TernaryOp(Node): - 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(self.cond) - if self.iftrue is not None: nodelist.append(self.iftrue) - if self.iffalse is not None: nodelist.append(self.iffalse) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'TernaryOp: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Label(Node): - 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(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Label: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class IdentifierType(Node): - def __init__(self, names, coord=None): - self.names = names - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'IdentifierType: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("names", repr(self.names))]) - else: - attrstr = ', '.join('%s' % v for v in [self.names]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FuncDef(Node): - 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(self.decl) - if self.body is not None: nodelist.append(self.body) - if self.param_decls is not None: nodelist.extend(self.param_decls) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FuncDef: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Enumerator(Node): - 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(self.value) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Enumerator: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class For(Node): - 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(self.init) - if self.cond is not None: nodelist.append(self.cond) - if self.next is not None: nodelist.append(self.next) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'For: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Assignment(Node): - 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(self.lvalue) - if self.rvalue is not None: nodelist.append(self.rvalue) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Assignment: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("op", repr(self.op))]) - else: - attrstr = ', '.join('%s' % v for v in [self.op]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FuncDecl(Node): - 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(self.args) - if self.type is not None: nodelist.append(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FuncDecl: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Enum(Node): - 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(self.values) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Enum: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ExprList(Node): - def __init__(self, exprs, coord=None): - self.exprs = exprs - self.coord = coord - - def children(self): - nodelist = [] - if self.exprs is not None: nodelist.extend(self.exprs) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ExprList: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Break(Node): - def __init__(self, coord=None): - self.coord = coord - - def children(self): - return () - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Break: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class DoWhile(Node): - 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(self.cond) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'DoWhile: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class StructRef(Node): - 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(self.name) - if self.field is not None: nodelist.append(self.field) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'StructRef: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("type", repr(self.type))]) - else: - attrstr = ', '.join('%s' % v for v in [self.type]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class BinaryOp(Node): - 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(self.left) - if self.right is not None: nodelist.append(self.right) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'BinaryOp: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("op", repr(self.op))]) - else: - attrstr = ', '.join('%s' % v for v in [self.op]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Compound(Node): - def __init__(self, decls, stmts, coord=None): - self.decls = decls - self.stmts = stmts - self.coord = coord - - def children(self): - nodelist = [] - if self.decls is not None: nodelist.extend(self.decls) - if self.stmts is not None: nodelist.extend(self.stmts) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Compound: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ArrayDecl(Node): - def __init__(self, type, dim, coord=None): - self.type = type - self.dim = dim - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - if self.dim is not None: nodelist.append(self.dim) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ArrayDecl: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Case(Node): - def __init__(self, expr, stmt, coord=None): - self.expr = expr - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.expr is not None: nodelist.append(self.expr) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Case: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Cast(Node): - 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(self.to_type) - if self.expr is not None: nodelist.append(self.expr) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Cast: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class TypeDecl(Node): - 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(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'TypeDecl: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("declname", repr(self.declname)), ("quals", repr(self.quals))]) - else: - attrstr = ', '.join('%s' % v for v in [self.declname, self.quals]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Default(Node): - def __init__(self, stmt, coord=None): - self.stmt = stmt - self.coord = coord - - def children(self): - nodelist = [] - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Default: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class PtrDecl(Node): - 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(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'PtrDecl: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("quals", repr(self.quals))]) - else: - attrstr = ', '.join('%s' % v for v in [self.quals]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Switch(Node): - 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(self.cond) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Switch: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Continue(Node): - def __init__(self, coord=None): - self.coord = coord - - def children(self): - return () - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Continue: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ParamList(Node): - def __init__(self, params, coord=None): - self.params = params - self.coord = coord - - def children(self): - nodelist = [] - if self.params is not None: nodelist.extend(self.params) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ParamList: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Return(Node): - def __init__(self, expr, coord=None): - self.expr = expr - self.coord = coord - - def children(self): - nodelist = [] - if self.expr is not None: nodelist.append(self.expr) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Return: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Typename(Node): - 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(self.type) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Typename: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("quals", repr(self.quals))]) - else: - attrstr = ', '.join('%s' % v for v in [self.quals]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ID(Node): - def __init__(self, name, coord=None): - self.name = name - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ID: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Goto(Node): - def __init__(self, name, coord=None): - self.name = name - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Goto: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Decl(Node): - def __init__(self, name, quals, storage, type, init, bitsize, coord=None): - self.name = name - self.quals = quals - self.storage = storage - self.type = type - self.init = init - self.bitsize = bitsize - self.coord = coord - - def children(self): - nodelist = [] - if self.type is not None: nodelist.append(self.type) - if self.init is not None: nodelist.append(self.init) - if self.bitsize is not None: nodelist.append(self.bitsize) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Decl: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("name", repr(self.name)), ("quals", repr(self.quals)), ("storage", repr(self.storage))]) - else: - attrstr = ', '.join('%s' % v for v in [self.name, self.quals, self.storage]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class Constant(Node): - def __init__(self, type, value, coord=None): - self.type = type - self.value = value - self.coord = coord - - def children(self): - nodelist = [] - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'Constant: ') - - if attrnames: - attrstr = ', '.join('%s=%s' % nv for nv in [("type", repr(self.type)), ("value", repr(self.value))]) - else: - attrstr = ', '.join('%s' % v for v in [self.type, self.value]) - buf.write(attrstr) - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class FileAST(Node): - def __init__(self, ext, coord=None): - self.ext = ext - self.coord = coord - - def children(self): - nodelist = [] - if self.ext is not None: nodelist.extend(self.ext) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'FileAST: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class ArrayRef(Node): - 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(self.name) - if self.subscript is not None: nodelist.append(self.subscript) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'ArrayRef: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class While(Node): - 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(self.cond) - if self.stmt is not None: nodelist.append(self.stmt) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'While: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class EnumeratorList(Node): - def __init__(self, enumerators, coord=None): - self.enumerators = enumerators - self.coord = coord - - def children(self): - nodelist = [] - if self.enumerators is not None: nodelist.extend(self.enumerators) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'EnumeratorList: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class EllipsisParam(Node): - def __init__(self, coord=None): - self.coord = coord - - def children(self): - return () - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'EllipsisParam: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - -class If(Node): - 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(self.cond) - if self.iftrue is not None: nodelist.append(self.iftrue) - if self.iffalse is not None: nodelist.append(self.iffalse) - return tuple(nodelist) - - def show(self, buf=sys.stdout, offset=0, attrnames=False, showcoord=False): - lead = ' ' * offset - buf.write(lead + 'If: ') - - if showcoord: - buf.write(' (at %s)' % self.coord) - buf.write('\n') - - for c in self.children(): - c.show(buf, offset + 2, attrnames, showcoord) - - diff --git a/plugins/pycparser/pycparser/c_lexer.py b/plugins/pycparser/pycparser/c_lexer.py deleted file mode 100644 index 97f9d3b..0000000 --- a/plugins/pycparser/pycparser/c_lexer.py +++ /dev/null @@ -1,443 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: clex.py -# -# CLexer class: lexer for the C language -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -import re -import sys - -import ply.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, 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. - - 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.type_lookup_func = type_lookup_func - self.filename = '' - - # Allow either "# line" or "# " to support GCC's - # cpp output - # - self.line_pattern = re.compile('([ \t]*line\W)|([ \t]*\d+)') - - 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 = ply.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): - g = self.lexer.token() - return g - - ######################-- 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 _find_tok_column(self, token): - i = token.lexpos - while i > 0: - if self.lexer.lexdata[i] == '\n': break - i -= 1 - return (token.lexpos - i) + 1 - - def _make_tok_location(self, token): - return (token.lineno, self._find_tok_column(token)) - - ## - ## Reserved keywords - ## - keywords = ( - 'AUTO', 'BREAK', 'CASE', 'CHAR', 'CONST', 'CONTINUE', - 'DEFAULT', 'DO', 'DOUBLE', 'ELSE', 'ENUM', 'EXTERN', - 'FLOAT', 'FOR', 'GOTO', 'IF', 'INT', 'LONG', 'REGISTER', - 'RETURN', 'SHORT', 'SIGNED', 'SIZEOF', 'STATIC', 'STRUCT', - 'SWITCH', 'TYPEDEF', 'UNION', 'UNSIGNED', 'VOID', - 'VOLATILE', 'WHILE', - ) - - keyword_map = {} - for r in keywords: - keyword_map[r.lower()] = r - - ## - ## 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', - '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', # '#' - ) - - ## - ## Regexes for use in tokens - ## - ## - - # valid C identifiers (K&R2: A.2.3) - identifier = r'[a-zA-Z_][0-9a-zA-Z_]*' - - # integer constants (K&R2: A.2.5.1) - integer_suffix_opt = r'(([uU][lL])|([lL][uU])|[uU]|[lL])?' - decimal_constant = '(0'+integer_suffix_opt+')|([1-9][0-9]*'+integer_suffix_opt+')' - octal_constant = '0[0-7]*'+integer_suffix_opt - hex_constant = '0[xX][0-9a-fA-F]+'+integer_suffix_opt - - bad_octal_constant = '0[0-7]*[89]' - - # character constants (K&R2: A.2.5.2) - # Note: a-zA-Z are allowed as escape chars to support #line - # directives with Windows paths as filenames (\dir\file...) - # - simple_escape = r"""([a-zA-Z\\?'"])""" - octal_escape = r"""([0-7]{1,3})""" - hex_escape = r"""(x[0-9a-fA-F]+)""" - bad_escape = r"""([\\][^a-zA-Z\\?'"x0-7])""" - - escape_sequence = r"""(\\("""+simple_escape+'|'+octal_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]?)' - - ## - ## Lexer states - ## - states = ( - # ppline: preprocessor line directives - # - ('ppline', 'exclusive'), - ) - - def t_PPHASH(self, t): - r'[ \t]*\#' - m = self.line_pattern.match( - t.lexer.lexdata, pos=t.lexer.lexpos) - - if m: - t.lexer.begin('ppline') - self.pp_line = self.pp_filename = None - #~ print "ppline starts on line %s" % t.lexer.lineno - 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('"') - #~ print "PP got filename: ", self.pp_filename - - @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): - msg = 'invalid #line directive' - self._error(msg, 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_LBRACE = r'\{' - t_RBRACE = r'\}' - t_COMMA = r',' - t_PERIOD = r'\.' - t_SEMI = r';' - t_COLON = r':' - t_ELLIPSIS = r'\.\.\.' - - 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_constant) - def t_INT_CONST_HEX(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) - - -if __name__ == "__main__": - filename = '../zp.c' - text = open(filename).read() - - #~ text = '"'+r"""ka \p ka"""+'"' - text = r""" - 546 - #line 66 "kwas\df.h" - id 4 - # 5 - dsf - """ - - def errfoo(msg, a, b): - print msg - sys.exit() - - def typelookup(namd): - return False - - clex = CLexer(errfoo, typelookup) - clex.build() - clex.input(text) - - while 1: - tok = clex.token() - if not tok: break - - #~ print type(tok) - print "-", tok.value, tok.type, tok.lineno, clex.filename, tok.lexpos - - diff --git a/plugins/pycparser/pycparser/c_parser.py b/plugins/pycparser/pycparser/c_parser.py deleted file mode 100644 index ba5cb90..0000000 --- a/plugins/pycparser/pycparser/c_parser.py +++ /dev/null @@ -1,1259 +0,0 @@ -#----------------------------------------------------------------- -# pycparser: cparse.py -# -# CParser class: Parser and AST builder for the C language -# -# Copyright (C) 2008, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - -import re -import sys -from types import StringType - -import ply.yacc - -import c_ast -from c_lexer import CLexer -from plyparser import PLYParser, Coord, ParseError - - -class CParser(PLYParser): - def __init__( - self, - lex_optimize=True, - lextab='pycparser.lextab', - yacc_optimize=True, - yacctab='pycparser.yacctab', - yacc_debug=False): - """ 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. - - 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. - """ - self.clex = CLexer( - error_func=self._lex_error_func, - type_lookup_func=self._lex_type_lookup_func) - - self.clex.build( - optimize=lex_optimize, - lextab=lextab) - self.tokens = self.clex.tokens - - rules_with_opt = [ - 'abstract_declarator', - 'constant_expression', - 'declaration_list', - 'declaration_specifiers', - 'expression', - 'identifier_list', - 'init_declarator_list', - 'parameter_type_list', - 'specifier_qualifier_list', - 'statement_list', - 'type_qualifier_list', - ] - - for rule in rules_with_opt: - self._create_opt_rule(rule) - - self.cparser = ply.yacc.yacc( - module=self, - start='translation_unit', - debug=yacc_debug, - optimize=yacc_optimize, - tabmodule=yacctab) - - # A table of identifiers defined as typedef types during - # parsing. - # - self.typedef_table = set([]) - - 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.typedef_table = set([]) - return self.cparser.parse(text, lexer=self.clex, debug=debuglevel) - - ######################-- PRIVATE --###################### - - def _lex_error_func(self, msg, line, column): - self._parse_error(msg, self._coord(line, column)) - - 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. - """ - return name in self.typedef_table - - def _add_typedef_type(self, name): - """ Adds names that were defined as new types with - typedef. - """ - self.typedef_table.add(name) - - # 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 x', 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 problem. - # - 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 a simple string type, 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, StringType): - if len(typename) > 1: - self._parse_error( - "Invalid multiple types specified", tn.coord) - else: - type.type = tn - return decl - - type.type = c_ast.IdentifierType(typename) - return decl - - def _add_declaration_specifier(self, declspec, newspec, kind): - """ Declaration specifiers are represented by a dictionary - with 3 entries: - * qual: a list of type qualifiers - * storage: a list of storage type qualifiers - * type: a list of type specifiers - - This method is given a declaration specifier, and a - new specifier of a given kind. - Returns the declaration specifier, with the new - specifier incorporated. - """ - spec = declspec or dict(qual=[], storage=[], type=[]) - spec[kind].append(newspec) - return spec - - def _build_function_definition(self, decl, spec, param_decls, body): - """ Builds a function definition. - """ - declaration = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - init=None, - bitsize=None, - coord=decl.coord) - - typename = spec['type'] - declaration = self._fix_decl_name_type(declaration, typename) - 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 - ## - def p_translation_unit_1(self, p): - """ translation_unit : external_declaration - """ - # Note: external_declaration is already a list - # - p[0] = c_ast.FileAST(p[1]) - - def p_translation_unit_2(self, p): - """ translation_unit : translation_unit external_declaration - """ - p[1].ext.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 - """ - p[0] = p[1] - - def p_pp_directive(self, p): - """ pp_directive : PPHASH - """ - self._parse_error('Directives not supported yet', - self._coord(p.lineno(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 : declarator declaration_list_opt compound_statement - """ - # no declaration specifiers - spec = dict(qual=[], storage=[], type=[]) - - p[0] = self._build_function_definition( - decl=p[1], - spec=spec, - param_decls=p[2], - body=p[3]) - - def p_function_definition_2(self, p): - """ function_definition : declaration_specifiers declarator declaration_list_opt compound_statement - """ - spec = p[1] - - p[0] = self._build_function_definition( - decl=p[2], - spec=spec, - 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 - """ - 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 - """ - spec = p[1] - is_typedef = 'typedef' in spec['storage'] - decls = [] - - # p[2] (init_declarator_list_opt) is either a list or None - # - if p[2] is None: - # Then it's a declaration of a struct / enum tag, - # without an actual declarator. - # - type = spec['type'] - if len(type) > 1: - coord = '?' - for t in type: - if hasattr(t, 'coord'): - coord = t.coord - break - - self._parse_error('Multiple type specifiers with a type tag', coord) - - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=type[0], - init=None, - bitsize=None, - coord=type[0].coord) - decls = [decl] - else: - for decl, init in p[2] or []: - if is_typedef: - decl = c_ast.Typedef( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - coord=decl.coord) - else: - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - init=init, - bitsize=None, - coord=decl.coord) - - typename = spec['type'] - fixed_decl = self._fix_decl_name_type(decl, typename) - - # Add the type name defined by typedef to a - # symbol table (for usage in the lexer) - # - if is_typedef: - self._add_typedef_type(fixed_decl.name) - - decls.append(fixed_decl) - - 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] - - def p_declaration_specifiers_1(self, p): - """ declaration_specifiers : type_qualifier declaration_specifiers_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'qual') - - def p_declaration_specifiers_2(self, p): - """ declaration_specifiers : type_specifier declaration_specifiers_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'type') - - def p_declaration_specifiers_3(self, p): - """ declaration_specifiers : storage_class_specifier declaration_specifiers_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'storage') - - def p_storage_class_specifier(self, p): - """ storage_class_specifier : AUTO - | REGISTER - | STATIC - | EXTERN - | TYPEDEF - """ - p[0] = p[1] - - def p_type_specifier_1(self, p): - """ type_specifier : VOID - | CHAR - | SHORT - | INT - | LONG - | FLOAT - | DOUBLE - | SIGNED - | UNSIGNED - | typedef_name - | enum_specifier - | struct_or_union_specifier - """ - p[0] = p[1] - - def p_type_qualifier(self, p): - """ type_qualifier : CONST - | 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 (declarator, intializer) pair - # If there's no initializer, returns (declarator, None) - # - def p_init_declarator(self, p): - """ init_declarator : declarator - | declarator EQUALS initializer - """ - p[0] = (p[1], p[3] if len(p) > 2 else None) - - def p_specifier_qualifier_list_1(self, p): - """ specifier_qualifier_list : type_qualifier specifier_qualifier_list_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'qual') - - def p_specifier_qualifier_list_2(self, p): - """ specifier_qualifier_list : type_specifier specifier_qualifier_list_opt - """ - p[0] = self._add_declaration_specifier(p[2], p[1], 'type') - - # 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]) - p[0] = klass( - name=p[2], - decls=None, - coord=self._coord(p.lineno(2))) - - def p_struct_or_union_specifier_2(self, p): - """ struct_or_union_specifier : struct_or_union LBRACE struct_declaration_list RBRACE - """ - klass = self._select_struct_union_class(p[1]) - p[0] = klass( - name=None, - decls=p[3], - coord=self._coord(p.lineno(2))) - - def p_struct_or_union_specifier_3(self, p): - """ struct_or_union_specifier : struct_or_union ID LBRACE struct_declaration_list RBRACE - | struct_or_union TYPEID LBRACE struct_declaration_list RBRACE - """ - klass = self._select_struct_union_class(p[1]) - p[0] = klass( - name=p[2], - decls=p[4], - coord=self._coord(p.lineno(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 - """ - p[0] = p[1] if len(p) == 2 else p[1] + p[2] - - def p_struct_declaration_1(self, p): - """ struct_declaration : specifier_qualifier_list struct_declarator_list SEMI - """ - spec = p[1] - decls = [] - - for struct_decl in p[2]: - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=struct_decl['decl'], - init=None, - bitsize=struct_decl['bitsize'], - coord=struct_decl['decl'].coord) - - typename = spec['type'] - decls.append(self._fix_decl_name_type(decl, typename)) - - p[0] = decls - - 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': 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._coord(p.lineno(1))) - - def p_enum_specifier_2(self, p): - """ enum_specifier : ENUM LBRACE enumerator_list RBRACE - """ - p[0] = c_ast.Enum(None, p[3], self._coord(p.lineno(1))) - - def p_enum_specifier_3(self, p): - """ enum_specifier : ENUM ID LBRACE enumerator_list RBRACE - | ENUM TYPEID LBRACE enumerator_list RBRACE - """ - p[0] = c_ast.Enum(p[2], p[4], self._coord(p.lineno(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: - p[0] = c_ast.Enumerator( - p[1], None, - self._coord(p.lineno(1))) - else: - p[0] = c_ast.Enumerator( - p[1], p[3], - self._coord(p.lineno(1))) - - def p_declarator_1(self, p): - """ declarator : direct_declarator - """ - p[0] = p[1] - - def p_declarator_2(self, p): - """ declarator : pointer direct_declarator - """ - p[0] = self._type_modify_decl(p[2], p[1]) - - def p_direct_declarator_1(self, p): - """ direct_declarator : ID - """ - p[0] = c_ast.TypeDecl( - declname=p[1], - type=None, - quals=None, - coord=self._coord(p.lineno(1))) - - def p_direct_declarator_2(self, p): - """ direct_declarator : LPAREN declarator RPAREN - """ - p[0] = p[2] - - def p_direct_declarator_3(self, p): - """ direct_declarator : direct_declarator LBRACKET constant_expression_opt RBRACKET - """ - arr = c_ast.ArrayDecl( - type=None, - dim=p[3], - coord=p[1].coord) - - p[0] = self._type_modify_decl(decl=p[1], modifier=arr) - - def p_direct_declarator_4(self, p): - """ direct_declarator : direct_declarator LPAREN parameter_type_list RPAREN - | direct_declarator LPAREN identifier_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_pointer(self, p): - """ pointer : TIMES type_qualifier_list_opt - | TIMES type_qualifier_list_opt pointer - """ - coord = self._coord(p.lineno(1)) - - p[0] = c_ast.PtrDecl( - quals=p[2] or [], - type=p[3] if len(p) > 3 else None, - coord=coord) - - 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()) - - 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] - - def p_parameter_declaration_1(self, p): - """ parameter_declaration : declaration_specifiers declarator - """ - spec = p[1] - decl = p[2] - - decl = c_ast.Decl( - name=None, - quals=spec['qual'], - storage=spec['storage'], - type=decl, - init=None, - bitsize=None, - coord=decl.coord) - - typename = spec['type'] or ['int'] - p[0] = self._fix_decl_name_type(decl, typename) - - def p_parameter_declaration_2(self, p): - """ parameter_declaration : declaration_specifiers abstract_declarator_opt - """ - spec = p[1] - decl = c_ast.Typename( - quals=spec['qual'], - type=p[2] or c_ast.TypeDecl(None, None, None)) - - typename = spec['type'] or ['int'] - - p[0] = self._fix_decl_name_type(decl, typename) - - 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 : LBRACE initializer_list RBRACE - | LBRACE initializer_list COMMA RBRACE - """ - p[0] = p[2] - - def p_initializer_list(self, p): - """ initializer_list : initializer - | initializer_list COMMA initializer - """ - if len(p) == 2: # single initializer - p[0] = c_ast.ExprList([p[1]], p[1].coord) - else: - p[1].exprs.append(p[3]) - p[0] = p[1] - - def p_type_name(self, p): - """ type_name : specifier_qualifier_list abstract_declarator_opt - """ - #~ print '==========' - #~ print p[1] - #~ print p[2] - #~ print p[2].children() - #~ print '==========' - - typename = c_ast.Typename( - quals=p[1]['qual'], - type=p[2] or c_ast.TypeDecl(None, None, None)) - - 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 constant_expression_opt RBRACKET - """ - arr = c_ast.ArrayDecl( - type=None, - dim=p[3], - 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 constant_expression_opt RBRACKET - """ - p[0] = c_ast.ArrayDecl( - type=c_ast.TypeDecl(None, None, None), - dim=p[2], - coord=self._coord(p.lineno(1))) - - def p_direct_abstract_declarator_4(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_5(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=p[1].coord) - - def p_compound_statement_1(self, p): - """ compound_statement : LBRACE statement_list_opt RBRACE """ - p[0] = c_ast.Compound( - decls=None, - stmts=p[2], - coord=self._coord(p.lineno(1))) - - def p_compound_statement_2(self, p): - """ compound_statement : LBRACE declaration_list RBRACE """ - p[0] = c_ast.Compound( - decls=p[2], - stmts=None, - coord=self._coord(p.lineno(1))) - - def p_compound_statement_3(self, p): - """ compound_statement : LBRACE declaration_list statement_list RBRACE """ - #~ print '((((((' - #~ print p[2] - #~ print p[3] - #~ print '((((((' - p[0] = c_ast.Compound( - decls=p[2], - stmts=p[3], - coord=self._coord(p.lineno(1))) - - # Note: this doesn't create an AST node, but a list of AST - # nodes that will be used as the statement list of a compound - # - def p_statement_list(self, p): - """ statement_list : statement - | statement_list statement - """ - if len(p) == 2: # single expr - p[0] = [p[1]] if p[1] else [] - else: - p[0] = p[1] + ([p[2]] if p[2] else []) - - def p_labeled_statement_1(self, p): - """ labeled_statement : ID COLON statement """ - p[0] = c_ast.Label(p[1], p[3], self._coord(p.lineno(1))) - - def p_labeled_statement_2(self, p): - """ labeled_statement : CASE constant_expression COLON statement """ - p[0] = c_ast.Case(p[2], p[4], self._coord(p.lineno(1))) - - def p_labeled_statement_3(self, p): - """ labeled_statement : DEFAULT COLON statement """ - p[0] = c_ast.Default(p[3], self._coord(p.lineno(1))) - - def p_selection_statement_1(self, p): - """ selection_statement : IF LPAREN expression RPAREN statement """ - p[0] = c_ast.If(p[3], p[5], None, self._coord(p.lineno(1))) - - def p_selection_statement_2(self, p): - """ selection_statement : IF LPAREN expression RPAREN statement ELSE statement """ - p[0] = c_ast.If(p[3], p[5], p[7], self._coord(p.lineno(1))) - - def p_selection_statement_3(self, p): - """ selection_statement : SWITCH LPAREN expression RPAREN statement """ - p[0] = c_ast.Switch(p[3], p[5], self._coord(p.lineno(1))) - - def p_iteration_statement_1(self, p): - """ iteration_statement : WHILE LPAREN expression RPAREN statement """ - p[0] = c_ast.While(p[3], p[5], self._coord(p.lineno(1))) - - def p_iteration_statement_2(self, p): - """ iteration_statement : DO statement WHILE LPAREN expression RPAREN """ - p[0] = c_ast.DoWhile(p[5], p[2], self._coord(p.lineno(1))) - - def p_iteration_statement_3(self, p): - """ iteration_statement : FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement """ - p[0] = c_ast.For(p[3], p[5], p[7], p[9], self._coord(p.lineno(1))) - - def p_jump_statement_1(self, p): - """ jump_statement : GOTO ID SEMI """ - p[0] = c_ast.Goto(p[2], self._coord(p.lineno(1))) - - def p_jump_statement_2(self, p): - """ jump_statement : BREAK SEMI """ - p[0] = c_ast.Break(self._coord(p.lineno(1))) - - def p_jump_statement_3(self, p): - """ jump_statement : CONTINUE SEMI """ - p[0] = c_ast.Continue(self._coord(p.lineno(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._coord(p.lineno(1))) - - def p_expression_statement(self, p): - """ expression_statement : expression_opt SEMI """ - 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] = 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], p[2].coord) - - 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._coord(p.lineno(1))) - - def p_unary_operator(self, p): - """ unary_operator : AND - | TIMES - | PLUS - | MINUS - | NOT - | LNOT - """ - p[0] = p[1] - - def p_postfix_exptession_1(self, p): - """ postfix_expression : primary_expression """ - p[0] = p[1] - - def p_postfix_exptession_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_exptession_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) - - def p_postfix_expression_4(self, p): - """ postfix_expression : postfix_expression PERIOD identifier - | postfix_expression ARROW identifier - """ - p[0] = c_ast.StructRef(p[1], p[2], p[3], 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_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 : STRING_LITERAL - | WSTRING_LITERAL - """ - p[0] = c_ast.Constant( - 'string', p[1], self._coord(p.lineno(1))) - - def p_primary_expression_4(self, p): - """ primary_expression : LPAREN expression RPAREN """ - p[0] = p[2] - - 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._coord(p.lineno(1))) - - def p_constant_1(self, p): - """ constant : INT_CONST_DEC - | INT_CONST_OCT - | INT_CONST_HEX - """ - p[0] = c_ast.Constant( - 'int', p[1], self._coord(p.lineno(1))) - - def p_constant_2(self, p): - """ constant : FLOAT_CONST """ - p[0] = c_ast.Constant( - 'float', p[1], self._coord(p.lineno(1))) - - def p_constant_3(self, p): - """ constant : CHAR_CONST - | WCHAR_CONST - """ - p[0] = c_ast.Constant( - 'char', p[1], self._coord(p.lineno(1))) - - def p_empty(self, p): - 'empty : ' - p[0] = None - - def p_error(self, p): - if p: - self._parse_error( - 'before: %s' % p.value, - self._coord(p.lineno)) - else: - self._parse_error('At end of input', '') - - -if __name__ == "__main__": - import pprint - import time - - t1 = time.time() - parser = CParser(lex_optimize=True, yacc_debug=True, yacc_optimize=False) - print time.time() - t1 - - buf = ''' - int (*k)(int); - ''' - - # set debuglevel to 2 for debugging - t = parser.parse(buf, 'x.c', debuglevel=0) - t.show(showcoord=True) diff --git a/plugins/pycparser/pycparser/ply/__init__.py b/plugins/pycparser/pycparser/ply/__init__.py deleted file mode 100644 index 853a985..0000000 --- a/plugins/pycparser/pycparser/ply/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# PLY package -# Author: David Beazley (dave@dabeaz.com) - -__all__ = ['lex','yacc'] diff --git a/plugins/pycparser/pycparser/ply/lex.py b/plugins/pycparser/pycparser/ply/lex.py deleted file mode 100644 index 37a9993..0000000 --- a/plugins/pycparser/pycparser/ply/lex.py +++ /dev/null @@ -1,1021 +0,0 @@ -# ----------------------------------------------------------------------------- -# ply: lex.py -# -# Copyright (C) 2001-2009, -# 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.3" -__tabversion__ = "3.2" # Version of table file used - -import re, sys, types, copy, os - -# This tuple contains known string types -try: - # Python 2.6 - StringTypes = (types.StringType, types.UnicodeType) -except AttributeError: - # Python 3.0 - StringTypes = (str, bytes) - -# Extract the code attribute of a function. Different implementations -# are for Python 2/3 compatibility. - -if sys.version_info[0] < 3: - def func_code(f): - return f.func_code -else: - def func_code(f): - return f.__code__ - -# 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.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.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 = 0 # 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,tabfile,outputdir=""): - return - - # ------------------------------------------------------------ - # readtab() - Read lexer information from a tab file - # ------------------------------------------------------------ - def readtab(self,tabfile,fdict): - if isinstance(tabfile,types.ModuleType): - lextab = tabfile - else: - if sys.version_info[0] < 3: - exec("import %s as lextab" % tabfile) - else: - env = { } - exec("import %s as lextab" % tabfile, env,env) - lextab = env['lextab'] - - if getattr(lextab,"_tabversion","0.0") != __version__: - raise ImportError("Inconsistent PLY version") - - self.lextokens = lextab._lextokens - self.lexreflags = lextab._lexreflags - self.lexliterals = lextab._lexliterals - self.lexstateinfo = lextab._lexstateinfo - self.lexstateignore = lextab._lexstateignore - self.lexstatere = { } - self.lexstateretext = { } - for key,lre in lextab._lexstatere.items(): - titem = [] - txtitem = [] - for i in range(len(lre)): - titem.append((re.compile(lre[i][0],lextab._lexreflags | re.VERBOSE),_names_to_funcs(lre[i][1],fdict))) - txtitem.append(lre[i][0]) - self.lexstatere[key] = titem - self.lexstateretext[key] = txtitem - self.lexstateerrorf = { } - for key,ef in lextab._lexstateerrorf.items(): - self.lexstateerrorf[key] = 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 not state 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.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 not newtok.type in self.lextokens: - raise LexError("%s:%d: Rule '%s' returned an unknown token type '%s'" % ( - func_code(func).co_filename, func_code(func).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:]) - - 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_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): - try: - raise RuntimeError - except RuntimeError: - e,b,t = sys.exc_info() - f = t.tb_frame - while levels > 0: - f = f.f_back - levels -= 1 - 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,re.VERBOSE | 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 in range(1,len(parts)): - if not parts[i] in names and parts[i] != '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.files = {} - self.error = 0 - - 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_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 = 1 - return - - if not isinstance(tokens,(list, tuple)): - self.log.error("tokens must be a list or tuple") - self.error = 1 - return - - if not tokens: - self.log.error("tokens is empty") - self.error = 1 - 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 = 1 - 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","") - - # 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 = 1 - continue - - except TypeError: - self.log.error("Invalid literals specification. literals must be a sequence of characters") - self.error = 1 - - 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 = 1 - 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 = 1 - continue - name, statetype = s - if not isinstance(name,StringTypes): - self.log.error("State name %s must be a string", repr(name)) - self.error = 1 - continue - if not (statetype == 'inclusive' or statetype == 'exclusive'): - self.log.error("State type for state %s must be 'inclusive' or 'exclusive'",name) - self.error = 1 - continue - if name in self.stateinfo: - self.log.error("State '%s' already defined",name) - self.error = 1 - 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 - - 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 = 1 - 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 == 'ignore': - line = func_code(t).co_firstlineno - file = func_code(t).co_filename - self.log.error("%s:%d: Rule '%s' must be defined as a string",file,line,t.__name__) - self.error = 1 - 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 = 1 - 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 = 1 - - # Sort the functions by line number - for f in self.funcsym.values(): - if sys.version_info[0] < 3: - f.sort(lambda x,y: cmp(func_code(x[1]).co_firstlineno,func_code(y[1]).co_firstlineno)) - else: - # Python 3.0 - f.sort(key=lambda x: func_code(x[1]).co_firstlineno) - - # Sort the strings by regular expression length - for s in self.strsym.values(): - if sys.version_info[0] < 3: - s.sort(lambda x,y: (len(x[1]) < len(y[1])) - (len(x[1]) > len(y[1]))) - else: - # Python 3.0 - 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 = func_code(f).co_firstlineno - file = func_code(f).co_filename - self.files[file] = 1 - - tokname = self.toknames[fname] - if isinstance(f, types.MethodType): - reqargs = 2 - else: - reqargs = 1 - nargs = func_code(f).co_argcount - if nargs > reqargs: - self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__) - self.error = 1 - continue - - if nargs < reqargs: - self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__) - self.error = 1 - continue - - if not f.__doc__: - self.log.error("%s:%d: No regular expression defined for rule '%s'",file,line,f.__name__) - self.error = 1 - continue - - try: - c = re.compile("(?P<%s>%s)" % (fname,f.__doc__), re.VERBOSE | self.reflags) - if c.match(""): - self.log.error("%s:%d: Regular expression for rule '%s' matches empty string", file,line,f.__name__) - self.error = 1 - except re.error: - _etype, e, _etrace = sys.exc_info() - self.log.error("%s:%d: Invalid regular expression for rule '%s'. %s", file,line,f.__name__,e) - if '#' in f.__doc__: - self.log.error("%s:%d. Make sure '#' in rule '%s' is escaped with '\\#'",file,line, f.__name__) - self.error = 1 - - # 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 = 1 - continue - - if not tokname in self.tokens and tokname.find("ignore_") < 0: - self.log.error("Rule '%s' defined for an unspecified token %s",name,tokname) - self.error = 1 - continue - - try: - c = re.compile("(?P<%s>%s)" % (name,r),re.VERBOSE | self.reflags) - if (c.match("")): - self.log.error("Regular expression for rule '%s' matches empty string",name) - self.error = 1 - except re.error: - _etype, e, _etrace = sys.exc_info() - 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 = 1 - - if not self.funcsym[state] and not self.strsym[state]: - self.log.error("No rules defined for state '%s'",state) - self.error = 1 - - # Validate the error function - efunc = self.errorf.get(state,None) - if efunc: - f = efunc - line = func_code(f).co_firstlineno - file = func_code(f).co_filename - self.files[file] = 1 - - if isinstance(f, types.MethodType): - reqargs = 2 - else: - reqargs = 1 - nargs = func_code(f).co_argcount - if nargs > reqargs: - self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,f.__name__) - self.error = 1 - - if nargs < reqargs: - self.log.error("%s:%d: Rule '%s' requires an argument", file,line,f.__name__) - self.error = 1 - - for f in self.files: - self.validate_file(f) - - - # ----------------------------------------------------------------------------- - # validate_file() - # - # 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 given file. - # ----------------------------------------------------------------------------- - - def validate_file(self,filename): - import os.path - base,ext = os.path.splitext(filename) - if ext != '.py': return # No idea what the file is. Return OK - - try: - f = open(filename) - lines = f.readlines() - f.close() - except IOError: - return # Couldn't find the file. Don't worry about it - - 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 l in lines: - m = fre.match(l) - if not m: - m = sre.match(l) - if m: - name = m.group(1) - prev = counthash.get(name) - if not prev: - counthash[name] = linen - else: - self.log.error("%s:%d: Rule %s redefined. Previously defined on line %d",filename,linen,name,prev) - self.error = 1 - linen += 1 - -# ----------------------------------------------------------------------------- -# lex(module) -# -# Build all of the regular expression rules from definitions in the supplied module -# ----------------------------------------------------------------------------- -def lex(module=None,object=None,debug=0,optimize=0,lextab="lextab",reflags=0,nowarn=0,outputdir="", debuglog=None, errorlog=None): - 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 - - if module: - _items = [(k,getattr(module,k)) for k in dir(module)] - ldict = dict(_items) - else: - ldict = get_caller_module_dict(2) - - # 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 = { } - for n in linfo.tokens: - lexobj.lextokens[n] = 1 - - # Get literals specification - if isinstance(linfo.literals,(list,tuple)): - lexobj.lexliterals = type(linfo.literals[0])().join(linfo.literals) - else: - lexobj.lexliterals = linfo.literals - - # 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 = func_code(f).co_firstlineno - file = func_code(f).co_filename - regex_list.append("(?P<%s>%s)" % (fname,f.__doc__)) - if debug: - debuglog.info("lex: Adding rule %s -> '%s' (state '%s')",fname,f.__doc__, 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 in range(len(re_text)): - debuglog.info("lex: state '%s' : regex[%d] = '%s'",state, i, re_text[i]) - - # 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") - - # Check state information for ignore and error rules - for s,stype in stateinfo.items(): - if stype == 'exclusive': - if not s in linfo.errorf: - errorlog.warning("No error rule is defined for exclusive state '%s'", s) - if not s in linfo.ignore and lexobj.lexignore: - errorlog.warning("No ignore rule is defined for exclusive state '%s'", s) - elif stype == 'inclusive': - if not s in linfo.errorf: - linfo.errorf[s] = linfo.errorf.get("INITIAL",None) - if not s 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: - lexobj.writetab(lextab,outputdir) - - 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 1: - 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_doc(f): - if hasattr(r,"__call__"): - f.__doc__ = r.__doc__ - else: - f.__doc__ = r - return f - return set_doc - -# Alternative spelling of the TOKEN decorator -Token = TOKEN - diff --git a/plugins/pycparser/pycparser/ply/yacc.py b/plugins/pycparser/pycparser/ply/yacc.py deleted file mode 100644 index 818de6d..0000000 --- a/plugins/pycparser/pycparser/ply/yacc.py +++ /dev/null @@ -1,3165 +0,0 @@ -# ----------------------------------------------------------------------------- -# ply: yacc.py -# -# Copyright (C) 2001-2009, -# 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! -# ---------------------------------------------------------------------------- - -__version__ = "3.3" -__tabversion__ = "3.2" # Table version - -#----------------------------------------------------------------------------- -# === User configurable parameters === -# -# Change these to modify the default behavior of yacc (if you wish) -#----------------------------------------------------------------------------- - -yaccdebug = 1 # 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 = 0 # 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 - -import re, types, sys, os.path - -# Compatibility function for python 2.6/3.0 -if sys.version_info[0] < 3: - def func_code(f): - return f.func_code -else: - def func_code(f): - return f.__code__ - -# Compatibility -try: - MAXINT = sys.maxint -except AttributeError: - MAXINT = sys.maxsize - -# Python 2.x/3.0 compatibility. -def load_ply_lex(): - if sys.version_info[0] < 3: - import lex - else: - import ply.lex as lex - return lex - -# 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)) - -#----------------------------------------------------------------------------- -# === 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 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 - - def errok(self): - self.errorok = 1 - - def restart(self): - del self.statestack[:] - del self.symstack[:] - sym = YaccSymbol() - sym.type = '$end' - self.symstack.append(sym) - self.statestack.append(0) - - def parse(self,input=None,lexer=None,debug=0,tracking=0,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. For the non-debugging version, - # copy this code to a method parseopt() and delete all of the sections - # enclosed in: - # - # #--! DEBUG - # statements - # #--! DEBUG - # - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - def parsedebug(self,input=None,lexer=None,debug=None,tracking=0,tokenfunc=None): - 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.) - 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: - lex = load_ply_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 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 1: - # 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 not lookahead: - if not lookaheadstack: - lookahead = get_token() # Get the next token - else: - lookahead = lookaheadstack.pop() - if not lookahead: - lookahead = YaccSymbol() - lookahead.type = "$end" - - # --! DEBUG - debug.debug('Stack : %s', - ("%s . %s" % (" ".join([xx.type for xx in symstack][1:]), str(lookahead))).lstrip()) - # --! DEBUG - - # Check the action table - ltype = lookahead.type - t = actions[state].get(ltype) - - 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:]])+"]",-t) - else: - debug.info("Action : Reduce rule [%s] with %s and goto state %d", p.str, [],-t) - - # --! 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:] - del statestack[-plen:] - 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) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - 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 - 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) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - 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 == 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 = 0 - errtoken = lookahead - if errtoken.type == "$end": - errtoken = None # End of file! - if self.errorfunc: - global errok,token,restart - errok = self.errok # Set some special functions available in error recovery - token = get_token - restart = self.restart - if errtoken and not hasattr(errtoken,'lexer'): - errtoken.lexer = lexer - tok = self.errorfunc(errtoken) - del errok, token, restart # Delete special functions - - 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 - t = YaccSymbol() - t.type = 'error' - if hasattr(lookahead,"lineno"): - t.lineno = lookahead.lineno - t.value = lookahead - lookaheadstack.append(lookahead) - lookahead = t - else: - symstack.pop() - statestack.pop() - state = statestack[-1] # Potential bug fix - - continue - - # Call an error function here - raise RuntimeError("yacc: internal parser error!!!\n") - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # parseopt(). - # - # Optimized version of parse() method. DO NOT EDIT THIS CODE DIRECTLY. - # Edit the debug version above, then copy any modifications to the method - # below while removing #--! DEBUG sections. - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - - def parseopt(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None): - 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.) - 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: - lex = load_ply_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 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 1: - # 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 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) - - 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:] - del statestack[-plen:] - 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) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - 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 - 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) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - if t == 0: - n = symstack[-1] - return getattr(n,"value",None) - - if t == 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 = 0 - errtoken = lookahead - if errtoken.type == '$end': - errtoken = None # End of file! - if self.errorfunc: - global errok,token,restart - errok = self.errok # Set some special functions available in error recovery - token = get_token - restart = self.restart - if errtoken and not hasattr(errtoken,'lexer'): - errtoken.lexer = lexer - tok = self.errorfunc(errtoken) - del errok, token, restart # Delete special functions - - 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 - t = YaccSymbol() - t.type = 'error' - if hasattr(lookahead,"lineno"): - t.lineno = lookahead.lineno - t.value = lookahead - lookaheadstack.append(lookahead) - lookahead = t - else: - symstack.pop() - statestack.pop() - state = statestack[-1] # Potential bug fix - - continue - - # Call an error function here - raise RuntimeError("yacc: internal parser error!!!\n") - - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - # parseopt_notrack(). - # - # Optimized version of parseopt() with line number tracking removed. - # DO NOT EDIT THIS CODE DIRECTLY. Copy the optimized version and remove - # code in the #--! TRACKING sections - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - def parseopt_notrack(self,input=None,lexer=None,debug=0,tracking=0,tokenfunc=None): - 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.) - 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: - lex = load_ply_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 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 1: - # 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 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) - - 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:] - del statestack[-plen:] - 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) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - 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 - 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) - symstack.pop() - statestack.pop() - state = statestack[-1] - sym.type = 'error' - lookahead = sym - errorcount = error_count - self.errorok = 0 - continue - # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - - if t == 0: - n = symstack[-1] - return getattr(n,"value",None) - - if t == 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 = 0 - errtoken = lookahead - if errtoken.type == '$end': - errtoken = None # End of file! - if self.errorfunc: - global errok,token,restart - errok = self.errok # Set some special functions available in error recovery - token = get_token - restart = self.restart - if errtoken and not hasattr(errtoken,'lexer'): - errtoken.lexer = lexer - tok = self.errorfunc(errtoken) - del errok, token, restart # Delete special functions - - 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 - t = YaccSymbol() - t.type = 'error' - if hasattr(lookahead,"lineno"): - t.lineno = lookahead.lineno - t.value = lookahead - lookaheadstack.append(lookahead) - lookahead = t - else: - symstack.pop() - statestack.pop() - state = statestack[-1] # Potential bug fix - - continue - - # Call an error function here - raise RuntimeError("yacc: internal parser error!!!\n") - -# ----------------------------------------------------------------------------- -# === Grammar Representation === -# -# The following functions, classes, and variables are used to represent and -# manipulate the rules that make up a grammar. -# ----------------------------------------------------------------------------- - -import re - -# 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 -> " % 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. Hack. Remove later - 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 -> " % 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 = { } # 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 '%s'" % 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 '%s'. Already defined as a token" % (file,line,prodname)) - if prodname == 'error': - raise GrammarError("%s:%d: Illegal rule name '%s'. error is a reserved word" % (file,line,prodname)) - if not _is_identifier.match(prodname): - raise GrammarError("%s:%d: Illegal rule name '%s'" % (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 '%s' may only be a single character" % (file,line,s, prodname)) - if not c 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 '%s' in rule '%s'" % (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,None) - if not prodprec: - raise GrammarError("%s:%d: Nothing known about the precedence of '%s'" % (file,line,precname)) - else: - self.UsedPrecedence[precname] = 1 - 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 not prodname 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 not t 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 ] - return 0 - - # ----------------------------------------------------------------------------- - # 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 reachable[s]: - # We've already reached symbol s. - return - reachable[s] = 1 - for p in self.Prodnames.get(s,[]): - for r in p.prod: - mark_reachable_from(r) - - reachable = { } - for s in list(self.Terminals) + list(self.Nonterminals): - reachable[s] = 0 - - mark_reachable_from( self.Productions[0].prod[0] ) - - return [s for s in list(self.Nonterminals) - if not reachable[s]] - - # ----------------------------------------------------------------------------- - # 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] = 1 - - terminates['$end'] = 1 - - # Nonterminals: - - # Initialize to false: - for n in self.Nonterminals: - terminates[n] = 0 - - # Then propagate termination until no change: - while 1: - some_change = 0 - 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 = 0 - break - else: - # didn't break from the loop, - # so every symbol s terminates - # so production p terminates. - p_terminates = 1 - - if p_terminates: - # symbol n terminates! - if not terminates[n]: - terminates[n] = 1 - some_change = 1 - # 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 not s in self.Prodnames and not s 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 not s in self.Prodnames and not s 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 = 0 - - # Add all the non- symbols of First[x] to the result. - for f in self.First[x]: - if f == '': - x_produces_empty = 1 - 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('') - - 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 1: - some_change = 0 - 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 = 1 - 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 1: - didadd = 0 - for p in self.Productions[1:]: - # Here is the production set - for i in range(len(p.prod)): - B = p.prod[i] - if B in self.Nonterminals: - # Okay. We got a non-terminal in a production - fst = self._first(p.prod[i+1:]) - hasempty = 0 - for f in fst: - if f != '' and f not in self.Follow[B]: - self.Follow[B].append(f) - didadd = 1 - if f == '': - hasempty = 1 - 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 = 1 - 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 1: - 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: - if sys.version_info[0] < 3: - exec("import %s as parsetab" % module) - else: - env = { } - exec("import %s as parsetab" % module, env, env) - parsetab = env['parsetab'] - - 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 - - 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 = 1 - while didadd: - didadd = 0 - 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 = 1 - - 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),None) - 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,None) - 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),None) - if not s1: - s1 = { } - s[id(n)] = s1 - gs.append(n) - s = s1 - g = s.get('$end',None) - 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: continue - if 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 = {} - num_nullable = 0 - while 1: - for p in self.grammar.Productions[1:]: - if p.len == 0: - nullable[p.name] = 1 - continue - for t in p.prod: - if not t in nullable: break - else: - nullable[p.name] = 1 - 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 state in range(len(C)): - for p in C[state]: - if p.lr_index < p.len - 1: - t = (state,p.prod[p.lr_index+1]) - if t[1] in self.grammar.Nonterminals: - if t not in trans: trans.append(t) - state = state + 1 - 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 not p.prod[li] 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 not i 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 not state 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, str(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,None) - 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. - sprec,slevel = Productions[st_actionp[a].number].prec - rprec,rlevel = Precedence.get(a,('right',0)) - 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,None) - 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 - rprec,rlevel = Productions[st_actionp[a].number].prec - sprec,slevel = Precedence.get(a,('right',0)) - 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,modulename,outputdir='',signature=""): - return - - - # ----------------------------------------------------------------------------- - # 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 - outf = open(filename,"wb") - 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,p.file,p.line)) - else: - outp.append((str(p),p.name,p.len,None,None,None)) - pickle.dump(outp,outf,pickle_protocol) - outf.close() - -# ----------------------------------------------------------------------------- -# === 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): - try: - raise RuntimeError - except RuntimeError: - e,b,t = sys.exc_info() - f = t.tb_frame - while levels > 0: - f = f.f_back - levels -= 1 - 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 '%s'" % (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.files = {} - self.grammar = [] - self.error = 0 - - 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_files() - return self.error - - # Compute a signature over the grammar - def signature(self): - try: - from hashlib import md5 - except ImportError: - from md5 import md5 - try: - sig = md5() - if self.start: - sig.update(self.start.encode('latin-1')) - if self.prec: - sig.update("".join(["".join(p) for p in self.prec]).encode('latin-1')) - if self.tokens: - sig.update(" ".join(self.tokens).encode('latin-1')) - for f in self.pfuncs: - if f[3]: - sig.update(f[3].encode('latin-1')) - except (TypeError,ValueError): - pass - return sig.digest() - - # ----------------------------------------------------------------------------- - # validate_file() - # - # 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_files(self): - # Match def p_funcname( - fre = re.compile(r'\s*def\s+(p_[a-zA-Z_0-9]*)\(') - - for filename in self.files.keys(): - base,ext = os.path.splitext(filename) - if ext != '.py': return 1 # No idea. Assume it's okay. - - try: - f = open(filename) - lines = f.readlines() - f.close() - except IOError: - continue - - counthash = { } - for linen,l in enumerate(lines): - linen += 1 - m = fre.match(l) - if m: - name = m.group(1) - prev = counthash.get(name) - if not prev: - counthash[name] = linen - else: - 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,str): - 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 = 1 - return - - eline = func_code(self.error_func).co_firstlineno - efile = func_code(self.error_func).co_filename - self.files[efile] = 1 - - if (func_code(self.error_func).co_argcount != 1+ismethod): - self.log.error("%s:%d: p_error() requires 1 argument",efile,eline) - self.error = 1 - - # Get the tokens map - def get_tokens(self): - tokens = self.pdict.get("tokens",None) - if not tokens: - self.log.error("No token list is defined") - self.error = 1 - return - - if not isinstance(tokens,(list, tuple)): - self.log.error("tokens must be a list or tuple") - self.error = 1 - return - - if not tokens: - self.log.error("tokens is empty") - self.error = 1 - 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 = 1 - return - - terminals = {} - for n in self.tokens: - if n in terminals: - self.log.warning("Token '%s' multiply defined", n) - terminals[n] = 1 - - # Get the precedence map (if any) - def get_precedence(self): - self.prec = self.pdict.get("precedence",None) - - # 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 = 1 - return - for level,p in enumerate(self.prec): - if not isinstance(p,(list,tuple)): - self.log.error("Bad precedence table") - self.error = 1 - return - - if len(p) < 2: - self.log.error("Malformed precedence entry %s. Must be (assoc, term, ..., term)",p) - self.error = 1 - return - assoc = p[0] - if not isinstance(assoc,str): - self.log.error("precedence associativity must be a string") - self.error = 1 - return - for term in p[1:]: - if not isinstance(term,str): - self.log.error("precedence items must be strings") - self.error = 1 - 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 name[:2] != 'p_': continue - if name == 'p_error': continue - if isinstance(item,(types.FunctionType,types.MethodType)): - line = func_code(item).co_firstlineno - file = func_code(item).co_filename - p_functions.append((line,file,name,item.__doc__)) - - # Sort all of the actions by line number - p_functions.sort() - 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 = 1 - return - - for line, file, name, doc in self.pfuncs: - func = self.pdict[name] - if isinstance(func, types.MethodType): - reqargs = 2 - else: - reqargs = 1 - if func_code(func).co_argcount > reqargs: - self.log.error("%s:%d: Rule '%s' has too many arguments",file,line,func.__name__) - self.error = 1 - elif func_code(func).co_argcount < reqargs: - self.log.error("%s:%d: Rule '%s' requires an argument",file,line,func.__name__) - self.error = 1 - elif not func.__doc__: - self.log.warning("%s:%d: No documentation string specified in function '%s' (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: - e = sys.exc_info()[1] - self.log.error(str(e)) - self.error = 1 - - # Looks like a valid grammar rule - # Mark the file in which defined. - self.files[file] = 1 - - # 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[0:2] == 'p_' and isinstance(v, (types.FunctionType, types.MethodType)): continue - if n[0:2] == 't_': continue - if n[0:2] == 'p_' and n != 'p_error': - self.log.warning("'%s' not defined as a function", n) - if ((isinstance(v,types.FunctionType) and func_code(v).co_argcount == 1) or - (isinstance(v,types.MethodType) and func_code(v).co_argcount == 2)): - try: - doc = v.__doc__.split(" ") - if doc[1] == ':': - self.log.warning("%s:%d: Possible grammar rule '%s' defined without p_ prefix", - func_code(v).co_filename, func_code(v).co_firstlineno,n) - except Exception: - pass - - self.grammar = grammar - -# ----------------------------------------------------------------------------- -# yacc(module) -# -# Build a parser -# ----------------------------------------------------------------------------- - -def yacc(method='LALR', debug=yaccdebug, module=None, tabmodule=tab_module, start=None, - check_recursion=1, optimize=0, write_tables=1, debugfile=debug_file,outputdir='', - debuglog=None, errorlog = None, picklefile=None): - - global parse # Reference to the parsing method of the last built parser - - # 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) - else: - pdict = get_caller_module_dict(2) - - # 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: - e = sys.exc_info()[1] - errorlog.warning("There was a problem loading the table file: %s", repr(e)) - except VersionError: - e = sys.exc_info() - errorlog.warning(str(e)) - except Exception: - pass - - if debuglog is None: - if debug: - debuglog = PlyLogger(open(debugfile,"w")) - else: - debuglog = NullLogger() - - debuglog.info("Created by PLY version %s (http://www.dabeaz.com/ply)", __version__) - - - errors = 0 - - # 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: - e = sys.exc_info()[1] - errorlog.warning("%s",str(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: - e = sys.exc_info()[1] - errorlog.error("%s",str(e)) - errors = 1 - - # Set the grammar start symbols - try: - if start is None: - grammar.set_start(pinfo.start) - else: - grammar.set_start(start) - except GrammarError: - e = sys.exc_info()[1] - errorlog.error(str(e)) - errors = 1 - - 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 '%s' used, but not defined as a token or a rule",prod.file,prod.line,sym) - errors = 1 - - unused_terminals = grammar.unused_terminals() - if unused_terminals: - debuglog.info("") - debuglog.info("Unused terminals:") - debuglog.info("") - for term in unused_terminals: - errorlog.warning("Token '%s' 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 '%s' 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 '%s' is unreachable",u) - - infinite = grammar.infinite_cycles() - for inf in infinite: - errorlog.error("Infinite recursion detected for symbol '%s'", inf) - errors = 1 - - unused_prec = grammar.unused_precedence() - for term, assoc in unused_prec: - errorlog.error("Precedence rule '%s' defined for unknown symbol '%s'", assoc, term) - errors = 1 - - 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 = {} - 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[state,id(rule),id(rejected)] = 1 - - 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: - lr.write_table(tabmodule,outputdir,signature) - - # Write a pickled version of the tables - if picklefile: - lr.pickle_table(picklefile,signature) - - # Build the parser - lr.bind_callables(pinfo.pdict) - parser = LRParser(lr,pinfo.error_func) - - parse = parser.parse - return parser diff --git a/plugins/pycparser/pycparser/plyparser.py b/plugins/pycparser/pycparser/plyparser.py deleted file mode 100644 index e396e71..0000000 --- a/plugins/pycparser/pycparser/plyparser.py +++ /dev/null @@ -1,67 +0,0 @@ -#----------------------------------------------------------------- -# plyparser.py -# -# PLYParser class and other utilites for simplifying programming -# parsers with PLY -# -# Copyright (C) 2008-2009, Eli Bendersky -# License: LGPL -#----------------------------------------------------------------- - - -class Coord(object): - """ Coordinates of a syntactic element. Consists of: - - File name - - Line number - - (optional) column number, for the Lexer - """ - 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 - _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 _parse_error(self, msg, coord): - raise ParseError("%s: %s" % (coord, msg)) - - -if __name__ == '__main__': - pp = PLYParser() - pp._create_opt_rule('java') - - ar = [4, 6] - pp.p_java_opt(ar) - - print ar - print pp.p_java_opt.__doc__ - - print dir(pp) diff --git a/plugins/pycparser/yacctab.py b/plugins/pycparser/yacctab.py deleted file mode 100644 index 7296f23..0000000 --- a/plugins/pycparser/yacctab.py +++ /dev/null @@ -1,250 +0,0 @@ - -# yacctab.py -# This file is automatically generated. Do not edit. -_tabversion = '3.2' - -_lr_method = 'LALR' - -_lr_signature = "\n\x9d\xda\xf6\xeb\xf5\x97'\n\xff\xf7b(G7V" - -_lr_action_items = {'VOID':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[6,6,-51,-61,-60,-49,-46,-47,-27,-23,6,-45,-57,-53,-58,-44,6,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,6,-56,-54,-59,-62,6,-70,6,-69,-95,-24,6,-85,-84,6,-38,-39,6,-97,6,6,6,-76,6,6,6,6,-29,-40,6,-77,-71,6,6,-98,-100,-99,6,6,-86,-30,6,-73,-78,-72,6,6,-88,-87,-127,-128,-129,]),'LBRACKET':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,25,28,31,33,34,36,37,38,39,40,42,43,44,46,48,49,50,54,56,57,58,59,60,67,73,76,78,83,84,85,86,87,90,95,97,101,102,106,107,111,116,125,126,136,137,138,139,140,149,153,160,183,184,185,186,191,192,197,229,231,236,238,239,242,258,259,260,288,292,295,320,321,327,328,329,347,348,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,52,-221,-96,-50,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,52,-85,-84,-22,-101,-103,-21,-41,-97,-221,-221,-219,-210,-220,-218,-208,151,-217,-199,-214,-209,-216,-215,-207,189,-104,-102,-71,-17,-68,-18,-67,-205,-206,189,-98,-100,-99,189,286,189,-86,-214,-73,-72,-204,-203,-202,189,189,-211,286,-88,-87,-200,-201,-126,-122,-124,-123,-125,]),'WCHAR_CONST':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[85,-38,-39,-198,85,-196,-195,85,85,-194,85,85,-193,-197,85,85,-40,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,85,-32,-35,-31,85,85,-33,85,85,-130,-36,85,-34,85,-155,-158,-156,-152,-153,-157,-159,85,-161,-162,-154,-160,85,85,85,-127,-146,85,-128,-145,85,-143,-131,85,85,85,-142,85,85,85,85,85,-141,-129,-144,-134,85,-132,85,85,-133,85,85,85,-138,-137,-135,85,-139,85,-136,85,-140,]),'FLOAT_CONST':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[86,-38,-39,-198,86,-196,-195,86,86,-194,86,86,-193,-197,86,86,-40,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,86,-32,-35,-31,86,86,-33,86,86,-130,-36,86,-34,86,-155,-158,-156,-152,-153,-157,-159,86,-161,-162,-154,-160,86,86,86,-127,-146,86,-128,-145,86,-143,-131,86,86,86,-142,86,86,86,86,86,-141,-129,-144,-134,86,-132,86,86,-133,86,86,86,-138,-137,-135,86,-139,86,-136,86,-140,]),'MINUS':([52,66,70,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,128,131,133,143,146,147,149,151,152,153,154,155,156,157,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[89,-38,-39,-198,-185,-219,-210,-220,-218,-208,89,-196,-187,-195,89,89,-217,-194,-199,89,-166,89,-214,-209,-193,167,-216,-215,-197,-207,89,89,-40,89,89,-191,-205,89,89,-206,-190,89,-188,-185,-189,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,89,-32,-35,-31,89,89,-33,89,89,-130,-36,89,-34,-214,89,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,89,-161,-162,-154,-160,89,-211,89,167,167,167,-171,167,167,167,-170,167,167,-168,-167,167,167,167,167,167,-169,89,-127,-146,89,-128,-145,89,-143,-131,89,89,89,-142,89,89,-192,-200,-201,89,-186,89,89,-141,-129,-144,-134,89,-132,89,89,-133,89,89,89,-138,-137,-135,89,-139,89,-136,89,-140,]),'RPAREN':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,25,28,31,33,34,36,37,38,39,40,42,43,44,45,46,48,49,50,53,54,56,57,58,59,60,67,73,76,78,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,112,113,114,115,116,117,118,119,125,126,136,137,138,139,140,147,149,152,153,154,156,157,158,159,160,161,162,163,183,184,185,186,187,188,190,191,192,193,197,218,231,236,237,238,239,241,242,243,257,258,259,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,281,282,283,284,287,288,289,290,291,292,295,302,319,320,321,323,324,325,327,328,329,331,339,341,344,345,346,347,348,360,362,365,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,-94,-221,-96,-50,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,73,-70,-69,-42,-95,-221,-85,-84,-22,-101,-103,-21,-41,-97,-221,-221,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-207,184,-11,185,-107,-221,-12,-105,-111,-104,-102,-71,-17,-68,-18,-67,-191,-205,242,-206,-190,-188,-185,256,-147,-221,-150,260,-189,-98,-100,-99,-221,-110,-2,-109,-121,-119,-1,-86,-10,-73,-72,319,-204,-203,-212,-202,321,-118,-221,-119,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-15,-16,327,328,-221,-120,-112,-106,-108,-88,-87,-9,-192,-200,-201,-151,-186,-148,-126,-122,-124,348,352,354,356,-213,-165,-123,-125,363,-221,367,]),'LONG':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[16,16,-51,-61,-60,-49,-46,-47,-27,-23,16,-45,-57,-53,-58,-44,16,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,16,-56,-54,-59,-62,16,-70,16,-69,-95,-24,16,-85,-84,16,-38,-39,16,-97,16,16,16,-76,16,16,16,16,-29,-40,16,-77,-71,16,16,-98,-100,-99,16,16,-86,-30,16,-73,-78,-72,16,16,-88,-87,-127,-128,-129,]),'PLUS':([52,66,70,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,128,131,133,143,146,147,149,151,152,153,154,155,156,157,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[91,-38,-39,-198,-185,-219,-210,-220,-218,-208,91,-196,-187,-195,91,91,-217,-194,-199,91,-166,91,-214,-209,-193,171,-216,-215,-197,-207,91,91,-40,91,91,-191,-205,91,91,-206,-190,91,-188,-185,-189,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,-32,-35,-31,91,91,-33,91,91,-130,-36,91,-34,-214,91,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,91,-161,-162,-154,-160,91,-211,91,171,171,171,-171,171,171,171,-170,171,171,-168,-167,171,171,171,171,171,-169,91,-127,-146,91,-128,-145,91,-143,-131,91,91,91,-142,91,91,-192,-200,-201,91,-186,91,91,-141,-129,-144,-134,91,-132,91,91,-133,91,91,91,-138,-137,-135,91,-139,91,-136,91,-140,]),'ELLIPSIS':([195,],[290,]),'GT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,172,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,172,-173,-171,-175,172,-174,-170,-177,172,-168,-167,-176,172,172,172,172,-169,-192,-200,-201,-186,]),'RBRACE':([66,70,75,77,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,121,122,123,131,133,134,135,145,147,149,153,154,156,157,161,163,196,198,200,203,206,207,209,211,212,214,217,223,224,226,228,235,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,293,294,296,297,299,300,301,303,304,307,308,313,319,320,321,323,324,332,333,334,335,336,338,343,346,349,350,353,358,359,361,363,366,368,],[-38,-39,136,-76,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-89,197,-92,-221,-40,231,-77,236,-191,-205,-206,-190,-188,-185,-150,-189,292,-90,295,-113,-32,-35,299,-31,303,-33,-20,-130,-36,-19,-34,-78,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-91,-93,-116,333,-127,-146,335,-128,-145,-143,-131,-142,-192,-200,-201,-151,-186,350,-114,-141,-129,-144,-134,-132,-165,-117,-115,-133,-138,-137,-135,-139,-136,-140,]),'ENUM':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[24,24,-51,-61,-60,-49,-46,-47,-27,-23,24,-45,-57,-53,-58,-44,24,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,24,-56,-54,-59,-62,24,-70,24,-69,-95,-24,24,-85,-84,24,-38,-39,24,-97,24,24,24,-76,24,24,24,24,-29,-40,24,-77,-71,24,24,-98,-100,-99,24,24,-86,-30,24,-73,-78,-72,24,24,-88,-87,-127,-128,-129,]),'PERIOD':([83,84,85,86,87,90,95,97,101,102,106,107,111,149,153,229,238,239,242,260,320,321,],[-219,-210,-220,-218,-208,150,-217,-199,-214,-209,-216,-215,-207,-205,-206,-214,-204,-203,-202,-211,-200,-201,]),'GE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,176,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,176,-173,-171,-175,176,-174,-170,-177,176,-168,-167,-176,176,176,176,176,-169,-192,-200,-201,-186,]),'INT_CONST_DEC':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[107,-38,-39,-198,107,-196,-195,107,107,-194,107,107,-193,-197,107,107,-40,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,107,-32,-35,-31,107,107,-33,107,107,-130,-36,107,-34,107,-155,-158,-156,-152,-153,-157,-159,107,-161,-162,-154,-160,107,107,107,-127,-146,107,-128,-145,107,-143,-131,107,107,107,-142,107,107,107,107,107,-141,-129,-144,-134,107,-132,107,107,-133,107,107,107,-138,-137,-135,107,-139,107,-136,107,-140,]),'ARROW':([83,84,85,86,87,90,95,97,101,102,106,107,111,149,153,229,238,239,242,260,320,321,],[-219,-210,-220,-218,-208,148,-217,-199,-214,-209,-216,-215,-207,-205,-206,-214,-204,-203,-202,-211,-200,-201,]),'DOUBLE':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[34,34,-51,-61,-60,-49,-46,-47,-27,-23,34,-45,-57,-53,-58,-44,34,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,34,-56,-54,-59,-62,34,-70,34,-69,-95,-24,34,-85,-84,34,-38,-39,34,-97,34,34,34,-76,34,34,34,34,-29,-40,34,-77,-71,34,34,-98,-100,-99,34,34,-86,-30,34,-73,-78,-72,34,34,-88,-87,-127,-128,-129,]),'MINUSEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,245,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'INT_CONST_OCT':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[106,-38,-39,-198,106,-196,-195,106,106,-194,106,106,-193,-197,106,106,-40,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,-32,-35,-31,106,106,-33,106,106,-130,-36,106,-34,106,-155,-158,-156,-152,-153,-157,-159,106,-161,-162,-154,-160,106,106,106,-127,-146,106,-128,-145,106,-143,-131,106,106,106,-142,106,106,106,106,106,-141,-129,-144,-134,106,-132,106,106,-133,106,106,106,-138,-137,-135,106,-139,106,-136,106,-140,]),'TIMESEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,254,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'OR':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,181,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,181,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,181,-178,-180,-181,-169,-192,-200,-201,-186,]),'SHORT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[2,2,-51,-61,-60,-49,-46,-47,-27,-23,2,-45,-57,-53,-58,-44,2,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,2,-56,-54,-59,-62,2,-70,2,-69,-95,-24,2,-85,-84,2,-38,-39,2,-97,2,2,2,-76,2,2,2,2,-29,-40,2,-77,-71,2,2,-98,-100,-99,2,2,-86,-30,2,-73,-78,-72,2,2,-88,-87,-127,-128,-129,]),'RETURN':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,213,-40,-32,-35,-31,213,-33,213,-130,-36,213,-34,-127,-146,213,-128,-145,-143,-131,213,-142,213,-141,-129,-144,-134,213,-132,213,-133,213,213,-138,-137,-135,-139,213,-136,213,-140,]),'RSHIFTEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,255,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'STATIC':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[8,8,-51,-61,-60,-49,-46,-47,-27,-23,8,-45,-57,-53,-58,-44,8,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,8,-56,-54,-59,-62,8,-70,-69,-95,-24,8,-85,-84,8,-38,-39,8,-97,8,-29,-40,-71,-98,-100,-99,8,8,-86,-30,8,-73,-72,8,8,-88,-87,-127,-128,-129,]),'SIZEOF':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[88,-38,-39,-198,88,-196,-195,88,88,-194,88,88,-193,-197,88,88,-40,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,88,-32,-35,-31,88,88,-33,88,88,-130,-36,88,-34,88,-155,-158,-156,-152,-153,-157,-159,88,-161,-162,-154,-160,88,88,88,-127,-146,88,-128,-145,88,-143,-131,88,88,88,-142,88,88,88,88,88,-141,-129,-144,-134,88,-132,88,88,-133,88,88,88,-138,-137,-135,88,-139,88,-136,88,-140,]),'UNSIGNED':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[15,15,-51,-61,-60,-49,-46,-47,-27,-23,15,-45,-57,-53,-58,-44,15,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,15,-56,-54,-59,-62,15,-70,15,-69,-95,-24,15,-85,-84,15,-38,-39,15,-97,15,15,15,-76,15,15,15,15,-29,-40,15,-77,-71,15,15,-98,-100,-99,15,15,-86,-30,15,-73,-78,-72,15,15,-88,-87,-127,-128,-129,]),'UNION':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[18,18,-51,-61,-60,-49,-46,-47,-27,-23,18,-45,-57,-53,-58,-44,18,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,18,-56,-54,-59,-62,18,-70,18,-69,-95,-24,18,-85,-84,18,-38,-39,18,-97,18,18,18,-76,18,18,18,18,-29,-40,18,-77,-71,18,18,-98,-100,-99,18,18,-86,-30,18,-73,-78,-72,18,18,-88,-87,-127,-128,-129,]),'COLON':([2,3,5,6,15,16,17,22,23,28,31,33,34,37,38,39,40,46,48,50,54,56,73,76,78,79,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,136,137,138,139,140,142,147,149,153,154,156,157,159,161,163,183,184,185,197,219,229,231,234,236,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,292,295,311,319,320,321,323,324,325,346,],[-51,-61,-60,-49,-57,-53,-58,-149,-94,-96,-50,-52,-55,-56,-54,-59,-62,-70,-69,-95,-85,-84,-97,-221,-221,143,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-71,-17,-68,-18,-67,232,-191,-205,-206,-190,-188,-185,-147,-150,-189,-98,-100,-99,-86,309,315,-73,143,-72,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,326,-181,-169,-88,-87,340,-192,-200,-201,-151,-186,-148,-165,]),'$end':([10,11,20,27,30,32,51,66,132,205,299,303,335,],[-27,-23,0,-26,-25,-28,-24,-38,-29,-30,-127,-128,-129,]),'WSTRING_LITERAL':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[84,-38,-39,-198,84,-196,-195,84,84,-194,84,84,-193,-197,84,84,-40,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,84,-32,-35,-31,84,84,-33,84,84,-130,-36,84,-34,84,-155,-158,-156,-152,-153,-157,-159,84,-161,-162,-154,-160,84,84,84,-127,-146,84,-128,-145,84,-143,-131,84,84,84,-142,84,84,84,84,84,-141,-129,-144,-134,84,-132,84,84,-133,84,84,84,-138,-137,-135,84,-139,84,-136,84,-140,]),'DIVIDE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,174,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,174,174,174,174,174,174,174,174,174,174,-168,-167,174,174,174,174,174,-169,-192,-200,-201,-186,]),'FOR':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,215,-40,-32,-35,-31,215,-33,215,-130,-36,215,-34,-127,-146,215,-128,-145,-143,-131,215,-142,215,-141,-129,-144,-134,215,-132,215,-133,215,215,-138,-137,-135,-139,215,-136,215,-140,]),'PLUSPLUS':([52,66,70,81,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,100,101,102,103,106,107,110,111,128,131,133,143,146,149,151,152,153,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,320,321,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[94,-38,-39,-198,-219,-210,-220,-218,-208,94,-196,149,-195,94,94,-217,-194,-199,94,94,-214,-209,-193,-216,-215,-197,-207,94,94,-40,94,94,-205,94,94,-206,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,94,-32,-35,-31,94,94,-33,94,94,-130,-36,94,-34,-214,94,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,94,-161,-162,-154,-160,94,-211,94,94,-127,-146,94,-128,-145,94,-143,-131,94,94,94,-142,94,94,-200,-201,94,94,94,-141,-129,-144,-134,94,-132,94,94,-133,94,94,94,-138,-137,-135,94,-139,94,-136,94,-140,]),'EQUALS':([23,28,50,64,73,82,83,84,85,86,87,90,95,97,101,102,106,107,111,123,130,147,149,153,154,156,157,163,183,184,185,229,238,239,242,260,319,320,321,324,],[-94,-96,-95,128,-97,-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,199,128,-191,-205,-206,-190,-188,247,-189,-98,-100,-99,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'ELSE':([206,207,211,214,224,228,299,300,303,304,307,313,334,335,336,338,343,353,358,359,361,363,366,368,],[-32,-35,-31,-33,-36,-34,-127,-146,-128,-145,-143,-142,-141,-129,-144,-134,-132,-133,-138,-137,364,-139,-136,-140,]),'EQ':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,178,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,178,-173,-171,-175,-179,-174,-170,-177,178,-168,-167,-176,178,-178,178,178,-169,-192,-200,-201,-186,]),'AND':([52,66,70,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,128,131,133,143,146,147,149,151,152,153,154,155,156,157,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[103,-38,-39,-198,-185,-219,-210,-220,-218,-208,103,-196,-187,-195,103,103,-217,-194,-199,103,-166,103,-214,-209,-193,179,-216,-215,-197,-207,103,103,-40,103,103,-191,-205,103,103,-206,-190,103,-188,-185,-189,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,103,-32,-35,-31,103,103,-33,103,103,-130,-36,103,-34,-214,103,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,103,-161,-162,-154,-160,103,-211,103,-172,179,-173,-171,-175,-179,-174,-170,-177,179,-168,-167,-176,179,-178,-180,179,-169,103,-127,-146,103,-128,-145,103,-143,-131,103,103,103,-142,103,103,-192,-200,-201,103,-186,103,103,-141,-129,-144,-134,103,-132,103,103,-133,103,103,103,-138,-137,-135,103,-139,103,-136,103,-140,]),'TYPEID':([0,1,2,3,5,6,7,8,9,10,11,12,14,15,16,17,18,19,20,21,22,23,24,27,28,29,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[22,22,-51,-61,-60,-49,46,-46,-47,-27,-23,22,-45,-57,-53,-58,-75,-44,22,-48,-149,-94,54,-26,-96,-74,-25,-50,-28,-52,-55,22,-56,-54,-59,-62,22,-70,22,-69,-95,-24,22,-85,-84,22,-38,-39,22,-97,22,22,22,-76,22,22,22,22,-29,-40,22,-77,-71,22,22,-98,-100,-99,22,22,-86,-30,22,-73,-78,-72,22,22,-88,-87,-127,-128,-129,]),'LBRACE':([7,18,23,24,28,29,41,46,48,50,54,56,64,66,68,70,71,72,73,128,129,131,133,183,184,185,204,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,332,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[47,-75,-94,55,-96,-74,-221,74,80,-95,120,124,-221,-38,-5,-39,131,-6,-97,204,131,131,-40,-98,-100,-99,204,-32,-35,-31,131,-33,131,-130,-36,131,-34,-127,-146,131,-128,-145,-143,-131,131,-142,131,204,-141,-129,-144,-134,131,-132,131,-133,131,131,-138,-137,-135,-139,131,-136,131,-140,]),'PPHASH':([0,10,11,20,27,30,32,51,66,132,205,299,303,335,],[32,-27,-23,32,-26,-25,-28,-24,-38,-29,-30,-127,-128,-129,]),'INT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[33,33,-51,-61,-60,-49,-46,-47,-27,-23,33,-45,-57,-53,-58,-44,33,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,33,-56,-54,-59,-62,33,-70,33,-69,-95,-24,33,-85,-84,33,-38,-39,33,-97,33,33,33,-76,33,33,33,33,-29,-40,33,-77,-71,33,33,-98,-100,-99,33,33,-86,-30,33,-73,-78,-72,33,33,-88,-87,-127,-128,-129,]),'SIGNED':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[37,37,-51,-61,-60,-49,-46,-47,-27,-23,37,-45,-57,-53,-58,-44,37,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,37,-56,-54,-59,-62,37,-70,37,-69,-95,-24,37,-85,-84,37,-38,-39,37,-97,37,37,37,-76,37,37,37,37,-29,-40,37,-77,-71,37,37,-98,-100,-99,37,37,-86,-30,37,-73,-78,-72,37,37,-88,-87,-127,-128,-129,]),'CONTINUE':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,216,-40,-32,-35,-31,216,-33,216,-130,-36,216,-34,-127,-146,216,-128,-145,-143,-131,216,-142,216,-141,-129,-144,-134,216,-132,216,-133,216,216,-138,-137,-135,-139,216,-136,216,-140,]),'NOT':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[110,-38,-39,-198,110,-196,-195,110,110,-194,110,110,-193,-197,110,110,-40,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,110,-32,-35,-31,110,110,-33,110,110,-130,-36,110,-34,110,-155,-158,-156,-152,-153,-157,-159,110,-161,-162,-154,-160,110,110,110,-127,-146,110,-128,-145,110,-143,-131,110,110,110,-142,110,110,110,110,110,-141,-129,-144,-134,110,-132,110,110,-133,110,110,110,-138,-137,-135,110,-139,110,-136,110,-140,]),'OREQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,253,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'MOD':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,182,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,182,182,182,182,182,182,182,182,182,182,-168,-167,182,182,182,182,182,-169,-192,-200,-201,-186,]),'RSHIFT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,164,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,164,-173,-171,164,164,164,-170,164,164,-168,-167,164,164,164,164,164,-169,-192,-200,-201,-186,]),'DEFAULT':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,219,-40,-32,-35,-31,219,-33,219,-130,-36,219,-34,-127,-146,219,-128,-145,-143,-131,219,-142,219,-141,-129,-144,-134,219,-132,219,-133,219,219,-138,-137,-135,-139,219,-136,219,-140,]),'CHAR':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[31,31,-51,-61,-60,-49,-46,-47,-27,-23,31,-45,-57,-53,-58,-44,31,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,31,-56,-54,-59,-62,31,-70,31,-69,-95,-24,31,-85,-84,31,-38,-39,31,-97,31,31,31,-76,31,31,31,31,-29,-40,31,-77,-71,31,31,-98,-100,-99,31,31,-86,-30,31,-73,-78,-72,31,31,-88,-87,-127,-128,-129,]),'WHILE':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,314,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,220,-40,-32,-35,-31,220,-33,220,-130,-36,220,-34,-127,-146,220,-128,-145,-143,-131,220,-142,342,220,-141,-129,-144,-134,220,-132,220,-133,220,220,-138,-137,-135,-139,220,-136,220,-140,]),'DIVEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,244,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'EXTERN':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[9,9,-51,-61,-60,-49,-46,-47,-27,-23,9,-45,-57,-53,-58,-44,9,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,9,-56,-54,-59,-62,9,-70,-69,-95,-24,9,-85,-84,9,-38,-39,9,-97,9,-29,-40,-71,-98,-100,-99,9,9,-86,-30,9,-73,-72,9,9,-88,-87,-127,-128,-129,]),'CASE':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,221,-40,-32,-35,-31,221,-33,221,-130,-36,221,-34,-127,-146,221,-128,-145,-143,-131,221,-142,221,-141,-129,-144,-134,221,-132,221,-133,221,221,-138,-137,-135,-139,221,-136,221,-140,]),'LAND':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,177,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,177,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-192,-200,-201,-186,]),'REGISTER':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[14,14,-51,-61,-60,-49,-46,-47,-27,-23,14,-45,-57,-53,-58,-44,14,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,14,-56,-54,-59,-62,14,-70,-69,-95,-24,14,-85,-84,14,-38,-39,14,-97,14,-29,-40,-71,-98,-100,-99,14,14,-86,-30,14,-73,-72,14,14,-88,-87,-127,-128,-129,]),'MODEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,246,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'NE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,169,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,169,-173,-171,-175,-179,-174,-170,-177,169,-168,-167,-176,169,-178,169,169,-169,-192,-200,-201,-186,]),'SWITCH':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,222,-40,-32,-35,-31,222,-33,222,-130,-36,222,-34,-127,-146,222,-128,-145,-143,-131,222,-142,222,-141,-129,-144,-134,222,-132,222,-133,222,222,-138,-137,-135,-139,222,-136,222,-140,]),'INT_CONST_HEX':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[95,-38,-39,-198,95,-196,-195,95,95,-194,95,95,-193,-197,95,95,-40,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,95,-32,-35,-31,95,95,-33,95,95,-130,-36,95,-34,95,-155,-158,-156,-152,-153,-157,-159,95,-161,-162,-154,-160,95,95,95,-127,-146,95,-128,-145,95,-143,-131,95,95,95,-142,95,95,95,95,95,-141,-129,-144,-134,95,-132,95,95,-133,95,95,95,-138,-137,-135,95,-139,95,-136,95,-140,]),'PLUSEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,249,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'STRUCT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[29,29,-51,-61,-60,-49,-46,-47,-27,-23,29,-45,-57,-53,-58,-44,29,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,29,-56,-54,-59,-62,29,-70,29,-69,-95,-24,29,-85,-84,29,-38,-39,29,-97,29,29,29,-76,29,29,29,29,-29,-40,29,-77,-71,29,29,-98,-100,-99,29,29,-86,-30,29,-73,-78,-72,29,29,-88,-87,-127,-128,-129,]),'CONDOP':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,180,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-192,-200,-201,-186,]),'BREAK':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,225,-40,-32,-35,-31,225,-33,225,-130,-36,225,-34,-127,-146,225,-128,-145,-143,-131,225,-142,225,-141,-129,-144,-134,225,-132,225,-133,225,225,-138,-137,-135,-139,225,-136,225,-140,]),'VOLATILE':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,25,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,57,59,64,66,70,72,73,74,75,76,77,78,80,98,125,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[40,40,-51,-61,-60,-49,-46,-47,-27,-23,40,-45,-57,-53,-58,-44,40,-48,-149,-94,40,-26,-96,-25,-50,-28,-52,-55,40,-56,-54,-59,-62,40,-70,40,-69,-95,-24,40,-85,-84,40,-103,40,-38,-39,40,-97,40,40,40,-76,40,40,40,-104,40,-29,-40,40,-77,-71,40,40,-98,-100,-99,40,40,-86,-30,40,-73,-78,-72,40,40,-88,-87,-127,-128,-129,]),'ANDEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,252,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'DO':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,227,-40,-32,-35,-31,227,-33,227,-130,-36,227,-34,-127,-146,227,-128,-145,-143,-131,227,-142,227,-141,-129,-144,-134,227,-132,227,-133,227,227,-138,-137,-135,-139,227,-136,227,-140,]),'LNOT':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[81,-38,-39,-198,81,-196,-195,81,81,-194,81,81,-193,-197,81,81,-40,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,-32,-35,-31,81,81,-33,81,81,-130,-36,81,-34,81,-155,-158,-156,-152,-153,-157,-159,81,-161,-162,-154,-160,81,81,81,-127,-146,81,-128,-145,81,-143,-131,81,81,81,-142,81,81,81,81,81,-141,-129,-144,-134,81,-132,81,81,-133,81,81,81,-138,-137,-135,81,-139,81,-136,81,-140,]),'CONST':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,25,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,57,59,64,66,70,72,73,74,75,76,77,78,80,98,125,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[3,3,-51,-61,-60,-49,-46,-47,-27,-23,3,-45,-57,-53,-58,-44,3,-48,-149,-94,3,-26,-96,-25,-50,-28,-52,-55,3,-56,-54,-59,-62,3,-70,3,-69,-95,-24,3,-85,-84,3,-103,3,-38,-39,3,-97,3,3,3,-76,3,3,3,-104,3,-29,-40,3,-77,-71,3,3,-98,-100,-99,3,3,-86,-30,3,-73,-78,-72,3,3,-88,-87,-127,-128,-129,]),'LOR':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,165,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-192,-200,-201,-186,]),'CHAR_CONST':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[83,-38,-39,-198,83,-196,-195,83,83,-194,83,83,-193,-197,83,83,-40,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,83,-32,-35,-31,83,83,-33,83,83,-130,-36,83,-34,83,-155,-158,-156,-152,-153,-157,-159,83,-161,-162,-154,-160,83,83,83,-127,-146,83,-128,-145,83,-143,-131,83,83,83,-142,83,83,83,83,83,-141,-129,-144,-134,83,-132,83,83,-133,83,83,83,-138,-137,-135,83,-139,83,-136,83,-140,]),'LSHIFT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,166,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,166,-173,-171,166,166,166,-170,166,166,-168,-167,166,166,166,166,166,-169,-192,-200,-201,-186,]),'GOTO':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,208,-40,-32,-35,-31,208,-33,208,-130,-36,208,-34,-127,-146,208,-128,-145,-143,-131,208,-142,208,-141,-129,-144,-134,208,-132,208,-133,208,208,-138,-137,-135,-139,208,-136,208,-140,]),'LE':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,168,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,168,-173,-171,-175,168,-174,-170,-177,168,-168,-167,-176,168,168,168,168,-169,-192,-200,-201,-186,]),'SEMI':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,26,28,31,33,34,35,36,37,38,39,40,42,43,44,46,48,49,50,54,56,61,62,63,64,65,66,67,69,70,73,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,130,131,133,136,141,142,144,147,149,153,154,156,157,159,161,163,183,184,185,197,201,202,203,206,207,210,211,212,213,214,216,217,218,223,224,225,226,227,228,229,231,233,236,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,292,295,298,299,300,301,302,303,304,305,306,307,308,309,313,315,317,318,319,320,321,323,324,325,333,334,335,336,337,338,340,343,346,350,351,352,353,354,356,357,358,359,361,363,364,366,367,368,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,-94,-221,-96,-50,-52,-55,66,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-95,-85,-84,-14,-37,-13,-65,-63,-38,-41,-221,-39,-97,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-65,-221,-40,-71,-79,-81,235,-191,-205,-206,-190,-188,-185,-147,-150,-189,-98,-100,-99,-86,-64,-66,-113,-32,-35,300,-31,-221,304,-33,307,-221,-10,-130,-36,313,-9,-221,-34,-214,-73,-83,-72,-204,-203,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,-88,-87,334,-127,-146,-221,-9,-128,-145,336,-221,-143,-131,-221,-142,-221,-82,-80,-192,-200,-201,-151,-186,-148,-114,-141,-129,-144,351,-134,-221,-132,-165,-115,-221,-221,-133,-221,-221,362,-138,-137,-135,-139,-221,-136,-221,-140,]),'LT':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,170,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,170,-173,-171,-175,170,-174,-170,-177,170,-168,-167,-176,170,170,170,170,-169,-192,-200,-201,-186,]),'COMMA':([1,2,3,5,6,8,9,12,14,15,16,17,19,21,22,23,25,28,31,33,34,36,37,38,39,40,42,43,44,46,48,49,50,54,56,57,58,59,60,61,64,65,67,73,82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,109,111,115,116,117,118,119,121,122,123,125,126,130,136,141,142,144,147,149,153,154,156,157,159,161,162,163,183,184,185,187,188,190,191,192,193,196,197,198,200,201,202,203,218,229,231,233,236,238,239,240,241,242,243,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,278,279,280,288,289,291,292,293,294,295,296,297,305,317,318,319,320,321,323,324,325,327,328,329,333,339,341,344,345,346,347,348,349,350,360,],[-221,-51,-61,-60,-49,-46,-47,-221,-45,-57,-53,-58,-44,-48,-149,-94,-221,-96,-50,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-95,-85,-84,-22,-101,-103,-21,127,-65,-63,-41,-97,-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,-164,-216,-215,-163,-207,-107,-221,194,195,-111,-89,198,-92,-104,-102,-65,-71,-79,-81,234,-191,-205,-206,-190,-188,-185,-147,-150,261,-189,-98,-100,-99,-110,-2,-109,-121,-119,-1,198,-86,-90,198,-64,-66,-113,261,-214,-73,-83,-72,-204,-203,261,-212,-202,322,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,261,-181,-169,-120,-112,-108,-88,-91,-93,-87,-116,332,261,-82,-80,-192,-200,-201,-151,-186,-148,-126,-122,-124,-114,261,261,261,-213,-165,-123,-125,-117,-115,261,]),'TYPEDEF':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[21,21,-51,-61,-60,-49,-46,-47,-27,-23,21,-45,-57,-53,-58,-44,21,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,21,-56,-54,-59,-62,21,-70,-69,-95,-24,21,-85,-84,21,-38,-39,21,-97,21,-29,-40,-71,-98,-100,-99,21,21,-86,-30,21,-73,-72,21,21,-88,-87,-127,-128,-129,]),'XOR':([82,83,84,85,86,87,90,95,97,99,101,102,104,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-166,-214,-209,173,-216,-215,-207,-191,-205,-206,-190,-188,-185,-189,-214,-204,-203,-202,-211,-172,173,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,173,-178,-180,173,-169,-192,-200,-201,-186,]),'AUTO':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,48,50,51,53,54,56,64,66,70,72,73,131,132,133,136,183,184,185,186,195,197,205,212,231,236,258,287,292,295,299,303,335,],[19,19,-51,-61,-60,-49,-46,-47,-27,-23,19,-45,-57,-53,-58,-44,19,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,19,-56,-54,-59,-62,19,-70,-69,-95,-24,19,-85,-84,19,-38,-39,19,-97,19,-29,-40,-71,-98,-100,-99,19,19,-86,-30,19,-73,-72,19,19,-88,-87,-127,-128,-129,]),'TIMES':([0,1,2,3,4,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,25,26,27,30,31,32,33,34,36,37,38,39,40,42,43,44,46,48,49,51,52,54,56,57,58,59,60,66,67,69,70,76,78,79,81,82,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,99,100,101,102,103,104,106,107,110,111,116,125,127,128,131,132,133,136,137,138,139,140,143,146,147,149,151,152,153,154,155,156,157,160,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,186,189,197,199,204,205,206,207,211,212,213,214,217,221,223,224,227,228,229,231,232,234,236,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,258,260,261,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,286,292,295,299,300,301,303,304,306,307,308,309,310,312,313,315,316,319,320,321,322,324,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[25,-221,-51,-61,25,-60,-49,-46,-47,-27,-23,-221,-45,-57,-53,-58,-44,25,-48,-149,-221,25,-26,-25,-50,-28,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-24,96,-85,-84,-22,25,-103,-21,-38,-41,25,-39,-221,-221,25,-198,-185,-219,-210,-220,-218,-208,96,-196,-187,-195,96,96,-217,-194,-199,96,-166,96,-214,-209,-193,175,-216,-215,-197,-207,25,-104,25,96,96,-29,-40,-71,-17,-68,-18,-67,96,96,-191,-205,96,96,-206,-190,96,-188,-185,25,-189,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,96,25,96,-86,96,96,-30,-32,-35,-31,96,96,-33,96,96,-130,-36,96,-34,-214,-73,96,25,-72,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,96,-161,-162,-154,-160,96,25,-211,96,175,175,175,175,175,175,175,175,175,175,-168,-167,175,175,175,175,175,-169,96,-88,-87,-127,-146,96,-128,-145,96,-143,-131,96,96,96,-142,96,96,-192,-200,-201,96,-186,96,96,-141,-129,-144,-134,96,-132,96,96,-133,96,96,96,-138,-137,-135,96,-139,96,-136,96,-140,]),'LPAREN':([0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,19,20,21,22,23,25,26,27,28,30,31,32,33,34,36,37,38,39,40,42,43,44,46,48,49,50,51,52,54,56,57,58,59,60,66,67,69,70,73,76,78,79,81,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,100,101,102,103,106,107,110,111,116,125,126,127,128,131,132,133,136,137,138,139,140,143,146,149,151,152,153,155,160,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,189,191,192,197,199,204,205,206,207,211,212,213,214,215,217,220,221,222,223,224,227,228,229,230,231,232,234,236,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,258,259,260,261,286,288,292,295,299,300,301,303,304,306,307,308,309,310,312,313,315,316,320,321,322,326,327,328,329,332,334,335,336,338,340,342,343,347,348,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[4,-221,-51,-61,4,-60,-49,-46,-47,-27,-23,-221,4,-45,-57,-53,-58,-44,4,-48,-149,53,-221,4,-26,-96,-25,-50,-28,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,53,-24,98,-85,-84,-22,-101,-103,-21,-38,-41,4,-39,-97,-221,-221,4,-198,-219,-210,-220,-218,-208,146,-196,152,-195,98,155,-217,-194,-199,98,155,-214,-209,-193,-216,-215,-197,-207,186,-104,-102,4,98,98,-29,-40,-71,-17,-68,-18,-67,98,98,-205,98,98,-206,98,258,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,98,-98,-100,-99,186,98,287,186,-86,98,98,-30,-32,-35,-31,98,98,-33,306,98,310,98,312,-130,-36,98,-34,-214,316,-73,98,4,-72,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,98,-161,-162,-154,-160,98,258,258,-211,98,98,287,-88,-87,-127,-146,98,-128,-145,98,-143,-131,98,98,98,-142,98,98,-200,-201,98,98,-126,-122,-124,98,-141,-129,-144,-134,98,355,-132,-123,-125,98,98,-133,98,98,98,-138,-137,-135,98,-139,98,-136,98,-140,]),'MINUSMINUS':([52,66,70,81,83,84,85,86,87,88,89,90,91,92,94,95,96,97,98,100,101,102,103,106,107,110,111,128,131,133,143,146,149,151,152,153,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,229,232,238,239,242,244,245,246,247,248,249,250,251,252,253,254,255,256,260,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,320,321,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[100,-38,-39,-198,-219,-210,-220,-218,-208,100,-196,153,-195,100,100,-217,-194,-199,100,100,-214,-209,-193,-216,-215,-197,-207,100,100,-40,100,100,-205,100,100,-206,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,-32,-35,-31,100,100,-33,100,100,-130,-36,100,-34,-214,100,-204,-203,-202,-155,-158,-156,-152,-153,-157,-159,100,-161,-162,-154,-160,100,-211,100,100,-127,-146,100,-128,-145,100,-143,-131,100,100,100,-142,100,100,-200,-201,100,100,100,-141,-129,-144,-134,100,-132,100,100,-133,100,100,100,-138,-137,-135,100,-139,100,-136,100,-140,]),'ID':([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,29,30,31,32,33,34,36,37,38,39,40,42,43,44,46,48,49,51,52,53,54,55,56,57,58,59,60,66,67,69,70,76,78,79,81,88,89,91,92,94,96,98,100,103,110,116,120,124,125,126,127,128,131,132,133,136,137,138,139,140,143,146,148,150,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,186,189,192,194,197,198,199,204,205,206,207,208,211,212,213,214,217,221,223,224,227,228,231,232,234,236,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,292,295,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[28,-221,-51,-61,28,-60,-49,48,-46,-47,-27,-23,-221,28,-45,-57,-53,-58,-75,-44,28,-48,-149,56,-221,28,-26,-74,-25,-50,-28,-52,-55,-221,-56,-54,-59,-62,-43,-7,-8,-70,-69,-42,-24,101,101,-85,123,-84,-22,-101,-103,-21,-38,-41,28,-39,-221,-221,28,-198,101,-196,-195,101,101,-194,101,101,-193,-197,28,123,123,-104,-102,28,101,229,-29,-40,-71,-17,-68,-18,-67,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,101,28,101,28,101,-86,123,101,101,-30,-32,-35,298,-31,229,101,-33,229,101,-130,-36,229,-34,-73,101,28,-72,-155,-158,-156,-152,-153,-157,-159,101,-161,-162,-154,-160,101,101,101,-88,-87,-127,-146,229,-128,-145,101,-143,-131,229,101,101,-142,229,101,101,101,101,-141,-129,-144,-134,229,-132,101,229,-133,229,101,229,-138,-137,-135,101,-139,229,-136,229,-140,]),'IF':([66,70,131,133,206,207,211,212,214,217,223,224,227,228,299,300,301,303,304,307,308,309,313,315,334,335,336,338,340,343,352,353,354,356,358,359,361,363,364,366,367,368,],[-38,-39,230,-40,-32,-35,-31,230,-33,230,-130,-36,230,-34,-127,-146,230,-128,-145,-143,-131,230,-142,230,-141,-129,-144,-134,230,-132,230,-133,230,230,-138,-137,-135,-139,230,-136,230,-140,]),'STRING_LITERAL':([52,66,70,81,88,89,91,92,94,96,98,100,103,110,128,131,133,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,206,207,211,212,213,214,217,221,223,224,227,228,232,244,245,246,247,248,249,250,251,252,253,254,255,256,261,286,299,300,301,303,304,306,307,308,309,310,312,313,315,316,322,326,332,334,335,336,338,340,343,351,352,353,354,355,356,358,359,361,362,363,364,366,367,368,],[102,-38,-39,-198,102,-196,-195,102,102,-194,102,102,-193,-197,102,102,-40,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,102,-32,-35,-31,102,102,-33,102,102,-130,-36,102,-34,102,-155,-158,-156,-152,-153,-157,-159,102,-161,-162,-154,-160,102,102,102,-127,-146,102,-128,-145,102,-143,-131,102,102,102,-142,102,102,102,102,102,-141,-129,-144,-134,102,-132,102,102,-133,102,102,102,-138,-137,-135,102,-139,102,-136,102,-140,]),'FLOAT':([0,1,2,3,5,6,8,9,10,11,12,14,15,16,17,19,20,21,22,23,27,28,30,31,32,33,34,36,37,38,39,40,41,46,47,48,50,51,53,54,56,64,66,70,72,73,74,75,76,77,78,80,98,131,132,133,134,135,136,145,146,183,184,185,186,195,197,205,212,231,235,236,258,287,292,295,299,303,335,],[38,38,-51,-61,-60,-49,-46,-47,-27,-23,38,-45,-57,-53,-58,-44,38,-48,-149,-94,-26,-96,-25,-50,-28,-52,-55,38,-56,-54,-59,-62,38,-70,38,-69,-95,-24,38,-85,-84,38,-38,-39,38,-97,38,38,38,-76,38,38,38,38,-29,-40,38,-77,-71,38,38,-98,-100,-99,38,38,-86,-30,38,-73,-78,-72,38,38,-88,-87,-127,-128,-129,]),'XOREQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,248,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'LSHIFTEQUAL':([82,83,84,85,86,87,90,95,97,101,102,106,107,111,147,149,153,154,156,157,163,229,238,239,242,260,319,320,321,324,],[-185,-219,-210,-220,-218,-208,-187,-217,-199,-214,-209,-216,-215,-207,-191,-205,-206,-190,-188,250,-189,-214,-204,-203,-202,-211,-192,-200,-201,-186,]),'RBRACKET':([52,82,83,84,85,86,87,90,93,95,97,99,101,102,104,105,106,107,108,109,111,147,149,153,154,156,157,159,161,163,189,238,239,240,242,260,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,279,280,285,286,319,320,321,323,324,325,330,346,],[-221,-185,-219,-210,-220,-218,-208,-187,-3,-217,-199,-166,-214,-209,-164,183,-216,-215,-4,-163,-207,-191,-205,-206,-190,-188,-185,-147,-150,-189,-221,-204,-203,320,-202,-211,-172,-184,-173,-171,-175,-179,-174,-170,-177,-182,-168,-167,-176,-183,-178,-180,-181,-169,329,-221,-192,-200,-201,-151,-186,-148,347,-165,]),} - -_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 - -_lr_goto_items = {'storage_class_specifier':([0,1,12,20,36,41,53,64,72,131,186,195,212,258,287,],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,]),'identifier_list_opt':([53,],[112,]),'selection_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[228,228,228,228,228,228,228,228,228,228,228,228,228,]),'constant':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,87,]),'unary_expression':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[82,147,82,156,157,163,157,157,82,157,157,157,157,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,82,157,82,82,82,82,157,157,157,157,82,157,82,157,82,157,82,157,157,157,157,157,157,157,157,82,157,157,157,157,157,157,157,157,157,157,]),'conditional_expression':([52,98,128,131,143,146,151,152,155,180,189,199,204,212,213,217,221,227,232,251,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[109,161,161,161,109,161,161,161,161,161,109,109,161,161,161,161,109,161,109,161,161,109,161,161,161,161,161,161,161,161,346,161,161,161,161,161,161,161,161,161,161,]),'struct_or_union_specifier':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,]),'initializer':([128,204,332,],[202,296,349,]),'abstract_declarator_opt':([116,160,],[187,257,]),'iteration_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[207,207,207,207,207,207,207,207,207,207,207,207,207,]),'init_declarator_list':([26,69,],[61,61,]),'init_declarator_list_opt':([26,69,],[62,62,]),'struct_declaration_list':([47,74,80,],[75,134,145,]),'enumerator':([55,120,124,198,],[121,121,121,293,]),'pp_directive':([0,20,],[10,10,]),'abstract_declarator':([116,160,186,258,],[188,188,284,284,]),'declaration_specifiers_opt':([1,12,36,],[42,49,67,]),'external_declaration':([0,20,],[11,51,]),'type_specifier':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[12,12,12,12,12,12,76,12,12,12,76,76,76,76,76,76,12,76,76,76,12,12,12,12,12,]),'compound_statement':([71,129,131,212,217,227,301,309,315,340,352,354,356,364,367,],[132,205,214,214,214,214,214,214,214,214,214,214,214,214,214,]),'pointer':([0,4,20,26,58,69,79,116,127,160,186,234,258,],[13,13,13,13,126,13,13,192,13,259,192,13,259,]),'type_name':([98,146,],[158,237,]),'postfix_expression':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,90,]),'parameter_type_list_opt':([186,258,287,],[283,283,331,]),'expression_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[206,206,206,206,206,206,206,206,206,206,206,206,206,]),'unary_operator':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,92,]),'cast_expression':([52,92,98,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[99,154,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,324,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,99,]),'initializer_list':([204,],[297,]),'struct_declarator_list':([79,],[144,]),'empty':([1,12,25,26,36,41,52,53,64,69,76,78,116,131,160,186,189,212,217,227,258,286,287,301,306,309,315,340,351,352,354,356,362,364,367,],[43,43,60,63,43,68,93,113,68,63,137,137,193,226,193,281,93,302,302,302,281,93,281,302,302,302,302,302,302,302,302,302,302,302,302,]),'assignment_operator':([157,],[251,]),'struct_or_union':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,]),'struct_declaration':([47,74,75,80,134,145,],[77,77,135,77,135,135,]),'assignment_expression':([98,128,131,146,151,152,155,180,204,212,213,217,227,251,261,301,306,309,310,312,315,316,322,332,340,351,352,354,355,356,362,364,367,],[159,203,159,159,159,241,159,159,203,159,159,159,159,323,325,159,159,159,159,159,159,159,345,203,159,159,159,159,159,159,159,159,159,]),'parameter_type_list':([53,186,258,287,],[114,282,282,282,]),'type_qualifier_list_opt':([25,],[58,]),'direct_declarator':([0,4,13,20,26,69,79,116,127,186,192,234,],[23,23,50,23,23,23,23,23,23,23,50,23,]),'type_qualifier_list':([25,],[57,]),'argument_expression_list':([152,],[243,]),'statement_list_opt':([131,],[209,]),'direct_abstract_declarator':([116,160,186,192,258,259,],[191,191,191,288,191,288,]),'specifier_qualifier_list_opt':([76,78,],[138,140,]),'constant_expression':([52,143,189,199,221,232,286,],[108,233,108,294,311,317,108,]),'expression_opt':([131,212,217,227,301,306,309,315,340,351,352,354,356,362,364,367,],[210,210,210,210,210,337,210,210,210,357,210,210,210,365,210,210,]),'primary_expression':([52,88,92,94,98,100,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,97,]),'declaration_specifiers':([0,1,12,20,36,41,53,64,72,131,186,195,212,258,287,],[26,44,44,26,44,69,116,69,69,69,116,116,69,116,116,]),'declaration':([0,20,41,64,72,131,212,],[27,27,70,70,133,70,133,]),'declarator':([0,4,20,26,69,79,116,127,186,234,],[41,45,41,64,130,142,190,130,45,142,]),'typedef_name':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,]),'identifier_list':([53,],[117,]),'jump_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[224,224,224,224,224,224,224,224,224,224,224,224,224,]),'declaration_list_opt':([41,64,],[71,129,]),'struct_declarator':([79,234,],[141,318,]),'function_definition':([0,20,],[30,30,]),'binary_expression':([52,98,128,131,143,146,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,199,204,212,213,217,221,227,232,251,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[104,104,104,104,104,104,104,104,104,262,263,264,265,266,267,268,269,270,271,272,273,274,275,276,277,104,279,280,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,104,]),'parameter_list':([53,186,258,287,],[118,118,118,118,]),'enum_specifier':([0,1,12,20,36,41,47,53,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,]),'decl_body':([0,20,41,64,72,131,212,],[35,35,35,35,35,35,35,]),'type_qualifier':([0,1,12,20,25,36,41,47,53,57,64,72,74,75,76,78,80,98,131,134,145,146,186,195,212,258,287,],[36,36,36,36,59,36,36,78,36,125,36,36,78,78,78,78,78,78,36,78,78,78,36,36,36,36,36,]),'constant_expression_opt':([52,189,286,],[105,285,330,]),'enumerator_list':([55,120,124,],[122,196,200,]),'labeled_statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[211,211,211,211,211,211,211,211,211,211,211,211,211,]),'declaration_list':([41,64,131,],[72,72,212,]),'specifier_qualifier_list':([47,74,75,76,78,80,98,134,145,146,],[79,79,79,139,139,79,160,79,79,160,]),'statement':([131,212,217,227,301,309,315,340,352,354,356,364,367,],[223,223,308,314,308,338,343,353,358,359,361,366,368,]),'translation_unit':([0,],[20,]),'init_declarator':([26,69,127,],[65,65,201,]),'parameter_declaration':([53,186,195,258,287,],[115,115,291,115,115,]),'identifier':([52,53,88,92,94,98,100,128,131,143,146,148,150,151,152,155,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,189,194,199,204,212,213,217,221,227,232,251,256,261,286,301,306,309,310,312,315,316,322,326,332,340,351,352,354,355,356,362,364,367,],[111,119,111,111,111,111,111,111,111,111,111,238,239,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,289,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,111,]),'expression':([98,131,146,151,155,180,212,213,217,227,301,306,309,310,312,315,316,340,351,352,354,355,356,362,364,367,],[162,218,162,240,162,278,218,305,218,218,218,218,218,339,341,218,344,218,218,218,218,360,218,218,218,218,]),'statement_list':([131,212,],[217,301,]),} - -_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 -_lr_productions = [ - ("S' -> translation_unit","S'",1,None,None,None), - ('abstract_declarator_opt -> empty','abstract_declarator_opt',1,'p_abstract_declarator_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('abstract_declarator_opt -> abstract_declarator','abstract_declarator_opt',1,'p_abstract_declarator_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('constant_expression_opt -> empty','constant_expression_opt',1,'p_constant_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('constant_expression_opt -> constant_expression','constant_expression_opt',1,'p_constant_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('declaration_list_opt -> empty','declaration_list_opt',1,'p_declaration_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('declaration_list_opt -> declaration_list','declaration_list_opt',1,'p_declaration_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('declaration_specifiers_opt -> empty','declaration_specifiers_opt',1,'p_declaration_specifiers_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('declaration_specifiers_opt -> declaration_specifiers','declaration_specifiers_opt',1,'p_declaration_specifiers_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('expression_opt -> empty','expression_opt',1,'p_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('expression_opt -> expression','expression_opt',1,'p_expression_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('identifier_list_opt -> empty','identifier_list_opt',1,'p_identifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('identifier_list_opt -> identifier_list','identifier_list_opt',1,'p_identifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('init_declarator_list_opt -> empty','init_declarator_list_opt',1,'p_init_declarator_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('init_declarator_list_opt -> init_declarator_list','init_declarator_list_opt',1,'p_init_declarator_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('parameter_type_list_opt -> empty','parameter_type_list_opt',1,'p_parameter_type_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('parameter_type_list_opt -> parameter_type_list','parameter_type_list_opt',1,'p_parameter_type_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('specifier_qualifier_list_opt -> empty','specifier_qualifier_list_opt',1,'p_specifier_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('specifier_qualifier_list_opt -> specifier_qualifier_list','specifier_qualifier_list_opt',1,'p_specifier_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('statement_list_opt -> empty','statement_list_opt',1,'p_statement_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('statement_list_opt -> statement_list','statement_list_opt',1,'p_statement_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('type_qualifier_list_opt -> empty','type_qualifier_list_opt',1,'p_type_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',41), - ('type_qualifier_list_opt -> type_qualifier_list','type_qualifier_list_opt',1,'p_type_qualifier_list_opt','/home/skybot/ext/parser/pycparser/plyparser.py',42), - ('translation_unit -> external_declaration','translation_unit',1,'p_translation_unit_1','/home/skybot/ext/parser/pycparser/c_parser.py',333), - ('translation_unit -> translation_unit external_declaration','translation_unit',2,'p_translation_unit_2','/home/skybot/ext/parser/pycparser/c_parser.py',340), - ('external_declaration -> function_definition','external_declaration',1,'p_external_declaration_1','/home/skybot/ext/parser/pycparser/c_parser.py',351), - ('external_declaration -> declaration','external_declaration',1,'p_external_declaration_2','/home/skybot/ext/parser/pycparser/c_parser.py',356), - ('external_declaration -> pp_directive','external_declaration',1,'p_external_declaration_3','/home/skybot/ext/parser/pycparser/c_parser.py',361), - ('pp_directive -> PPHASH','pp_directive',1,'p_pp_directive','/home/skybot/ext/parser/pycparser/c_parser.py',366), - ('function_definition -> declarator declaration_list_opt compound_statement','function_definition',3,'p_function_definition_1','/home/skybot/ext/parser/pycparser/c_parser.py',375), - ('function_definition -> declaration_specifiers declarator declaration_list_opt compound_statement','function_definition',4,'p_function_definition_2','/home/skybot/ext/parser/pycparser/c_parser.py',387), - ('statement -> labeled_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',398), - ('statement -> expression_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',399), - ('statement -> compound_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',400), - ('statement -> selection_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',401), - ('statement -> iteration_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',402), - ('statement -> jump_statement','statement',1,'p_statement','/home/skybot/ext/parser/pycparser/c_parser.py',403), - ('decl_body -> declaration_specifiers init_declarator_list_opt','decl_body',2,'p_decl_body','/home/skybot/ext/parser/pycparser/c_parser.py',417), - ('declaration -> decl_body SEMI','declaration',2,'p_declaration','/home/skybot/ext/parser/pycparser/c_parser.py',497), - ('declaration_list -> declaration','declaration_list',1,'p_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',506), - ('declaration_list -> declaration_list declaration','declaration_list',2,'p_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',507), - ('declaration_specifiers -> type_qualifier declaration_specifiers_opt','declaration_specifiers',2,'p_declaration_specifiers_1','/home/skybot/ext/parser/pycparser/c_parser.py',512), - ('declaration_specifiers -> type_specifier declaration_specifiers_opt','declaration_specifiers',2,'p_declaration_specifiers_2','/home/skybot/ext/parser/pycparser/c_parser.py',517), - ('declaration_specifiers -> storage_class_specifier declaration_specifiers_opt','declaration_specifiers',2,'p_declaration_specifiers_3','/home/skybot/ext/parser/pycparser/c_parser.py',522), - ('storage_class_specifier -> AUTO','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',527), - ('storage_class_specifier -> REGISTER','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',528), - ('storage_class_specifier -> STATIC','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',529), - ('storage_class_specifier -> EXTERN','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',530), - ('storage_class_specifier -> TYPEDEF','storage_class_specifier',1,'p_storage_class_specifier','/home/skybot/ext/parser/pycparser/c_parser.py',531), - ('type_specifier -> VOID','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',536), - ('type_specifier -> CHAR','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',537), - ('type_specifier -> SHORT','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',538), - ('type_specifier -> INT','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',539), - ('type_specifier -> LONG','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',540), - ('type_specifier -> FLOAT','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',541), - ('type_specifier -> DOUBLE','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',542), - ('type_specifier -> SIGNED','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',543), - ('type_specifier -> UNSIGNED','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',544), - ('type_specifier -> typedef_name','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',545), - ('type_specifier -> enum_specifier','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',546), - ('type_specifier -> struct_or_union_specifier','type_specifier',1,'p_type_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',547), - ('type_qualifier -> CONST','type_qualifier',1,'p_type_qualifier','/home/skybot/ext/parser/pycparser/c_parser.py',552), - ('type_qualifier -> VOLATILE','type_qualifier',1,'p_type_qualifier','/home/skybot/ext/parser/pycparser/c_parser.py',553), - ('init_declarator_list -> init_declarator','init_declarator_list',1,'p_init_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',558), - ('init_declarator_list -> init_declarator_list COMMA init_declarator','init_declarator_list',3,'p_init_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',559), - ('init_declarator -> declarator','init_declarator',1,'p_init_declarator','/home/skybot/ext/parser/pycparser/c_parser.py',567), - ('init_declarator -> declarator EQUALS initializer','init_declarator',3,'p_init_declarator','/home/skybot/ext/parser/pycparser/c_parser.py',568), - ('specifier_qualifier_list -> type_qualifier specifier_qualifier_list_opt','specifier_qualifier_list',2,'p_specifier_qualifier_list_1','/home/skybot/ext/parser/pycparser/c_parser.py',573), - ('specifier_qualifier_list -> type_specifier specifier_qualifier_list_opt','specifier_qualifier_list',2,'p_specifier_qualifier_list_2','/home/skybot/ext/parser/pycparser/c_parser.py',578), - ('struct_or_union_specifier -> struct_or_union ID','struct_or_union_specifier',2,'p_struct_or_union_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',586), - ('struct_or_union_specifier -> struct_or_union TYPEID','struct_or_union_specifier',2,'p_struct_or_union_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',587), - ('struct_or_union_specifier -> struct_or_union LBRACE struct_declaration_list RBRACE','struct_or_union_specifier',4,'p_struct_or_union_specifier_2','/home/skybot/ext/parser/pycparser/c_parser.py',596), - ('struct_or_union_specifier -> struct_or_union ID LBRACE struct_declaration_list RBRACE','struct_or_union_specifier',5,'p_struct_or_union_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',605), - ('struct_or_union_specifier -> struct_or_union TYPEID LBRACE struct_declaration_list RBRACE','struct_or_union_specifier',5,'p_struct_or_union_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',606), - ('struct_or_union -> STRUCT','struct_or_union',1,'p_struct_or_union','/home/skybot/ext/parser/pycparser/c_parser.py',615), - ('struct_or_union -> UNION','struct_or_union',1,'p_struct_or_union','/home/skybot/ext/parser/pycparser/c_parser.py',616), - ('struct_declaration_list -> struct_declaration','struct_declaration_list',1,'p_struct_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',623), - ('struct_declaration_list -> struct_declaration_list struct_declaration','struct_declaration_list',2,'p_struct_declaration_list','/home/skybot/ext/parser/pycparser/c_parser.py',624), - ('struct_declaration -> specifier_qualifier_list struct_declarator_list SEMI','struct_declaration',3,'p_struct_declaration_1','/home/skybot/ext/parser/pycparser/c_parser.py',629), - ('struct_declarator_list -> struct_declarator','struct_declarator_list',1,'p_struct_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',650), - ('struct_declarator_list -> struct_declarator_list COMMA struct_declarator','struct_declarator_list',3,'p_struct_declarator_list','/home/skybot/ext/parser/pycparser/c_parser.py',651), - ('struct_declarator -> declarator','struct_declarator',1,'p_struct_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',659), - ('struct_declarator -> declarator COLON constant_expression','struct_declarator',3,'p_struct_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',664), - ('struct_declarator -> COLON constant_expression','struct_declarator',2,'p_struct_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',665), - ('enum_specifier -> ENUM ID','enum_specifier',2,'p_enum_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',673), - ('enum_specifier -> ENUM TYPEID','enum_specifier',2,'p_enum_specifier_1','/home/skybot/ext/parser/pycparser/c_parser.py',674), - ('enum_specifier -> ENUM LBRACE enumerator_list RBRACE','enum_specifier',4,'p_enum_specifier_2','/home/skybot/ext/parser/pycparser/c_parser.py',679), - ('enum_specifier -> ENUM ID LBRACE enumerator_list RBRACE','enum_specifier',5,'p_enum_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',684), - ('enum_specifier -> ENUM TYPEID LBRACE enumerator_list RBRACE','enum_specifier',5,'p_enum_specifier_3','/home/skybot/ext/parser/pycparser/c_parser.py',685), - ('enumerator_list -> enumerator','enumerator_list',1,'p_enumerator_list','/home/skybot/ext/parser/pycparser/c_parser.py',690), - ('enumerator_list -> enumerator_list COMMA','enumerator_list',2,'p_enumerator_list','/home/skybot/ext/parser/pycparser/c_parser.py',691), - ('enumerator_list -> enumerator_list COMMA enumerator','enumerator_list',3,'p_enumerator_list','/home/skybot/ext/parser/pycparser/c_parser.py',692), - ('enumerator -> ID','enumerator',1,'p_enumerator','/home/skybot/ext/parser/pycparser/c_parser.py',703), - ('enumerator -> ID EQUALS constant_expression','enumerator',3,'p_enumerator','/home/skybot/ext/parser/pycparser/c_parser.py',704), - ('declarator -> direct_declarator','declarator',1,'p_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',716), - ('declarator -> pointer direct_declarator','declarator',2,'p_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',721), - ('direct_declarator -> ID','direct_declarator',1,'p_direct_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',726), - ('direct_declarator -> LPAREN declarator RPAREN','direct_declarator',3,'p_direct_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',735), - ('direct_declarator -> direct_declarator LBRACKET constant_expression_opt RBRACKET','direct_declarator',4,'p_direct_declarator_3','/home/skybot/ext/parser/pycparser/c_parser.py',740), - ('direct_declarator -> direct_declarator LPAREN parameter_type_list RPAREN','direct_declarator',4,'p_direct_declarator_4','/home/skybot/ext/parser/pycparser/c_parser.py',750), - ('direct_declarator -> direct_declarator LPAREN identifier_list_opt RPAREN','direct_declarator',4,'p_direct_declarator_4','/home/skybot/ext/parser/pycparser/c_parser.py',751), - ('pointer -> TIMES type_qualifier_list_opt','pointer',2,'p_pointer','/home/skybot/ext/parser/pycparser/c_parser.py',761), - ('pointer -> TIMES type_qualifier_list_opt pointer','pointer',3,'p_pointer','/home/skybot/ext/parser/pycparser/c_parser.py',762), - ('type_qualifier_list -> type_qualifier','type_qualifier_list',1,'p_type_qualifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',772), - ('type_qualifier_list -> type_qualifier_list type_qualifier','type_qualifier_list',2,'p_type_qualifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',773), - ('parameter_type_list -> parameter_list','parameter_type_list',1,'p_parameter_type_list','/home/skybot/ext/parser/pycparser/c_parser.py',778), - ('parameter_type_list -> parameter_list COMMA ELLIPSIS','parameter_type_list',3,'p_parameter_type_list','/home/skybot/ext/parser/pycparser/c_parser.py',779), - ('parameter_list -> parameter_declaration','parameter_list',1,'p_parameter_list','/home/skybot/ext/parser/pycparser/c_parser.py',787), - ('parameter_list -> parameter_list COMMA parameter_declaration','parameter_list',3,'p_parameter_list','/home/skybot/ext/parser/pycparser/c_parser.py',788), - ('parameter_declaration -> declaration_specifiers declarator','parameter_declaration',2,'p_parameter_declaration_1','/home/skybot/ext/parser/pycparser/c_parser.py',797), - ('parameter_declaration -> declaration_specifiers abstract_declarator_opt','parameter_declaration',2,'p_parameter_declaration_2','/home/skybot/ext/parser/pycparser/c_parser.py',815), - ('identifier_list -> identifier','identifier_list',1,'p_identifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',827), - ('identifier_list -> identifier_list COMMA identifier','identifier_list',3,'p_identifier_list','/home/skybot/ext/parser/pycparser/c_parser.py',828), - ('initializer -> assignment_expression','initializer',1,'p_initializer_1','/home/skybot/ext/parser/pycparser/c_parser.py',837), - ('initializer -> LBRACE initializer_list RBRACE','initializer',3,'p_initializer_2','/home/skybot/ext/parser/pycparser/c_parser.py',842), - ('initializer -> LBRACE initializer_list COMMA RBRACE','initializer',4,'p_initializer_2','/home/skybot/ext/parser/pycparser/c_parser.py',843), - ('initializer_list -> initializer','initializer_list',1,'p_initializer_list','/home/skybot/ext/parser/pycparser/c_parser.py',848), - ('initializer_list -> initializer_list COMMA initializer','initializer_list',3,'p_initializer_list','/home/skybot/ext/parser/pycparser/c_parser.py',849), - ('type_name -> specifier_qualifier_list abstract_declarator_opt','type_name',2,'p_type_name','/home/skybot/ext/parser/pycparser/c_parser.py',858), - ('abstract_declarator -> pointer','abstract_declarator',1,'p_abstract_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',873), - ('abstract_declarator -> pointer direct_abstract_declarator','abstract_declarator',2,'p_abstract_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',881), - ('abstract_declarator -> direct_abstract_declarator','abstract_declarator',1,'p_abstract_declarator_3','/home/skybot/ext/parser/pycparser/c_parser.py',886), - ('direct_abstract_declarator -> LPAREN abstract_declarator RPAREN','direct_abstract_declarator',3,'p_direct_abstract_declarator_1','/home/skybot/ext/parser/pycparser/c_parser.py',896), - ('direct_abstract_declarator -> direct_abstract_declarator LBRACKET constant_expression_opt RBRACKET','direct_abstract_declarator',4,'p_direct_abstract_declarator_2','/home/skybot/ext/parser/pycparser/c_parser.py',900), - ('direct_abstract_declarator -> LBRACKET constant_expression_opt RBRACKET','direct_abstract_declarator',3,'p_direct_abstract_declarator_3','/home/skybot/ext/parser/pycparser/c_parser.py',910), - ('direct_abstract_declarator -> direct_abstract_declarator LPAREN parameter_type_list_opt RPAREN','direct_abstract_declarator',4,'p_direct_abstract_declarator_4','/home/skybot/ext/parser/pycparser/c_parser.py',918), - ('direct_abstract_declarator -> LPAREN parameter_type_list_opt RPAREN','direct_abstract_declarator',3,'p_direct_abstract_declarator_5','/home/skybot/ext/parser/pycparser/c_parser.py',928), - ('compound_statement -> LBRACE statement_list_opt RBRACE','compound_statement',3,'p_compound_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',936), - ('compound_statement -> LBRACE declaration_list RBRACE','compound_statement',3,'p_compound_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',943), - ('compound_statement -> LBRACE declaration_list statement_list RBRACE','compound_statement',4,'p_compound_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',950), - ('statement_list -> statement','statement_list',1,'p_statement_list','/home/skybot/ext/parser/pycparser/c_parser.py',964), - ('statement_list -> statement_list statement','statement_list',2,'p_statement_list','/home/skybot/ext/parser/pycparser/c_parser.py',965), - ('labeled_statement -> ID COLON statement','labeled_statement',3,'p_labeled_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',973), - ('labeled_statement -> CASE constant_expression COLON statement','labeled_statement',4,'p_labeled_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',977), - ('labeled_statement -> DEFAULT COLON statement','labeled_statement',3,'p_labeled_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',981), - ('selection_statement -> IF LPAREN expression RPAREN statement','selection_statement',5,'p_selection_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',985), - ('selection_statement -> IF LPAREN expression RPAREN statement ELSE statement','selection_statement',7,'p_selection_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',989), - ('selection_statement -> SWITCH LPAREN expression RPAREN statement','selection_statement',5,'p_selection_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',993), - ('iteration_statement -> WHILE LPAREN expression RPAREN statement','iteration_statement',5,'p_iteration_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',997), - ('iteration_statement -> DO statement WHILE LPAREN expression RPAREN','iteration_statement',6,'p_iteration_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',1001), - ('iteration_statement -> FOR LPAREN expression_opt SEMI expression_opt SEMI expression_opt RPAREN statement','iteration_statement',9,'p_iteration_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',1005), - ('jump_statement -> GOTO ID SEMI','jump_statement',3,'p_jump_statement_1','/home/skybot/ext/parser/pycparser/c_parser.py',1009), - ('jump_statement -> BREAK SEMI','jump_statement',2,'p_jump_statement_2','/home/skybot/ext/parser/pycparser/c_parser.py',1013), - ('jump_statement -> CONTINUE SEMI','jump_statement',2,'p_jump_statement_3','/home/skybot/ext/parser/pycparser/c_parser.py',1017), - ('jump_statement -> RETURN expression SEMI','jump_statement',3,'p_jump_statement_4','/home/skybot/ext/parser/pycparser/c_parser.py',1021), - ('jump_statement -> RETURN SEMI','jump_statement',2,'p_jump_statement_4','/home/skybot/ext/parser/pycparser/c_parser.py',1022), - ('expression_statement -> expression_opt SEMI','expression_statement',2,'p_expression_statement','/home/skybot/ext/parser/pycparser/c_parser.py',1027), - ('expression -> assignment_expression','expression',1,'p_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1031), - ('expression -> expression COMMA assignment_expression','expression',3,'p_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1032), - ('typedef_name -> TYPEID','typedef_name',1,'p_typedef_name','/home/skybot/ext/parser/pycparser/c_parser.py',1044), - ('assignment_expression -> conditional_expression','assignment_expression',1,'p_assignment_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1048), - ('assignment_expression -> unary_expression assignment_operator assignment_expression','assignment_expression',3,'p_assignment_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1049), - ('assignment_operator -> EQUALS','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1062), - ('assignment_operator -> XOREQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1063), - ('assignment_operator -> TIMESEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1064), - ('assignment_operator -> DIVEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1065), - ('assignment_operator -> MODEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1066), - ('assignment_operator -> PLUSEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1067), - ('assignment_operator -> MINUSEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1068), - ('assignment_operator -> LSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1069), - ('assignment_operator -> RSHIFTEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1070), - ('assignment_operator -> ANDEQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1071), - ('assignment_operator -> OREQUAL','assignment_operator',1,'p_assignment_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1072), - ('constant_expression -> conditional_expression','constant_expression',1,'p_constant_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1077), - ('conditional_expression -> binary_expression','conditional_expression',1,'p_conditional_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1081), - ('conditional_expression -> binary_expression CONDOP expression COLON conditional_expression','conditional_expression',5,'p_conditional_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1082), - ('binary_expression -> cast_expression','binary_expression',1,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1090), - ('binary_expression -> binary_expression TIMES binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1091), - ('binary_expression -> binary_expression DIVIDE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1092), - ('binary_expression -> binary_expression MOD binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1093), - ('binary_expression -> binary_expression PLUS binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1094), - ('binary_expression -> binary_expression MINUS binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1095), - ('binary_expression -> binary_expression RSHIFT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1096), - ('binary_expression -> binary_expression LSHIFT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1097), - ('binary_expression -> binary_expression LT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1098), - ('binary_expression -> binary_expression LE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1099), - ('binary_expression -> binary_expression GE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1100), - ('binary_expression -> binary_expression GT binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1101), - ('binary_expression -> binary_expression EQ binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1102), - ('binary_expression -> binary_expression NE binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1103), - ('binary_expression -> binary_expression AND binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1104), - ('binary_expression -> binary_expression OR binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1105), - ('binary_expression -> binary_expression XOR binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1106), - ('binary_expression -> binary_expression LAND binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1107), - ('binary_expression -> binary_expression LOR binary_expression','binary_expression',3,'p_binary_expression','/home/skybot/ext/parser/pycparser/c_parser.py',1108), - ('cast_expression -> unary_expression','cast_expression',1,'p_cast_expression_1','/home/skybot/ext/parser/pycparser/c_parser.py',1116), - ('cast_expression -> LPAREN type_name RPAREN cast_expression','cast_expression',4,'p_cast_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1120), - ('unary_expression -> postfix_expression','unary_expression',1,'p_unary_expression_1','/home/skybot/ext/parser/pycparser/c_parser.py',1124), - ('unary_expression -> PLUSPLUS unary_expression','unary_expression',2,'p_unary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1128), - ('unary_expression -> MINUSMINUS unary_expression','unary_expression',2,'p_unary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1129), - ('unary_expression -> unary_operator cast_expression','unary_expression',2,'p_unary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1130), - ('unary_expression -> SIZEOF unary_expression','unary_expression',2,'p_unary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1135), - ('unary_expression -> SIZEOF LPAREN type_name RPAREN','unary_expression',4,'p_unary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1136), - ('unary_operator -> AND','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1144), - ('unary_operator -> TIMES','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1145), - ('unary_operator -> PLUS','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1146), - ('unary_operator -> MINUS','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1147), - ('unary_operator -> NOT','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1148), - ('unary_operator -> LNOT','unary_operator',1,'p_unary_operator','/home/skybot/ext/parser/pycparser/c_parser.py',1149), - ('postfix_expression -> primary_expression','postfix_expression',1,'p_postfix_exptession_1','/home/skybot/ext/parser/pycparser/c_parser.py',1154), - ('postfix_expression -> postfix_expression LBRACKET expression RBRACKET','postfix_expression',4,'p_postfix_exptession_2','/home/skybot/ext/parser/pycparser/c_parser.py',1158), - ('postfix_expression -> postfix_expression LPAREN argument_expression_list RPAREN','postfix_expression',4,'p_postfix_exptession_3','/home/skybot/ext/parser/pycparser/c_parser.py',1162), - ('postfix_expression -> postfix_expression LPAREN RPAREN','postfix_expression',3,'p_postfix_exptession_3','/home/skybot/ext/parser/pycparser/c_parser.py',1163), - ('postfix_expression -> postfix_expression PERIOD identifier','postfix_expression',3,'p_postfix_expression_4','/home/skybot/ext/parser/pycparser/c_parser.py',1168), - ('postfix_expression -> postfix_expression ARROW identifier','postfix_expression',3,'p_postfix_expression_4','/home/skybot/ext/parser/pycparser/c_parser.py',1169), - ('postfix_expression -> postfix_expression PLUSPLUS','postfix_expression',2,'p_postfix_expression_5','/home/skybot/ext/parser/pycparser/c_parser.py',1174), - ('postfix_expression -> postfix_expression MINUSMINUS','postfix_expression',2,'p_postfix_expression_5','/home/skybot/ext/parser/pycparser/c_parser.py',1175), - ('primary_expression -> identifier','primary_expression',1,'p_primary_expression_1','/home/skybot/ext/parser/pycparser/c_parser.py',1180), - ('primary_expression -> constant','primary_expression',1,'p_primary_expression_2','/home/skybot/ext/parser/pycparser/c_parser.py',1184), - ('primary_expression -> STRING_LITERAL','primary_expression',1,'p_primary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1188), - ('primary_expression -> WSTRING_LITERAL','primary_expression',1,'p_primary_expression_3','/home/skybot/ext/parser/pycparser/c_parser.py',1189), - ('primary_expression -> LPAREN expression RPAREN','primary_expression',3,'p_primary_expression_4','/home/skybot/ext/parser/pycparser/c_parser.py',1195), - ('argument_expression_list -> assignment_expression','argument_expression_list',1,'p_argument_expression_list','/home/skybot/ext/parser/pycparser/c_parser.py',1199), - ('argument_expression_list -> argument_expression_list COMMA assignment_expression','argument_expression_list',3,'p_argument_expression_list','/home/skybot/ext/parser/pycparser/c_parser.py',1200), - ('identifier -> ID','identifier',1,'p_identifier','/home/skybot/ext/parser/pycparser/c_parser.py',1209), - ('constant -> INT_CONST_DEC','constant',1,'p_constant_1','/home/skybot/ext/parser/pycparser/c_parser.py',1213), - ('constant -> INT_CONST_OCT','constant',1,'p_constant_1','/home/skybot/ext/parser/pycparser/c_parser.py',1214), - ('constant -> INT_CONST_HEX','constant',1,'p_constant_1','/home/skybot/ext/parser/pycparser/c_parser.py',1215), - ('constant -> FLOAT_CONST','constant',1,'p_constant_2','/home/skybot/ext/parser/pycparser/c_parser.py',1221), - ('constant -> CHAR_CONST','constant',1,'p_constant_3','/home/skybot/ext/parser/pycparser/c_parser.py',1226), - ('constant -> WCHAR_CONST','constant',1,'p_constant_3','/home/skybot/ext/parser/pycparser/c_parser.py',1227), - ('empty -> ','empty',0,'p_empty','/home/skybot/ext/parser/pycparser/c_parser.py',1233), -] diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..2ea4d03 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +lxml +pycparser