예제 #1
0
    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
예제 #2
0
    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
예제 #3
0
        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
예제 #5
0
    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
예제 #7
0
    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
예제 #8
0
            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
예제 #9
0
    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
예제 #10
0
    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
예제 #12
0
    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
예제 #13
0
    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
예제 #14
0
        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_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
예제 #16
0
    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
예제 #17
0
        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()))
예제 #18
0
    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
예제 #19
0
    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
예제 #21
0
        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
예제 #22
0
    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
예제 #23
0
        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()))
예제 #24
0
    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
예제 #25
0
    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
예제 #26
0
    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
예제 #30
0
    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_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
예제 #32
0
        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())}
예제 #33
0
    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
예제 #34
0
    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
예제 #35
0
    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
예제 #36
0
    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
예제 #37
0
    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
예제 #38
0
    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
예제 #40
0
    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
예제 #41
0
    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
예제 #42
0
        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
예제 #43
0
    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
예제 #44
0
    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
예제 #45
0
    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
예제 #46
0
    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
예제 #47
0
        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())
            }
예제 #48
0
        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
예제 #49
0
        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
예제 #50
0
    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
예제 #52
0
    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 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()))
예제 #55
0
    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 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
예제 #57
0
    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
예제 #58
0
    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
        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()))