diff options
author | Joseph Hunkeler <jhunkeler@gmail.com> | 2016-07-03 19:01:41 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunkeler@gmail.com> | 2016-07-03 19:01:41 -0400 |
commit | 22da810587d1b489a3f7434cd9d7e52927b9a742 (patch) | |
tree | 32d151203a524cccd7ed10797f26f3e02c1aa4ca /steuermann/specfile.py | |
parent | 5dc89dafb0bd7ecd41936baa3bfe6805adc1a0b2 (diff) | |
download | steuermann-22da810587d1b489a3f7434cd9d7e52927b9a742.tar.gz |
Remove generated specfile from repository
Diffstat (limited to 'steuermann/specfile.py')
-rw-r--r-- | steuermann/specfile.py | 688 |
1 files changed, 0 insertions, 688 deletions
diff --git a/steuermann/specfile.py b/steuermann/specfile.py deleted file mode 100644 index dcd8305..0000000 --- a/steuermann/specfile.py +++ /dev/null @@ -1,688 +0,0 @@ -# THIS FILE WAS AUTOMATICALLY GENERATED - -# Parse a Steuermann Spec file -# -# This is an exyapps grammer in specfile.exy -import nodes - - -# Begin -- grammar generated by Yapps -import sys, re -###### included from /usr/stsci/pyssgdev/Python-2.7.1/lib/python2.7/site-packages/exyapps/runtime.py -# exyapps - yet another python parser system -# Copyright 1999-2003 by Amit J. Patel <amitp@cs.stanford.edu> -# Enhancements copyright 2003-2004 by Matthias Urlichs <smurf@debian.org> -# Copyright 2011 by Association of Universities for Research in Astronomy -# -# This software can be distributed under the terms of the MIT -# open source license, either found in the LICENSE file or at -# <http://www.opensource.org/licenses/mit-license.php> -# -# ----- -# -# Changes from the debian version: -# - indented with spaces, not tabs -# - when you instantiate the parser object, you can pass in an object -# data=XXX that will be available to the parser as self.data; this -# is basically a hook to provide parser-global data. -# -# Note that this file is incorporated directly into the generated parser. -# Take care when defining new file-global names because the generated -# parser has its own globals. - -"""Run time libraries needed to run parsers generated by Yapps. - -This module defines parse-time exception classes, a scanner class, a -base class for parsers produced by Yapps, and a context class that -keeps track of the parse stack. - -""" - -import sys, re - -MIN_WINDOW=4096 -# File lookup window - -class SyntaxError(Exception): - """When we run into an unexpected token, this is the exception to use""" - def __init__(self, pos=None, msg="Bad Token", context=None): - Exception.__init__(self) - self.pos = pos - self.msg = msg - self.context = context - - def __str__(self): - if not self.pos: return 'SyntaxError' - else: return 'SyntaxError@%s(%s)' % (repr(self.pos), self.msg) - -class NoMoreTokens(Exception): - """Another exception object, for when we run out of tokens""" - pass - -class Token(object): - """Yapps token. - - This is a container for a scanned token. - """ - - def __init__(self, type,value, pos=None): - """Initialize a token.""" - self.type = type - self.value = value - self.pos = pos - - def __repr__(self): - output = '<%s: %s' % (self.type, repr(self.value)) - if self.pos: - output += " @ " - if self.pos[0]: - output += "%s:" % self.pos[0] - if self.pos[1]: - output += "%d" % self.pos[1] - if self.pos[2] is not None: - output += ".%d" % self.pos[2] - output += ">" - return output - -in_name=0 -class Scanner(object): - """Yapps scanner. (lexical analyzer) - - The Yapps scanner can work in context sensitive or context - insensitive modes. The token(i) method is used to retrieve the - i-th token. It takes a restrict set that limits the set of tokens - it is allowed to return. In context sensitive mode, this restrict - set guides the scanner. In context insensitive mode, there is no - restriction (the set is always the full set of tokens). - - """ - - def __init__(self, patterns, ignore, input="", - file=None,filename=None,stacked=False): - """Initialize the scanner. - - Parameters: - patterns : [(terminal, uncompiled regex), ...] or None - ignore : {terminal:None, ...} - input : string - - If patterns is None, we assume that the subclass has - defined self.patterns : [(terminal, compiled regex), ...]. - Note that the patterns parameter expects uncompiled regexes, - whereas the self.patterns field expects compiled regexes. - - The 'ignore' value is either None or a callable, which is called - with the scanner and the to-be-ignored match object; this can - be used for include file or comment handling. - """ - - if not filename: - global in_name - filename="<f.%d>" % in_name - in_name += 1 - - self.input = input - self.ignore = ignore - self.file = file - self.filename = filename - self.pos = 0 - self.del_pos = 0 # skipped - self.line = 1 - self.del_line = 0 # skipped - self.col = 0 - self.tokens = [] - self.stack = None - self.stacked = stacked - - self.last_read_token = None - self.last_token = None - self.last_types = None - - if patterns is not None: - # Compile the regex strings into regex objects - self.patterns = [] - for terminal, regex in patterns: - self.patterns.append( (terminal, re.compile(regex)) ) - - def stack_input(self, input="", file=None, filename=None): - """Temporarily parse from a second file.""" - - # Already reading from somewhere else: Go on top of that, please. - if self.stack: - # autogenerate a recursion-level-identifying filename - if not filename: - filename = 1 - else: - try: - filename += 1 - except TypeError: - pass - # now pass off to the include file - self.stack.stack_input(input,file,filename) - else: - - try: - filename += 0 - except TypeError: - pass - else: - filename = "<str_%d>" % filename - -# self.stack = object.__new__(self.__class__) -# Scanner.__init__(self.stack,self.patterns,self.ignore,input,file,filename, stacked=True) - - # Note that the pattern+ignore are added by the generated - # scanner code - self.stack = self.__class__(input,file,filename, stacked=True) - - def get_pos(self): - """Return a file/line/char tuple.""" - if self.stack: return self.stack.get_pos() - - return (self.filename, self.line+self.del_line, self.col) - -# def __repr__(self): -# """Print the last few tokens that have been scanned in""" -# output = '' -# for t in self.tokens: -# output += '%s\n' % (repr(t),) -# return output - - def print_line_with_pointer(self, pos, length=0, out=sys.stderr): - """Print the line of 'text' that includes position 'p', - along with a second line with a single caret (^) at position p""" - - file,line,p = pos - if file != self.filename: - if self.stack: return self.stack.print_line_with_pointer(pos,length=length,out=out) - print("(%s: not in input buffer)" % file, file=out) - return - - text = self.input - p += length-1 # starts at pos 1 - - origline=line - line -= self.del_line - spos=0 - if line > 0: - while 1: - line = line - 1 - try: - cr = text.index("\n",spos) - except ValueError: - if line: - text = "" - break - if line == 0: - text = text[spos:cr] - break - spos = cr+1 - else: - print("(%s:%d not in input buffer)" % (file,origline), file=out) - return - - # Now try printing part of the line - text = text[max(p-80, 0):p+80] - p = p - max(p-80, 0) - - # Strip to the left - i = text[:p].rfind('\n') - j = text[:p].rfind('\r') - if i < 0 or (0 <= j < i): i = j - if 0 <= i < p: - p = p - i - 1 - text = text[i+1:] - - # Strip to the right - i = text.find('\n', p) - j = text.find('\r', p) - if i < 0 or (0 <= j < i): i = j - if i >= 0: - text = text[:i] - - # Now shorten the text - while len(text) > 70 and p > 60: - # Cut off 10 chars - text = "..." + text[10:] - p = p - 7 - - # Now print the string, along with an indicator - print('> ',text, file=out) - print('> ',' '*p + '^', file=out) - - def grab_input(self): - """Get more input if possible.""" - if not self.file: return - if len(self.input) - self.pos >= MIN_WINDOW: return - - data = self.file.read(MIN_WINDOW) - if data is None or data == "": - self.file = None - - # Drop bytes from the start, if necessary. - if self.pos > 2*MIN_WINDOW: - self.del_pos += MIN_WINDOW - self.del_line += self.input[:MIN_WINDOW].count("\n") - self.pos -= MIN_WINDOW - self.input = self.input[MIN_WINDOW:] + data - else: - self.input = self.input + data - - def getchar(self): - """Return the next character.""" - self.grab_input() - - c = self.input[self.pos] - self.pos += 1 - return c - - def token(self, restrict, context=None): - """Scan for another token.""" - - while 1: - if self.stack: - try: - return self.stack.token(restrict, context) - except StopIteration: - self.stack = None - - # Keep looking for a token, ignoring any in self.ignore - self.grab_input() - - # special handling for end-of-file - if self.stacked and self.pos==len(self.input): - raise StopIteration - - # Search the patterns for the longest match, with earlier - # tokens in the list having preference - best_match = -1 - best_pat = '(error)' - best_m = None - for p, regexp in self.patterns: - # First check to see if we're ignoring this token - if restrict and p not in restrict and p not in self.ignore: - continue - m = regexp.match(self.input, self.pos) - if m and m.end()-m.start() > best_match: - # We got a match that's better than the previous one - best_pat = p - best_match = m.end()-m.start() - best_m = m - - # If we didn't find anything, raise an error - if best_pat == '(error)' and best_match < 0: - msg = 'Bad Token' - if restrict: - msg = 'Trying to find one of '+', '.join(restrict) - raise SyntaxError(self.get_pos(), msg, context=context) - - ignore = best_pat in self.ignore - value = self.input[self.pos:self.pos+best_match] - if not ignore: - tok=Token(type=best_pat, value=value, pos=self.get_pos()) - - self.pos += best_match - - npos = value.rfind("\n") - if npos > -1: - self.col = best_match-npos - self.line += value.count("\n") - else: - self.col += best_match - - # If we found something that isn't to be ignored, return it - if not ignore: - if len(self.tokens) >= 10: - del self.tokens[0] - self.tokens.append(tok) - self.last_read_token = tok - # print repr(tok) - return tok - else: - ignore = self.ignore[best_pat] - if ignore: - ignore(self, best_m) - - def peek(self, *types, **kw): - """Returns the token type for lookahead; if there are any args - then the list of args is the set of token types to allow""" - context = kw.get("context",None) - if self.last_token is None: - self.last_types = types - self.last_token = self.token(types,context) - elif self.last_types: - for t in types: - if t not in self.last_types: - raise NotImplementedError("Unimplemented: restriction set changed") - return self.last_token.type - - def scan(self, type, **kw): - """Returns the matched text, and moves to the next token""" - context = kw.get("context",None) - - if self.last_token is None: - tok = self.token([type],context) - else: - if self.last_types and type not in self.last_types: - raise NotImplementedError("Unimplemented: restriction set changed") - - tok = self.last_token - self.last_token = None - if tok.type != type: - if not self.last_types: self.last_types=[] - raise SyntaxError(tok.pos, 'Trying to find '+type+': '+ ', '.join(self.last_types)+", got "+tok.type, context=context) - return tok.value - -class Parser(object): - """Base class for Yapps-generated parsers. - - """ - - def __init__(self, scanner, data=None): - self._scanner = scanner - self.data = data - - def _stack(self, input="",file=None,filename=None): - """Temporarily read from someplace else""" - self._scanner.stack_input(input,file,filename) - self._tok = None - - def _peek(self, *types, **kw): - """Returns the token type for lookahead; if there are any args - then the list of args is the set of token types to allow""" - return self._scanner.peek(*types, **kw) - - def _scan(self, type, **kw): - """Returns the matched text, and moves to the next token""" - return self._scanner.scan(type, **kw) - -class Context(object): - """Class to represent the parser's call stack. - - Every rule creates a Context that links to its parent rule. The - contexts can be used for debugging. - - """ - - def __init__(self, parent, scanner, rule, args=()): - """Create a new context. - - Args: - parent: Context object or None - scanner: Scanner object - rule: string (name of the rule) - args: tuple listing parameters to the rule - - """ - self.parent = parent - self.scanner = scanner - self.rule = rule - self.args = args - while scanner.stack: scanner = scanner.stack - self.token = scanner.last_read_token - - def __str__(self): - output = '' - if self.parent: output = str(self.parent) + ' > ' - output += self.rule - return output - -def print_error(err, scanner, max_ctx=None): - """Print error messages, the parser stack, and the input text -- for human-readable error messages.""" - # NOTE: this function assumes 80 columns :-( - # Figure out the line number - pos = err.pos - if not pos: - pos = scanner.get_pos() - - file_name, line_number, column_number = pos - print('%s:%d:%d: %s' % (file_name, line_number, column_number, err.msg), file=sys.stderr) - - scanner.print_line_with_pointer(pos) - - context = err.context - token = None - while context: - print('while parsing %s%s:' % (context.rule, tuple(context.args)), file=sys.stderr) - if context.token: - token = context.token - if token: - scanner.print_line_with_pointer(token.pos, length=len(token.value)) - context = context.parent - if max_ctx: - max_ctx = max_ctx-1 - if not max_ctx: - break - -def wrap_error_reporter(parser, rule, *args,**kw): - try: - return getattr(parser, rule)(*args,**kw) - except SyntaxError as e: - print_error(e, parser._scanner) - except NoMoreTokens: - print('Could not complete parsing; stopped around here:', file=sys.stderr) - print(parser._scanner, file=sys.stderr) -###### end of runtime.py - -class specfileScanner(Scanner): - patterns = [ - ('"="', re.compile('=')), - ('"$"', re.compile('$')), - ('[ \r\t\n]+', re.compile('[ \r\t\n]+')), - ('#.*\n', re.compile('#.*\n')), - ('END', re.compile('$')), - ('HOSTGROUP', re.compile('HOSTGROUP')), - ('IF', re.compile('IF')), - ('IFNOT', re.compile('IFNOT')), - ('TABLE', re.compile('TABLE')), - ('HOST', re.compile('HOST')), - ('CMD', re.compile('CMD')), - ('OPT', re.compile('OPT')), - ('AFTER', re.compile('AFTER')), - ('RUN', re.compile('RUN')), - ('LOCAL', re.compile('LOCAL')), - ('IMPORT', re.compile('IMPORT')), - ('RESOURCE', re.compile('RESOURCE')), - ('DEBUG', re.compile('DEBUG')), - ('name', re.compile('[a-zA-Z0-9_.-]+')), - ('STAR', re.compile('\\*')), - ('cmdname', re.compile('[a-zA-Z0-9_.-]+')), - ('tablename', re.compile('[a-zA-Z0-9_.-]+')), - ('wildname', re.compile('[@]{0,1}[*?a-zA-Z0-9_.-]+')), - ('string', re.compile('"[^"]*"')), - ('SLASH', re.compile('/')), - ('COLON', re.compile(':')), - ('hostgroup', re.compile('@[a-zA-Z0-9_.-]+')), - ('number', re.compile('[0-9]+')), - ('RES_ALL', re.compile('all')), - ('RES_AVAILABLE', re.compile('available')), - ('CONDITIONS', re.compile('CONDITIONS[^"]*\n[\\s]*END[ \t]*\n')), - ] - def __init__(self, str,*args,**kw): - Scanner.__init__(self,None,{'[ \r\t\n]+':None,'#.*\n':None,},str,*args,**kw) - -class specfile(Parser): - Context = Context - def start(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'start', []) - table_list = self.table_list(_context) - self._scan('"$"', context=_context) - return table_list - - def table_list(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'table_list', []) - while 1: - table_section = self.table_section(_context) - if self._peek('DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', '"$"', 'IF', 'IFNOT', 'COLON', 'name', 'hostgroup', 'CMD', context=_context) not in ['DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP']: break - - def table_section(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'table_section', []) - _token = self._peek('DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', context=_context) - if _token == 'DEBUG': - DEBUG = self._scan('DEBUG', context=_context) - string = self._scan('string', context=_context) - print("-->debug: %s"%string) - elif _token == 'HOSTGROUP': - hostgroup_def = self.hostgroup_def(_context) - elif _token == 'CONDITIONS': - CONDITIONS = self._scan('CONDITIONS', context=_context) - nodes.declare_conditions( CONDITIONS, self._scanner.filename ) - elif _token == 'TABLE': - TABLE = self._scan('TABLE', context=_context) - tablename = self._scan('tablename', context=_context) - table_name = tablename - HOST = self._scan('HOST', context=_context) - hostlist = [ ] - while 1: - _token = self._peek('name', 'hostgroup', context=_context) - if _token == 'name': - name = self._scan('name', context=_context) - hostlist.append(name) - else: # == 'hostgroup' - hostgroup = self._scan('hostgroup', context=_context) - hostlist = hostlist + nodes.get_hostgroup( hostgroup ) - if self._peek('name', 'hostgroup', 'IF', 'IFNOT', 'CMD', context=_context) not in ['name', 'hostgroup']: break - while 1: - cond_command = self.cond_command(tablename,hostlist, _context) - if self._peek('IF', 'IFNOT', 'CMD', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'COLON', 'name', 'hostgroup', context=_context) not in ['IF', 'IFNOT', 'CMD']: break - else: # == 'IMPORT' - IMPORT = self._scan('IMPORT', context=_context) - string = self._scan('string', context=_context) - self.data.import_list.append( string[1:-1] ) - - def hostgroup_def(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'hostgroup_def', []) - HOSTGROUP = self._scan('HOSTGROUP', context=_context) - hostgroup = self._scan('hostgroup', context=_context) - nodes.define_hostgroup( hostgroup) - while 1: - hostgroup_front = self.hostgroup_front(hostgroup, _context) - hostgroup_back = self.hostgroup_back(hostgroup,hostgroup_front, _context) - if self._peek('IF', 'IFNOT', 'COLON', 'name', 'hostgroup', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'CMD', context=_context) not in ['IF', 'IFNOT', 'COLON']: break - - def hostgroup_front(self, hg, _parent=None): - _context = self.Context(_parent, self._scanner, 'hostgroup_front', [hg]) - _token = self._peek('IF', 'IFNOT', 'COLON', context=_context) - if _token == 'IF': - IF = self._scan('IF', context=_context) - name = self._scan('name', context=_context) - return nodes.check_condition(name, self._scanner.filename ) - elif _token == 'IFNOT': - IFNOT = self._scan('IFNOT', context=_context) - name = self._scan('name', context=_context) - return not nodes.check_condition(name, self._scanner.filename ) - else: # == 'COLON' - return True - - def hostgroup_back(self, hg,accept_nodes, _parent=None): - _context = self.Context(_parent, self._scanner, 'hostgroup_back', [hg,accept_nodes]) - COLON = self._scan('COLON', context=_context) - while self._peek('name', 'hostgroup', 'IF', 'IFNOT', 'COLON', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'CMD', context=_context) in ['name', 'hostgroup']: - _token = self._peek('name', 'hostgroup', context=_context) - if _token == 'name': - name = self._scan('name', context=_context) - if accept_nodes : nodes.add_hostgroup( hg, name ) - else: # == 'hostgroup' - hostgroup = self._scan('hostgroup', context=_context) - if accept_nodes : nodes.add_hostgroup( hg, hostgroup ) - - def cond_command(self, table_name,hostlist, _parent=None): - _context = self.Context(_parent, self._scanner, 'cond_command', [table_name,hostlist]) - _token = self._peek('IF', 'IFNOT', 'CMD', context=_context) - if _token == 'IF': - IF = self._scan('IF', context=_context) - name = self._scan('name', context=_context) - COLON = self._scan('COLON', context=_context) - command = self.command(_context) - if nodes.check_condition(name, self._scanner.filename ) : self.data.add_command_list( table_name, hostlist, [ command ] ) - elif _token == 'IFNOT': - IFNOT = self._scan('IFNOT', context=_context) - name = self._scan('name', context=_context) - COLON = self._scan('COLON', context=_context) - command = self.command(_context) - if not nodes.check_condition(name, self._scanner.filename ) : self.data.add_command_list( table_name, hostlist, [ command ] ) - else: # == 'CMD' - command = self.command(_context) - self.data.add_command_list( table_name, hostlist, [ command ] ) - - def command(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'command', []) - CMD = self._scan('CMD', context=_context) - cmd_pos = self._scanner.get_pos() - script_type = 'l' - resources = { 'cpu' : 1 } - cmdname = self._scan('cmdname', context=_context) - cmd_name=cmdname; script=cmdname; x_after_clause = [ ] - if self._peek('RUN', 'LOCAL', 'RESOURCE', 'AFTER', 'IF', 'IFNOT', 'CMD', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'COLON', 'name', 'hostgroup', context=_context) in ['RUN', 'LOCAL']: - _token = self._peek('RUN', 'LOCAL', context=_context) - if _token == 'RUN': - RUN = self._scan('RUN', context=_context) - string = self._scan('string', context=_context) - script = string[1:-1]; script_type='r' - else: # == 'LOCAL' - LOCAL = self._scan('LOCAL', context=_context) - string = self._scan('string', context=_context) - script = string[1:-1]; script_type='l' - while self._peek('RESOURCE', 'AFTER', 'IF', 'IFNOT', 'CMD', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'COLON', 'name', 'hostgroup', context=_context) in ['RESOURCE', 'AFTER']: - after_pos = self._scanner.get_pos() - if self._peek('RESOURCE', 'AFTER', context=_context) == 'RESOURCE': - RESOURCE = self._scan('RESOURCE', context=_context) - resource_defs = self.resource_defs(_context) - resources.update(resource_defs) - AFTER = self._scan('AFTER', context=_context) - optword = self.optword(_context) - after_spec = self.after_spec(_context) - x_after_clause.append( (after_spec, optword, after_pos) ) - return ( cmd_name, script, script_type, x_after_clause, cmd_pos, resources ) - - def resource_defs(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'resource_defs', []) - rl = { } - while self._peek('name', 'AFTER', context=_context) == 'name': - name = self._scan('name', context=_context) - self._scan('"="', context=_context) - _token = self._peek('number', 'RES_ALL', 'RES_AVAILABLE', context=_context) - if _token == 'number': - number = self._scan('number', context=_context) - ans = int(number) - elif _token == 'RES_ALL': - RES_ALL = self._scan('RES_ALL', context=_context) - ans = 'all' - else: # == 'RES_AVAILABLE' - RES_AVAILABLE = self._scan('RES_AVAILABLE', context=_context) - ans = 'available' - rl[name] = ans - print(rl) ; return rl - - def optword(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'optword', []) - _token = self._peek('OPT', 'wildname', context=_context) - if _token == 'OPT': - OPT = self._scan('OPT', context=_context) - return 0 - else: # == 'wildname' - return 1 - - def after_spec(self, _parent=None): - _context = self.Context(_parent, self._scanner, 'after_spec', []) - wildname = self._scan('wildname', context=_context) - rval = wildname - if self._peek('COLON', 'SLASH', 'RESOURCE', 'AFTER', 'IF', 'IFNOT', 'CMD', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'name', 'hostgroup', context=_context) == 'COLON': - COLON = self._scan('COLON', context=_context) - wildname = self._scan('wildname', context=_context) - rval = rval + ':' + wildname - if self._peek('SLASH', 'RESOURCE', 'AFTER', 'IF', 'IFNOT', 'CMD', '"$"', 'DEBUG', 'CONDITIONS', 'TABLE', 'IMPORT', 'HOSTGROUP', 'COLON', 'name', 'hostgroup', context=_context) == 'SLASH': - SLASH = self._scan('SLASH', context=_context) - wildname = self._scan('wildname', context=_context) - rval = rval + '/' + wildname - return rval - - -def parse(rule, text): - P = specfile(specfileScanner(text)) - return wrap_error_reporter(P, rule) - -# End -- grammar generated by Yapps - - - |