def generate_or(me, pattern, peg, result, stream, failure, tail, peg_args): data = "" success = gensym("success") for pattern in pattern.patterns: # TODO: lazily create this out = gensym("or") my_result = newResult() fail = lambda : "goto %s;" % out if pattern == pattern.patterns[-1]: fail = failure data += """ { Result %(new-result)s(%(result)s.getPosition()); %(code)s %(result)s = %(new-result)s; } goto %(success)s; %(out)s: """ % {'new-result': my_result, 'result': result, 'code': pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip(), 'success': success, 'out': out} data += "%s:\n" % success return data
def generate_or(me, pattern, peg, result, stream, failure, tail, peg_args): data = "" success = gensym("success") for pattern in pattern.patterns: # TODO: lazily create this out = gensym("or") my_result = newResult() fail = lambda: "goto %s;" % out if pattern == pattern.patterns[-1]: fail = failure data += """ { Result %(new-result)s(%(result)s.getPosition()); %(code)s %(result)s = %(new-result)s; } goto %(success)s; %(out)s: """ % { 'new-result': my_result, 'result': result, 'code': pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip(), 'success': success, 'out': out } data += "%s:\n" % success return data
def generate_repeat_many(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: ; """ % { '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 } return data
def generate_not(me, pattern, peg, result, stream, failure, tail, peg_args): not_label = gensym("not") my_result = newResult() my_fail = lambda: "goto %s;" % not_label data = """ Result %(new-result)s(%(result)s); %(code)s %(fail)s %(not)s: %(result)s.setValue(Value((void*)0)); """ % { 'new-result': my_result, 'result': result, 'code': pattern.next.generate_cpp(peg, my_result, stream, my_fail, None, peg_args).strip(), 'fail': failure(), 'not': not_label, 'result': result } 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_bind(me, pattern, peg, result, stream, failure, tail, peg_args): if pattern.pattern.isLineInfo(): name = gensym("line_info") data = """ Stream::LineInfo %(name)s = %(stream)s.getLineInfo(%(result)s.getPosition()); %(variable)s = &%(name)s; """ % { 'name': name, 'stream': stream, 'result': result, 'variable': pattern.variable } else: data = """ %(code)s %(variable)s = %(result)s.getValues(); """ % { 'code': pattern.pattern.generate_cpp(peg, result, stream, failure, tail, peg_args).strip(), 'variable': pattern.variable, 'result': 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 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_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_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_maybe(me, pattern, result, previous_result, stream, failure): save = gensym("save") fail = lambda : """ %s = Result.new(%s) %s.setValue(nil) """ % (result, save, result) data = """ %s = %s.getPosition() %s """ % (save, result, pattern.pattern.generate_v1(me, result, previous_result, stream, fail)) return data
def generate_maybe(me, pattern, peg, result, stream, failure, tail, peg_args): save = gensym("save") fail = lambda: """ %s = Result(%s); %s.setValue(Value((void*) 0)); """ % (result, save, result) data = """ int %s = %s.getPosition(); %s """ % (save, result, pattern.pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)) return data
def generate_maybe(me, pattern, result, previous_result, stream, failure): save = gensym("save") fail = lambda: """ %s = Result(%s) %s.setValue(None) """ % (result, save, result) data = """ %s = %s.getPosition() %s """ % (save, result, pattern.pattern.generate_python(result, previous_result, stream, fail)) 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_or(me, pattern, result, previous_result, stream, failure): data = "" fail = failure save = gensym("save") for next_pattern in pattern.patterns[::-1]: data = """ %s = Result(%s) %s """ % (result, save, next_pattern.generate_python(result, previous_result, stream, fail).strip()) fail = lambda : data return """ %s = %s.getPosition() %s """ % (save, result, data)
def generate_or(me, pattern, peg, result, stream, failure, tail, peg_args): data = "" success = gensym("success") for pattern in pattern.patterns: # TODO: lazily create this out = gensym("or") my_result = newResult() fail = lambda: "goto %s;" % out if pattern == pattern.patterns[-1]: fail = failure data += """ { Result %s(%s.getPosition()); %s %s = %s; } goto %s; %s: """ % (my_result, result, pattern.generate_cpp(peg, my_result, stream, fail, tail, peg_args).strip(), result, my_result, success, out) data += "%s:\n" % success 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_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_maybe(me, pattern, peg, result, stream, failure, tail, peg_args): save = gensym("save") fail = lambda: """ %(result)s = Result(%(save)s); %(result)s.setValue(Value((void*) 0)); """ % {'result': result, 'save': save} data = """ int %(save)s = %(result)s.getPosition(); %(code)s """ % {'save': save, 'result': result, 'code': pattern.pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)} 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, 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 generate_or(me, pattern, result, previous_result, stream, failure): data = "" fail = failure save = gensym("save") for next_pattern in pattern.patterns[::-1]: data = """ %s = Result(%s) %s """ % (result, save, next_pattern.generate_python(result, previous_result, stream, fail).strip()) fail = lambda: data return """ %s = %s.getPosition() %s """ % (save, result, data)
def generate_bind(me, pattern, peg, result, stream, failure, tail, peg_args): if pattern.pattern.isLineInfo(): name = gensym("line_info") data = """ Stream::LineInfo %s = %s.getLineInfo(%s.getPosition()); %s = &%s; """ % (name, stream, result, pattern.variable, name) else: data = """ %s %s = %s.getValues(); """ % (pattern.pattern.generate_cpp( peg, result, stream, failure, tail, peg_args).strip(), pattern.variable, result) 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*) (intptr_t) %(temp)s)); %(result)s.nextPosition(); } else { %(fail)s } """ % { 'temp': gensym(), 'stream': stream, 'result': result, 'fail': indent(failure()) } return data
def generate_not(me, pattern, peg, result, stream, failure, tail, peg_args): not_label = gensym("not") my_result = newResult() my_fail = lambda: "goto %s;" % not_label data = """ Result %s(%s); %s %s %s: %s.setValue(Value((void*)0)); """ % (my_result, result, pattern.next.generate_cpp( peg, my_result, stream, my_fail, None, peg_args).strip(), failure(), not_label, result) return data
def generate_repeat_many(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: ; """ % {'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} return data
def generate_not(me, pattern, peg, result, stream, failure, tail, peg_args): not_label = gensym("not") my_result = newResult() my_fail = lambda : "goto %s;" % not_label data = """ Result %(new-result)s(%(result)s); %(code)s %(fail)s %(not)s: %(result)s.setValue(Value((void*)0)); """ % {'new-result': my_result, 'result': result, 'code': pattern.next.generate_cpp(peg, my_result, stream, my_fail, None, peg_args).strip(), 'fail': failure(), 'not': not_label, 'result': result} return data
def generate_bind(me, pattern, peg, result, stream, failure, tail, peg_args): if pattern.pattern.isLineInfo(): name = gensym("line_info"); data = """ Stream::LineInfo %(name)s = %(stream)s.getLineInfo(%(result)s.getPosition()); %(variable)s = &%(name)s; """ % {'name': name, 'stream': stream, 'result': result, 'variable': pattern.variable} else: data = """ %(code)s %(variable)s = %(result)s.getValues(); """ % {'code': pattern.pattern.generate_cpp(peg, result, stream, failure, tail, peg_args).strip(), 'variable': pattern.variable, 'result': result} 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*) (intptr_t) %(letter)s)); } else { %(failure)s } """ % { 'letter': letter, 'stream': stream, 'result': result, 'range': pattern.range, 'failure': 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() old_data = """ { Result %s(%s.getPosition()); %s %s = %s; } %s %s """ % (my_result, result, pattern_result, result, my_result, success, label(out[0])) data = """ { int %s = %s.getPosition(); %s } %s %s """ % (previous_position, result, indent(pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)), success, label(out[0])) return data
def generate_repeat_many(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: ; """ % (result, my_result, result, indent( pattern.next.generate_cpp( peg, my_result, stream, my_fail, tail, peg_args).strip()), result, my_result, loop_done) 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_maybe(me, pattern, peg, result, stream, failure, tail, peg_args): save = gensym("save") fail = lambda: """ %(result)s = Result(%(save)s); %(result)s.setValue(Value((void*) 0)); """ % { 'result': result, 'save': save } data = """ int %(save)s = %(result)s.getPosition(); %(code)s """ % { 'save': save, 'result': result, 'code': pattern.pattern.generate_cpp(peg, result, stream, fail, tail, peg_args) } 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() old_data = """ { Result %s(%s.getPosition()); %s %s = %s; } %s %s """ % (my_result, result, pattern_result, result, my_result, success, label(out[0])) data = """ { int %s = %s.getPosition(); %s } %s %s """ % (previous_position, result, indent(pattern.generate_cpp(peg, result, stream, fail, tail, peg_args)), success, label(out[0])) return data success_out = gensym('success') data = """ %s %s %s: ; """ % ('\n'.join([ newPattern(pattern, stream, result, "goto %s;" % success_out).strip() for pattern in rule.patterns ]), failure(), 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 = """ %s = rule_%s(%s, %s.getPosition()%s%s); if (%s.error()){ %s } """ % (result, pattern.rule, 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