def generate_repeat_once(me, pattern, peg, result, stream, failure, tail, peg_args): loop_done = gensym("loop") my_fail = lambda: "goto %s;" % loop_done my_result = newResult() data = """ %(result)s.reset(); do{ Result %(new-result)s(%(result)s.getPosition()); %(code)s %(result)s.addResult(%(new-result)s); } while (true); %(loop-done)s: if (%(result)s.matches() == 0){ %(fail)s } """ % { 'result': result, 'new-result': my_result, 'code': indent( pattern.next.generate_cpp(peg, my_result, stream, my_fail, tail, peg_args).strip()), 'loop-done': loop_done, 'fail': indent(failure()) } return data
def generate_repeat_once(me, pattern, result, previous_result, stream, failure): my_fail = lambda: "raise PegError" my_result = newResult() my_result2 = newResult() data = """ begin while (true) %s = Result.new(%s.getPosition()) %s %s.addResult(%s) end rescue PegError if %s.matches() == 0 %s end end """ % (my_result, result, indent( indent( pattern.next.generate_v1(me, my_result, result, stream, my_fail).strip())), result, my_result, result, failure()) return data
def doString(): length = len(pattern.letters) if special_char(pattern.letters): length = 1 comparison = "compareChar" if pattern.options == "{case}": comparison = "compareCharCase" data = """ %(result)s.setValue(Value((void*) "%(string)s")); for (int i = 0; i < %(length)d; i++){ if (%(compare)s("%(string)s"[i], %(stream)s.get(%(result)s.getPosition()))){ %(result)s.nextPosition(); } else { %(failure)s } } """ % { 'result': result, 'string': pattern.letters.replace('"', '\\"'), 'length': length, 'compare': comparison, 'stream': stream, 'failure': indent(indent(failure())) } return data
def generate_repeat_many(me, pattern, result, previous_result, stream, failure): my_fail = lambda : "raise PegError" my_result = newResult() data = """ try: while True: %s = Result(%s.getPosition()); %s %s.addResult(%s); except PegError: pass """ % (my_result, result, indent(indent(pattern.next.generate_python(my_result, result, stream, my_fail).strip())), result, my_result) return data
def generate_sequence(me, pattern, peg, result, stream, failure, tail, peg_args): if len(pattern.patterns) == 1: return pattern.patterns[0].generate_cpp(peg, result, stream, failure, tail, peg_args) else: # for each pattern, save the result in a temporary variable. only create # temporaries if the result is used. looking up a variable through the # 'args' accessor tells the code generator to generate the variable data = [] def invalid(d): raise Exception("Invalid result %s" % d) args = invalid use_args = [] arg_num = 0 fail = False for apattern in pattern.patterns: use_args.append("") do_tail = None if apattern == pattern.patterns[-1]: do_tail = tail else: # lexical scope is broken so we need another function here def make(n, old_arg, my_result): def get(d): # print "Looking for %s arg_num is %d result is %s. previous is %s" % (d, n, my_result, old_arg) if d == n: use_args[n - 1] = "Result %s = %s;" % (my_result, result) return my_result return old_arg(d) return get arg_num += 1 args = make(arg_num, args, newResult()) data.append(""" %s """ % (indent( apattern.generate_cpp(peg, result, stream, failure, do_tail, args).strip()))) return "{\n%s\n}" % indent('\n'.join( ["%s\n%s" % (x[0], x[1]) for x in zip(data, use_args)]))
def generate_repeat_many(me, pattern, result, previous_result, stream, failure): my_fail = lambda : "raise PegError" my_result = newResult() data = """ begin while true %s = Result.new(%s.getPosition()) %s %s.addResult(%s) end rescue PegError end """ % (my_result, result, indent(indent(pattern.next.generate_v1(me, my_result, result, stream, my_fail).strip())), result, my_result) return data
def generate_rule(me, pattern, result, previous_result, stream, failure): def fix(v): return "%s.getValues()[%s]" % (previous_result, int(v.group(1)) - 1) def change(arg): if arg.startswith('@'): return arg[1:] return 'lambda{|*args| rule_%s(*args)}' % arg rule_parameters = "" if pattern.rules != None: rule_parameters = ", %s" % ", ".join( [change(f) for f in pattern.rules]) parameters = "" if pattern.parameters != None: parameters = ", %s" % ",".join( [me.fixup_ruby(p, fix) for p in pattern.parameters]) data = """ # puts "Trying rule '%s'" %s = rule_%s(%s, %s.getPosition()%s%s) if %s == nil %s end """ % (pattern.rule, result, pattern.rule, stream, result, rule_parameters, parameters, result, indent(failure())) return data
def newPattern(pattern, stream, result, success): # my_result = newResult() previous_position = gensym('position') out = [False] def label(n): if n != False: return "%s:" % n return "" def fail(): if out[0] == False: out[0] = newOut() return "%s.setPosition(%s);\ngoto %s;" % (result, previous_position, out[0]) # pattern_result = pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip() data = """ { int %(previous)s = %(result)s.getPosition(); %(code)s } %(success)s %(label)s """ % {'previous': previous_position, 'result': result, 'code': indent(pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)), 'success': success, 'label': label(out[0])} return data
def generate_call_rule(me, pattern, peg, result, stream, failure, tail, peg_args): def change(arg): if arg.startswith('@'): return arg[1:] return 'rule_%s' % arg rule_parameters = "" if pattern.rules != None: rule_parameters = ", %s" % ", ".join( [change(f) for f in pattern.rules]) parameters = "" if pattern.values != None: parameters = ", %s" % ", ".join( [me.fixup_cpp(p, peg_args) for p in pattern.values]) # parameters = ", %s" % fix_param(pattern.parameters) def argify(name, many): if many == None or len(many) == 0: return "" return ", " + ",".join([name] * len(many)) cast = "Result (*)(Stream &, const int%s%s)" % (argify( 'void *', pattern.rules), argify('Value', pattern.values)) data = """ %s = ((%s) %s)(%s, %s.getPosition()%s%s); if (%s.error()){ %s } """ % (result, cast, pattern.name, stream, result, rule_parameters, parameters, result, indent(failure())) return data
def generate_call_rule(me, pattern, result, previous_result, stream, failure): def fix(v): return "%s.getValues()[%s]" % (previous_result, int(v.group(1)) - 1) def change(arg): if arg.startswith('@'): return arg[1:] return 'rule_%s' % arg rule_parameters = "" if pattern.rules != None: rule_parameters = ", %s" % ", ".join( [change(f) for f in pattern.rules]) parameters = "" if pattern.values != None: parameters = ", %s" % ",".join( [me.fixup_python(p, fix) for p in pattern.values]) data = """ # print "Trying rule " + '%s' %s = %s(%s, %s.getPosition()%s%s) if %s == None: %s """ % (pattern.name, result, pattern.name, stream, result, rule_parameters, parameters, result, indent(failure())) return data
def generate_eof(me, pattern, result, previous_result, stream, failure): data = """ if chr(0) == %s.get(%s.getPosition()): %s.nextPosition() %s.setValue(chr(0)) else: %s """ % (stream, result, result, result, indent(failure())) return data
def generate_eof(me, pattern, result, previous_result, stream, failure): data = """ if 0.chr() == %s.get(%s.getPosition()) then %s.nextPosition() %s.setValue(0.chr()) else %s end """ % (stream, result, result, result, indent(failure())) return data
def doAscii(): data = """ if ord(%s.get(%s.getPosition())) == %s: %s.nextPosition() %s.setValue(%s); else: %s """ return data % (stream, result, pattern.letters, result, result, pattern.letters, indent(failure()))
def generate_code(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ { Value value((void*) 0); %(code)s %(result)s.setValue(value); } """ % {'code': me.fixup_cpp(indent(pattern.code.strip()), peg_args), 'result': result} return data
def doAscii(): data = """ if %s.get(%s.getPosition()).ord() == %s then %s.nextPosition() %s.setValue(%s) else %s end """ return data % (stream, result, pattern.letters, result, result, pattern.letters, indent(failure()))
def generate_eof(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ if ('\\0' == %s.get(%s.getPosition())){ %s.nextPosition(); %s.setValue(Value((void *) '\\0')); } else { %s } """ % (stream, result, result, result, indent(failure())) return data
def generate_code(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ { Value value((void*) 0); %s %s.setValue(value); } """ % (me.fixup_cpp(indent(pattern.code.strip()), peg_args), result) return data
def generate_any(me, pattern, result, previous_result, stream, failure): temp = gensym() data = """ %s = %s.get(%s.getPosition()) if %s != chr(0): %s.setValue(%s) %s.nextPosition() else: %s """ % (temp, stream, result, temp, result, temp, result, indent(failure())) return data
def doString(): length = len(pattern.letters) if special_char(pattern.letters): length = 1 comparison = "compareChar" if pattern.options == "{case}": comparison = "compareCharCase" data = """ %s.setValue(Value((void*) "%s")); for (int i = 0; i < %d; i++){ if (%s("%s"[i], %s.get(%s.getPosition()))){ %s.nextPosition(); } else { %s } } """ % (result, pattern.letters.replace('"', '\\"'), length, comparison, pattern.letters.replace( '"', '\\"'), stream, result, result, indent(indent(failure()))) return data
def generate_repeat_many(me, pattern, result, previous_result, stream, failure): my_fail = lambda: "raise PegError" my_result = newResult() data = """ try: while True: %s = Result(%s.getPosition()); %s %s.addResult(%s); except PegError: pass """ % (my_result, result, indent( indent( pattern.next.generate_python( my_result, result, stream, my_fail).strip())), result, my_result) return data
def doAscii(): data = """ %s.setValue(Value((void*) %s)); if ((unsigned char) %s.get(%s.getPosition()) == (unsigned char) %s){ %s.nextPosition(); } else { %s } """ return data % (result, pattern.letters, stream, result, pattern.letters, result, indent(failure()))
def generate_eof(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ if ('\\0' == %(stream)s.get(%(result)s.getPosition())){ %(result)s.nextPosition(); %(result)s.setValue(Value((void *) '\\0')); } else { %(fail)s } """ % {'stream': stream, 'result': result, 'fail': indent(failure())} return data
def generate_repeat_many(me, pattern, result, previous_result, stream, failure): my_fail = lambda: "raise PegError" my_result = newResult() data = """ begin while true %s = Result.new(%s.getPosition()) %s %s.addResult(%s) end rescue PegError end """ % (my_result, result, indent( indent( pattern.next.generate_v1( me, my_result, result, stream, my_fail).strip())), result, my_result) return data
def generate_range(me, pattern, result, previous_result, stream, failure): letter = gensym("letter") data = """ %s = %s.get(%s.getPosition()) if '%s'.index(%s) != nil then %s.nextPosition() %s.setValue(%s) else %s end """ % (letter, stream, result, pattern.range, letter, result, result, letter, indent(failure())) return data
def generate_maybe(me, pattern, result, previous_result, stream, failure): save = gensym("save") fail = lambda : """raise PegError""" data = """ try: %s = %s.getPosition() %s except PegError: %s = Result(%s) %s.setValue(None) """ % (save, result, indent(pattern.pattern.generate_python(result, previous_result, stream, fail)), result, save, result) return data
def generate_range(me, pattern, result, previous_result, stream, failure): letter = gensym("letter") data = """ %s = %s.get(%s.getPosition()) if %s in '%s': %s.nextPosition() %s.setValue(%s) else: %s """ % (letter, stream, result, letter, pattern.range, result, result, letter, indent(failure())) return data
def generate_not(me, pattern, result, previous_result, stream, failure): my_result = newResult() my_fail = lambda : "raise NotError" data = """ %s = Result(%s.getPosition()); try: %s %s except NotError: %s.setValue(None) """ % (my_result, result, indent(pattern.next.generate_python(my_result, result, stream, my_fail).strip()), failure(), result) return data
def doAscii(): data = """ %(result)s.setValue(Value((void*) %(string)s)); if ((unsigned char) %(stream)s.get(%(result)s.getPosition()) == (unsigned char) %(string)s){ %(result)s.nextPosition(); } else { %(failure)s } """ return data % {'result': result, 'string': pattern.letters, 'stream': stream, 'failure': indent(failure())}
def generate_predicate(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ { bool %(variable)s = true; %(code)s if (!%(variable)s){ %(fail)s } } """ % {'variable': pattern.variable, 'code': me.fixup_cpp(indent(pattern.code.strip()), peg_args), 'fail': failure()} return data
def generate_repeat_once(me, pattern, peg, result, stream, failure, tail, peg_args): loop_done = gensym("loop") my_fail = lambda : "goto %s;" % loop_done my_result = newResult() data = """ %(result)s.reset(); do{ Result %(new-result)s(%(result)s.getPosition()); %(code)s %(result)s.addResult(%(new-result)s); } while (true); %(loop-done)s: if (%(result)s.matches() == 0){ %(fail)s } """ % {'result': result, 'new-result': my_result, 'code': indent(pattern.next.generate_cpp(peg, my_result, stream, my_fail, tail, peg_args).strip()), 'loop-done': loop_done, 'fail': indent(failure())} return data
def generate_any(me, pattern, peg, result, stream, failure, tail, peg_args): temp = gensym() data = """ char %s = %s.get(%s.getPosition()); if (%s != '\\0'){ %s.setValue(Value((void*) (long) %s)); %s.nextPosition(); } else { %s } """ % (temp, stream, result, temp, result, temp, result, indent(failure())) return data
def generate_predicate(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ { bool %s = true; %s if (!%s){ %s } } """ % (pattern.variable, me.fixup_cpp(indent(pattern.code.strip()), peg_args), pattern.variable, failure()) return data
def generate_sequence(me, pattern, peg, result, stream, failure, tail, peg_args): if len(pattern.patterns) == 1: return pattern.patterns[0].generate_cpp(peg, result, stream, failure, tail, peg_args) else: # for each pattern, save the result in a temporary variable. only create # temporaries if the result is used. looking up a variable through the # 'args' accessor tells the code generator to generate the variable data = [] def invalid(d): raise Exception("Invalid result %s" % d) args = invalid use_args = [] arg_num = 0 fail = False for apattern in pattern.patterns: use_args.append("") do_tail = None if apattern == pattern.patterns[-1]: do_tail = tail else: # lexical scope is broken so we need another function here def make(n, old_arg, my_result): def get(d): # print "Looking for %s arg_num is %d result is %s. previous is %s" % (d, n, my_result, old_arg) if d == n: use_args[n-1] = "Result %s = %s;" % (my_result, result) return my_result return old_arg(d) return get arg_num += 1 args = make(arg_num, args, newResult()) data.append(""" %s """ % (indent(apattern.generate_cpp(peg, result, stream, failure, do_tail, args).strip()))) return "{\n%s\n}" % indent('\n'.join(["%s\n%s" % (x[0], x[1]) for x in zip(data, use_args)]))
def generate_not(me, pattern, result, previous_result, stream, failure): my_result = newResult() my_fail = lambda : "raise NotError" data = """ %s = Result.new(%s.getPosition()) begin %s %s rescue NotError %s.setValue(nil) end """ % (my_result, result, indent(pattern.next.generate_v1(my_result, result, stream, my_fail).strip()), failure(), result) return data
def generate_range(me, pattern, peg, result, stream, failure, tail, peg_args): letter = gensym("letter") data = """ char %s = %s.get(%s.getPosition()); if (%s != '\\0' && strchr("%s", %s) != NULL){ %s.nextPosition(); %s.setValue(Value((void*) (long) %s)); } else { %s } """ % (letter, stream, result, letter, pattern.range, letter, result, result, letter, indent(failure())) return data
def generate_repeat_once(me, pattern, peg, result, stream, failure, tail, peg_args): loop_done = gensym("loop") my_fail = lambda: "goto %s;" % loop_done my_result = newResult() data = """ %s.reset(); do{ Result %s(%s.getPosition()); %s %s.addResult(%s); } while (true); %s: if (%s.matches() == 0){ %s } """ % (result, my_result, result, indent( pattern.next.generate_cpp(peg, my_result, stream, my_fail, tail, peg_args).strip()), result, my_result, loop_done, result, indent(failure())) return data
def doString(): length = len(pattern.letters) if special_char(pattern.letters): length = 1 data = """ if '%s' == %s.get(%s.getPosition(), %s) then %s.nextPosition(%s) %s.setValue('%s') else %s end """ % (pattern.letters, stream, result, length, result, length, result, pattern.letters, indent(failure())) return data
def generate_any(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ char %(temp)s = %(stream)s.get(%(result)s.getPosition()); if (%(temp)s != '\\0'){ %(result)s.setValue(Value((void*) (long) %(temp)s)); %(result)s.nextPosition(); } else { %(fail)s } """ % {'temp': gensym(), 'stream': stream, 'result': result, 'fail': indent(failure())} return data
def generate_code(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ { Value value((void*) 0); %(code)s %(result)s.setValue(value); } """ % { 'code': me.fixup_cpp(indent(pattern.code.strip()), peg_args), 'result': result } return data
def generate_eof(me, pattern, peg, result, stream, failure, tail, peg_args): data = """ if ('\\0' == %(stream)s.get(%(result)s.getPosition())){ %(result)s.nextPosition(); %(result)s.setValue(Value((void *) '\\0')); } else { %(fail)s } """ % { 'stream': stream, 'result': result, 'fail': indent(failure()) } return data
def generate_maybe(me, pattern, result, previous_result, stream, failure): save = gensym("save") fail = lambda: """raise PegError""" data = """ try: %s = %s.getPosition() %s except PegError: %s = Result(%s) %s.setValue(None) """ % (save, result, indent( pattern.pattern.generate_python(result, previous_result, stream, fail)), result, save, result) return data
def doAscii(): data = """ %(result)s.setValue(Value((void*) %(string)s)); if ((unsigned char) %(stream)s.get(%(result)s.getPosition()) == (unsigned char) %(string)s){ %(result)s.nextPosition(); } else { %(failure)s } """ return data % { 'result': result, 'string': pattern.letters, 'stream': stream, 'failure': indent(failure()) }
def doString(): length = len(pattern.letters) if special_char(pattern.letters): length = 1 import re letters = re.sub(r"'", "\\'", pattern.letters) data = """ if '%s' == %s.get(%s.getPosition(), %s): %s.nextPosition(%s) %s.setValue('%s') else: %s """ % (letters, stream, result, length, result, length, result, letters, indent(failure())) return data
def doString(): length = len(pattern.letters) if special_char(pattern.letters): length = 1 comparison = "compareChar" if pattern.options == "{case}": comparison = "compareCharCase" data = """ %(result)s.setValue(Value((void*) "%(string)s")); for (int i = 0; i < %(length)d; i++){ if (%(compare)s("%(string)s"[i], %(stream)s.get(%(result)s.getPosition()))){ %(result)s.nextPosition(); } else { %(failure)s } } """ % {'result': result, 'string': pattern.letters.replace('"', '\\"'), 'length': length, 'compare': comparison, 'stream': stream, 'failure': indent(indent(failure()))} return data
def generate_range(me, pattern, peg, result, stream, failure, tail, peg_args): letter = gensym("letter") data = """ char %(letter)s = %(stream)s.get(%(result)s.getPosition()); if (%(letter)s != '\\0' && strchr("%(range)s", %(letter)s) != NULL){ %(result)s.nextPosition(); %(result)s.setValue(Value((void*) (long) %(letter)s)); } else { %(failure)s } """ % {'letter': letter, 'stream': stream, 'result': result, 'range': pattern.range, 'failure': indent(failure())} return data
def doString(): length = len(pattern.letters) if special_char(pattern.letters): length = 1 import re letters = re.sub(r"'", "\\'", pattern.letters) if letters == "\n": letters = "\\n" if letters == "\r": letters = "\\r" if letters == "\t": letters = "\\t" data = """ if '%s' == %s.get(%s.getPosition(), %s): %s.nextPosition(%s) %s.setValue('%s') else: %s """ % (letters, stream, result, length, result, length, result, letters, indent(failure())) return data
def generate_call_rule(me, pattern, peg, result, stream, failure, tail, peg_args): def change(arg): if arg.startswith('@'): return arg[1:] return 'rule_%s' % arg rule_parameters = "" if pattern.rules != None: rule_parameters = ", %s" % ", ".join([change(f) for f in pattern.rules]) parameters = "" if pattern.values != None: parameters = ", %s" % ", ".join([me.fixup_cpp(p, peg_args) for p in pattern.values]) # parameters = ", %s" % fix_param(pattern.parameters) def argify(name, many): if many == None or len(many) == 0: return "" return ", " + ",".join([name] * len(many)) cast = "Result (*)(Stream &, const int%s%s)" % (argify('void *', pattern.rules), argify('Value', pattern.values)) data = """ %(result)s = ((%(cast)s) %(name)s)(%(stream)s, %(result)s.getPosition()%(rule-parameters)s%(parameters)s); if (%(result)s.error()){ %(fail)s } """ % {'result': result, 'cast': cast, 'name': pattern.name, 'stream': stream, 'rule-parameters': rule_parameters, 'parameters': parameters, 'result': result, 'fail': indent(failure())} return data
def generate_call_rule(me, pattern, result, previous_result, stream, failure): def fix(v): return "%s.getValues()[%s]" % (previous_result, int(v.group(1)) - 1) def change(arg): if arg.startswith('@'): return arg[1:] return 'lambda{|*args| rule_%s(*args)}' % arg rule_parameters = "" if pattern.rules != None: rule_parameters = ", %s" % ", ".join([change(f) for f in pattern.rules]) parameters = "" if pattern.values != None: parameters = ", %s" % ",".join([me.fixup_ruby(p, fix) for p in pattern.values]) data = """ # print "Trying rule " + '%s' %s = %s.call(%s, %s.getPosition()%s%s) if %s == nil %s end """ % (pattern.name, result, pattern.name, stream, result, rule_parameters, parameters, result, indent(failure())) return data
def generate_rule(me, pattern, peg, result, stream, failure, tail, peg_args): rule = peg.getRule(pattern.rule) if rule != None and rule.isInline(): # TODO: add rule parameters and regular parameters for inlined rules if tail != None: raise Exception("Do not combine inlined rules that use tail recursion") def newPattern(pattern, stream, result, success): # my_result = newResult() previous_position = gensym('position') out = [False] def label(n): if n != False: return "%s:" % n return "" def fail(): if out[0] == False: out[0] = newOut() return "%s.setPosition(%s);\ngoto %s;" % (result, previous_position, out[0]) # pattern_result = pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip() data = """ { int %(previous)s = %(result)s.getPosition(); %(code)s } %(success)s %(label)s """ % {'previous': previous_position, 'result': result, 'code': indent(pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)), 'success': success, 'label': label(out[0])} return data success_out = gensym('success') data = """ %(code)s %(fail)s %(success)s: ; """ % {'code': '\n'.join([newPattern(pattern, stream, result, "goto %s;" % success_out).strip() for pattern in rule.patterns]), 'fail': failure(), 'success': success_out} return data else: # TODO: add rule parameters here if tail != None: if len(tail) == 0: return "" else: if pattern.parameters == None or len(tail) != len(pattern.parameters): raise Exception("Expected parameters %s but got %s while calling rule '%s'" % (tail, pattern.parameters, pattern.rule)) return '\n'.join(["%s = %s;" % (q[0], me.fixup_cpp(q[1], peg_args)) for q in zip(tail, pattern.parameters)]) else: def change(arg): if arg.startswith('@'): return arg[1:] if peg.getRule(arg) == None: raise Exception("Cannot find rule '%s' while trying to call rule '%s'" % (arg, pattern.rule)) return '(void*) rule_%s' % arg rule_parameters = "" if pattern.rules != None: rule_parameters = ", %s" % ", ".join([change(f) for f in pattern.rules]) parameters = "" if pattern.parameters != None: parameters = ", %s" % ", ".join([me.fixup_cpp(p, peg_args) for p in pattern.parameters]) # parameters = ", %s" % fix_param(pattern.parameters) data = """ %(result)s = rule_%(rule)s(%(stream)s, %(result)s.getPosition()%(rule-parameters)s%(parameters)s); if (%(result)s.error()){ %(fail)s } """ % {'result': result, 'rule': pattern.rule, 'stream': stream, 'rule-parameters': rule_parameters, 'parameters': parameters, 'fail': indent(failure())} return data
def singleFile(): result_strings = {'initialize-state': '', 'copy-state-r': '', 'assign-state-r': '', 'get/set-state': '', 'state-id': ''} if self.transactions: result_strings = {'initialize-state': ',\n stateId(0)', 'copy-state-r': ',\n stateId(r.stateId)', 'assign-state-r': 'stateId = r.stateId;', 'get/set-state': indent("""State * getState() const { return state; } void setState(State * state){ this->state = state; } """), 'state-id': maybe_state_id } result_class = result_code % result_strings current_state = '' if self.transactions: current_state = indent("""State * currentState; unsigned int stateId;""") state_functions = '' if self.transactions: state_functions = indent(""" State * getCurrentState(){ return currentState; } State * startTransaction(){ State * newState = State::createState(current); current->setNextState(newState); return newState; } void abortTransaction(State * state){ State * parent = state->getParent(); /* The state should always have a parent because the top most state * will never be aborted. */ if (parent != NULL){ parent->setNextState(NULL); currentState = parent; } } void commitTransaction(State * state){ } unsigned int newId(){ unsigned int use = counter; counter += 1; return use; }""") maybe_initialize_state_counter = '' if self.transactions: maybe_initialize_state_counter = indent("""stateId = 0; currentState = State::createState(NULL);""") strings = {'top-code': top_code, 'namespace-start': namespace_start, 'start-code': start_cpp_code % {'result-class': result_class, 'chunks': chunks, 'initialize-state-counter': maybe_initialize_state_counter, 'state-class': maybe_state_stuff, 'state-functions': state_functions, 'current-state': current_state, 'error-size': self.error_size}, 'rules': '\n'.join([prototype(rule) for rule in use_rules]), 'more-code': more_code, 'generated': '\n'.join([rule.generate_cpp(self, findAccessor(rule)) for rule in use_rules]), 'start': self.start, 'namespace-end': namespace_end} data = """ %(top-code)s #include <list> #include <string> #include <vector> #include <map> #include <fstream> #include <sstream> #include <iostream> #include <string.h> %(namespace-start)s %(start-code)s std::string ParseException::getReason() const { return message; } int ParseException::getLine() const { return line; } int ParseException::getColumn() const { return column; } Result errorResult(-1); %(rules)s %(more-code)s %(generated)s static const void * doParse(Stream & stream, bool stats, const std::string & context){ errorResult.setError(); Result done = rule_%(start)s(stream, 0); if (done.error()){ stream.reportError(context); } if (stats){ stream.printStats(); } return done.getValues().getValue(); } const void * parse(const std::string & filename, bool stats = false){ Stream stream(filename); return doParse(stream, stats, filename); } const void * parse(const char * in, bool stats = false){ Stream stream(in); return doParse(stream, stats, "memory"); } const void * parse(const char * in, int length, bool stats = false){ Stream stream(in, length); return doParse(stream, stats, "memory"); } %(namespace-end)s """ % strings return data
def makeChunks(rules): import math values_per_chunk = self.chunks #values_per_chunk = int(math.sqrt(len(rules))) #if values_per_chunk < 5: # values_per_chunk = 5 all = [] pre = "" chunk_to_rules = {} for i in xrange(0,int(math.ceil(float(len(rules)) / values_per_chunk))): values = rules[i*values_per_chunk:(i+1)*values_per_chunk] name = "Chunk%d" % i chunk_to_rules[name.lower()] = values chunk_accessors.extend([Accessor(".%s" % name.lower(), "->chunk_%s" % rule.name, name, rule) for rule in values]) value_data = """ struct %(name)s{ %(items)s }; """ % {'name': name, 'items': indent("\n".join(["Result chunk_%s;" % rule.name for rule in values]))} all.append(name) pre += value_data def sumChunk(chunk): data = """ (%s != NULL ? (%s) : 0) """ % (chunk, '\n+ '.join(["(%s->chunk_%s.calculated() ? 1 : 0)" % (chunk, rule.name) for rule in chunk_to_rules[chunk]])) return data hit_count = '+'.join([sumChunk(chunk) for chunk in chunk_to_rules.keys()]) # Disable for now hit_count = "0" data = """ %(pre)s struct Column{ Column(): %(initializers)s{ } %(members)s int hitCount(){ return %(hit-count)s; } int maxHits(){ return %(rules)s; } ~Column(){ %(deletes)s } }; """ % {'pre': pre, 'initializers': indent(indent("\n,".join(["%s(0)" % x.lower() for x in all]))), 'members': indent("\n".join(["%s * %s;" % (x, x.lower()) for x in all])), 'hit-count': hit_count, 'rules': len(rules), 'deletes': indent(indent("\n".join(["delete %s;" % x.lower() for x in all])))} return data