def normal_wrapup(fn_word_params, fn_word_offset, args, last_arg, tuple_offset,
                  has_ellipsis, lineno, lexpos):
    print >> Output_file, "    args = []"
    for arg in args: print >> Output_file, "    " + arg
    if fn_word_params is None:
        if not has_ellipsis and len(args) == 1:
            print >> Output_file, "    p[0] = args[0]"
        else:
            print >> Output_file, "    p[0] = tuple(args)"
    else:
        if fn_word_params:
            output("""
              p[0] = ast.ast.from_parser(
                       scanner_init.get_syntax_position_info(p),
                       $kw_args, *args)
              """,
              output_file = Output_file,
              target_indent = 4,
              kw_args = ', '.join("%s=%s" %
                                     (key, value % {'offset': fn_word_offset})
                                     for key, value in fn_word_params))
        elif fn_word_offset is None:
            scanner_init.syntaxerror(
              "empty parameter list on nonterminal declaration",
              lineno = lineno, lexpos = lexpos)
        else:
            output("""
              p[0] = ast.ast.from_parser(
                       scanner_init.get_syntax_position_info(p),
                       p[$offset], *args)
              """,
              output_file = Output_file,
              target_indent = 4,
              offset = fn_word_offset)
def p_parameterized_word(p):
    ''' parameterized_word : simple_word param_list
    '''
    rule_text, type, offset, prep_code, params = p[1]
    if params:
        scanner_init.syntaxerror("duplicate initialization parameters",
                                 lineno=p.lineno(2), lexpos=p.lexpos(2))
    param_list = p[2]
    p[0] = rule_text, 'fn_word', offset, prep_code, param_list
def gen_alternatives(rule_name, alternatives, wrapup_fn, param_list = None):
    for words, lineno, lexpos in alternatives:
        p_fn_name = crud.gensym('p_' + rule_name)
        output("""
            def $fn_name(p):
                r''' $rule_name : $production
                '''
            """,
            output_file = Output_file,
            fn_name = p_fn_name, rule_name = rule_name,
            production = ' '.join(word[0] for word in words))
        prep = []
        args = []
        last_arg = None
        tuple_offset = None
        has_ellipsis = False
        if param_list is not None:
            fn_word_params = param_list
            fn_word_offset = None
        else:
            fn_word_params = None
            fn_word_offset = None
        for i, (rule_text, type, offset, prep_code, params) in enumerate(words):
            if prep_code: prep.append(prep_code % {'offset': offset + i + 1})
            if type == 'fn_word':
                if fn_word_params is not None:
                    scanner_init.syntaxerror(
                      "duplicate function words in production",
                      lineno = lineno, lexpos = lexpos)
                fn_word_offset = offset + i + 1
                fn_word_params = params
            else:
                assert not params, "non function word has parameters"
                if type == 'ignore':
                    pass
                elif type == 'single_arg':
                    args.append('args.append(p[%d])' % (offset + i + 1))
                    last_arg = offset + i + 1
                elif type == 'tuple':
                    args.append('args.append(p[%d])' % (offset + i + 1))
                    if tuple_offset is not None:
                        if not has_ellipsis:
                            tuple_offset = 'dup'
                    else:
                        tuple_offset = i
                elif type == 'ellipsis':
                    args.append('args.extend(p[%d])' % (offset + i + 1))
                    has_ellipsis = True

        if prep:
            print >> Output_file, '\n'.join('    ' + p for p in prep)

        wrapup_fn(fn_word_params, fn_word_offset, args, last_arg, tuple_offset,
                  has_ellipsis, lineno, lexpos)
        print >> Output_file
def wrapup_tuple(fn_word_params, fn_word_offset, args, last_arg, tuple_offset,
                 has_ellipsis, lineno, lexpos):
    if fn_word_params is not None:
        print >> Output_file, "    args = []"
        for arg in args: print >> Output_file, "    " + arg
        if fn_word_params:
            output("""
              p[0] = (ast.ast.from_parser(
                        scanner_init.get_syntax_position_info(p),
                        $kw_args, *args),)
              """,
              output_file = Output_file,
              target_indent = 4,
              kw_args = ', '.join("%s=%s" %
                                    (key, value % {'offset': fn_word_offset})
                                    for key, value in fn_word_params))
        else:
            output("""
              p[0] = (ast.ast.from_parser(
                        scanner_init.get_syntax_position_info(p),
                        p[$offset], *args),)
              """,
              output_file = Output_file,
              target_indent = 4,
              offset = fn_word_offset)
    elif has_ellipsis:
        scanner_init.syntaxerror(
          "ellipsis in production without function word",
          lineno = lineno, lexpos = lexpos)
    elif tuple_offset == 'dup':
        scanner_init.syntaxerror("duplicate tuples in production",
                                 lineno = lineno, lexpos = lexpos)
    elif tuple_offset is None:
        # Make a singleton tuple out of a single argument.
        if len(args) == 1:
            print >> Output_file, "    args = []"
            print >> Output_file, '    ' + args[0]
            print >> Output_file, "    p[0] = tuple(args)"
        else:
            scanner_init.SyntaxError("no tuple in production")
    else:
        print >> Output_file, "    p[0] = p[%d]" % (tuple_offset + 1)