Пример #1
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", "IFX"),
        ("nonassoc", "ELSE"),
        ("right", "="),
        ("left", "OR"),
        ("left", "AND"),
        ("left", "|"),
        ("left", "^"),
        ("left", "&"),
        ("nonassoc", "<", ">", "EQ", "NEQ", "LE", "GE"),
        ("left", "SHL", "SHR"),
        ("left", "+", "-"),
        ("left", "*", "/", "%"),
    )

    def p_error(self, p):
        if not p:
            print("Syntax error at end of input")
        else:
            pass

    def handle_error(self, type, p):
        print(
            "Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(
                p.lineno, self.scanner.find_tok_column(p), p.type, p.value
            )
        )

    def p_program(self, p):
        """program : declarations fundefs_opt instructions_opt"""
        p[0] = Program(p[1], p[2], p[3])

    # declarations

    def p_declarations(self, p):
        """declarations : declarations declaration"""
        if p[2]:
            p[0] = DeclarationList(p[1].dec_list + [p[2]])
        else:
            p[0] = p[1]

    def p_no_declarations(self, p):
        """declarations : """
        p[0] = DeclarationList([])

    # END declarations

    # declaration

    def p_declaration(self, p):
        """declaration : TYPE inits ';'"""
        p[0] = Declaration(p[1], p[2])

    def p_error_declaration(self, p):
        """declaration : error ';'"""
        self.handle_error("declaration", p[1])

    # END declaration

    # inits

    def p_inits(self, p):
        """inits : inits ',' init"""

        p[0] = InitList(p[1].init_list + [p[3]])

    def p_single_init(self, p):
        """inits : init """
        p[0] = InitList([p[1]])

    # END inits

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3])

    # instructions_opt

    def p_instructions_opt(self, p):
        """instructions_opt : instructions"""
        p[0] = p[1]

    def p_empty_instructions_opt(self, p):
        """instructions_opt : """
        p[0] = InstructionList([])

    # END instructions_opt

    # instructions

    def p_instructions(self, p):
        """instructions : instructions instruction"""
        p[0] = InstructionList(p[1].instr_list + [p[2]])

    def p_sinle_instruction(self, p):
        """instructions : instruction """
        p[0] = InstructionList([p[1]])

    # END instructions

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    # print_instr

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'"""
        p[0] = PrintInstr(p[2])

    def p_print_instr_err(self, p):
        """print_instr : PRINT error ';' """
        self.handle_error("print", p[2])

    # END print_instr

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = Labeled_instr(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = Assignment(p[1], p[3])

    # choice_instr

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX """
        p[0] = ChoiceInstr(p[3], p[5])

    def p_choice_instr_with_else(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction """
        p[0] = ChoiceInstr(p[3], p[5], p[7])

    def p_error_choice_instr(self, p):
        """choice_instr : IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        self.handle_error("IF", p[3])

    # END choice)instr

    # while_instr

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction """
        p[0] = WhileInstr(p[3], p[5])

    def p_error_while_instr(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        self.handle_error("while", p[3])

    # END while_instr

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = RepeatInstr(p[4], p[2])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = Return(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = KeyWord("continue")

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = KeyWord("break")

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        p[0] = Compound_instr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = Condition(p[1])

    def p_const_I(self, p):
        """const : INTEGER"""
        p[0] = Integer(p[1])

    def p_const_F(self, p):
        """const : FLOAT"""
        p[0] = Float(p[1])

    def p_const_S(self, p):
        """const : STRING"""
        p[0] = String(p[1])

    # expression

    def p_expression(self, p):
        """expression : ID '(' expr_list_or_empty ')' """
        p[0] = ExpressionIdWithList(p[1], p[3])

    def p_expression_const(self, p):
        """expression : const """
        p[0] = p[1]

    def p_expression_id(self, p):
        """expression : ID """
        p[0] = Id(p[1])

    def p_expression_with_par(self, p):
        """expression : '(' expression ')' """
        p[0] = p[2]

    def p_expression_two_exprs(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression """
        p[0] = BinExpr(p[2], p[1], p[3])

    def p_expression_err(self, p):
        """expression : ID '(' error ')'
                      | '(' error ')'"""
        self.handle_error("Expr", p[2])

    # END expression

    # expr_list_or_empty

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list"""
        p[0] = p[1]

    def p_empty_expr_list(self, p):
        """expr_list_or_empty : """
        p[0] = ExprList([])

    # END expr_list_or_empty

    # expr_list

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression"""
        p[0] = ExprList(p[1].expr_list + [p[3]])

    def p_single_expr(self, p):
        """expr_list : expression """
        p[0] = ExprList([p[1]])

    # END expr_list

    # fundefs_opt

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs"""
        p[0] = p[1]

    def p_empty_fundefs_opt(self, p):
        """fundefs_opt : """
        p[0] = FunctionList([])

    # END fundefs_opt

    # fundefs

    def p_fundefs(self, p):
        """fundefs : fundefs fundef"""
        p[0] = FunctionList(p[1].fun_list + [p[2]])

    def p_single_fundef(self, p):
        """fundefs : fundef """
        p[0] = FunctionList([p[1]])

    # END fundefs

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = Function(p[1], p[2], p[4], p[6])

    # args_list_or_empty

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list"""
        p[0] = p[1]

    def p_empty_args_list(self, p):
        """args_list_or_empty : """
        p[0] = ArgsList([])

    # END args_list_or_empty

    # args_list

    def p_args_list(self, p):
        """args_list : args_list ',' arg"""
        p[0] = ArgsList(p[1].args_list + [p[3]])

    def p_single_arg_list(self, p):
        """args_list : arg """
        p[0] = ArgsList([p[1]])

    # END args_list

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Arg(p[1], p[2])
Пример #2
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.errors = False

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        self.errors = True
        err_format = "Syntax error at line {0}, column {1}: LexToken({2}, '{3}')"
        if p:
            print(
                err_format.format(p.lineno, self.scanner.find_tok_column(p),
                                  p.type, p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        #     ^            ^         ^          ^
        #    p[0]         p[1]      p[2]       p[3]
        program = AST.Program(p[1], p[2], p[3])
        p[0] = program

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:  # occurs when declarations -> declarations declaration
            p[1].declarations.append(p[2])
            p[0] = p[1]
        else:  # occurs when declarations -> epsilon
            p[0] = AST.Declarations()

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 3:  # occurs when error
            p[0] = p[1]
        else:
            p[0] = AST.Declaration(p[1], p[2])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:  # occurs when inits -> inits, init
            p[0] = p[1]
            p[0].inits.append(p[3])
        else:  # occurs when inits -> init
            p[0] = AST.Inits()
            p[0].inits.append(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:  # occurs when instructions -> instructions instruction
            p[1].instructions.append(p[2])
            p[0] = p[1]
        else:  # occurs when instructions -> instruction
            p[0] = AST.Instructions()
            p[0].instructions.append(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p[2], p.lineno(1))

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1], p[3], p.lineno(1))

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3], p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 8:
            p[0] = AST.IfElseInstr(p[3], p[5], p[7])
        else:
            p[0] = AST.IfInstr(p[3], p[5])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[4], p[2])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        lineno = p.lineno(1)
        try:
            int(p[1])
            p[0] = AST.Integer(p[1], lineno)
        except ValueError:
            try:
                float(p[1])
                p[0] = AST.Float(p[1], lineno)
            except ValueError:
                p[0] = AST.String(p[1], lineno)

    def p_id_expr(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p[1], p.lineno(1))

    def p_const_expr(self, p):
        """expression : const"""
        p[0] = p[1]

    def p_paren_expression(self, p):
        """expression : '(' expression ')'
                      | '(' error ')'"""
        p[0] = AST.ParenExpr(p[2])

    def p_funcall(self, p):
        """expression : ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        p[0] = AST.Funcall(p[1], p[3], p.lineno(1))

    def p_bin_expression(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""
        p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(2))  # operator pierwszy

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        p[0] = AST.ExprList()
        if len(p) == 4:
            p[0].cons_expr(p[1].expr_list, p[3])
        else:
            p[0].append_expr(p[1])

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        p[0] = AST.FundefList()
        if len(p) == 3:
            p[0].cons_fun(p[2].fundef_list, p[1])
        elif len(p) == 2:
            p[0].append_fun(p[1])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(p[1], p[2], p[4], p[6], p.lineno(1))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.ArgList()  # empty

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        p[0] = AST.ArgList()
        if len(p) == 4:
            p[0].cons_arg(p[1].arg_list, p[3])
        else:
            p[0].append_arg(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2], p.lineno(1))
Пример #3
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print("Unexpected end of input")


    def p_program(self, p):
        """program : blocks"""

        p[0] = AST.Program(p[1])
        # p[0] = ('PROGRAM',p[1], p[2], p[3])


    def p_blocks(self, p):
        """blocks : blocks block
                  |"""
        if len(p) == 3:
            p[0] = p[1]
            p[0].addArgument(p[2])
        else:
            p[0] = AST.BlockList()


    def p_block(self, p):
        """block : declaration
                 | fundef
                 | instruction"""
        p[0] = AST.Block(p[1])


    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """


        if len(p) == 3:
            p[0] = p[1]
            p[0].addArgument(p[2])
        else:
            p[0] = AST.DeclarationList()
        # else:
        #     p[0] = AST.Declarations(p[1], p[2])

        # if len(p) == 2:
        #     p[0] = ("DECLARATIONS", p[1])
        # elif len(p) == 3:
        #     p[0] = ("DECLARATIONS", p[1], p[2])
        # else:
        #     p[0] = ("DECLARATIONS")


    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """


        p[0] = AST.Declaration(p[1], p[2])
        # p[0] = ("DECLARATION",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = AST.InitList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.InitList()
            p[0].addArgument(p[1])

        # p[0] = ("INITS", p[1])

    def p_init(self, p):
        """init : ID '=' expression """

        p[0] = AST.Init(p[1], p[2], p[3], p.lineno(1))
        # p[0] = ("INIT", p[1], p[2], p[3])

    #
    # def p_instructions_opt(self, p):
    #     """instructions_opt : instructions
    #                         | """
    #     if len(p) == 2:
    #         p[0] = AST.Instructions(p[1], None)
    #     else:
    #         p[0] = AST.Instructions(None, None)
    #     # else:
    #     #     p[0] = AST.Instructions(p[1], p[2])
    #     #
    #     #
    #     # p[0] = ("INSTRUCTIONS_OPT", p[1])


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """

        if len(p) == 3:
            p[0] = AST.InstructionList() if p[1] is None else p[1]
            p[0].addArgument(p[2])
        else:
            p[0] = AST.InstructionList()
            p[0].addArgument(p[1])
        # p[0] = ("INSTRUCTIONS", p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """

        # for i in (0, len(p)):
        #     print(str(i) + " " + str(p[i]))




        p[0] = p[1]
        # p[0] = ("INSTRUCTION", p[1])


    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """

        p[0] = AST.PrintInstruction(p[1], p[2], p.lineno(1))
        # p[0] = ("PRINT_INSTR", p[1], p[2], p[3])


    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3], p.lineno(1))
        # p[0] = ("LABELED_INSTR", p[1], p[2], p[3])


    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[2], p[3], p.lineno(1))
        # p[0] = ("ASSIGNMENT", p[1], p[2], p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

        # for i in range(0, len(p)):
        #     print(str(i) + " " + str(p[i]))
        if len(p) > 7:
            p[0] = AST.ChoiceInstr(p[3], p[5], p[7], p.lineno(1))
        else:
            p[0] = AST.ChoiceInstr(p[3], p[5], None, p.lineno(1))

        # p[0] = ("CHOICE_INSTR", p[1], p[3], p[5])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5], p.lineno(1))
        # p[0] = ("WHILE_INSTR", p[1], p[3], p[5], )


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4], p.lineno(1))
        # p[0] = ("REPEAt_INSTR", p[1], p[2], p[3])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return_instr(p[2], p.lineno(1))
        # p[0] = ("REPEAT_INSTR", p[1], p[2], p[3])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstr(p[2], p[3])
        # p[0] = ("COMPOUND_INSTR", p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""

        # p[0] = AST.Const(p.slice[1].type)
        p[0] = {
            'INTEGER': lambda : AST.Integer(p[1]),
            'FLOAT': lambda : AST.Float(p[1]),
            'STRING': lambda : AST.String(p[1])
        }[p.slice[1].type]()
        # p[0] = ("CONST", p[1])


    def p_expression_id(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p[1], p.lineno(1))

    def p_expression(self, p):
        """expression : const
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """



        # for i in range(0, len(p)):
        #     print(str(i) + " " + str(p[i]))
        #
        # if len(p) == 2:
        #     p[0] = AST.BinExpr(None,p[1],None)
        #
        # else:
        #     p[0] = AST.BinExpr(p[2],p[1],p[3])


        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4 and p[1] != '(':
            p[0] = AST.BinExpr(p[2],p[1],p[3], p.lineno(2))
        elif len(p) == 4:
            p[0] = AST.UnaryExpr(p[2])
        elif len(p) == 5:
            p[0] = AST.FunctionExpression(p[1], p[3], p.lineno(1))
        #
        #
        # if len(p) == 2:
        #     p[0] = AST.BinExpr(None,p[1],None)
        # elif len(p) == 4 and p[1] != '(':
        #     p[0] = p[0] = AST.BinExpr(p[2],p[1],p[3])
        # elif len(p) == 4:
        #     p[0] = AST.BinExpr(None,p[2],None)
        # elif len(p) == 5:
        #     p[0] = AST.BinExpr(None, p[1], p[3])

        # p[0] = ("EXPRESSIONxD" + str(len(p)),)
        # for i in range(1, len(p)):
        #         p[0] += (p[i],)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = None
        # p[0] = ("EXPRESSION_LIST_OR_EMPTY",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """


        if len(p) == 4:
            p[0] = AST.ExpressionList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].addArgument(p[1])

        # p[0] = ("EXPRESSION_LIST",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)


    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """

        p[0] = AST.Fundef( p[1], p[2], p[4], p[6], p.lineno(1))
        # p[0] = ("FUNDEF",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """


        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = None

        # p[0] = ("ARGS_LIST_OR_EMPTY",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """



        if len(p) == 4:
            p[0] = AST.ArgList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ArgList()
            p[0].addArgument(p[1])

        # p[0] = ("ARGS_LIST",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2])
Пример #4
0
class Cparser(object):

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.no_error = True

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        self.no_error = False
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, 
                                                                               self.scanner.find_tok_column(p), 
                                                                               p.type, 
                                                                               p.value))
        else:
            print("Unexpected end of input")

    
    def p_program(self, p):
        """program : blocks"""
        p[0] = AST.Program(p[1])
        p[0].line = self.scanner.lexer.lineno
        if self.no_error:
            # p[0].print_tree(0)
            pass
			
    def p_blocks(self, p):
        """blocks : blocks block
                  | block """
        if len(p) > 2:
            p[0] = AST.Blocks(p[2], p[1])
        else:
            p[0] = AST.Blocks(p[1], None)
        p[0].line = self.scanner.lexer.lineno
		
    def p_block(self, p):
        """block : fundef
                 | instruction
                 | declaration """
        p[0] = p[1]
        p[0].line = self.scanner.lexer.lineno

            
#    def p_declarations(self, p):
#       """declarations : declarations declaration
#                      | """
#        if self.no_error:
#            if len(p) > 1:
#                p[0] = AST.Declarations(p[1], p[2])
#            else:
#                p[0] = AST.Declarations(None, None)
#            p[0].line = self.scanner.lexer.lineno
                       
    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) > 3:
            p[0] = AST.Declaration(p[1], p[2], None)
        else:
            p[0] = AST.Declaration(None, None, p[1])
        p[0].line = self.scanner.lexer.lineno
                       
                       
    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) > 2:
            p[0] = AST.Inits(p[1], p[3])
        else:
            p[0] = AST.Inits(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno
        
    
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) > 2:
            p[0] = AST.Instructions(p[1], p[2])
        else:
            p[0] = AST.Instructions(None, p[1])
        p[0].line = self.scanner.lexer.lineno 
    
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]
        p[0].line = self.scanner.lexer.lineno
    
    
    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        if isinstance(p[2], AST.Expression):
            p[0] = AST.Print(p[2], None)
        else:
            p[0] = AST.Print(None, p[2])
        p[0].line = self.scanner.lexer.lineno
        
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.Labeled(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno
     
    
    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno
    
 
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if isinstance(p[3], AST.Condition):
            if len(p) == 8 and p[6].lower() == "else":
                if_node = AST.If(p[3], p[5], None)
                if_node.line = self.scanner.lexer.lineno
                else_node = AST.Else(p[7])
                else_node.line = self.scanner.lexer.lineno
                p[0] = AST.Choice(if_node, else_node)
            else:
                if_node = AST.If(p[3], p[5], None)
                if_node.line = self.scanner.lexer.lineno
                p[0] = AST.Choice(if_node, None)
        else:
            if len(p) == 8 and p[6].lower() == "else":
                if_node = AST.If(None, p[5], p[3])
                if_node.line = self.scanner.lexer.lineno
                else_node = AST.Else(p[7])
                else_node.line = self.scanner.lexer.lineno
                p[0] = AST.Choice(if_node, else_node)
            else:
                if_node = AST.If(None, p[5], p[3])
                if_node.line = self.scanner.lexer.lineno
                p[0] = AST.Choice(if_node, None)
        p[0].line = self.scanner.lexer.lineno

    
    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        if isinstance(p[3], AST.Condition):
            p[0] = AST.While(p[3], p[5], None)
        else:
            p[0] = AST.While(None, p[5], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatUntil(p[2], p[4])
        p[0].line = self.scanner.lexer.lineno
    
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return(p[2])
        p[0].line = self.scanner.lexer.lineno
    
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Continue()
        p[0].line = self.scanner.lexer.lineno

    
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Break()
        p[0].line = self.scanner.lexer.lineno
    
    def p_compound_instr(self, p):
        """compound_instr : '{' blocks '}' """
        p[0] = AST.Compound(p[2])
        p[0].line = self.scanner.lexer.lineno
    
    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]
        p[0].line = self.scanner.lexer.lineno

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = AST.Const(p[1])
        p[0].line = self.scanner.lexer.lineno
    
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            if isinstance(p[1], AST.Const):
                p[0] = p[1]
            else:
                p[0] = AST.Id(p[1])
        elif len(p) == 4:
            if p[1] == "(":
                if isinstance(p[2], AST.Expression):
                    p[0] = AST.ExpressionInPar(p[2], None)
                else:
                    p[0] = AST.ExpressionInPar(None, p[2])
            else:
                p[0] = AST.BinExpr(p[1], p[2], p[3])
        else:
            if isinstance(p[3], AST.ExpressionList):
                p[0] = AST.IdWithPar(p[1], p[3], None)
            else:
                p[0] = AST.IdWithPar(p[1], None, p[3])
        p[0].line = self.scanner.lexer.lineno
    
    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) > 1:
            p[0] = AST.ExpressionList(p[1], None)
        else:
            p[0] = AST.ExpressionList(None, None)
        p[0].line = self.scanner.lexer.lineno
    
    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) > 2:
            p[0] = AST.ExpressionList(p[1], p[3])
        else:
            p[0] = AST.ExpressionList(None, p[1])
        p[0].line = self.scanner.lexer.lineno
    
    #def p_fundefs_opt(self, p):
    #    """fundefs_opt : fundefs
    #                   | """
      
#    def p_fundefs(self, p):
#        """fundefs : fundefs fundef
#                   | fundef  """
#        if len(p) > 2:
#            p[0] = AST.FunctionDefinitions(p[2], p[1])
#        else:
#            p[0] = AST.FunctionDefinitions(p[1], None)
#       p[0].line = self.scanner.lexer.lineno
            
          
    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionDefinition(p[1],p[2],p[4],p[6])
        p[0].line = self.scanner.lexer.lineno
    
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        
        if len(p) > 1:
            p[0] = AST.ArgumentList(p[1], None)
        else:
            p[0] = AST.ArgumentList(None, None)
        p[0].line = self.scanner.lexer.lineno
        
    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) > 2:
            p[0] = AST.ArgumentList(p[1], p[3])
        else:
            p[0] = AST.ArgumentList(None, p[1])
        p[0].line = self.scanner.lexer.lineno
        
    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Argument(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno
Пример #5
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : blocks"""

        p[0] = AST.Program(p[1])
        # p[0] = ('PROGRAM',p[1], p[2], p[3])

    def p_blocks(self, p):
        """blocks : blocks block
                  |"""
        if len(p) == 3:
            p[0] = AST.Blocks(p[1], p[2])
        else:
            p[0] = AST.Blocks(None, None)

    def p_block(self, p):
        """block : declaration
                 | fundef
                 | instruction"""
        p[0] = AST.Block(p[1])

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """

        if len(p) == 3:
            p[0] = AST.Declarations(p[1], p[2])
        else:
            p[0] = AST.Declarations(None, None)
        # else:
        #     p[0] = AST.Declarations(p[1], p[2])

        # if len(p) == 2:
        #     p[0] = ("DECLARATIONS", p[1])
        # elif len(p) == 3:
        #     p[0] = ("DECLARATIONS", p[1], p[2])
        # else:
        #     p[0] = ("DECLARATIONS")

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """

        p[0] = AST.Declaration(p[1], p[2])
        # p[0] = ("DECLARATION",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 2:
            p[0] = AST.Inits(None, p[1])
        else:
            p[0] = AST.Inits(p[1], p[3])

        # p[0] = ("INITS", p[1])

    def p_init(self, p):
        """init : ID '=' expression """

        p[0] = AST.Init(p[1], p[2], p[3])
        # p[0] = ("INIT", p[1], p[2], p[3])

    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        if len(p) == 2:
            p[0] = AST.Instructions(p[1], None)
        else:
            p[0] = AST.Instructions(None, None)
        # else:
        #     p[0] = AST.Instructions(p[1], p[2])
        #
        #
        # p[0] = ("INSTRUCTIONS_OPT", p[1])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """

        if len(p) == 2:
            p[0] = AST.Instructions(p[1], None)
        else:
            p[0] = AST.Instructions(p[1], p[2])
        # p[0] = ("INSTRUCTIONS", p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """

        # for i in (0, len(p)):
        #     print(str(i) + " " + str(p[i]))

        p[0] = AST.Instruction(p[1])
        # p[0] = ("INSTRUCTION", p[1])

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """

        p[0] = AST.PrintInstruction(p[1], p[2])
        # p[0] = ("PRINT_INSTR", p[1], p[2], p[3])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3])
        # p[0] = ("LABELED_INSTR", p[1], p[2], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[2], p[3])
        # p[0] = ("ASSIGNMENT", p[1], p[2], p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

        # for i in range(0, len(p)):
        #     print(str(i) + " " + str(p[i]))
        p[0] = AST.ChoiceInstr(p[3], p[5], p[7])
        # p[0] = ("CHOICE_INSTR", p[1], p[3], p[5])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])
        # p[0] = ("WHILE_INSTR", p[1], p[3], p[5], )

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4])
        # p[0] = ("REPEAt_INSTR", p[1], p[2], p[3])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return_instr(p[2])
        # p[0] = ("REPEAT_INSTR", p[1], p[2], p[3])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        p[0] = AST.CompoundInstr(p[2], p[3])
        # p[0] = ("COMPOUND_INSTR", p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = AST.Const(p[1])
        # p[0] = ("CONST", p[1])

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """

        # for i in range(0, len(p)):
        #     print(str(i) + " " + str(p[i]))
        #
        # if len(p) == 2:
        #     p[0] = AST.BinExpr(None,p[1],None)
        #
        # else:
        #     p[0] = AST.BinExpr(p[2],p[1],p[3])

        if len(p) == 2:
            p[0] = AST.BinExpr(None, p[1], None)
        elif len(p) == 4 and p[1] != '(':
            p[0] = p[0] = AST.BinExpr(p[2], p[1], p[3])
        elif len(p) == 4:
            p[0] = AST.BinExpr(None, p[2], None)
        elif len(p) == 5:
            p[0] = AST.BinExpr(None, p[1], p[3])

        # p[0] = ("EXPRESSIONxD" + str(len(p)),)
        # for i in range(1, len(p)):
        #         p[0] += (p[i],)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = AST.FunDefs(p[1], None)
        else:
            p[0] = AST.FunDefs(p[1], p[2])
        # p[0] = ("EXPRESSION_LIST_OR_EMPTY",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """

        if len(p) == 2:
            p[0] = AST.ExpressionList(p[1], None)
        else:
            p[0] = AST.ExpressionList(p[1], p[3])

        # p[0] = ("EXPRESSION_LIST",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """

        p[0] = AST.Fundef(p[1], p[2], p[4], p[6])
        # p[0] = ("FUNDEF",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """

        if len(p) == 2:
            p[0] = AST.ArgList(p[1], None)

        # p[0] = ("ARGS_LIST_OR_EMPTY",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """

        if len(p) == 2:
            p[0] = AST.ArgList(p[1], None)
        else:
            p[0] = AST.ArgList(p[1], p[3])

        # p[0] = ("ARGS_LIST",)
        #
        # for i in range(1, len(p)):
        #     p[0] += (p[i],)

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2])
Пример #6
0
class Parser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = AST.Program(AST.Declarations.mapTypedDeclarations(p[1]), utils.flatten(p[2]),
                           AST.Instructions(utils.flatten(p[3])))
        p[0].set_parents()
        p[0].set_scope()
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) > 1:
            p[0] = [p[1], p[2]]
        else:
            p[0] = []

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        p[0] = AST.TypedDeclarations(p[1], utils.flatten(p[2]))
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """

        if len(p) > 2:
            p[0] = [p[1], p[3]]
        else:
            p[0] = [p[1]]


    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Declaration(p[1], p[3])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) > 2:
            p[0] = [p[1], p[2]]
        else:
            p[0] = [p[1]]


    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]


    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstruction(p[2])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)


    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1], p[3])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.AssignmentInstruction(p[1], p[3])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) > 6:
            p[0] = AST.ChoiceElseInstruction(p[3], p[5], p[7])
        else:
            p[0] = AST.ChoiceInstruction(p[3], p[5])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)


    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstruction(p[3], p[5])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstruction(AST.Instructions(p[2]), p[4])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstruction(p[2])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)


    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstructions(AST.Declarations.mapTypedDeclarations(p[2]),
                                        AST.Instructions(utils.flatten(p[3])))
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = p[1]


    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """

        if len(p) == 2:
            p[0] = p[1]
            return

        if p[1] == '(':
            p[0] = AST.GroupingOperator(p[2])
            p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)
            return

        if p[2] == '(':
            p[0] = AST.FunctionCallOperator(p[1], p[3])
            p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)
            return

        if p[2] == "+":
            p[0] = AST.SumOperator(p[1], p[3])
        if p[2] == "-":
            p[0] = AST.DifferenceOperator(p[1], p[3])
        if p[2] == "*":
            p[0] = AST.MultiplyOperator(p[1], p[3])
        if p[2] == "/":
            p[0] = AST.DivOperator(p[1], p[3])
        if p[2] == "%":
            p[0] = AST.ModuloOperator(p[1], p[3])
        if p[2] == "^":
            p[0] = AST.BitXorOperator(p[1], p[3])
        if p[2] == "&":
            p[0] = AST.BitAndOperator(p[1], p[3])
        if p[2] == "|":
            p[0] = AST.BitOrOperator(p[1], p[3])

        if p[2] == "<<":
            p[0] = AST.ShiftLeftOperator(p[1], p[3])
        if p[2] == ">>":
            p[0] = AST.ShiftRightOperator(p[1], p[3])

        if p[2] == "||":
            p[0] = AST.LogicalOrOperator(p[1], p[3])
        if p[2] == "&&":
            p[0] = AST.LogicalAndOperator(p[1], p[3])

        if p[2] == "==":
            p[0] = AST.EqualOperator(p[1], p[3])
        if p[2] == "!=":
            p[0] = AST.NotEqualOperator(p[1], p[3])

        if p[2] == ">":
            p[0] = AST.GreaterThanOperator(p[1], p[3])
        if p[2] == ">=":
            p[0] = AST.GreaterEqualOperator(p[1], p[3])
        if p[2] == "<":
            p[0] = AST.LowerThanOperator(p[1], p[3])
        if p[2] == "<=":
            p[0] = AST.LowerEqualOperator(p[1], p[3])

        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) > 1:
            p[0] = utils.flatten(p[1])
        else:
            p[0] = []


    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) > 2:
            p[0] = [p[1], p[3]]
        else:
            p[0] = [p[1]]


    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """

        if len(p) > 1:
            p[0] = [p[1], p[2]]
        else:
            p[0] = []

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunDef(p[1], p[2], p[4], p[6])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """

        if len(p) > 1:
            p[0] = utils.flatten(p[1])
        else:
            p[0] = []

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """

        if len(p) > 2:
            p[0] = [p[1], p[3]]
        else:
            p[0] = [p[1]]

    def p_arg(self, p):
        """arg : TYPE ID """

        p[0] = AST.Arg(p[1], p[2])
        p[0].set_position(p.lexer.lexer.lineno, p.lexer.lexer.lexpos)
Пример #7
0
Файл: Cparser.py Проект: jswk/tk
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input\nMost likely you haven\'t included a single instruction')


    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = AST.AST(p[1], p[2], p[3])


    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        try:
            p[0] = p[1] + [p[2]]
        except IndexError:
            p[0] = []


    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        try:
            p[3]
            p[0] = AST.Declaration(p[1], p[2])
        except IndexError:
            p[0] = AST.Error(p[1])


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        try:
            p[0] = p[1] + [p[3]]
        except IndexError:
            p[0] = [p[1]]


    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = self.add_pos(AST.Init(self.add_pos(AST.Variable(p[1]), p), p[3]), p)


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        try:
            p[0] = p[1] + [p[2]]
        except IndexError:
            p[0] = [p[1]]


    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]


    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.Print(p[2])


    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3])


    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(self.add_pos(AST.Variable(p[1]), p), p[3])


    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        try:
          p[0] = AST.If(p[3], p[5], p[7])
        except IndexError:
          p[0] = AST.If(p[3], p[5], None)


    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.While(p[3], p[5])


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instruction UNTIL condition ';' """
        p[0] = AST.Repeat(p[2], p[4])


    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = self.add_pos(AST.Return(p[2]), p)


    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = self.add_pos(AST.Continue(), p)


    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = self.add_pos(AST.Break(), p)


    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstruction(p[2], p[3])


    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]


    def p_const_int(self, p):
        """const : INTEGER"""
        p[0] = self.add_pos(AST.Integer(p[1]), p)

    def p_const_float(self, p):
        """const : FLOAT"""
        p[0] = self.add_pos(AST.Float(p[1]), p)

    def p_const_string(self, p):
        """const : STRING"""
        p[0] = self.add_pos(AST.String(p[1]), p)


    def p_expression_simple(self, p):
        """expression : const
                      | '(' expression ')' """
        try:
            p[0] = p[2]
        except IndexError:
            p[0] = p[1]

    def p_expression_id(self, p):
        """expression : ID """
        p[0] = self.add_pos(AST.Variable(p[1]), p)

    def p_expression_binexpr(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression """
        p[0] = self.add_pos(AST.BinExpr(p[1], p[2], p[3]), p)

    def p_expression_funcall(self, p):
        """expression : ID '(' expr_list_or_empty ')' """
        p[0] = self.add_pos(AST.Funcall(self.add_pos(AST.Variable(p[1]), p), p[3]), p)

    def p_expression_error(self, p):
        """expression : '(' error ')'
                      | ID '(' error ')' """
        pos = self.get_pos(p, 1)
        try:
            p[4]
            p[0] = AST.Error("Malformed function call {0}({1}) at line:{2} column:{3}".format(p[1], p[3], pos[0], pos[1]))
        except IndexError:
            p[0] = AST.Error("Malformed braced expression ({0}) at line:{1} column:{2}".format(p[2], pos[0], pos[1]))


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        try:
            p[0] = p[1]
        except IndexError:
            p[0] = []


    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        try:
            p[0] = p[1] + [p[3]]
        except IndexError:
            p[0] = [p[1]]


    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        try:
            p[0] = [p[1]] + p[2]
        except IndexError:
            p[0] = []

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = self.add_pos(AST.Fundef(p[2], p[1], p[4], p[6]), p)

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        try:
          p[0] = p[1]
        except IndexError:
          p[0] = []

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        try:
          p[0] = p[1] + [p[3]]
        except IndexError:
          p[0] = [p[1]]

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = self.add_pos(AST.Arg(p[1], p[2]), p)

    def add_pos(self, el, p, i = 1):
        el.pos = self.get_pos(p, i)
        return el

    def get_pos(self, p, i = 1):
        def find_column(input,token):
            last_cr = input.rfind('\n',0,token)
            if last_cr < 0:
                last_cr = 0
            column = (token - last_cr)
            return column
        try:
            out = p[i].pos
        except AttributeError:
            out = (p.lineno(i), find_column(self.scanner.lexer.lexdata, p.lexpos(i)))
        # print("{}:{} -> {}:{}".format(p.slice, i, out[0], out[1]))
        return out
Пример #8
0
# object oriented version

import sys

from scanner import Scanner  # Scanner needs to be provided manually

if __name__ == '__main__':

    try:
        filename = sys.argv[1] if len(sys.argv) > 1 else "example.txt"
        file = open(filename, "r")
    except IOError:
        print(f"Cannot open {filename} file")
        sys.exit(0)

    text = file.read()
    lexer = Scanner()
    lexer.build()

    # Give the lexer some input
    lexer.input(text)

    # Tokenize
    while True:
        tok = lexer.token()
        if not tok:
            break  # No more input
        line_number, token_type, token_value = tok.lineno, tok.type, tok.value
        print(f"({line_number}): {token_type}({token_value})")
Пример #9
0
class Cparser(object):

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""

        p[0] = AST.Program(p.lineno(1), p[1], p[2], p[3])
        print(p[0])

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """

        if len(p) == 3:
            p[0] = AST.Declarations(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.Epsilon(p.lineno(0))

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            p[0] = AST.Declaration(p.lineno(1), p[2], p[1])
        else:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
            sys.exit(-1)

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """

        if len(p) == 2:
            p[0] = AST.Inits(p.lineno(1), p[1])
        else:
            p[0] = AST.Inits(p.lineno(1), p[1], p[3])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p.lineno(1), p[1], p[3])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """

        if len(p) == 3:
            p[0] = AST.Instructions(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.Instructions(p.lineno(1), p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """

        if isinstance(p[2], AST.Expr):
            p[0] = AST.PrintInstr(p.lineno(1), p[2])
        else:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
            sys.exit(-1)

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """

        p[0] = AST.LabeledInstr(p.lineno(1), p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """

        p[0] = AST.Assignment(p.lineno(1), p[1], p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

        if len(p) == 6:
            if isinstance(p[3], AST.Condition):
                p[0] = AST.IfInstr(p.lineno(1), p[3], p[5])
            else:
                print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
                sys.exit(-1)
        else:
            if isinstance(p[3], AST.Condition):
                p[0] = AST.IfElseInstr(p.lineno(1), p[3], p[5], p[7])
            else:
                print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
                sys.exit(-1)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """

        if isinstance(p[3], AST.Condition):
            p[0] = AST.WhileInstr(p.lineno(1), p[3], p[5])
        else:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
            sys.exit(-1)

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """

        p[0] = AST.RepeatInstr(p.lineno(1), p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """

        p[0] = AST.ReturnInstr(p.lineno(1), p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """

        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """

        p[0] = AST.BreakInstr(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """

        p[0] = AST.CompoundInstr(p.lineno(1), p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""

        p[0] = AST.Condition(p.lineno(1), p[1])

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        if (p[1].isdigit()):
            if "." in p[1]:
                p[0] = AST.Float(p.lineno(1), p[1])
            else:
                p[0] = AST.Integer(p.lineno(1), p[1])
        else:
            p[0] = AST.String(p.lineno(1), p[1])

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """

        if len(p) == 2:
            p[0] = AST.UnExpr(p.lineno(1), p[1])
        elif len(p) == 4:
            if p[1] == '(':
                if isinstance(p[2], AST.Expr):
                    p[0] = AST.BrackExpr(p.lineno(1), p[2])
                else:
                    print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
                    sys.exit(-1)
            else:
                p[0] = AST.BinExpr(p.lineno(1), p[2], p[1], p[3])
        else:
            if isinstance(p[3], AST.ExprList) or isinstance(p[3], AST.Epsilon):
                p[0] = AST.FunCall(p.lineno(1), p[1], p[3])
            else:
                print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
                sys.exit(-1)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """

        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Epsilon(p.lineno(0))

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """

        if len(p) == 4:
            p[0] = AST.ExprList(p.lineno(1), p[1], p[3])
        else:
            p[0] = AST.ExprList(p.lineno(1), p[1])

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """

        if len(p) == 3:
            p[0] = AST.FunDefs(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.Epsilon(p.lineno(0))

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """

        p[0] = AST.FunDef(p.lineno(1), p[1], p[2], p[4], p[6])


    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """

        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Epsilon(p.lineno(0))

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """

        if len(p) == 4:
            p[0] = AST.ArgsList(p.lineno(1), p[1], p[3])
        else:
            p[0] = AST.ArgsList(p.lineno(1), p[1])

    def p_arg(self, p):
        """arg : TYPE ID """

        p[0] = AST.Arg(p.lineno(1), p[2], p[1])
Пример #10
0
class Cparser(object):


	def __init__(self):
		self.scanner = Scanner()
		self.scanner.build()
		self.symbol_table = SymbolTable.SymbolTable("main_table")

	tokens = Scanner.tokens

	precedence = (
	   ("nonassoc", 'IFX'),
	   ("nonassoc", 'ELSE'),
	   ("right", '='),
	   ("left", 'OR'),
	   ("left", 'AND'),
	   ("left", '|'),
	   ("left", '^'),
	   ("left", '&'),
	   ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
	   ("left", 'SHL', 'SHR'),
	   ("left", '+', '-'),
	   ("left", '*', '/', '%'),
	)
	
	operation_results = {
	
#~ ARITHMETIC OPERATORS ----------------------
		"+": {
			"int": {
				"int": "int",
				"float": "float",
				"string": None,
				"bool": None
			},
			"float": {
				"int": "float",
				"float": "float",
				"string": None,
				"bool": None
			},
			"string": {
				"int": None,
				"float": None,
				"string": "string",
				"bool": None
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		"-": {
			"int": {
				"int": "int",
				"float": "float",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "float",
				"float": "float",
				"string": None,
				"bool": None	
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},	
		"*": {
			"int": {
				"int": "int",
				"float": "int",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "float",
				"float": "float",
				"string": None,
				"bool": None	
			},
			"string": {
				"int": "string",
				"float": None,
				"string": None,
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		"/": {
			"int": {
				"int": "int",
				"float": "float",
				"string": None,
				"bool": None		
			},
			"float": {
				"int": "float",
				"float": "float",
				"string": None,
				"bool": None	
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		"%": {
			"int": {
				"int": "int",
				"float": None,
				"string": None,
				"bool": None		
			},
			"float": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},

#~ COMPARISON OPERATORS ----------------------
		"<": {
			"int": {
				"int": "bool",
				"float": "bool",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "bool",
				"float":  "bool",
				"string": None,
				"bool": None		
			},
			"string": {
				"int": None,
				"float": None,
				"string":  "bool",
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		"<=": {
			"int": {
				"int": "bool",
				"float": "bool",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "bool",
				"float":  "bool",
				"string": None,
				"bool": None		
			},
			"string": {
				"int": None,
				"float": None,
				"string":  "bool",
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		">=": {
			"int": {
				"int": "bool",
				"float": "bool",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "bool",
				"float":  "bool",
				"string": None,
				"bool": None		
			},
			"string": {
				"int": None,
				"float": None,
				"string":  "bool",
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		">": {
			"int": {
				"int": "bool",
				"float": "bool",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "bool",
				"float":  "bool",
				"string": None,
				"bool": None		
			},
			"string": {
				"int": None,
				"float": None,
				"string":  "bool",
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		"==": {
			"int": {
				"int": "bool",
				"float": "bool",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "bool",
				"float":  "bool",
				"string": None,
				"bool": None		
			},
			"string": {
				"int": None,
				"float": None,
				"string":  "bool",
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": "bool"				
			}
		},
		"!=": {
			"int": {
				"int": "bool",
				"float": "bool",
				"string": None,
				"bool": None	
			},
			"float": {
				"int": "bool",
				"float":  "bool",
				"string": None,
				"bool": None		
			},
			"string": {
				"int": None,
				"float": None,
				"string":  "bool",
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": "bool"				
			}
		},
		
#~ LOGICAL OPERATORS ----------------------
		"&&": {
			"int": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"float": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"bool": {
				"int": None,
				"float": None,
				"string":  None,
				"bool": "bool"	
			}			
		},
		"\|\|": {
			"int": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"float": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None
			},
			"bool": {
				"int": None,
				"float": None,
				"string":  None,
				"bool": "bool"	
			}			
		},	

#~ BITWISE OPERATORS ----------------------
		">>": {
			"int": {
				"int": "int",
				"float": None,
				"string": None,
				"bool": None		
			},
			"float": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		},
		"<<": {
			"int": {
				"int": "int",
				"float": None,
				"string": None,
				"bool": None		
			},
			"float": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"string": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None	
			},
			"bool": {
				"int": None,
				"float": None,
				"string": None,
				"bool": None				
			}
		}
	}

	def p_error(self, p):
		if p:
			print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
		else:
			print("Unexpected end of input")


	def p_program(self, p):
		"""program : blocks"""

		program = AST.Program(p[1])
		p[0] = program

	def p_blocks(self, p):
		"""blocks : blocks block
				  | block"""

		if(len(p) > 2):
			if(isinstance(p[2], list)):
				p[1].extend(p[2])
			else:
				p[1].append(p[2])
			p[0] = p[1]
		else:
			if(isinstance(p[1], list)):
				p[0] = p[1]
			else:
				p[0] = [p[1]]


	def p_block(self, p):
		"""block : declaration
				 | fundef
				 | instruction"""

		p[0] = p[1]


	def p_declaration(self, p):
		"""declaration : TYPE inits ';'
					   | error ';' """

		if(len(p) > 2):
			p[0] = p[2]
			declared_type = p[1]
			#~ print("Adding new variable declarations...")
			
			#~ for i in range(len(p[0])):
				#~ declaration = p[0][i]
				#~ id = declaration.left
				#~ name = id.name
				#~ 
				#~ if(id.type != declared_type):
					#~ if(declared_type == "int" and id.type == "float"):
						#~ print("Line [" + str(p.lineno(1)) + "]: Warning! Implicit cast from float to int!")
					#~ elif(declared_type != "float" or id.type != "int"):
						#~ print("Line [" + str(p.lineno(1)) + "]: Invalid declaration type!")
				#~ 
				#~ if(not self.symbol_table.put(name, SymbolTable.VariableSymbol(declared_type, name))):
					#~ print("Line [" + str(p.lineno(1)) + "]: Multiple variable declarations in the same scope!")
			
		else:
			p[0] = p[1]

	def p_inits(self, p):
		"""inits : inits ',' init
				 | init """

		if(len(p) > 3):
			p[1].append(p[3])
			p[0] = p[1]
		else:
			p[0] = [p[1]]


	def p_init(self, p):
		"""init : ID '=' expression """

		decl = AST.Declaration(AST.Id(p[3].type, p[1], p.lineno(1)), p[3], p.lineno(1))
		p[0] = decl


	def p_instructions(self, p):
		"""instructions : instructions instruction
						| instruction """

		if(len(p) > 2):
			if(isinstance(p[2], list)):
				p[1].extend(p[2])
			else:
				p[1].append(p[2])
			p[0] = p[1]
		else:
			if(isinstance(p[1], list)):
				p[0] = p[1]
			else:
				p[0] = [p[1]]


	def p_instruction(self, p):
		"""instruction : print_instr
					   | labeled_instr
					   | assignment
					   | choice_instr
					   | while_instr
					   | repeat_instr
					   | return_instr
					   | break_instr
					   | continue_instr
					   | compound_instr
					   | expression ';' """
		p[0] = p[1]

	def p_print_instr(self, p):
		"""print_instr : PRINT expr_list ';'
					   | PRINT error ';' """

		instruction = AST.PrintInstr(p[2], p.lineno(1))
		p[0] = instruction


	def p_return_instr(self, p):
		"""return_instr : RETURN expression ';' """

		instruction = AST.ReturnInstr(p[2], p.lineno(1))
		p[0] = instruction


	def p_choice_instr(self, p):
		"""choice_instr : IF '(' condition ')' instruction  %prec IFX
						| IF '(' condition ')' instruction ELSE instruction
						| IF '(' error ')' instruction  %prec IFX
						| IF '(' error ')' instruction ELSE instruction """

		if(len(p) > 7):
			instruction = AST.IfInstr(p[3], p[5], p.lineno(1), p[7])
			p[0] = instruction

		elif(len(p) > 5):
			instruction = AST.IfInstr(p[3], p[5], p.lineno(1))
			p[0] = instruction


	def p_while_instr(self, p):
		"""while_instr : WHILE '(' condition ')' instruction
					   | WHILE '(' error ')' instruction """

		instruction = AST.WhileInstr(p[3], p[5], p.lineno(1))
		p[0] = instruction


	def p_repeat_instr(self, p):
		"""repeat_instr : REPEAT instructions UNTIL condition ';' """

		instruction = AST.RepeatUntilInstr(p[4], p[2], p.lineno(1))
		p[0] = instruction


	def p_continue_instr(self, p):
		"""continue_instr : CONTINUE ';' """

		instruction = AST.ContinueInstr("CONTINUE", p.lineno(1))
		p[0] = instruction


	def p_break_instr(self, p):
		"""break_instr : BREAK ';' """

		instruction = AST.BreakInstr("BREAK", p.lineno(1))
		p[0] = instruction


	def p_labeled_instr(self, p):
		"""labeled_instr : ID ':' instruction """

		p[0] = p[3]


	def p_assignment(self, p):
		"""assignment : ID '=' expression ';' """

		declared_var = self.symbol_table.get(p[1])
		actual_type = p[3].type
		
		#~ if(declared_var is not None):
			#~ declared_type = declared_var.type
		#~ else:
			#~ declared_type = "__UNKNOWN__"
#~ 
		#~ if(declared_type != actual_type):
			#~ if(declared_type == "int" and actual_type == "float"):
				#~ print("Line [" + str(p.lineno(1)) + "]: Warning! Implicit type convertion (float -> int)!")
			#~ elif(declared_type != "float" or actual_type != "int"):
				#~ if(declared_type == "__UNKNOWN__"):
					#~ print("Line [" + str(p.lineno(1)) + "]: Variable has not been declared!")
				#~ else:
					#~ print("Line [" + str(p.lineno(1)) + "]: Assignment type mismatch!")
		#~ 
		expr = AST.AssignInstr(actual_type, AST.Id(actual_type, p[1], p.lineno(1)), p[3], p.lineno(1))
		p[0] = expr


	def p_compound_instr(self, p):
		"""compound_instr : '{' blocks '}' """

		p[0] = p[2]


	def p_condition(self, p):
		"""condition : expression"""

		if(p[1].type != "bool"):
			print("Line [" + str(p.lineno(p[1]) + "]: Condition should be of type BOOL!"))
			
		condition = AST.Condition(p[1], p.lineno(1))
		p[0] = condition


	def p_bin_expression(self, p):
		"""bin_expression : expression '+' expression
						  | expression '-' expression
						  | expression '*' expression
						  | expression '/' expression
						  | expression '%' expression
						  | expression '|' expression
						  | expression '&' expression
						  | expression '^' expression
						  | expression AND expression
						  | expression OR expression
						  | expression SHL expression
						  | expression SHR expression
						  | expression EQ expression
						  | expression NEQ expression
						  | expression '>' expression
						  | expression '<' expression
						  | expression LE expression
						  | expression GE expression """
		
		left_expr = p[1]
		op = p[2]
		right_expr = p[3]
		
		result_type = self.operation_results[op][left_expr.type][right_expr.type]
		expr = AST.BinExpr(result_type, op, left_expr, right_expr, p.lineno(1))
		
		#~ result_type = self.operation_results[op][left_expr.type][right_expr.type]
		#~ 
		#~ if(result_type is not None):
			#~ expr = AST.BinExpr(result_type, op, left_expr, right_expr, p.lineno(1))
		#~ else:
			#~ expr = AST.BinExpr("__UNKNOWN__", op, left_expr, right_expr, p.lineno(1))
			#~ print("Line [" + str(p.lineno(2)) + "]: Invalid binary expression!")
			#~ 
			
		p[0] = expr

	def p_const_int(self, p):
		"""const : INTEGER """
		
		const = AST.Const("int", p[1], p.lineno(1))
		p[0] = const
		
	def p_const_float(self, p):
		"""const : FLOAT """
		
		const = AST.Const("float", p[1], p.lineno(1))
		p[0] = const
	
	def p_const_string(self, p):
		"""const : STRING """
		
		const = AST.Const("string", p[1], p.lineno(1))
		p[0] = const


	def p_id(self, p):
		"""id : ID"""
		
		identifier = AST.Id("?", p[1], p.lineno(1))
		p[0] = identifier


	def p_expression(self, p):
		"""expression : id
					  | const
					  | bin_expression
					  | paren_expression
					  | funcall"""
		p[0] = p[1]


	def p_paren_expression(self, p):
		"""paren_expression : '(' expression ')'
							| '(' error ')' """
		p[0] = p[2]


	def p_expr_list_or_empty(self, p):
		"""expr_list_or_empty : expr_list
							  | """
		if(len(p) > 1):
			p[0] = p[1]
		else:
			p[0] = []


	def p_expr_list(self, p):
		"""expr_list : expr_list ',' expression
					 | expression """

		if(len(p) > 3):
			p[1].append(p[3])
			p[0] = p[1]
		else:
			p[0] = [p[1]]

	def p_fundef(self, p):
		"""fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
		
		return_type = p[1]
		fun_name = p[2]
		fun_id = AST.Id(p[1], p[2], p.lineno(1))
		args = p[4]
		fundef = AST.FunDefinition(return_type, fun_id, args, p.lineno(1), p[6])
		p[0] = fundef


	def p_funcall(self, p):
		"""funcall : ID '(' expr_list_or_empty ')'
				   | ID '(' error ')' """

		funcall = AST.FunCall(AST.Id("?", p[1], p.lineno(1)), p[3], p.lineno(1))
		p[0] = funcall


	def p_args_list_or_empty(self, p):
		"""args_list_or_empty : args_list
							  | """

		if(len(p) > 1):
			p[0] = p[1]
		else:
			p[0] = []

	def p_args_list(self, p):
		"""args_list : args_list ',' arg
					 | arg """

		if(len(p) > 3):
			p[1].append(p[3])
			p[0] = p[1]
		else:
			p[0] = [p[1]]


	def p_arg(self, p):
		"""arg : TYPE ID """

		arg = AST.FunArg(p[1], p[2], p.lineno(1))
		p[0] = arg
Пример #11
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.errorsOccured = False

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))

        else:
            print('At end of input')
        self.errorsOccured = True

    def p_program(self, p):
        """program : classdefs declarations fundefs instructions"""
        p[0] = AST.Program(p[1], p[2], p[3], p[4])

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) > 1:
            p[1].list.append(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.Declarations()

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | id classinits ';'
                       | error ';' """
        if len(p) > 2:
            p[0] = AST.Declaration(p[1], p[2])
        else:
            p[0] = p[1]

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) > 2:
            p[1].list.append(p[3])
            p[0] = p[1]
        else:
            inits = AST.Inits()
            inits.list.append(p[1])
            p[0] = inits

    def p_init(self, p):
        """init : id '=' expression """
        p[0] = AST.Init(p[1], p[3])

    def p_classinits(self, p):
        """classinits : classinits ',' classinit
                      | classinit """
        if len(p) > 2:
            p[1].list.append(p[3])
            p[0] = p[1]
        else:
            classinits = AST.Classinits()
            classinits.list.append(p[1])
            p[0] = classinits

    def p_classinit(self, p):
        """classinit : id """
        p[0] = AST.Classinit(p[1])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 2:
            instructions = AST.Instructions()
            instructions.list.append(p[1])
            p[0] = instructions
        else:
            p[1].list.append(p[2])
            p[0] = p[1]

    def p_instruction(self, p):
        """instruction : expression ';'
                       | print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : id ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3])

    def p_assignment(self, p):
        """assignment : access '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3])

    def p_access(self, p):
        """access : id
                  | id '.' id """

        if len(p) == 2:
            access = AST.Access(p.lineno(1))
            access.list.append(p[1])
            p[0] = access
        else:
            access = AST.Access(p.lineno(1))
            access.list.append(p[1])
            access.list.append(p[3])
            p[0] = access

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 6:
            p[0] = AST.ChoiceInstr(p[3], p[5], None)
        else:
            p[0] = AST.ChoiceInstr(p[3], p[5], p[7])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Continue()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Break()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}'"""
        p[0] = AST.CompoundInstr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])

    def p_const(self, p):
        """const : integer
                 | float
                 | string"""
        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        p[0] = AST.Integer(p[1], p.lineno(1))

    def p_float(self, p):
        """float : FLOAT"""
        p[0] = AST.Float(p[1], p.lineno(1))

    def p_string(self, p):
        """string : STRING"""
        p[0] = AST.String(p[1][1:-1], p.lineno(1))

    def p_id(self, p):
        """id : ID"""
        p[0] = AST.Id(p[1], p.lineno(1))

    def p_expression(self, p):
        """expression : const
                      | access
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | access '(' expr_list_or_empty ')'
                      | access '(' error ')' """
        if len(p) == 2:
            p[0] = p[1]
        elif p[1] == '(':
            p[0] = AST.ParExpr(p[2])
        elif len(p) == 4:
            p[0] = AST.BinExpr(p[1], p[2], p[3])
        else:
            p[0] = AST.FunExpr(p[1], p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 1:
            p[0] = AST.ExprList()
        else:
            p[0] = p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[1].list.append(p[3])
            p[0] = p[1]
        else:
            toReturn = AST.ExprList()
            toReturn.list.append(p[1])
            p[0] = toReturn

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.FunDefs()

    def p_fundef(self, p):
        """fundef : TYPE id '(' args_list_or_empty ')' compound_instr
                  | id id '(' args_list_or_empty ')' compound_instr"""
        p[0] = AST.FunDef(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 1:
            p[0] = AST.ArgList()
        else:
            p[0] = p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 2:
            argList = AST.ArgList()
            argList.list.append(p[1])
            p[0] = argList
        else:
            p[1].list.append(p[3])
            p[0] = p[1]

    def p_arg(self, p):
        """arg : TYPE id
               | id id"""
        p[0] = AST.Arg(p[1], p[2])

    def p_classdefs(self, p):
        """classdefs : classdef classdefs
                   |  """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.ClassDefs()

    def p_classdef(self, p):
        """classdef : accessmodificator CLASS id classcontent
                  | accessmodificator CLASS id EXTENDS id classcontent"""
        if len(p) < 7:
            p[0] = AST.ClassDef(p[1], p[3], None, p[4])
        else:
            p[0] = AST.ClassDef(p[1], p[3], p[5], p[6])

    def p_classcontent(self, p):
        """classcontent : '{' fielddefs ';' methoddefs '}' """
        p[0] = AST.Classcontent(p[2], p[4])

    def p_fielddefs(self, p):
        """fielddefs : fielddef fielddefs
                     | """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.Fielddefs()

    def p_fielddef(self, p):
        """fielddef : accessmodificator declaration """
        p[0] = AST.Fielddef(p[1], p[2])

    def p_methoddefs(self, p):
        """methoddefs : methoddef methoddefs
                     | """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.Methoddefs()

    def p_methoddef(self, p):
        """methoddef : accessmodificator fundef"""
        p[0] = AST.Methoddef(p[1], p[2])

    def p_accessmodificator(self, p):
        """accessmodificator : PRIVATE
                             | PROTECTED
                             | PUBLIC"""
        p[0] = p[1]
Пример #12
0
class Mparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.args = {}
        self.const = {}

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("nonassoc", 'LT', 'GT', 'EQ', 'NE', 'LE', 'GE'),
        ("left", '+', '-'),
        ("left", '*', '/'),
        ("left", 'DOTADD', 'DOTSUB'),
        ("left", 'DOTMUL', 'DOTDIV'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : instructions"""

        p[0] = AST.Program(p[1])
        print(p[0])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """

        if len(p) == 3:
            p[1].instrs.append(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.Instructions(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | for_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""

        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """

        p[0] = AST.Print(p[2])

    def p_assignment(self, p):
        """assignment : id assign_operator expression ';' 
                      | ref assign_operator expression ';' """

        p[0] = AST.Assignment(p[1], p[2], p[3])

    def p_ref(self, p):
        """ref : id '[' expr_list ']' """

        p[0] = AST.Ref(p[1], p[3])

    def p_assign_operator(self, p):
        """assign_operator : '='
                           | ADDASSIGN
                           | SUBASSIGN
                           | MULASSIGN
                           | DIVASSIGN"""

        p[0] = AST.Assign_operator(p[1])

    def p_vector(self, p):
        """vector : '[' expressions ']' """

        p[0] = AST.Vector(p[2])

    def p_expressions_or_vectors(self, p):
        """expressions : expression
                       | expressions ',' expression """

        if len(p) == 4:
            p[1].exprs.append(p[3])
            p[0] = p[1]
        else:
            p[0] = AST.Expressions(p[1])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

        if len(p) == 6:
            p[0] = AST.Choice(p[3], p[5])
        else:
            p[0] = AST.Choice(p[3], p[5], p[7])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """

        p[0] = AST.While(p[3], p[5])

    def p_for_instr(self, p):
        """for_instr : FOR id '=' range instruction"""

        p[0] = AST.For(p[2], p[4], p[5])

    def p_range(self, p):
        """range : expression ':' expression"""

        p[0] = AST.Range(p[1], p[3])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """

        p[0] = AST.Return(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """

        p[0] = AST.Continue()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """

        p[0] = AST.Break()

    def p_compound_instr(self, p):
        """compound_instr : '{' instructions '}' """

        p[0] = AST.ComInstructions(p[2])

    def p_condition(self, p):
        """condition : expression"""

        p[0] = p[1]

    def p_const(self, p):
        """const : INTNUM
                 | FLOATNUM
                 | STRING"""

        p[0] = AST.Const(p[1])

    def p_expression(self, p):
        """expression : const
                      | id
                      | ref
                      | vector
                      | matrix_operation
                      | matrix_function
                      | minus_matrix
                      | matrix_transposed
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression EQ expression
                      | expression NE expression
                      | expression LT expression
                      | expression GT expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'"""

        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4:
            if p[1] == '(':
                p[0] = p[2]
            else:
                if p[2] in ['+', '-', '*', '/']:
                    p[0] = AST.BinExpr(p[1], p[2], p[3])
                else:
                    p[0] = AST.Condition(p[1], p[2], p[3])

    def p_id(self, p):
        """id : ID"""

        p[0] = AST.Variable(p[1], 0)

    def p_matrix_operation(self, p):
        """matrix_operation : matrix dot_operation matrix"""

        p[0] = AST.Matrix_operation(p[1], p[2], p[3])

    def p_dot_operation(self, p):
        """dot_operation : DOTADD
                         | DOTSUB
                         | DOTMUL
                         | DOTDIV"""

        p[0] = AST.Dot_operation(p[1])

    def p_matrix(self, p):
        """matrix : id
                  | minus_matrix
                  | matrix_transposed"""

        p[0] = AST.Matrix(p[1])

    def p_matrix_transposed(self, p):
        """matrix_transposed : matrix "'" """

        p[0] = AST.Matrix_transposed(p[1])

    def p_minus_matrix(self, p):
        """minus_matrix : "-" matrix """

        p[0] = AST.Minus_matrix(p[2])

    def p_matrix_function(self, p):
        """matrix_function : ZEROS '(' expressions ')'
                           | ONES '(' expressions ')'
                           | EYE  '(' expressions ')' """

        p[0] = AST.Matrix_function(p[1], p[3])

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """

        if len(p) == 4:
            p[1].exprs.append(p[3])
            p[0] = p[1]
        else:
            p[0] = AST.Expressions(p[1])
Пример #13
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : blocks"""
        p[0] = AST.Program(p[1])
        TreePrinter()
        print p[0]

    def p_blocks(self, p):
        """blocks : blocks block
                  | """
        if len(p) == 3:
            p[0] = p[1] + [p[2]]
        else:
            p[0] = []

    def p_block(self, p):
        """block : declaration
                 | instruction
                 | fundef"""
        p[0] = AST.Block(p[1])

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) > 3:
            p[0] = AST.Declaration(p[2])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        else:
            p[0] = [p[1]]

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Variable(p[1], p[3])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = [p[1]]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        p[0] = [AST.Instruction(p[1], p[2])]

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = [AST.Instruction(p[2], [p[1], p[3]])]

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = [AST.Instruction(p[2], [p[1], p[3]])]

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 6:
            p[0] = [AST.Instruction(p[1], [p[3], p[5]])
                    ]  #Instruction(IF, [condition, instruction])
        elif len(p) == 8:
            p[0] = [
                AST.Instruction(p[1], [p[3], p[5]]),
                AST.Instruction(p[6], [p[7]])
            ]  #Instruction(IF, [condition, instruction])
            #Instruction(ELSE, [instruction])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = [AST.Instruction(p[1], [p[3], p[5]])]

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instruction UNTIL condition ';' """
        p[0] = [AST.Instruction(p[1], [p[2]]), AST.Instruction(p[3], [p[4]])]

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = [AST.Instruction(p[1], [p[2]])]

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = [AST.Instruction(p[1], [])]

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = [AST.Instruction(p[1], [])]

    def p_compound_instr(self, p):
        """compound_instr : '{' comp_instr_blocks '}' """
        p[0] = p[2]

    def p_comp_instr_blocks(self, p):
        """comp_instr_blocks : comp_instr_blocks comp_instr_block
                             | """
        if len(p) == 3:
            p[0] = p[1] + [p[2]]
        else:
            p[0] = []

    def p_comp_instr_block(self, p):
        """comp_instr_block : declaration
                            | instruction"""
        p[0] = AST.Block(p[1])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        if type(p[1]) == int:
            p[0] = AST.Const(AST.Integer(p[1]))
        elif type(p[1]) == float:
            p[0] = AST.Const(AST.Float(p[1]))
        elif type(p[1]) == str:
            p[0] = AST.Const(AST.String(p[1]))

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 4:
            if (p[1] == '('):
                p[0] = p[2]
            else:
                p[0] = AST.BinExpr(p[2], p[1], p[3])
        elif len(p) == 5:
            p[0] = AST.Instruction('FUNCALL', [p[1], p[3]])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = []

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        else:
            p[0] = [p[1]]

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = []

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        else:
            p[0] = [p[1]]

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2])
Пример #14
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def handle_error(self, where, p):
        print("Syntax error in %s at line %d, column %d, at token LexToken(%s, '%s')" %\
          (where, p.lineno, self.scanner.find_tok_column(p), p.type, p.value))

    def p_error(self, p):
        if not p:
            print 'Unexpected end of input'
        else:
            # let the productions handle the error on their own
            pass

    def p_program(self, p):
        """program : ext_declarations fundefs instructions"""
        p[0] = Program(p[1], p[2], p[3], pos(p))
        p[0].printTree(0)

    def p_ext_declarations(self, p):
        """ext_declarations : declarations"""
        p[0] = p[1]

    def p_declarations(self, p):
        """declarations : declarations declaration"""
        if p[2]:
            p[0] = DeclarationList(p[1].decls + [p[2]])
        else:  # error
            p[0] = p[1]

    def p_declarations_single(self, p):
        """declarations : declaration"""
        if p[1]:
            p[0] = DeclarationList([p[1]])
        else:  # error
            p[0] = DeclarationList([])

    def p_declaration_blank(self, p):
        """declarations : """
        p[0] = DeclarationList([])

    def p_declaration_fundef(self, p):
        """declaration : fundefs"""
        p[0] = p[1]

    def p_declaration(self, p):
        """declaration : TYPE inits ';' """
        p[0] = Declaration(p[1], p[2], pos(p))

    def p_declaration_error(self, p):
        """declaration : error ';' """
        self.handle_error('declaration', p[1])

    def p_inits(self, p):
        """inits : inits ',' init"""
        p[0] = InitList(p[1].inits + [p[3]])

    def p_inits_single(self, p):
        """inits : init"""
        p[0] = InitList([p[1]])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3])

    def p_instructions(self, p):
        """instructions : instructions instruction"""
        if p[2]:
            p[0] = InstructionList(p[1].instrs + [p[2]])
        else:
            p[0] = p[1]

    def p_instructions_single(self, p):
        """instructions : instruction """
        if p[1]:
            p[0] = InstructionList([p[1]])
        else:
            p[0] = InstructionList([])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';' """
        p[0] = PrintInstruction(p[2])

    def p_print_error(self, p):
        """print_instr : PRINT error ';' """
        self.handle_error('print instruction', p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = LabeledInstruction(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        if p[3]:
            p[0] = Assignment(p[1], p[3], pos(p))
        else:  # error
            pass

    def p_assignment_error(self, p):
        """assignment : ID '=' error ';' """
        self.handle_error('assignment', p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX"""
        p[0] = ChoiceInstruction(p[3], p[5])

    def p_choice_instr_else(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction"""
        p[0] = ChoiceInstruction(p[3], p[5], p[7])

    def p_choice_instr_error(self, p):
        """choice_instr : IF '(' error ')' instruction  %prec IFX"""
        self.handle_error('if condition', p[3])

    def p_choice_instr_else_error(self, p):
        """choice_instr : IF '(' error ')' instruction ELSE instruction"""
        self.handle_error('if condition', p[3])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction"""
        p[0] = WhileInstruction(p[1], p[3], p[5])

    def p_while_error(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        self.handle_error('while instruction', p[3])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = RepeatInstruction(p[1], p[2], p[3], p[4])

    def p_repeat_error(self, p):
        """repeat_instr : REPEAT instructions UNTIL error ';' """
        self.handle_error('repeat instruction', p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = ReturnInstruction(p[2], pos(p))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = ContinueInstruction()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = BreakInstruction()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = CompoundInstructions(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const_integer(self, p):
        """const : INTEGER"""
        p[0] = Integer(p[1])

    def p_const_float(self, p):
        """const : FLOAT"""
        p[0] = Float(p[1])

    def p_const_string(self, p):
        """const : STRING"""
        p[0] = String(p[1])

    def p_expression_const(self, p):
        """expression : const"""
        p[0] = p[1]

    def p_expression_id(self, p):
        "expression : ID"
        p[0] = Variable(p[1], pos(p))

    def p_expression_brackets(self, p):
        "expression : '(' expression ')'"
        p[0] = p[2]

    def p_expression_brackets_error(self, p):
        "expression : '(' error ')'"
        self.handle_error("expression (bracket)", p[2])

    def p_expression_fun_call(self, p):
        "expression : ID '(' expr_list_or_empty ')'"
        p[0] = FunctionCall(p[1], p[3], pos(p))

    def p_expression_fun_call_error(self, p):
        "expression : ID '(' error ')'"
        self.handle_error('function call', p[3])

    def p_expression_binary_op(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""

        p[0] = BinExpr(p[1], p[2], p[3], pos(p))

    def p_expr_list_non_empty(self, p):
        """expr_list_or_empty : expr_list"""
        p[0] = p[1]

    def p_expr_list_empty(self, p):
        """expr_list_or_empty : """
        p[0] = ExprList([])

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression"""
        p[0] = ExprList(p[1].exprs + [p[3]])

    def p_expr_list_single(self, p):
        """expr_list : expression"""
        p[0] = ExprList([p[1]])

    # def p_fundefs(self, p):
    #     """fundefs : fundefs fundef
    #                | fundef """
    #     if p[2]:
    #         p[0] = FunctionDefList(p[1].fundefs + [ p[2] ])
    #     else:
    #         p[0] = FunctionDefList([ p[1] ])

    def p_fundefs(self, p):
        """fundefs : fundefs fundef"""
        p[0] = FunctionDefList(p[1].fundefs + [p[2]])

    def p_fundefs_single(self, p):
        """fundefs : fundef"""
        p[0] = FunctionDefList([p[1]])

    def p_fundefs_empty(self, p):
        """fundefs : """
        p[0] = FunctionDefList([])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = FunctionDef(p[1], p[2], p[4], p[6], pos(p))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if p[1]:
            p[0] = p[1]
        else:
            p[0] = ArgsList([])

    # def p_args_list(self, p):
    #     """args_list : args_list ',' arg
    #                  | arg """
    #     if p[3]:
    #         p[0] = ArgsList(p[1].args + [ p[3] ])
    #     else:
    #         p[0] = ArgsList([ p[1] ])

    def p_args_list(self, p):
        """args_list : args_list ',' arg"""
        p[0] = ArgsList(p[1].args + [p[3]])

    def p_args_list_single(self, p):
        """args_list : arg"""
        p[0] = ArgsList([p[1]])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Arg(p[1], p[2])
Пример #15
0
class Cparser(object):


     def __init__(self):
          self.scanner = Scanner()
          self.scanner.build()
          self.error = False

     tokens = Scanner.tokens

     precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
     )


     def p_error(self, p):
          if p:
               self.error = True
               print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
               while 1:
               	       tok = yacc.token()
               	       if not tok or tok.type == 'RBRACE': break
               yacc.restart()
          else:
               print('At end of input')

     
     
     def p_program(self, p):
          """program : declarations fundefs instructions"""
          p[0] = AST.Program(p[1], p[2], p[3], p.lineno(1))
     
     def p_declarations(self, p):
          """declarations : declarations declaration
                              | """
          if len(p) > 2:
            p[0] = p[1]
            p[1].append(p[2])
          else:
            p[0] = []
                          
     
     def p_declaration(self, p):
          """declaration : TYPE inits ';'"""
          if len(p) > 3:
               p[0] = AST.Variable(p[1], p[2], p.lineno(1))

     def p_inits(self, p):
          """inits : inits ',' init
                     | init """
          if len(p) > 2:
               p[0] = p[1]
               p[1].append(p[3])
          else:
               p[0] = [p[1]]


     def p_init(self, p):
          """init : ID '=' expression
                     | ID """
          if len(p) > 3:
              p[0] = AST.Declaration(p[1], p[2], p[3], p.lineno(1))
          else:
              p[0] = AST.Declaration(p[1], None, None, p.lineno(1))


     
     def p_instructions(self, p):
          """instructions : instructions instruction
                              | instruction 
                              | """
          if len(p) > 2:
               p[0] = p[1]
               p[1].append(p[2])
          elif len(p) == 2:
               p[0] = [p[1]]
          else:
               p[0] = []
     
     
     def p_instruction(self, p):
          """instruction : print_instr
                            | labeled_instr
                            | assignment
                            | choice_instr
                            | while_instr 
                            | repeat_instr 
                            | return_instr
                            | break_instr
                            | continue_instr
                            | compound_instr
                            | funcall"""
          p[0] = p[1]
     
     
     def p_print_instr(self, p):
          """print_instr : PRINT expression ';'
                            | PRINT error ';' """
          p[0] = AST.Print(p[2], p.lineno(1))
     
     
     def p_labeled_instr(self, p):
          """labeled_instr : ID ':' instruction """
          p[0] = AST.Label(p[1], p[3], p.lineno(1))
     
     
     def p_assignment(self, p):
          """assignment : ID '=' expression ';' """
          p[0] = AST.Assignment(p[1], p[2], p[3], p.lineno(1))
     
     
     def p_choice_instr(self, p):
          """choice_instr : IF '(' condition ')' instruction  %prec IFX
                              | IF '(' condition ')' instruction ELSE instruction
                              | IF '(' error ')' instruction  %prec IFX
                              | IF '(' error ')' instruction ELSE instruction """
          if len(p) > 6:     
               p[0] = AST.ChoiceInstructionWithElse(p[3], p[5], p[7], p.lineno(1))
          else:
               p[0] = AST.ChoiceInstruction(p[3], p[5], p.lineno(1))

     def p_while_instr(self, p):
          """while_instr : WHILE '(' condition ')' instruction
                            | WHILE '(' error ')' instruction """
          p[0] = AST.WhileLoop(p[3], p[5], p.lineno(1))


     def p_repeat_instr(self, p):
          """repeat_instr : REPEAT instructions UNTIL condition ';' """
          p[0] = AST.RepeatUntilLoop(p[2], p[4], p.lineno(1))
     
     
     def p_return_instr(self, p):
          """return_instr : RETURN expression ';' """
          p[0] = AST.Return(p[2], p.lineno(1))
     
     def p_continue_instr(self, p):
          """continue_instr : CONTINUE ';' """
          p[0] = AST.Continue(p.lineno(1))
     
     def p_break_instr(self, p):
          """break_instr : BREAK ';' """
          p[0] = AST.Break(p.lineno(1))
     
     def p_compound_instr(self, p):
          """compound_instr : '{' declarations instructions '}' """
          p[0] = AST.CompoundInstruction(p[2], p[3], p.lineno(1))

     
     def p_condition(self, p):
          """condition : expression"""
          p[0] = p[1]

     def p_const_int(self, p):
          """const : INTEGER"""
          p[0] = AST.Integer(p[1], p.lineno(1))


     def p_const_float(self, p):
          """const : FLOAT"""
          p[0] = AST.Float(p[1], p.lineno(1))

     def p_const_char(self, p):
          """const : CHAR"""
          p[0] = AST.Char(p[1], p.lineno(1))

     def p_expression(self, p):
          """expression : const
                           | ID"""
          p[0] = p[1]
     
     def p_expression_function(self, p):
          """expression : ID '(' expr_list_or_empty ')'
                           | ID '(' error ')' """
          p[0] = AST.FunctionCall(p[1], p[3], p.lineno(1))                 
          
     
     def p_expression_binop(self, p):
          """expression : expression '+' expression
                           | expression '-' expression
                           | expression '*' expression
                           | expression '/' expression
                           | expression '%' expression
                           | expression '|' expression
                           | expression '&' expression
                           | expression '^' expression
                           | expression AND expression
                           | expression OR expression
                           | expression SHL expression
                           | expression SHR expression"""
          p[0] = AST.BinExpr(p[1], p[2], p[3], p.lineno(2))
          
     def p_expression_relop(self, p):
          """expression : expression EQ expression
                           | expression NEQ expression
                           | expression '>' expression
                           | expression '<' expression
                           | expression LE expression
                           | expression GE expression"""
          p[0] = AST.RelExpr(p[1], p[2], p[3], p.lineno(2))
          
     def p_expression_group(self, p):
          """expression : '(' expression ')'
                         | '(' error ')'"""
          p[0] = p[2]
     
     def p_expr_list_or_empty(self, p):
          """expr_list_or_empty : expr_list
                                     | """
          if len(p) == 2:
               p[0] = p[1]
          else:
               p[0] = []
     
     def p_expr_list(self, p):
          """expr_list : expr_list ',' expression
                          | expression """
          if len(p) > 2:
               p[0] = p[1]
               p[1].append(p[3])
          else:
               p[0] = [p[1]]
     
     
     def p_fundefs(self, p):
          """fundefs : fundef fundefs
                       |  """
          if len(p) > 2:
               p[0] = p[2]
               p[2].append(p[1])
          else:
               p[0] = []

     def p_fundef(self, p):
          """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
          p[0] = AST.FunctionDefinition(p[1], p[2], p[4], p[6], p.lineno(1))
          
     def p_funcall(self, p):
          """funcall : ID '(' expr_list_or_empty ')' ';'
                           | ID '(' error ')' ';'"""
          p[0] = AST.FunctionCall(p[1], p[3], p.lineno(1))  
     
     
     def p_args_list_or_empty(self, p):
          """args_list_or_empty : args_list
                                     | """
          if len(p) == 2:
               p[0] = p[1]
          else:
               p[0] = []
     
     def p_args_list(self, p):
          """args_list : args_list ',' arg 
                          | arg """
          if len(p) > 2:
               p[0] = p[1]
               p[1].append(p[3])
          else:
               p[0] = [p[1]]
     
     def p_arg(self, p):
          """arg : TYPE ID """
          p[0] = AST.Argument(p[1], p[2], p.lineno(2))
Пример #16
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = AST.Main(p.lineno(1), p[1], p[2], p[3])

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) != 1:
            p[0] = AST.DeclarationsMany(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.DeclarationsNone(p.lineno(0))

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) != 3:
            p[0] = AST.DeclarationMany(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.DeclarationSingle(p.lineno(1), p[1])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) != 2:
            p[0] = AST.InitsMany(p.lineno(1), p[3], p[1])
        else:
            p[0] = AST.InitsSingle(p.lineno(1), p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p.lineno(1), p[1], p[3])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) != 2:
            p[0] = AST.InstructionsMany(p.lineno(1), p[2], p[1])
        else:
            p[0] = AST.InstructionsSingle(p.lineno(1), p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = AST.Instruction(p.lineno(1), p[1])

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.Print_instr(p.lineno(1), p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.Labeled_instr(p.lineno(1), p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p.lineno(1), p[1], p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) != 8:
            p[0] = AST.Choice_instr(p.lineno(1), p[3], p[5])
        else:
            p[0] = AST.Choice_instr_with_else(p.lineno(1), p[3], p[5], p[7])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.While_instr(p.lineno(1), p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.Repeat_instr(p.lineno(1), p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return_instr(p.lineno(1), p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Continue_instr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Break_instr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.Compound_instr(p.lineno(1), p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        #p[0] = AST.Condition(p.lineno(1), p[1])
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        (value, types) = p[1]
        if types == "int":
            p[0] = AST.Integer(p.lineno(1), p[1])
        elif types == "float":
            p[0] = AST.Float(p.lineno(1), p[1])
        else:
            p[0] = AST.String(p.lineno(1), p[1])

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            if isinstance(p[1], str):
                p[0] = AST.ExpressionSimple(p.lineno(1), p[1])
            else:
                #p[0] = AST.ExpressionSimple(p[1].lineno, p[1])
                p[0] = p[1]
        else:
            if p[1] == '(' and p[3] == ')':
                p[0] = AST.ExprInBrackets(p.lineno(1), p[2])
            else:
                if p[2] == '(' and p[4] == ')':
                    p[0] = AST.Funcalls(p.lineno(1), p[1], p[3])
                else:
                    p[0] = AST.BinExpr(p.lineno(2), p[1], p[2], p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = AST.ExpressionList() if p[1] is None else p[1]
            p[0].addExpression(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].addExpression(p[1])

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) != 1:
            p[0] = AST.Fundefs_many(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.Fundefs(p.lineno(0))

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(p.lineno(1), p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            p[0] = AST.ArgumentList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ArgumentList()
            p[0].addArgument(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p.lineno(1), p[1], p[2])
Пример #17
0
def testFile(fname):
    lex = Scanner()
    lex.build()
    
    readFile(fname, lex.Lexer)
Пример #18
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')

    
    
    def p_program(self, p):
        """program : toplevel_statements """
        p[0] = p[1]
        
        
    def p_toplevel_statements(self, p):
        """toplevel_statements : toplevel_statements toplevel_statement
                  | """
        if len(p) == 3:
            p[1].toplevel_statements.append(p[2])
            p[0] = p[1]
            return
        p[0] = AST.ToplevelStatements()
        
    def p_toplevel_statement(self, p):
        """toplevel_statement : declaration
                 | instruction
                 | fundef """
        p[0] = p[1]
        
    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            p[1].declarations.append(p[2])
            p[0] = p[1]
            return
        p[0] = AST.Declarations()
        

    
    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            p[0] = AST.Declaration(p[1], p[2])
        else:
            p[0] = p[1]
            
        
        
    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[1].inits.append(p[3])
            p[0] = p[1]
            return
        p[0] = AST.Inits()
        p[0].inits.append(p[1])       
            
    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3])
        
    
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[1].instructions.append(p[2])
            p[0] = p[1]
            return
        p[0] = AST.Instructions()
        p[0].instructions.append(p[1])
    
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]
    
    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        if len(p) == 4:
            p[0] = AST.PrintStatement(p[2])
    
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1],p[3])
        
    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Init(p[1], p[3])
        
    
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 8:
            p[0] = AST.IfStatement(p[3], p[5], p[7])
            return
        p[0] = AST.IfStatement(p[3], p[5])
    
    
    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileLoop(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatLoop(p[2], p[4])
    
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnValue(p[2])
        
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction(p[2])
        
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction(p[2], p[4])
    
    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstruction(p[2], p[3])
    
    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        if p[1].isdigit():
            if isinstance(num(p[1]), int):
                p[0] = AST.Integer(num(p[1]))
                return
            if isinstance(num(p[1]), float):
                p[0] = AST.Float(num(p[1]))
                return
        p[0] = AST.String(p[1])
    
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            if isinstance(p[1], AST.Const):
                p[0] = AST.Const(p[1])
                return
            id = AST.String(p[1])
            p[0] = AST.Const(id)
            return
        if isinstance(p[1], AST.Expression) & isinstance(p[3], AST.Expression):
            p[0] = AST.BinExpr(p[2], p[1], p[3])
            return
        if p[1] == '(':
            p[0] = p[2]
            return
        if p[2] == '(':
            p[0] = AST.FunCall(p[1], p[3])
    
    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
            return
        p[0] = AST.Expressions()
        
    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[1].expression_list.append(p[3])
            p[0] = p[1]
            return
        p[0] = AST.Expressions()
        p[0].expression_list.append(p[1])
    
    
        
    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        
        p[0] = AST.FunDef(p[1], p[2], p[4], p[6])
        
        
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
                              
        if len(p) == 2:
            p[0] = p[1]
            return
        p[0] = AST.ArgumentList()
        
        
    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[1].argument_list.append(p[3])
            p[0] = p[1]
            return
        p[0] = AST.ArgumentList()
        p[0].argument_list.append(p[1])
        
    def p_arg(self, p):
        """arg : TYPE ID """
 
        p[0] = AST.Argument(p[1], p[2])
Пример #19
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IF'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '^'),
        ("nonassoc", '<', '>', '=', 'NEQ', 'LE', 'GE'),
        ("left", '+', '-'),
        ("left", '*', '/', 'MOD', 'DIV'),
    )

    error_encountered = False


    def convert_from_string(self, value, lineno):
        try:
            return Integer(int(value), lineno)
        except ValueError:
            try:
                return Float(float(value), lineno)
            except ValueError:
                return String(value, lineno)

    def p_error(self, p):
        self.error_encountered = True
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print('At end of input')


    def p_program(self, p):
        """program : program_header declarations compound_statement '.'"""
        p[0] = Program(p[1], p[2], p[3])


    def p_program_header(self, p):
        """program_header : PROGRAM_LITERAL ID ';'
                          | PROGRAM_LITERAL ID '(' id_list ')' ';' """
        if len(p) == 4:
            p[0] = ProgramHeader(p[2])
        else:
            p[0] = ProgramHeader(p[2], p[4])

    def p_declarations(self, p):
        """declarations : constant_definitions type_definitions variable_declarations procedure_declarations"""
        p[0] = Declarations(p[1], p[2], p[3], p[4])

    def p_constant_definitions(self, p):
        """constant_definitions : CONST constant_definition_list
                                | """
        if len(p) == 1:
            p[0] = list()
        else:
            p[0] = p[2]


    def p_constant_definition_list(self, p):
        """constant_definition_list : constant_definition_list const_def
                                    | const_def """
        if len(p) == 2:
            p[0] = list()
            p[0].append(p[1])
        else:
            p[1].append(p[2])
            p[0] = p[1]


    def p_const_def(self, p):
        """const_def : ID '=' CONSTANT ';'"""
        const_value = self.convert_from_string(p[3], p.lineno(1))
        p[0] = ConstDef(const_value, p[1], p.lineno(1))


    def p_type_definitions(self, p):
        """type_definitions : TYPE type_definition_list
                            | """
        if len(p) == 1:
            p[0] = list()
        else:
            p[0] = p[2]


    def p_type_definition_list(self, p):
        """type_definition_list : type_definition_list type_def
                                | type_def"""
        if len(p) == 2:
            p[0] = list()
            p[0].append(p[1])
        else:
            p[1].append(p[2])
            p[0] = p[1]

    def p_type_def(self, p):
        """type_def : ID '=' type_specifier ';'"""
        pass

    def p_variable_declarations(self, p):
        """variable_declarations : VAR variable_declaration_list
                                 | """
        if len(p) == 1:
            p[0] = list()
        else:
            p[0] = p[2]

    def p_variable_declaration_list(self, p):
        """variable_declaration_list : variable_declaration_list var_dec
                                     | var_dec"""
        if len(p) == 2:
            p[0] = list()
            p[0].append(p[1])
        else:
            p[1].append(p[2])
            p[0] = p[1]

    # def p_variable_declaration_list_error(self, p):
    #     """variable_declaration_list : error"""
    #     print "Bad declaration at line ", p.lineno(1)
    #     self.error_encountered = True

    def p_var_dec(self, p):
        """var_dec : id_list ':' type_specifier ';' """
        p[0] = VarDec(p[3], p[1], p.lineno(3))

    def p_procedure_declarations(self, p):
        """procedure_declarations : procedure_declarations proc_dec
                                  | """
        if len(p) == 1:
            p[0] = list()
        else:
            p[1].append(p[2])
            p[0] = p[1]

    def p_proc_dec(self, p):
        """proc_dec :  proc_header declarations compound_statement ';'
                    | func_header declarations compound_statement ';' """
        if len(p) == 5:
            p[0] = ProcDec(p[1], p[2], p[3])

    def p_proc_header(self, p):
        """proc_header : PROCEDURE ID arguments ';' """
        p[0] = ProcHeader(p[2], p[3], p.lineno(1))

    def p_func_header(self, p):
        """func_header : FUNCTION ID arguments ':' type_specifier ';' """
        if p[5] == "integer":
            p[0] = FuncHeader(p[2], p[3], "int", p.lineno(1))
        else:
             p[0] = FuncHeader(p[2], p[3], p[5], p.lineno(1))

    def p_arguments(self, p):
        """arguments : '(' argument_list ')'
                     | """
        if len(p) == 4:
            p[0] = p[2]
        else:
            p[0] = list()

    def p_argument_list(self, p):
        """argument_list : argument_list ';' arg
                         | arg """
        if len(p) == 4:
            p[1].extend(p[3])
            p[0] = p[1]
        else:
            p[0] = p[1]

    # def p_argument_list_error(self, p):
    #     """argument_list : error"""
    #     print "Syntax error in argument at line ", p.lineno(1)
    #     self.error_encountered = True

    def p_arg(self, p):
        """arg : id_list ':' type_specifier """
        id_list = None
        type_specifier = None
        result = list()
        id_list = p[1]
        type_specifier = p[3]
        if type_specifier == "integer":
            type_specifier = "int"
        elif type_specifier == "real":
            type_specifier = "float"
        for id in id_list:
            #print id
            result.append(Argument(id, type_specifier, p.lineno(1)))
        p[0] = result


    def p_compound_statement(self, p):
        """compound_statement : BEGIN statement_list END"""
        p[0] = CompoundStatement(p[2])


    def p_compound_statement_error(self, p):
        """compound_statement : BEGIN error END"""
        print "Linia: %d. Blad syntaktyczny w instrukcji zlozonej." % p.lineno(1)
        self.error_encountered = True


    def p_statement_list(self, p):
        """statement_list : statement_list ';' statement
                          | statement """
        if len(p) == 2:
            p[0] = list()
            p[0].append(p[1])
        else:
            p[1].append(p[3])
            p[0] = p[1]

    def p_statement(self, p):
        """statement : compound_statement
                     | assignment_statement
                     | procedure_call
                     | for_statement
                     | while_statement
                     | if_statement
                     | case_statement
                     | repeat_statement
                     | """
        p[0] = p[1]


    def p_assignment_statement(self, p):
        """assignment_statement : variable ASSIGN expression"""
        p[0] = AssignmentStatement(p[1], p[3], p.lineno(2))

    def p_procedure_call(self, p):
        """procedure_call : ID actuals"""
        p[0] = ProcedureCall(p[1], p[2], p.lineno(1))

    def p_for_statement(self, p):
        """for_statement : FOR ID ASSIGN expression TO expression DO statement
                         | FOR ID ASSIGN expression DOWNTO expression DO statement"""
        pass

    def p_while_statement(self, p):
        """while_statement : WHILE expression DO statement"""
        p[0] = WhileStatement(p[2], p[4], p.lineno(1))


    def p_while_statement_error(self, p):
        """while_statement : WHILE error DO statement"""
        print "Linia: %d. Blad syntaktyczny w w warunku petli while." % p.lineno(1)
        self.error_encountered = True

    def p_if_statement(self, p):
        """if_statement : IF expression THEN statement
                        | IF expression THEN statement ELSE statement"""
        if len(p) == 5:
            p[0] = IfStatement(p.lineno(1), p[2], p[4])
        else:
            p[0] = IfStatement(p.lineno(1), p[2], p[4], p[6])

    def p_if_statement_error(self, p):
        """if_statement : IF error THEN statement
                        | IF error THEN statement ELSE statement"""
        print "Linia: %d. Blad syntaktyczny w warunku instrukcji warunkowej." % p.lineno(1)
        self.error_encountered = True

    def p_repeat_statement(self, p):
        """repeat_statement : REPEAT statement_list UNTIL expression"""
        p[0] = RepeatStatement(p[2], p[4], p.lineno(1))

    def p_repeat_statement_error(self, p):
        """repeat_statement : REPEAT error UNTIL expression"""
        print "Linia: %d. Blad syntaktyczny w ciele instrukcji repeat." % p.lineno(1)
        self.error_encountered = True


    def p_case_statement(self, p):
        """case_statement : CASE expression OF  case_list END"""
        pass


    def p_case_list(self, p):
        """case_list : case_list ';' case
                     | case"""
        pass


    def p_case(self, p):
        """case : constant_list ':' statement"""
        pass


    def p_constant_list(self, p):
        """constant_list : constant_list ',' CONSTANT
                         | CONSTANT"""
        pass


    def p_expression(self, p):
        """expression : simple_expression
                      | simple_expression '=' simple_expression
                      | simple_expression NEQ simple_expression
                      | simple_expression '<' simple_expression
                      | simple_expression LE simple_expression
                      | simple_expression '>' simple_expression
                      | simple_expression GE simple_expression
                      """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = BinaryExpression(p[1], p[2], p[3], p.lineno(2))


    def p_simple_expression(self, p):
        """simple_expression : term
                             | simple_expression '+' term
                             | simple_expression '-' term
                             | simple_expression OR term
                            """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = BinaryExpression(p[1], p[2], p[3], p.lineno(1))

    def p_term(self, p):
        """term : factor
                | term '*' factor
                | term '/' factor
                | term DIV factor
                | term MOD factor
                | term AND factor
                   """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = BinaryExpression(p[1], p[2], p[3], p.lineno(1))

    def p_factor(self, p):
        """factor : '(' expression ')'
                  | '+' factor
                  | '-' factor
                  | NOT factor
                  | function_call
                  | CONSTANT
                  | variable
                  """
        if len(p) == 4:
            p[0] = p[2]
        elif len(p) == 3:
            p[0] = UnaryExpression(p[2, p[1]])
        elif isinstance(p[1], ProcedureCall) or isinstance(p[1], Variable) or isinstance(p[1], FunctionCall):
            p[0] = p[1]
        else:
            p[0] = self.convert_from_string(p[1], p.lineno(1))

    def p_function_call(self, p):
        """function_call : ID actuals"""
        p[0] = FunctionCall(p[1], p[2], p.lineno(1))


    def p_actuals(self, p):
        """actuals : '(' expression_list ')'
                   | '(' ')'"""
        if len(p) == 4:
            p[0] = p[2]
        else:
            p[0] = list()
        for i in p[0]:
            if isinstance(i, str):
                print i

    def p_actuals_error(self, p):
        """actuals : '(' error ')' """
        print "Linia: %d. Blad w liscie argumentow." % (p.lineno(1))


    def p_expression_list(self, p):
        """expression_list : expression_list ',' expression
                           | expression"""
        if len(p) == 2:
            p[0] = list()
            p[0].append(p[1])
        else:
            p[1].append(p[3])
            p[0] = p[1]


    def p_variable(self, p):
        """variable : ID
                    | variable '.' ID
                    | variable '^'
                    | variable '[' expression_list ']'
                    """
        if len(p) == 2:
            p[0] = Variable(p[1], p.lineno(1))

    # TODO: other types of variables

    def p_type_specifier(self, p):
        """type_specifier : TYPE
                          | '^' type_specifier
                          | '(' id_list ')'
                          | CONSTANT DOUBLE_DOT CONSTANT
                          | ARRAY '[' dimension_list ']' OF type_specifier
                          | RECORD field_list END
                          | FILE OF type_specifier """
        if len(p) == 2:
            p[0] = p[1]

    def p_dimension_list(self, p):
        """dimension_list : dimension_list ',' dimension
                          | dimension"""
        pass

    def p_dimension(self, p):
        """dimension : CONSTANT DOUBLE_DOT CONSTANT
                     | ID"""
        pass

    def p_field_list(self, p):
        """field_list : field_list ';' field
                      | field"""
        pass

    def p_field(self, p):
        """field : id_list ':' type_specifier"""
        pass

    def p_id_list(self, p):
        """id_list : id_list ',' ID
                   | ID"""
        if len(p) == 2:
            p[0] = list()
            p[0].append(p[1])
        else:
            p[1].append(p[3])
            p[0] = p[1]
Пример #20
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print("Unexpected end of input")

    # DONE
    def p_program(self, p):
        """program : declarations fundefs_opt instructions_opt"""
        declarations = p[1]
        fundefs_opt = p[2]
        instructions_opt = p[3]
        p[0] = AST.Program(declarations, fundefs_opt, instructions_opt)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            if p[1] is None:
                p[0] = AST.DeclarationsList()
            else:
                p[0] = p[1]
            p[0].addDecl(p[2])
        else:
            p[0] = AST.DeclarationsList()

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            type = p[1]
            inits = p[2]
            p[0] = AST.Declaration(type, inits)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            if p[1] is None:
                p[0] = AST.Inits()
            else:
                p[0] = p[1]
            p[0].addInit(p[3])
        else:
            p[0] = AST.Inits()
            p[0].addInit(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        expression = p[3]
        p[0] = AST.Init(id, expression)
        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        if p[1] is not None:
            p[0] = AST.Instructions_opt(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            if p[1] is None:
                p[0] = AST.InstructionsList()
            else:
                p[0] = p[1]
            p[0].addInstr(p[2])
        else:
            p[0] = AST.InstructionsList()
            p[0].addInstr(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        expr_list = p[2]
        p[0] = AST.PrintInstruction(expr_list)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        instruction = p[3]
        p[0] = AST.LabeledInstruction(id, instruction)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        expression = p[3]
        p[0] = AST.Assigment(id, expression)
        p[0].lineno = self.scanner.lexer.lineno

    # ?
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        instruction = p[5]
        if len(p) == 8:
            alternativeInstruction = p[7]
        else:
            alternativeInstruction = None
        p[0] = AST.ChoiceInstruction(condition, instruction, alternativeInstruction)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileInstruction(condition, instruction)

        p[0].lineno = self.scanner.lexer.lineno

    # ?
    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        instructions = p[2]
        condition = p[4]
        p[0] = AST.RepeatInstruction(instructions, condition)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        expression = p[2]
        p[0] = AST.ReturnInstruction(expression)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        declarations = p[2]
        instructions_opt = p[3]
        p[0] = AST.CompoundInstruction(declarations, instructions_opt)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]
        p[0].lineno = self.scanner.lexer.lineno

    # ?
    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = AST.Const(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            if isinstance(p[1], AST.Const):
                value = p[1]
            else:
                value = AST.Id(p[1])
            p[0] = value
        elif p[1] is '(':
            p[0] = p[2]
        elif p[2] is '(' and p[1] is not '(':
            name = p[1]
            args = p[3]
            p[0] = AST.FunctionCalling(name, args)
        else:
            firstExpr = p[1]
            secExpr = p[3]
            operator = p[2]
            p[0] = AST.BinExpr(operator, firstExpr, secExpr)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 1:
            p[0] = None
        else:
            p[0] = p[1]

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            if p[1] is None:
                p[0] = AST.Expressions
            else:
                p[0] = p[1]
            p[0].addExpression(p[3])
        else:
            p[0] = AST.Expressions()
            p[0].addExpression(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs
                       | """
        if p[1] is not None:
            fundefs = p[1]
            p[0] = AST.FunDefs_opt(fundefs)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_fundefs(self, p):
        """fundefs : fundefs fundef
                   | fundef """
        if len(p) == 3:
            if p[1] is None:
                p[0] = AST.FunDefs()
            else:
                p[0] = p[1]
            p[0].addFunDef(p[2])
        else:
            p[0] = AST.FunDefs()
            p[0].addFunDef(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        type = p[1]
        id = p[2]
        args = p[4]
        comp = p[6]
        p[0] = AST.FunDef(type, id, args, comp)

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 1:
            p[0] = None
        else:
            p[0] = p[1]

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            if p[1] is None:
                p[0] = AST.ArgsList()
            else:
                p[0] = p[1]
            p[0].addArg(p[3])
        else:
            p[0] = AST.ArgsList()
            p[0].addArg(p[1])

        p[0].lineno = self.scanner.lexer.lineno

    # DONE
    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        id = p[2]
        p[0] = AST.Arg(type, id)

        p[0].lineno = self.scanner.lexer.lineno
Пример #21
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno(1), self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print("Unexpected end of input")


    #do nowej gramatyki:
    def p_program(self, p):
        """program : blocks"""
        p[0] = p[1]
        # print p[0]

    #do nowej gramatyki:
    def p_blocks(self, p):
        """blocks : blocks block
                  | block"""
        if len(p) != 3:
            #after |
            p[0] = AST.Blocks()
            p[0].push(p[1])
        else:
            if p[1] is None:
                p[0] = AST.Blocks()
            else:
                p[0] = p[1]
            p[0].push(p[2])

    #do nowej gramatyki:
    def p_block(self, p):
        """block : declarations fundefs_opt instructions_opt"""
        p[0] = AST.Block(p[1], p[2], p[3])


    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) != 3:
            #after |
            p[0] = AST.Declarations()
        else:
            #put right `declarations` to left `declarations` and append `declaration`
            if p[1] is None:
                p[0] = AST.Declarations()
            else:
                p[0] = p[1]
            p[0].push(p[2])


    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            type = p[1]
            inits = p[2]
            p[0] = AST.Declaration(type, inits, p.lineno(1))

    #variable initialization
    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = p[1]
            p[0].push(p[3])
        else:
            p[0] = AST.Inits()
            p[0].push(p[1])


    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))


    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = None


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        #almost same as declarations
        if len(p) != 3:
            #after |
            p[0] = AST.Instructions()
            p[0].push(p[1])
        else:
            if p[1] is None:
                p[0] = AST.Instructions()
            else:
                p[0] = p[1]
            p[0].push(p[2])


    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1] #bo zamieniamy instruction na cos po prawej

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        expr = p[2]
        p[0] = AST.PrintInstr(expr, p.lineno(1))

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        instr = p[3]
        p[0] = AST.LabeledInstr(id, instr)

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        expr = p[3]
        p[0] = AST.AssignmentInstr(id, expr, p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        instruction = p[5]
        if len(p) >= 8:
            else_instr = p[7]
        else:
            else_instr = None
        p[0] = AST.ChoiceInstr(condition, instruction, else_instr, p.lineno(1) )

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileInstr(condition, instruction)


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        condition = p[4]
        instruction = p[2]
        p[0] = AST.RepeatInstr(condition, instruction)

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        expr = p[2]
        p[0] = AST.ReturnInstr(expr, p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        if len(p[2].declarations) != 0:
            p[0] = AST.CompoundInstr(p[2], p[3], p.lineno(1))
        else:
            p[0] = AST.CompoundInstr(None, p[3], p.lineno(1))

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = p[1]

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')'"""
        #typ 0 - const i ID
        #typ 1 - wszystkie te `expression` cos `expression`
        #typ 2 - to w nawiasach
        #typ 3 - to z ID na poczatku
        if len(p) == 2:
            p[0] = AST.Const(p[1], p.lineno(1))
        elif p[1] != "(" and p[2] == "(": #lapiemy 3 typ czyli wywolanie funkcji
            functionName = p[1]
            args = p[3]
            p[0] = AST.CastFunction(functionName, args, p.lineno(1))
        elif p[1] == "(": #2 typ
            p[0] = AST.ExprInBrackets(p[2], p.lineno(1))
        else: #1 typ
            p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(1))


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) != 1:
            p[0] = p[1]
        else:
            p[0] = None


    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) != 4:
            p[0] = AST.ExprList()
            p[0].push(p[1])
        else:
            p[0] = AST.ExprList() if p[1] is None else p[1]
            p[0].push(p[3])

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs
                       | """
        if len(p) > 1:
            p[0] = p[1]
        else:
            p[0] = None

    def p_fundefs(self, p):
        """fundefs : fundefs fundef
                   | fundef """
        if len(p) == 3:
            p[0] = p[1]
            p[0].push(p[2])
        else:
            p[0] = AST.FunctionList()
            p[0].push(p[1])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Function(p[1], p[2], p[4], p[6], p.lineno(1))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 1:
            p[0] = None
        else:
            p[0] = p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            if p[1] is None:
                p[0] = AST.Arguments()
            else:
                p[0] = p[1]
            p[0].push(p[3])
        else:
            p[0] = AST.Arguments()
            p[0].push(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        id = p[2]
        p[0] = AST.Argument(type, id, p.lineno(1))
Пример #22
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : children children children"""
        declarations = None if len(p[1].declarations) == 0 else p[1]
        fundefs = None if len(p[2].fundefs) == 0 else p[2]
        print AST.Program(declarations, fundefs, p[3])

    def p_declarations(self, p):
        """children : children declaration
                        | """
        if len(p) == 3:
            p[0] = AST.DeclarationList() if p[1] is None else p[1]
            p[0].addDeclaration(p[2])
        else:
            p[0] = AST.DeclarationList()

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            type = p[1]
            inits = p[2]
            p[0] = AST.Declaration(type, inits)

    def p_inits(self, p):
        """children : children ',' init
                 | init """
        if len(p) == 4:
            p[0] = AST.InitList() if p[1] is None else p[1]
            p[0].addInit(p[3])
        else:
            p[0] = AST.InitList()
            p[0].addInit(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        expr = p[3]
        p[0] = AST.Init(id, expr)

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = AST.InstructionList() if p[1] is None else p[1]
            p[0].addInstruction(p[2])
        else:
            p[0] = AST.InstructionList()
            p[0].addInstruction(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        expr = p[2]
        p[0] = AST.PrintInstruction(expr)

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        instruction = p[3]
        p[0] = AST.LabeledInstruction(id, instruction)

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        expr = p[3]
        p[0] = AST.AssignmentInstruction(id, expr)

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        action = p[5]
        alternateAction = None if len(p) < 8 else p[7]
        p[0] = AST.ChoiceInstruction(condition, action, alternateAction)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileInstruction(condition, instruction)

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT children UNTIL condition ';' """
        instructions = p[2]
        condition = p[4]
        p[0] = AST.RepeatInstruction(instructions, condition)

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        expression = p[2]
        p[0] = AST.ReturnInstruction(expression)

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()

    def p_compound_instr(self, p):
        """compound_instr : '{' children children '}' """
        if len(p[2].declarations) == 0:
            p[0] = AST.CompoundInstruction(None, p[3])
        else:
            p[0] = AST.CompoundInstruction(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = p[1]

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            value = p[1]
            p[0] = AST.Const(value)
        elif p[2] == "(" and p[1] != "(":
            funcName = p[1]
            args = p[3]
            p[0] = AST.InvocationExpression(funcName, args)
        elif p[1] == "(":
            interior = p[2]
            p[0] = AST.GroupedExpression(interior)
        else:
            lhs = p[1]
            op = p[2]
            rhs = p[3]
            p[0] = AST.BinExpr(lhs, op, rhs)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = AST.ExpressionList() if p[1] is None else p[1]
            p[0].addExpression(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].addExpression(p[1])

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[0] = p[2]
            p[0].addFunction(p[1])
        else:
            p[0] = AST.FunctionExpressionList()

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionExpression(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = None if len(p) == 0 else p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[0] = AST.ArgumentList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ArgumentList()
            p[0].addArgument(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        name = p[2]
        p[0] = AST.Argument(type, name)
Пример #23
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.errors = False

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        self.errors = True
        err_format = "Syntax error at line {0}, column {1}: LexToken({2}, '{3}')"
        if p:
            print(err_format.format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        #     ^            ^         ^          ^
        #    p[0]         p[1]      p[2]       p[3]
        program = AST.Program(p[1], p[2], p[3])
        p[0] = program

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:  # occurs when declarations -> declarations declaration
            p[1].declarations.append(p[2])
            p[0] = p[1]
        else:  # occurs when declarations -> epsilon
            p[0] = AST.Declarations()

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 3:  # occurs when error
            p[0] = p[1]
        else:
            p[0] = AST.Declaration(p[1], p[2])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:  # occurs when inits -> inits, init
            p[0] = p[1]
            p[0].inits.append(p[3])
        else:  # occurs when inits -> init
            p[0] = AST.Inits()
            p[0].inits.append(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:  # occurs when instructions -> instructions instruction
            p[1].instructions.append(p[2])
            p[0] = p[1]
        else:  # occurs when instructions -> instruction
            p[0] = AST.Instructions()
            p[0].instructions.append(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p[2], p.lineno(1))

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1], p[3], p.lineno(1))

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3], p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 8:
            p[0] = AST.IfElseInstr(p[3], p[5], p[7])
        else:
            p[0] = AST.IfInstr(p[3], p[5])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[4], p[2])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        lineno = p.lineno(1)
        try:
            int(p[1])
            p[0] = AST.Integer(p[1], lineno)
        except ValueError:
            try:
                float(p[1])
                p[0] = AST.Float(p[1], lineno)
            except ValueError:
                p[0] = AST.String(p[1], lineno)

    def p_id_expr(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p[1], p.lineno(1))

    def p_const_expr(self, p):
        """expression : const"""
        p[0] = p[1]

    def p_paren_expression(self, p):
        """expression : '(' expression ')'
                      | '(' error ')'"""
        p[0] = AST.ParenExpr(p[2])

    def p_funcall(self, p):
        """expression : ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        p[0] = AST.Funcall(p[1], p[3], p.lineno(1))

    def p_bin_expression(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""
        p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(2))  # operator pierwszy

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        p[0] = AST.ExprList()
        if len(p) == 4:
            p[0].cons_expr(p[1].expr_list, p[3])
        else:
            p[0].append_expr(p[1])

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        p[0] = AST.FundefList()
        if len(p) == 3:
            p[0].cons_fun(p[2].fundef_list, p[1])
        elif len(p) == 2:
            p[0].append_fun(p[1])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(p[1], p[2], p[4], p[6], p.lineno(1))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.ArgList()  # empty

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        p[0] = AST.ArgList()
        if len(p) == 4:
            p[0].cons_arg(p[1].arg_list, p[3])
        else:
            p[0].append_arg(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2], p.lineno(1))
Пример #24
0
class Cparser(object):


	def __init__(self):
		self.scanner = Scanner()
		self.scanner.build()
		self.operation_results = OperationResults.operation_results

	tokens = Scanner.tokens

	precedence = (
	   ("nonassoc", 'IFX'),
	   ("nonassoc", 'ELSE'),
	   ("right", '='),
	   ("left", 'OR'),
	   ("left", 'AND'),
	   ("left", '|'),
	   ("left", '^'),
	   ("left", '&'),
	   ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
	   ("left", 'SHL', 'SHR'),
	   ("left", '+', '-'),
	   ("left", '*', '/', '%'),
	)

	def p_error(self, p):
		if p:
			print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
		else:
			print("Unexpected end of input")


	def p_program(self, p):
		"""program : blocks"""

		program = AST.Program(p[1])
		p[0] = program


	def p_blocks(self, p):
		"""blocks : blocks block
				  | block"""

		if(len(p) > 2):
			if(isinstance(p[2], list)):
				p[1].extend(p[2])
			else:
				p[1].append(p[2])
			p[0] = p[1]
		else:
			if(isinstance(p[1], list)):
				p[0] = p[1]
			else:
				p[0] = [p[1]]


	def p_block(self, p):
		"""block : declaration
				 | fundef
				 | instruction"""

		p[0] = p[1]


	def p_declaration(self, p):
		"""declaration : TYPE inits ';'
					   | error ';' """

		if(len(p) > 2):
			p[0] = p[2]
			declared_type = p[1]
			
			for i in range(len(p[0])):
				p[0][i].left.type = declared_type

		else:
			p[0] = p[1]


	def p_inits(self, p):
		"""inits : inits ',' init
				 | init """

		if(len(p) > 3):
			p[1].append(p[3])
			p[0] = p[1]
		else:
			p[0] = [p[1]]


	def p_init(self, p):
		"""init : ID '=' expression """

		decl = AST.Declaration(AST.Id("UNKNOWN", p[1], p.lineno(1)), p[3], p.lineno(1))
		p[0] = decl
		

	def p_instructions(self, p):
		"""instructions : instructions instruction
						| instruction """

		if(len(p) > 2):
			if(isinstance(p[2], list)):
				p[1].extend(p[2])
			else:
				p[1].append(p[2])
			p[0] = p[1]
		else:
			if(isinstance(p[1], list)):
				p[0] = p[1]
			else:
				p[0] = [p[1]]


	def p_instruction(self, p):
		"""instruction : print_instr
					   | labeled_instr
					   | assignment
					   | choice_instr
					   | while_instr
					   | repeat_instr
					   | return_instr
					   | break_instr
					   | continue_instr
					   | compound_instr
					   | expression ';' """
		p[0] = p[1]

	def p_print_instr(self, p):
		"""print_instr : PRINT expr_list ';'
					   | PRINT error ';' """

		instruction = AST.PrintInstr(p[2], p.lineno(1))
		p[0] = instruction


	def p_return_instr(self, p):
		"""return_instr : RETURN expression ';' """

		instruction = AST.ReturnInstr(p[2], p.lineno(1))
		p[0] = instruction


	def p_choice_instr(self, p):
		"""choice_instr : IF '(' condition ')' instruction  %prec IFX
						| IF '(' condition ')' instruction ELSE instruction
						| IF '(' error ')' instruction  %prec IFX
						| IF '(' error ')' instruction ELSE instruction """

		if(len(p) > 7):
			instruction = AST.IfInstr(p[3], p[5], p.lineno(1), p[7])
			p[0] = instruction

		elif(len(p) > 5):
			instruction = AST.IfInstr(p[3], p[5], p.lineno(1))
			p[0] = instruction


	def p_while_instr(self, p):
		"""while_instr : WHILE '(' condition ')' instruction
					   | WHILE '(' error ')' instruction """

		instruction = AST.WhileInstr(p[3], p[5], p.lineno(1))
		p[0] = instruction


	def p_repeat_instr(self, p):
		"""repeat_instr : REPEAT instructions UNTIL condition ';' """

		instruction = AST.RepeatUntilInstr(p[4], p[2], p.lineno(1))
		p[0] = instruction


	def p_continue_instr(self, p):
		"""continue_instr : CONTINUE ';' """

		instruction = AST.ContinueInstr(p.lineno(1))
		p[0] = instruction


	def p_break_instr(self, p):
		"""break_instr : BREAK ';' """

		instruction = AST.BreakInstr(p.lineno(1))
		p[0] = instruction


	def p_labeled_instr(self, p):
		"""labeled_instr : ID ':' instruction """

		p[0] = p[3]


	def p_assignment(self, p):
		"""assignment : ID '=' expression ';' """

		expr = AST.AssignInstr("UNKNOWN", AST.Id("UNKNOWN", p[1], p.lineno(1)), p[3], p.lineno(1))
		p[0] = expr


	def p_compound_instr(self, p):
		"""compound_instr : '{' blocks '}' """

		p[0] = p[2]


	def p_condition(self, p):
		"""condition : expression"""
			
		p[0] = p[1]


	def p_bin_expression(self, p):
		"""bin_expression : expression '+' expression
						  | expression '-' expression
						  | expression '*' expression
						  | expression '/' expression
						  | expression '%' expression
						  | expression '|' expression
						  | expression '&' expression
						  | expression '^' expression
						  | expression AND expression
						  | expression OR expression
						  | expression SHL expression
						  | expression SHR expression
						  | expression EQ expression
						  | expression NEQ expression
						  | expression '>' expression
						  | expression '<' expression
						  | expression LE expression
						  | expression GE expression """
		
		left_expr = p[1]
		op = p[2]
		right_expr = p[3]
		expr = AST.BinExpr("UNKNOWN", op, left_expr, right_expr, p.lineno(2))
			
		p[0] = expr

	def p_const_int(self, p):
		"""const : INTEGER """
		
		const = AST.Const("int", p[1], p.lineno(1))
		p[0] = const
		
	def p_const_float(self, p):
		"""const : FLOAT """
		
		const = AST.Const("float", p[1], p.lineno(1))
		p[0] = const
	
	def p_const_string(self, p):
		"""const : STRING """
		
		const = AST.Const("string", p[1], p.lineno(1))
		p[0] = const


	def p_id(self, p):
		"""id : ID"""
		
		identifier = AST.Id("UNKNOWN", p[1], p.lineno(1))
		p[0] = identifier


	def p_expression(self, p):
		"""expression : id
					  | const
					  | bin_expression
					  | paren_expression
					  | funcall"""
		p[0] = p[1]


	def p_paren_expression(self, p):
		"""paren_expression : '(' expression ')'
							| '(' error ')' """
		p[0] = p[2]


	def p_expr_list_or_empty(self, p):
		"""expr_list_or_empty : expr_list
							  | """
		if(len(p) > 1):
			p[0] = p[1]
		else:
			p[0] = []


	def p_expr_list(self, p):
		"""expr_list : expr_list ',' expression
					 | expression """

		if(len(p) > 3):
			p[1].append(p[3])
			p[0] = p[1]
		else:
			p[0] = [p[1]]

	def p_fundef(self, p):
		"""fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
		
		return_type = p[1]
		fun_name = p[2]
		fun_id = AST.Id(p[1], p[2], p.lineno(1))
		args = p[4]
		fundef = AST.FunDefinition(fun_id, args, p.lineno(1), p[6])
		p[0] = fundef


	def p_funcall(self, p):
		"""funcall : ID '(' expr_list_or_empty ')'
				   | ID '(' error ')' """

		funcall = AST.FunCall(AST.Id("UNKNOWN", p[1], p.lineno(1)), p[3], p.lineno(1))
		p[0] = funcall


	def p_args_list_or_empty(self, p):
		"""args_list_or_empty : args_list
							  | """

		if(len(p) > 1):
			p[0] = p[1]
		else:
			p[0] = []

	def p_args_list(self, p):
		"""args_list : args_list ',' arg
					 | arg """

		if(len(p) > 3):
			p[1].append(p[3])
			p[0] = p[1]
		else:
			p[0] = [p[1]]


	def p_arg(self, p):
		"""arg : TYPE ID """

		arg = AST.Id(p[1], p[2], p.lineno(1))
		p[0] = arg
Пример #25
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.tree = None

    tokens = Scanner.tokens

    # precedence = (
    #    ("nonassoc", 'IFX'),
    #    ("nonassoc", 'ELSE'),
    #    ("right", '='),
    #    ("left", 'OR'),
    #    ("left", 'AND'),
    #    ("left", '|'),
    #    ("left", '^'),
    #    ("left", '&'),
    #    ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
    #    ("left", 'SHL', 'SHR'),
    #    ("left", '+', '-'),
    #    ("left", '*', '/', '%'),
    # )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : typeDeclarations"""
        p[0] = AST.Program(p.lineno(1), p[1])

        
        print p[0]

    def p_typeDeclarations(self, p):
        """typeDeclarations : typeDeclaration
                            | typeDeclarations typeDeclaration"""
        if len(p) == 2:
            p[0] = AST.TypeDeclarations(p.lineno(1), p[1])
        elif len(p) > 2:
            p[0] = AST.TypeDeclarations(p.lineno(1), p[2], p[1])

    def p_typeDeclaration(self, p):
        """typeDeclaration : classDeclaration
                            | interfaceDeclaration"""
        p[0] = AST.TypeDeclaration(p.lineno(1), p[1])

    def p_classDeclaration(self, p):
        """classDeclaration : classModifier CLASS ID inherited classBody"""
        p[0] = AST.ClassDeclaration(p.lineno(1), p[1], p[3], p[4], p[5])

    def p_classModifier(self, p):
        """classModifier : ACCESS modifier
                            | modifier
                            | ACCESS
                            | """
        if len(p) == 2:
            p[0] = AST.ClassModifier(p.lineno(1), p[1])
        elif len(p) > 2:
            p[0] = AST.ClassModifier(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.ClassModifier()

    def p_modifier(self, p):
        """modifier : ABSTRACT
                    | FINAL"""
        p[0] = AST.Modifier()

    def p_inherited(self, p):
        """inherited : extends implements
                    | extends
                    | implements
                    | """
        if len(p) == 2:
            p[0] = AST.Inherited(p.lineno(1), p[1])
        elif len(p) > 2:
            p[0] = AST.Inherited(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.Inherited()
         
        print p[0]   
        

    def p_extends(self, p):
        """extends : EXTENDS ID"""
        p[0] = AST.Extend(p.lineno(1), p[2])

    def p_implements(self, p):
        """implements : IMPLEMENTS implement """
        p[0] = AST.Implements(p.lineno(1), p[2])

    def p_implement(self, p):
        """implement : implement ',' ID
                    | ID """
        if len(p) == 2:
            p[0] = AST.Implement(p.lineno(1), p[1])
        else:
            p[0] = AST.Implement(p.lineno(1), p[3], p[1])

    def p_classBody(self, p):
        """classBody : '{' classBodyDeclarations '}'
                    | '{'   '}' """
        if len(p) > 3:
            p[0] = AST.ClassBody(p.lineno(1), p[2])
        else:
            p[0] = AST.ClassBody()

    def p_classBodyDeclarations(self, p):
        """classBodyDeclarations : classBodyDeclaration
                                | classBodyDeclarations classBodyDeclaration"""
        if len(p) == 2:
            p[0] = AST.ClassBodyDeclarations(p.lineno(1), p[1])
        else:
            p[0] = AST.ClassBodyDeclarations(p.lineno(1), p[2], p[1])

    def p_classBodyDeclaration(self, p):
        """classBodyDeclaration : classMemberDeclaration
                                | constructorDeclaration"""
        p[0] = AST.ClassBodyDeclaration(p.lineno(1), p[1])

    def p_classMemberDeclaration(self, p):
        """classMemberDeclaration : fieldDeclaration
                                | methodDeclaration"""
        p[0] = AST.ClassMemeberDeclaration(p.lineno(1), p[1])

    def p_constructorDeclaration(self, p):
        """constructorDeclaration : ACCESS constructorDeclarator BODY
                                | constructorDeclarator BODY"""
        if len(p) == 3:
            p[0] = AST.ConstructorDeclaration(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.ConstructorDeclaration(p.lineno(1), p[2], p[3], p[1])

    def p_constructorDeclarator(self, p):
        """constructorDeclarator : ID '(' parameterList ')'
                                | ID '(' ')' """
        if len(p) == 4:
            p[0] = AST.ConstructorDeclarator(p.lineno(1), p[1])
        else:
            p[0] = AST.ConstructorDeclarator(p.lineno(1), p[1], p[3])

    def p_parameterList(self, p):
        """parameterList : parameter
                        | parameterList ',' parameter"""
        if len(p) == 2:
            p[0] = AST.ParameterList(p.lineno(1), p[1])
        else:
            p[0] = AST.ParameterList(p.lineno(1), p[3], p[1])

    def p_parameter(self, p):
        """parameter : TYPE VARID"""
        p[0] = AST.Parameter(p.lineno(1), p[1], p[2])

    def p_fieldDeclaration(self, p):
        """fieldDeclaration : fieldModifiers types variableDeclarator ';'
                            | types variableDeclarator ';' """
        if len(p) == 4:
            p[0] = AST.FieldDclaration(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.FieldDclaration(p.lineno(1), p[2], p[3], p[1])

    def p_fieldsModifiers(self, p):
        """fieldModifiers : ACCESS fieldModifier
                        | ACCESS
                        | fieldModifier"""
        if len(p) == 2:
            p[0] = AST.FieldModifiers(p.lineno(1), p[1])
        else:
            p[0] = AST.FieldModifiers(p.lineno(1), p[1], p[2])

    def p_fieldModifier(self, p):
        """fieldModifier : fieldModifierStatic fieldModifierFinal
                        | fieldModifierStatic
                        | fieldModifierFinal"""
        if len(p) == 3:
            p[0] = AST.FieldModifier(p.lineno(1), p[1], p[2])
        else:
            p[0] = AST.FieldModifier(p.lineno(1), p[1])

    def p_fieldModifierStatic(self, p):
        """fieldModifierStatic : STATIC"""
        p[0] = AST.FieldModifierStatic()

    def p_fieldModifierFinal(self, p):
        """fieldModifierFinal : FINAL"""
        p[0] = AST.FieldModifierFinal()

    def p_types(self, p):
        """types : TYPE
                | ID"""
        p[0] = AST.Types(p.lineno(1), p[1])

    def p_variableDeclarator(self, p):
        """variableDeclarator : VARID
                                | variableDeclarator '[' ']'
                                | VARID '<' types '>' """
        if len(p) > 4:
            p[0] = AST.VariableDeclarator(p.lineno(1), p[1], p[3])
        else:
            p[0] = AST.VariableDeclarator(p.lineno(1), p[1])

    def p_methodDeclaration(self, p):
        """methodDeclaration : methodHeader BODY"""
        p[0] = AST.MethodDeclaration(p.lineno(1), p[1], p[2])

    def p_methodHeader(self, p):
        """methodHeader : methodModifiers mTypes methodDeclarator
                        | mTypes methodDeclarator"""
        if len(p) == 3:
            p[0] = AST.MethodHeader(p.lineno(1), p[1],p[2])
        else:
            p[0] = AST.MethodHeader(p.lineno(1), p[2], p[3], p[1])

    def p_mTypes(self, p):
        """mTypes : types
                | voids"""
        p[0] = AST.MTypes(p.lineno(1), p[1])

    def p_voids(self, p):
        """voids : VOID"""
        p[0] = AST.Voids()

    def p_methodModifiers(self, p):
        """methodModifiers : ACCESS methodModifier
                            | methodModifier"""
        if len(p) == 2:
            p[0] = AST.MethodModifiers(p.lineno(1), p[1])
        else:
            p[0] = AST.MethodModifiers(p.lineno(1), p[1], p[2])

    def p_methodModifier(self, p):
        """methodModifier : fieldModifier methodModifier
                        | methodModifierAbstract
                        | methodModifierSynchronized"""
        p[0] = AST.MethodModifier()

    def p_methodModifierAbstract(self, p):
        """methodModifierAbstract : ABSTRACT"""
        p[0] = AST.MethodModifierAbstract()

    def p_methodModifierSynchronized(self, p):
        """methodModifierSynchronized : SYNCHRONIZED"""
        p[0] = AST.MethodModifierAbstract()

    def p_methodDeclarator(self, p):
        """methodDeclarator : VARID '(' parameterList ')' """
        p[0] = AST.MethodDeclarator(p.lineno(1), p[1], p[3])

    def p_interfaceDeclaration(self, p):
        """interfaceDeclaration : interfaceModifier INTERFACE ID extendsInterfaces interfaceBody"""
        p[0] = AST.InterfaceDeclaration(p.lineno(1), p[1], p[3], p[4], p[5])

    def p_interfaceModifier(self, p):
        """interfaceModifier : ACCESS
                            | """
        if len(p) == 2:
            p[0] = AST.InterfaceModifier(p.lineno(1), p[1])
        else:
            p[0] = AST.InterfaceModifier()

    def p_extendsInterfaces(self, p):
        """extendsInterfaces : EXTENDS ID
                            | extendsInterfaces ',' ID"""
        if len(p) == 3:
            p[0] = AST.ExtendsInterfaces(p.lineno(1), p[2])
        else:
            p[0] = AST.ExtendsInterfaces(p.lineno(1), p[3], p[1])

    def p_interfaceBody(self, p):
        """interfaceBody : '{' interfaceBodyDeclarations '}' """
        if len(p) == 3:
            AST.InterfaceBody()
        else:
            AST.InterfaceBody(p.lineno(1), p[2])

    def p_interfaceBodyDeclarations(self, p):
        """interfaceBodyDeclarations : interfaceBodyDeclaration
                                    | interfaceBodyDeclarations interfaceBodyDeclaration"""
        if len(p) == 2:
            p[0] = AST.InterfaceBodyDeclarations(p.lineno(1), p[1])
        else:
            p[0] = AST.InterfaceBodyDeclarations(p.lineno(1), p[2], p[1])

    def p_interfaceBodyDeclaration(self, p):
        """interfaceBodyDeclaration : fieldModifiers types VARID ';' """
        p[0] = AST.InterfaceBodyDeclaration(p.lineno(1), p[1], p[2],p[3])
Пример #26
0
class Mparser(object):

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IF'),
        ("nonassoc", 'ELSE'),
        ("nonassoc", 'ADDASSIGN', 'SUBASSIGN', 'MULASSIGN', 'DIVASSIGN'),
        ("right", '='),
        ("nonassoc", '<', '>'),
        ("nonassoc", 'SMALLEREQ', 'GREATEREQ', 'NOTEQ', 'EQ'),
        ("left", '+', '-'),
        ("left", 'MATRIX_PLUS', 'MATRIX_MINUS'),
        ("left", '*', '/'),
        ("left", 'MATRIX_TIMES', 'MATRIX_DIVIDE'),
        ("left", '\''),
        ("left", 'UMINUS')
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0} : LexToken({1}, '{2}')".format(p.lineno, p.type, p.value))
            #p[0] = AST.Error(p.lineno, p.type, p.value)
        else:
            print("Unexpected end of input")
            #p[0] = AST.Error

    def p_program(self, p):
        """program : instructions_opt"""
        p[0] = AST.Program(p[1])
        print(AST.Program(p[1]))

    #------ instructions: ------
    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        p[0] = p[1]

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = AST.InstructionList() if p[1] is None else p[1]
            p[0].add_instruction(p[2])
        else:
            p[0] = AST.InstructionList()
            p[0].add_instruction(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | if_instr
                       | for_instr
                       | while_instr
                       | break_instr
                       | cont_instr
                       | return_instr
                       | assignment
                       | '{' instructions '}' """
        if (p[1] == '{'):
            p[0] = p[2]
        else:
            p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT multi_print ';'"""
        p[0] = AST.PrintInstr(p[2], p.lineno(1))

    def p_multi_print(self, p):
        """multi_print : multi_print ',' expression
                       | expression"""
        if (not isinstance(p[0], list)):
            p[0] = []
        if (len(p) == 4):
            p[0] = p[1]
            p[0].append(p[3])
        else:
            p[0].append(p[1])

    def p_if_instr(self, p):
        """if_instr  : IF  '(' condition ')' instruction
                     | IF  '(' condition ')' instruction ELSE instruction"""
        if(len(p) > 6):
            p[0] = AST.IfInstr(p.lineno(1), p[3], p[5], p[7])
        else:
            p[0] = AST.IfInstr(p.lineno(1), p[3], p[5])

    def p_for_instr(self, p):
        """for_instr : FOR id '=' range_instr instruction"""
        p[0] = AST.ForInstr(p[2], p[4], p[5], p.lineno(1))

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction"""
        p[0] = AST.WhileInstr(p[3], p[5], p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr(p.lineno(1))

    def p_cont_instr(self, p):
        """cont_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';'"""
        p[0] = AST.ReturnInstr(p[2],p.lineno(1))

    def p_eye_instr(self, p):
        """eye_instr : EYE '(' int ')'"""
        p[0] = AST.EyeInstr(p[3], p.lineno(1))

    def p_zeros_instr(self, p):
        """zeros_instr : ZEROS '(' int ')' """
        p[0] = AST.ZerosInstr(p[3], p.lineno(1))

    def p_ones_instr(self, p):
        """ones_instr : ONES '(' int ')' """
        p[0] = AST.OnesInstr(p[3], p.lineno(1))

    def p_assignment(self, p):
        """assignment : id assign_ops matrix ';'
                      | id assign_ops expression ';'
                      | id '[' INTNUM ',' INTNUM ']' assign_ops expression ';' """
        if(len(p)<6):
            p[0] = AST.AssInstr(p[2], p[1], p[3], p.lineno(1))
        else:
            p[0] = AST.AssTabInstr(p[7], p[1], AST.IntNum(p[3], p.lineno(1)), AST.IntNum(p[5], p.lineno(1)), p[8], p.lineno(1))

    def p_assign_ops(self, p):
        """assign_ops : SUBASSIGN
                      | ADDASSIGN
                      | DIVASSIGN
                      | MULASSIGN
                      | '=' """
        p[0] = p[1]

    def p_range_instr(self, p):
        """range_instr : int ':' int
                       | int ':' id
                       | id ':' id
                       | id ':' int"""
        p[0] = AST.RangeInstr(p[1],p[3])


    def p_int(self, p):
        """int : INTNUM"""
        p[0] = AST.IntNum(p[1], p.lineno(1))

    def p_float(self, p):
        """float : FLOATNUM"""
        p[0] = AST.FloatNum(p[1], p.lineno(1))

    def p_condition(self, p):
        """condition : expression EQ expression
                     | expression NOTEQ expression
                     | expression GREATEREQ expression
                     | expression SMALLEREQ expression
                     | expression '>' expression
                     | expression '<' expression"""
        p[0] = AST.CondInstr(p[1], p[2], p[3])

    def p_number_or_id(self, p):
        """number_or_id : int
                        | float
                        | id"""
        p[0] = p[1]
        p[0] = p[1]

    #------ expressions: ------

    def p_expression_group(self, p):
        """expression : '(' expression ')'"""
        p[0] = p[2]

    def p_binary_operators(self, p):
        """ expression : expression '+' expression
                       | expression '-' expression
                       | expression '*' expression
                       | expression '/' expression
                       | number_or_id
                       | '-' expression   %prec UMINUS
                       | m_expr
                       | string
                       | ones_instr
                       | zeros_instr
                       | eye_instr
                       | matrix """      #TODO: sprawdzic!!!
        if(len(p) == 4):
            p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(1))
        elif(len(p) == 3):
            p[0] = AST.NegatedExpr(p[2])
        else:
            p[0] = p[1]

    def p_string(self, p):
        """ string : STRING"""
        p[0] = AST.String(p[1], p.lineno(1))

    #------ matrix parse: ------

    def p_matrix(self, p):
        """matrix : '[' body ']'
                  | matrix_transp
                  | id"""
        if len(p) == 4:
            p[0] = AST.Matrix(p[2], p.lineno(1))
        else:
            p[0] = p[1]

    def p_id(self, p):
        """id : ID"""
        p[0] = AST.Variable(p[1], p.lineno(1))

    def p_matrix_transp(self, p):
        """matrix_transp : matrix "'" """
        p[0] = AST.MatrixTransp(p[1])

    def p_body(self, p):
        '''body : rows_with_brackets
                | rows_with_semicolons'''
        p[0] = p[1]

    def p_rows_with_brackets(self, p):
        '''rows_with_brackets : '[' row ']'
                              | rows_with_brackets ',' '[' row ']' '''
        if (not isinstance(p[0], list)):
            p[0] = []
        if (len(p) != 4):
            p[0] = p[1]
            p[0].append(p[4])
        else:
            p[0].append(p[2])

    def p_rows_with_semicolons(self, p):
        '''rows_with_semicolons : row
                                | rows_with_semicolons ';' row'''
        if (not isinstance(p[0], list)):
            p[0] = []

        if (len(p) != 2):
            p[0] = p[1]
            p[0].append(p[3])
        else:
            p[0].append(p[1])

    def p_row(self, p):
        """row : NUMBER
               | row ',' NUMBER """
        if(not isinstance(p[0], list)):
            p[0] = []
        if(len(p) != 2):
            p[0] = p[1]
            p[0].append(p[3])
        else:
            p[0].append(p[1])

    def p_number(self, p):
        """NUMBER : int
                  | float"""
        p[0] = p[1]

    #------ matrix operations: ------

    def p_matrix_matrix_operations(self, p): #zamiast matrix expression
        '''m_expr : matrix MATRIX_PLUS matrix
                  | matrix MATRIX_MINUS matrix
                  | matrix MATRIX_TIMES matrix
                  | matrix MATRIX_DIVIDE matrix'''
        p[0] = AST.Matrix_bin_ops(p[1], p[2], p[3])
Пример #27
0
class Mparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ('left', ','),
        ('right', '=', 'ADDASSIGN', 'SUBASSIGN', 'MULASSIGN', 'DIVASSIGN'),
        ("left", "EQ", "NEQ"),
        ("left", "<", ">", "LEQ", "GEQ"),
        ("left", '+', '-', 'DOTADD', 'DOTSUB'),
        ('left', '*', '/', 'DOTMUL', 'DOTDIV'),
        ('right', 'UMINUS'),
    )

    def p_error(self, p):
        if p:
            error_type = "Syntax error at line " + \
                "{0}, pos {1}: LexToken({2}, '{3}')""".format(
                p.lineno, self.scanner.find_column(p), p.type, p.value)
        else:
            error_type = "Unexpected end of input"

        raise Exception

    def p_program(self, p):
        """program : instructions_opt"""

        p[0] = Program(p[1], line_no=p.lineno)

    def p_instructions_opt_1(self, p):
        """instructions_opt : instructions """

        p[0] = InstructionsOpt(p[1], line_no=p.lineno)

    def p_instructions_opt_2(self, p):
        """instructions_opt : """

    def p_instructions_1(self, p):
        """instructions : instructions instruction """

        p[0] = p[1] + [p[2]]

    def p_instructions_2(self, p):
        """instructions : instruction """

        p[0] = [p[1]]

    def p_instruction(self, p):
        """instruction : inst ';'
                       | condition 
                       | expr ';' 
                       | inst ','
                       | expr ',' """

        p[0] = p[1]

    def p_inst_assign(self, p):
        """inst : ids '=' expr
                | ids ADDASSIGN expr
                | ids SUBASSIGN expr
                | ids MULASSIGN expr
                | ids DIVASSIGN expr """

        p[0] = Assign(p[1], p[2], p[3], line_no=p.lineno(2))

    def p_ids(self, p):
        """ids : ID
               | ID '[' values ']' """

        if len(p) <= 2:
            p[0] = Variable(p[1], line_no=p.lineno(1))
        else:
            p[0] = Variable(p[1], p[3], line_no=p.lineno(1))

    def p_break(self, p):
        """inst : BREAK """

        p[0] = Instruction(p[1], line_no=p.lineno(1))

    def p_continue(self, p):
        """inst : CONTINUE """

        p[0] = Instruction(p[1], line_no=p.lineno(1))

    def p_return(self, p):
        """inst : RETURN
                | RETURN values 
                | RETURN expr """

        value = None

        if len(p) > 2:
            value = p[2]

        p[0] = Instruction(p[1], value, line_no=p.lineno(1))

    def p_print(self, p):
        """inst : PRINT values
                | PRINT expr """

        p[0] = Instruction(p[1], p[2], line_no=p.lineno(1))

    def p_expr_binary(self, p):
        """expr : expr '+' expr
                | expr '-' expr
                | expr '*' expr
                | expr '/' expr """

        p[0] = BinExpr(p[2], p[1], p[3], line_no=p.lineno(2))

    def p_expr_elementwise(self, p):
        """expr : expr DOTADD expr
                | expr DOTSUB expr
                | expr DOTMUL expr
                | expr DOTDIV expr """

        p[0] = BinExpr(p[2], p[1], p[3], line_no=p.lineno(2))

    def p_expr_eq(self, p):
        """expr : expr EQ expr
                | expr GEQ expr
                | expr LEQ expr
                | expr NEQ expr
                | expr '<' expr
                | expr '>' expr"""

        p[0] = Equality(p[2], p[1], p[3], line_no=p.lineno(2))

    def p_expr_paren(self, p):
        """expr : '(' expr ')' """

        p[0] = p[2]

    def p_expr_transpose(self, p):
        """expr : expr "'" """

        p[0] = Transpose(p[2], p[1], line_no=p.lineno(2))

    def p_expr_negative(self, p):
        """expr : '-' expr %prec UMINUS"""

        p[0] = Negation(p[2], line_no=p.lineno(1))

    def p_expr(self, p):
        """expr : ids
                | integer
                | float
                | string
                | matrix """

        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTNUM """

        p[0] = IntNum(p[1], line_no=p.lineno(1))

    def p_float(self, p):
        """float : FLOAT """

        p[0] = FloatNum(p[1], line_no=p.lineno(1))

    def p_string(self, p):
        """string : STRING """

        p[0] = String(p[1], line_no=p.lineno(1))

    def p_matrix_operations(self, p):
        """matrix : ZEROS '(' values ')'
                  | ONES '(' values ')'
                  | EYE '(' values ')' """

        p[0] = MatrixOperation(p[1], p[3], line_no=p.lineno(1))

    def p_matrix_init(self, p):
        """matrix : '[' rows ']'
                  | '[' rows ';' ']' """

        p[0] = Matrix(p[2], line_no=p.lineno(1))

    def p_rows(self, p):
        """rows : values """

        p[0] = [p[1]]

    def p_rows_2(self, p):
        """rows : rows ';' values """

        p[0] = p[1] + [p[3]]

    def p_values(self, p):
        """values : expr """

        p[0] = [p[1]]

    def p_values_2(self, p):
        """values : values ',' expr """

        p[0] = p[1] + [p[3]]

    def p_block(self, p):
        """ block : '{' instructions_opt '}' """

        p[0] = p[2]

    def p_block_2(self, p):
        """ block : instruction """

        p[0] = InstructionsOpt([p[1]], line_no=p.lineno)

    def p_conditional(self, p):
        """ condition : if_condition
                      | for_condition
                      | while_condition """

        p[0] = p[1]

    def p_if(self, p):
        """ if_condition : if_cond"""

        p[0] = p[1]

    def p_if_2(self, p):
        """ if_condition : if_cond ELSE block"""

        p[0] = p[1]
        p[0].else_block = p[3]

    def p_if_3(self, p):
        """ if_condition : if_cond ELSE if_condition"""

        p[0] = p[1]
        p[0].else_cond = p[3]

    def p_if_cond(self, p):
        """ if_cond : IF '(' expr ')' block """

        p[0] = IfCondition(p[3], p[5], line_no=p.lineno)

    def p_for(self, p):
        """ for_condition : FOR ids '=' range block """

        p[0] = ForCondition(p[2], p[4], p[5], line_no=p.lineno(3))

    def p_range(self, p):
        """ range : expr ':' expr """

        p[0] = Range(p[1], p[3], line_no=p.lineno(2))

    def p_while(self, p):
        """ while_condition : WHILE '(' expr ')' block """

        p[0] = WhileCondition(p[3], p[5], line_no=p.lineno(1))
Пример #28
0
class PascalParser(object):
    #precedence rules for operators
    precedence = (
        ('left', '+', '-'),
        ('left', '*', '/')
    )

    #Each parser action is defined as the following:
    #def p_<name>(self, p):
    #    """Grammar rule"""
    #    <action code>

    #p is a list object that contains objects that represent the symbols in the grammar rule
    #For example:
    #""" assign : ident ASSIGN_OP expression"""
    #     p[0]    p[1]    p[2]      p[3] 

    #data can be bubbled up to parent rules by assignment to p[0]

    #region Actions
    def p_program(self, p):
        """program : program_decl"""
        p[0] = p[1]
        print(p[1])

    def p_program_decl(self, p):
        """program_decl : program_ident compound_statement '.' """
        p[0] = p[1]
    
    def p_program_decl_err(self, p):
        """program_decl : program_ident error '.' """
        p[0] = p[1]
    
    def p_program_decl_wvar(self, p):
        """program_decl : program_ident variable_decl_sec compound_statement '.'"""
        p[0] = p[1]
    
    def p_program_decl_wvar_err_a(self, p):
        """program_decl : program_ident error compound_statement '.'"""
        print(f"Err line {p.lineno(2)}")
        for s in p[3]:
            print('\t' + s + ';')
        p[0] = p[1]
    
    def p_program_decl_wvar_err_b(self, p):
        """program_decl : program_ident variable_decl_sec error '.'"""
        print("Compund statement error")
        p[0] = p[1]
    
    def p_program_ident(self, p):
        """program_ident : PROGRAM identifier ';'"""
        p[0] = str(p[1]) + " " + p[2]

    def p_program_ident_error(self, p):
        """program_ident : PROGRAM error ';'"""
        print("Program Identifier Error")

    def p_variable_decl_sec(self, p):
        """variable_decl_sec : VAR variable_decl_sec_inner"""
    
    def p_variable_decl_sec_err(self, p):
        """variable_decl_sec : VAR error"""
        print("Variable inner error")
    
    def p_variable_decl_sec_inner(self, p):
        """variable_decl_sec_inner : variable_declaration ';'
            | variable_decl_sec_inner variable_declaration ';'"""
    
    def p_variable_declaration(self, p):
        """variable_declaration : identifier_list ':' type"""
        s_type = "none"
        s_data = None

        if p[3] == "Integer":
            s_type = "int"
            s_data = 1

        for s in p[1]:
            self.interpreter.newsym(s, s_type, s_data)
    
    def p_identifier(self, p):
        """identifier : NAME"""
        p[0] = p[1]
    
    def p_identifier_list(self, p):
        """identifier_list : identifier
            | identifier_list ',' identifier"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            if p[1] is None:
                p[0] = [p[3]]
            else:
                p[0] = p[1]
                p[0].append(p[3])
    
    def p_type(self, p):
        """type : INTEGER"""
        p[0] = p[1]
    
    def p_compound_statement(self, p):
        """compound_statement : BEGIN statement_list END"""
        p[0] = p[2]
    
    def p_compound_statement_err(self, p):
        """compound_statement : BEGIN error END"""
        print("Compund Statement Error")
    
    def p_statement_list(self, p):
        """statement_list : statement
            | statement_list statement"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            if p[1] is None:
                p[0] = [p[2]]
            else:
                p[0] = p[1]
                p[0].append(p[2])
    
    def p_statement(self, p):
        """statement : assignment_statement
            | function_statement
            | compound_statement"""
        p[0] = p[1]
    
    def p_assignment_statement(self, p):
        """assignment_statement : identifier OP_ASSIGN actual_value ';'"""
        up = f"{p[1]} := {p[3]}"
        p[0] = up

    def p_assignment_err(self, p):
        """assignment_statement : identifier OP_ASSIGN error ';'"""
        print(f"Syntax error line {p.lineno(3)}: Malformed expression")
    
    def p_function_statement(self, p):
        """function_statement : function_designator ';'"""
        param = []
        name = ''
        desig = p[1]
        if(len(desig) == 2):
            name, param = desig
        else:
            name = desig
        sym = self.interpreter.getsym(name)
        sym.data(*param)
    
    def p_function_designator(self, p):
        """function_designator : identifier
            | identifier actual_parameter_list"""
        if len(p) == 2:
            p[0] = (p[1])
        else:
            p[0] = (p[1], p[2])

    def p_actual_parameter_list(self, p):
        """actual_parameter_list : '(' actual_parameter_list_inner ')'"""
        up = p[2]
        p[0] = up
    
    def p_actual_parameter_list_inner(self, p):
        """actual_parameter_list_inner : actual_parameter
            | actual_parameter_list_inner ',' actual_parameter"""
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            if p[1] is None:
                p[0] = [p[3]]
            else:
                p[0] = p[1]
                p[0].append(p[3])
    
    def p_actual_parameter(self, p):
        """actual_parameter : actual_value"""
        p[0] = p[1]
    
    def p_actual_value(self, p):
        """actual_value : expression"""
        up = p[1]
        exp = ''.join(p[1])
        p[0] = eval(exp)
    
    def p_expression(self, p):
        """expression : term
            | '-' term
            | '+' term
            | expression addition_operator term"""
        up = None

        if len(p) == 2:
            up = p[1]
        elif len(p) == 3:
            up = [p[1], *p[2]]
        else:
            up = p[1] + [p[2], *p[3]]
        
        p[0] = up

    
    def p_expression_err_a(self, p):
        """expression : error addition_operator term"""
        print("Expression error type A")
    
    def p_expression_err_b(self, p):
        """expression : expression error term"""
        print("Expression error type B")
    
    def p_expression_err_c(self, p):
        """expression : expression addition_operator error"""
        print("Expression error type C")
    
    def p_addition_operator(self, p):
        """addition_operator : '+'
            | '-'"""
        p[0] = p[1]
    
    def p_term(self, p):
        """term : factor
            | term multiplication_operator factor"""
        up = None
        if len(p) == 2:
            up = [p[1]]
        else:
            up = p[1] + [p[2], p[3]]
        p[0] = up
    
    def p_multiplication_operator_m(self, p):
        """multiplication_operator : '*'
            | '/'"""
        up = p[1]
        if up == '/':
            up = '//'
        p[0] = up
    
    def p_factor_str(self, p):
        """factor : STRING"""
        p[0] = p[1]

    def p_factor_exp(self, p):
        """factor : '(' expression ')'"""
        p[0] = p[1]
    
    def p_factor_ident(self, p):
        """factor : identifier"""
        p[0] = str(self.interpreter.getsym(p[1]).data)
    
    def p_error(self, p):
        print("Syntax error in input!")
        print(p)
    #endregion

    #Helper methods
    def Parse(self, text):
        self.interpreter = Interpreter()
        self.Yacc.parse(text, lexer=self.Lexer.Lexer, tracking=True)

    def build(self,**kwargs):
        self.Lexer = Scanner()
        self.Lexer.build()
        self.tokens = self.Lexer.tokens
        self.Yacc = yacc.yacc(module=self, **kwargs)
Пример #29
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')

    
    
    def p_program(self, p):
        """program : declarations fundefs instructions"""
    
    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
                     
    
    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """


    def p_init(self, p):
        """init : ID '=' expression """


    
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
    
    
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
    
    
    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
    
    
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
    
    
    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
    
    
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

    
    
    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
    
    
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
    
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
    
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
    
    
    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """

    
    def p_condition(self, p):
        """condition : expression"""


    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
    
    
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
    
    
    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
    
    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
    
    
    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
    
    
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
    
    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
    
    def p_arg(self, p):
        """arg : TYPE ID """
Пример #30
0
class Cparser(object):

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')


    def p_program(self, p):
        """program : children children children"""
        declarations = None if len(p[1].declarations) == 0 else p[1]
        fundefs = None if len(p[2].fundefs) == 0 else p[2]
        print AST.Program(declarations, fundefs, p[3])

    def p_declarations(self, p):
        """children : children declaration
                        | """
        if len(p) == 3:
            p[0] = AST.DeclarationList() if p[1] is None else p[1]
            p[0].addDeclaration(p[2])
        else:
            p[0] = AST.DeclarationList()
                     
    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            type = p[1]
            inits = p[2]
            p[0] = AST.Declaration(type, inits)

    def p_inits(self, p):
        """children : children ',' init
                 | init """
        if len(p) == 4:
            p[0] = AST.InitList() if p[1] is None else p[1]
            p[0].addInit(p[3])
        else:
            p[0] = AST.InitList()
            p[0].addInit(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        expr = p[3]
        p[0] = AST.Init(id, expr)
    
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = AST.InstructionList() if p[1] is None else p[1]
            p[0].addInstruction(p[2])
        else:
            p[0] = AST.InstructionList()
            p[0].addInstruction(p[1])
    
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]
    
    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        expr = p[2]
        p[0] = AST.PrintInstruction(expr)
    
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        instruction = p[3]
        p[0] = AST.LabeledInstruction(id, instruction)

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        expr = p[3]
        p[0] = AST.AssignmentInstruction(id, expr)
    
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        action = p[5]
        alternateAction = None if len(p) < 8 else p[7]
        p[0] = AST.ChoiceInstruction(condition, action, alternateAction)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileInstruction(condition, instruction)

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT children UNTIL condition ';' """
        instructions = p[2]
        condition = p[4]
        p[0] = AST.RepeatInstruction(instructions, condition)
    
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        expression = p[2]
        p[0] = AST.ReturnInstruction(expression)
    
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()
    
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()
 
    def p_compound_instr(self, p):
        """compound_instr : '{' children children '}' """
        if len(p[2].declarations) == 0:
            p[0] = AST.CompoundInstruction(None, p[3])
        else:
            p[0] = AST.CompoundInstruction(p[2], p[3])
        
    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = p[1]
    
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            value = p[1]
            p[0] = AST.Const(value)
        elif p[2] == "(" and p[1] != "(":
            funcName = p[1]
            args = p[3]
            p[0] = AST.InvocationExpression(funcName, args)
        elif p[1] == "(":
            interior = p[2]
            p[0] = AST.GroupedExpression(interior)
        else:
            lhs = p[1]
            op = p[2]
            rhs = p[3]
            p[0] = AST.BinExpr(lhs, op, rhs)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = AST.ExpressionList() if p[1] is None else p[1]
            p[0].addExpression(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].addExpression(p[1])
    
    
    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[0] = p[2]
            p[0].addFunction(p[1])
        else:
            p[0] = AST.FunctionExpressionList()

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionExpression(p[1], p[2], p[4], p[6])
    
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = None if len(p) == 0 else p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[0] = AST.ArgumentList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ArgumentList()
            p[0].addArgument(p[1])
            
    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        name = p[2]
        p[0] = AST.Argument(type, name)
Пример #31
0
class MParser(object):

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens + Scanner.literals

    precedence = (
       ('nonassoc', 'IFX'),
       ('nonassoc', 'ELSE'),
       ('left', ','),
       ('right', '=', 'PLUSASSIGN', 'MINUSASSIGN', 'MULASSIGN', 'DIVASSIGN'),
       ('left', 'EQ', 'NEQ'),
       ('left', '>', '<', 'LESSEQ', 'MOREEQ'),
       ('left', '+', '-'),
       ('left', '*', '/'),
       ('nonassoc', 'UMINUS'),
       ('left', 'DOTPLUS', 'DOTMINUS'),#?
       ('left', 'DOTMUL', 'DOTDIV'),#?
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : instructions_opt"""
        p[0] = AST.Program(p[1])
        print(p[0])

    def p_instructions_opt_1(self, p):
        """instructions_opt : instructions """
        p[0] = p[1]

    def p_instructions_opt_2(self, p):
        """instructions_opt : """

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction"""
        if len(p) == 3:
            p[0] = AST.InstructionList() if p[1] is None else p[1]
            p[0].add_instruction(p[2])
        else:
            p[0] = AST.InstructionList()
            p[0].add_instruction(p[1])

    def p_instruction(self, p):
        """instruction : if_else_instr
                       | while_instr
                       | for_instr
                       | break_instr
                       | continue_instr
                       | return_instr
                       | print_instr
                       | instr_block
                       | assignment ';'"""
        p[0] = p[1]

    def p_if_else_inst(self, p):
        """if_else_instr : IF '(' expression ')' instruction %prec IFX 
                         | IF '(' expression ')' instruction ELSE instruction
                         | IF '(' error ')' instruction  %prec IFX
                         | IF '(' error ')' instruction ELSE instruction """
        else_inst = p[7] if len(p) == 8 else None
        p[0] = AST.IfElseInstr(p[3], p[5], else_inst)

    def p_while_inst(self, p):
        """while_instr : WHILE '(' expression ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5], p.lineno(1))

    def p_for_inst(self, p):
        """for_instr : FOR for_init instruction"""
        p[0] = AST.ForInstr(p[2], p[3])

    def p_for_init(self, p):
        """for_init : ID '=' expression ':' expression"""
        p[0] = AST.ForInit(p[1], p[3], p[5], p.lineno(1))

    def p_break_inst(self, p):
        """break_instr : BREAK ';'"""
        p[0] = AST.BreakInstr(p.lineno(1))

    def p_continue_inst(self, p):
        """continue_instr : CONTINUE ';'"""
        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';'"""
        p[0] = AST.ReturnInstr(p[2], p.lineno(1))

    def p_print_instr(self, p):
        """print_instr : PRINT print_vars ';'
                       | PRINT error ';'"""
        p[0] = AST.PrintInstr(p[2], p.lineno(1))

    def p_print_vars(self, p):
        """print_vars : print_vars ',' print_var
                      | print_var"""
        if len(p) == 4:
            p[0] = AST.PrintVarsList() if p[1] is None else p[1]
            p[0].add_var(p[3])
        else:
            p[0] = AST.PrintVarsList()
            p[0].add_var(p[1])

    def p_print_var(self, p):
        """print_var : STRING
                     | expression """
        p[0] = p[1]

    def p_complex_instr(self, p):
        """instr_block : '{' instructions '}'"""
        p[0] = AST.InstrBlock(p[2])

    def p_number_int(self, p):
        """number : INT"""
        p[0] = AST.Integer(p[1], p.lineno(1))

    def p_number_float(self, p):
        """number : FLOAT"""
        p[0] = AST.Float(p[1], p.lineno(1))

    def p_lvalue(self, p):
        """lvalue : ID
                  | ID '[' INT ']'
                  | ID '[' INT ',' INT ']'"""
        if len(p) == 2:
            p[0] = AST.LValue(p[1], None, p.lineno(1))
        else:
            p[0] = AST.LValue(p[1], [p[3]], p.lineno(1)) if len(p) == 5 else AST.LValue(p[1], [p[3], p[5]], p.lineno(1))

    def p_assignment(self, p):
        """assignment : lvalue assign_op expression"""
        p[0] = AST.AssignmentInstr(p[1], p[2], p[3], p.lineno(1))

    def p_assign_op(self, p):
        """assign_op : '='
                     | PLUSASSIGN
                     | MINUSASSIGN
                     | MULASSIGN
                     | DIVASSIGN"""
        p[0] = p[1]

    def p_expression(self, p):
        """expression : number
                      | lvalue
                      | matrix_init
                      | '(' expression ')'
                      | '-' expression %prec UMINUS
                      | expression '\\''"""
        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 3:
            p[0] = AST.UnOperation(p[1], p[2], p.lineno(1)) if p[1] == '-' else AST.UnOperation(p[2], p[1], p.lineno(2))
        else:
            p[0] = p[2]

    def p_rel_op(self, p):
        """expression : expression '<' expression
                      | expression '>' expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression LESSEQ expression
                      | expression MOREEQ expression"""
        p[0] = AST.BinOperation(p[2], p[1], p[3], p.lineno(2))

    def p_num_op(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression"""
        p[0] = AST.BinOperation(p[2], p[1], p[3], p.lineno(2))

    def p_dot_op(self, p):
        """expression : expression DOTPLUS expression
                      | expression DOTMINUS expression
                      | expression DOTMUL expression
                      | expression DOTDIV expression"""
        p[0] = AST.BinOperation(p[2], p[1], p[3], p.lineno(2))

    def p_matrix_init(self, p):
        """matrix_init : eye
                       | ones
                       | zeros
                       | '[' matrix_rows ']'
                       | '[' scopes ']'"""
        p[0] = p[1] if len(p) == 2 else p[2]

    def p_eye(self, p):
        """eye : EYE '(' expression ')' """
        p[0] = AST.EyeInit(p[3], p.lineno(1))

    def p_ones(self, p):
        """ones : ONES '(' expression ')' """
        p[0] = AST.OnesInit(p[3], p.lineno(1))

    def p_zeros(self, p):
        """zeros : ZEROS '(' expression ')' """
        p[0] = AST.ZerosInit(p[3], p.lineno(1))

    def p_matrix_rows(self, p):
        """matrix_rows : matrix_rows ';' row_elems
                       | row_elems """
        if len(p) == 4:
            p[0] = AST.Matrix(p.lineno(1)) if p[1] is None else p[1]
            p[0].add_row(p[3])
        else:
            p[0] = AST.Matrix(p.lineno(1))
            p[0].add_row(p[1])

    def p_row_elems(self, p):
        """row_elems : row_elems ',' number
                     | number """
        if len(p) == 4:
            p[0] = AST.MatrixRow(p.lineno(1)) if p[1] is None else p[1]
            p[0].add_elem(p[3])
        else:
            p[0] = AST.MatrixRow(p.lineno(1))
            p[0].add_elem(p[1])

    def p_scopes(self, p):
        """scopes : scope
                | scopes ';' scope """

        if len(p) == 4:
            p[0] = AST.Matrix(p.lineno(1)) if p[1] is None else p[1]
            p[0].add_row(p[3])
        else:
            p[0] = AST.Matrix(p.lineno(1))
            p[0].add_row(p[1])

    def p_scope(self, p):
        """scope : INT ':' INT
                | number ':' number ':' number"""

        p[0] = AST.MatrixRow(p.lineno(1))
        if len(p) == 4:
            p[0].add_from_scope(p[1], 1, p[3])
        else:
            p[0].add_from_scope(p[1], p[3], p[5])
Пример #32
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : declarations fundefs_opt instructions_opt"""
        print(
            AST.Program(declarations=p[1],
                        fundefs_opt=p[2],
                        instructions_opt=p[3]))

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            p[0] = AST.Declarations() if p[1] is None else p[1]
            p[0].add(p[2])
        else:
            p[0] = AST.Declarations()

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            p[0] = AST.Declaration(d_type=p[1], inits=p[2])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = AST.Inits() if p[1] is None else p[1]
            p[0].add(p[3])
        else:
            p[0] = AST.Inits()
            p[0].add(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        d_id = p[1]
        expr = p[3]
        p[0] = AST.Init(d_id, expr)

    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Instructions()

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = AST.Instructions() if p[1] is None else p[1]
            p[0].add(p[2])
        else:
            p[0] = AST.Instructions()
            p[0].add(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        expression_list = p[2]
        p[0] = AST.PrintInstruction(expression_list)

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(id=p[1], expression=p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

        else_instruction = None if len(p) < 8 else p[7]
        p[0] = AST.ChoiceInstruction(condition=p[3],
                                     instruction=p[5],
                                     else_instruction=else_instruction)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstruction(condition=p[3], instruction=p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstruction(condition=p[4], instructions=p[2])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstruction(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        p[0] = AST.CompoundInstruction(declarations=p[2],
                                       instructions_opt=p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = p[1]

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            p[0] = AST.Const(p[1])
        elif p[1] == '(':
            p[0] = p[2]
        elif p[2] == '(':
            p[0] = AST.Funcall(id=p[1], expression_list=p[3])
        else:
            p[0] = AST.BinExpr(left=p[1], op=p[2], right=p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = ExpressionList()

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = AST.Expressions() if p[1] is None else p[1]
            p[0].add(p[3])
        else:
            p[0] = AST.Expressions()
            p[0].add(p[1])

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs
                       | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Fundefs()

    def p_fundefs(self, p):
        """fundefs : fundefs fundef
                   | fundef """
        if len(p) == 3:
            p[0] = AST.Fundefs() if p[1] is None else p[1]
            p[0].add(p[2])
        else:
            p[0] = AST.Fundefs()
            p[0].add(p[1])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(d_type=p[1],
                          id=p[2],
                          arguments=p[4],
                          compound_instructions=p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Arguments()

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """

        if len(p) == 4:
            p[0] = AST.Arguments() if p[1] is None else p[1]
            p[0].add(p[3])
        else:
            p[0] = AST.Arguments()
            p[0].add(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Argument(type=p[1], id=p[2])
Пример #33
0
class Cparser(object):

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if not p:
            print('Syntax error at end of input')
        else:
            pass

    def handle_error(self, type, p):
        print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')"
              .format(p.lineno,
                      self.scanner.find_tok_column(p),
                      p.type,
                      p.value))

    def p_program(self, p):
        """program : declarations fundefs_opt instructions_opt"""
        p[0] = Program(p[1], p[2], p[3])


# declarations

    def p_declarations(self, p):
        """declarations : declarations declaration"""
        if p[2]:
            p[0] = DeclarationList(p[1].dec_list + [p[2]])
        else:
            p[0] = p[1]

    def p_no_declarations(self, p):
        """declarations : """
        p[0] = DeclarationList([])

# END declarations


# declaration

    def p_declaration(self, p):
        """declaration : TYPE inits ';'"""
        p[0] = Declaration(p[1], p[2])

    def p_error_declaration(self, p):
        """declaration : error ';'"""
        self.handle_error('declaration', p[1])

# END declaration

# inits

    def p_inits(self, p):
        """inits : inits ',' init"""

        p[0] = InitList(p[1].init_list + [p[3]])

    def p_single_init(self, p):
        """inits : init """
        p[0] = InitList([p[1]])

# END inits

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3])


# instructions_opt

    def p_instructions_opt(self, p):
        """instructions_opt : instructions"""
        p[0] = p[1]

    def p_empty_instructions_opt(self, p):
        """instructions_opt : """
        p[0] = InstructionList([])

# END instructions_opt

# instructions

    def p_instructions(self, p):
        """instructions : instructions instruction"""
        p[0] = InstructionList(p[1].instr_list + [p[2]])

    def p_sinle_instruction(self, p):
        """instructions : instruction """
        p[0] = InstructionList([p[1]])

# END instructions

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]


# print_instr

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'"""
        p[0] = PrintInstr(p[2])

    def p_print_instr_err(self, p):
        """print_instr : PRINT error ';' """
        self.handle_error('print', p[2])

# END print_instr

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = Labeled_instr(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = Assignment(p[1], p[3])


# choice_instr

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX """
        p[0] = ChoiceInstr(p[3], p[5])

    def p_choice_instr_with_else(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction """
        p[0] = ChoiceInstr(p[3], p[5], p[7])

    def p_error_choice_instr(self, p):
        """choice_instr : IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        self.handle_error('IF', p[3])

# END choice)instr


# while_instr

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction """
        p[0] = WhileInstr(p[3], p[5])

    def p_error_while_instr(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        self.handle_error('while', p[3])

# END while_instr

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = RepeatInstr(p[4], p[2])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = Return(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = KeyWord("continue")

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = KeyWord("break")

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        p[0] = Compound_instr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = Condition(p[1])

    def p_const_I(self, p):
        """const : INTEGER"""
        p[0] = Integer(p[1])

    def p_const_F(self, p):
        """const : FLOAT"""
        p[0] = Float(p[1])

    def p_const_S(self, p):
        """const : STRING"""
        p[0] = String(p[1])
# expression

    def p_expression(self, p):
        """expression : ID '(' expr_list_or_empty ')' """
        p[0] = ExpressionIdWithList(p[1], p[3])

    def p_expression_const(self, p):
        """expression : const """
        p[0] = p[1]

    def p_expression_id(self, p):
        """expression : ID """
        p[0] = Id(p[1])

    def p_expression_with_par(self, p):
        """expression : '(' expression ')' """
        p[0] = p[2]

    def p_expression_two_exprs(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression """
        p[0] = BinExpr(p[2], p[1], p[3])

    def p_expression_err(self, p):
        """expression : ID '(' error ')'
                      | '(' error ')'"""
        self.handle_error('Expr', p[2])

# END expression


# expr_list_or_empty

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list"""
        p[0] = p[1]

    def p_empty_expr_list(self, p):
        """expr_list_or_empty : """
        p[0] = ExprList([])

# END expr_list_or_empty


# expr_list

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression"""
        p[0] = ExprList(p[1].expr_list + [p[3]])

    def p_single_expr(self, p):
        """expr_list : expression """
        p[0] = ExprList([p[1]])

# END expr_list


# fundefs_opt

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs"""
        p[0] = p[1]

    def p_empty_fundefs_opt(self, p):
        """fundefs_opt : """
        p[0] = FunctionList([])

# END fundefs_opt


# fundefs

    def p_fundefs(self, p):
        """fundefs : fundefs fundef"""
        p[0] = FunctionList(p[1].fun_list + [p[2]])

    def p_single_fundef(self, p):
        """fundefs : fundef """
        p[0] = FunctionList([p[1]])

# END fundefs

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = Function(p[1], p[2], p[4], p[6])


# args_list_or_empty

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list"""
        p[0] = p[1]

    def p_empty_args_list(self, p):
        """args_list_or_empty : """
        p[0] = ArgsList([])

# END args_list_or_empty


# args_list

    def p_args_list(self, p):
        """args_list : args_list ',' arg"""
        p[0] = ArgsList(p[1].args_list + [p[3]])

    def p_single_arg_list(self, p):
        """args_list : arg """
        p[0] = ArgsList([p[1]])

# END args_list

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Arg(p[1], p[2])
Пример #34
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program :  instruction_list"""
        p[0] = AST.Program(p[1])

    def p_instruction_list(self, p):
        """instruction_list : instruction_list instruction_item
                            | """
        if len(p) == 3:
            p[0] = list(p[1]) if p[1] else []
            p[0].append(p[2])
        else:
            p[0] = []

    def p_instruction_item(self, p):
        """instruction_item : declaration
                            | fundef
                            | instruction"""
        p[0] = p[1]

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            p[0] = list(p[1]) if p[1] else []
            p[0].append(p[2])
        else:
            p[0] = []

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            p[0] = AST.Declaration(AST.Name(p[1]), p[2])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = list(p[1])
            p[0].append(p[3])
        else:
            p[0] = [p[1]]

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Initializer(AST.Name(p[1]), p[3])

    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        if len(p) == 2:
            p[0] = list(p[1])
        else:
            p[0] = []

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = list(p[1])
            p[0].append(p[2])
        else:
            p[0] = [p[1]]

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(AST.Name(p[1]), p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(AST.Name(p[1]), p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        p[0] = AST.IfInstr(p[3], p[5], None if len(p) < 8 else p[7])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : integer
                 | float
                 | string"""
        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        p[0] = AST.Integer(p[1])

    def p_float(self, p):
        """float : FLOAT"""
        p[0] = AST.Float(p[1])

    def p_string(self, p):
        """string : STRING"""
        p[0] = AST.String(p[1])

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            if isinstance(p[1], AST.Const):
                p[0] = p[1]
            else:
                p[0] = AST.Name(p[1])
        elif p[1] == '(':
            p[0] = AST.EnclosedExpr(p[2])
        elif p[2] == '(':
            p[0] = AST.MethodCallExpr(AST.Name(p[1]), p[3])
        else:
            p[0] = AST.BinaryExpr(p[1], AST.Operator(p[2]), p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = list(p[1])
        else:
            p[0] = []

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = list(p[1])
            p[0].append(p[3])
        else:
            p[0] = [p[1]]

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs
                       | """
        if len(p) == 2:
            p[0] = list(p[1])
        else:
            p[0] = []

    def p_fundefs(self, p):
        """fundefs : fundefs fundef
                   | fundef """
        if len(p) == 3:
            p[0] = list(p[1])
            p[0].append(p[2])
        else:
            p[0] = [p[1]]

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionDef(AST.Name(p[1]), AST.Name(p[2]), p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = list(p[1])
        else:
            p[0] = []

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            p[0] = list(p[1])
            p[0].append(p[3])
        else:
            p[0] = [p[1]]

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Argument(AST.Name(p[1]), AST.Name(p[2]))
Пример #35
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : sections"""
        p[0] = AST.Program(p[1])

    def p_sections(self, p):
        """sections : sections section
                      | """
        p[0] = [] if len(p) == 1 else p[1] + [p[2]]

    def p_section(self, p):
        """section    : fundef
                        | statement """
        p[0] = p[1]

    def p_statement(self, p):
        """statement    : declaration
                        | instruction """
        p[0] = p[1]

    def p_statements(self, p):
        """statements : statements statement
                    | statement"""
        p[0] = [p[1]] if len(p) == 2 else p[1] + [p[2]]

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        p[0] = p[1] if len(p) == 3 else AST.Declaration(p[1], p[2])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        p[0] = p[1] + [p[3]] if len(p) == 4 else [p[1]]

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        p[0] = p[1] + [p[2]] if len(p) == 3 else [p[1]]

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3], p.lineno(1))

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3], p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        p[0] = AST.ChoiceInstr(*p[3::2])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' statements '}' """
        p[0] = AST.CompoundInstr(p[2])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : float
                 | integer
                 | string"""
        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        p[0] = AST.Integer(p[1])


    def p_float(self, p):
        """float : FLOAT"""
        p[0] = AST.Float(p[1])


    def p_string(self, p):
        """string : STRING"""
        p[0] = AST.String(p[1])

    def p_bin_expr(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""
        p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(2))

    def p_funcall_expr(self, p):
        """expression : ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        p[0] = AST.FunCall(p[1], p[3], p.lineno(1))

    def p_bracket_expr(self, p):
        """ expression : '(' expression ')'
                       | '(' error ')'"""
        p[0] = p[2]

    def p_expression(self, p):
        """expression : const
                      | ID"""
        p[0] = AST.Identifier(p[1], p.lineno(1)) if type(p[1]) is str else p[1]

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = [] if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        p[0] = [p[1]] if len(p) == 2 else p[1] + [p[3]]

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' '{' statements '}' """
        p[0] = AST.FunDef(p[1], p[2], p[4], p[7], p.lineno(1), p.lineno(8))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = [] if len(p) == 1 else p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        p[0] = [p[1]] if len(p) == 2 else p[1] + [p[3]]

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.FunArg(p[1], p[2], p.lineno(1))
Пример #36
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print("Unexpected end of input")


    def p_file(self, p):
        """file : program"""
        program = p[1]
        print AST.File(program)


    def p_program(self, p):
        """program : program_parts
                    | """
        p[0] = p[1] if len(p) == 2 else AST.Epsilon()

    def p_program_parts(self, p):
        """program_parts : program_parts program_part
                        | program_part"""
        if len(p) == 3:
            p[0] = p[1]
            p[0].appendPart(p[2])
        else:
            p[0] = AST.ProgramParts()
            p[0].appendPart(p[1])


    def p_program_part(self, p):
        """program_part : declaration
                        | instruction
                        | fundef"""
        p[0] = p[1]


    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        type = p[1]
        inits = p[2]
        p[0] = AST.Declaration(type, inits)


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = p[1]
            p[0].addInit(p[3])
        else:
            p[0] = AST.InitList()
            p[0].addInit(p[1])


    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        expression = p[3]
        p[0] = AST.Init(id, expression)


    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]


    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstruction(p[2])


    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1], p[3])


    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3])


    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        instruction = p[5]
        elseInstruction = p[7] if len(p) == 8 else None
        p[0] = AST.ChoiceInstruction(condition, instruction, elseInstruction)


    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileLoop(condition, instruction)


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT program_parts UNTIL condition ';' """
        program_parts = p[2]
        condition = p[4]
        p[0] = AST.RepeatInstruction(program_parts, condition)


    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstruction(p[2])


    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()


    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()


    def p_compound_instr(self, p):
        """compound_instr : '{' program_parts '}' """
        program_parts = p[2]
        p[0] = AST.CompoundInstruction(program_parts)


    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])


    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = AST.Const(p[1])


    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        lenp = len(p)
        if lenp == 2:
            p[0] = p[1]
        elif lenp == 4:
            if p[1] == '(':
                if p[2] == ')':
                    p[0] = AST.Epsilon
                else:
                    p[0] = p[2]
            else:
                p[0] = AST.BinExpr(p[2], p[1], p[3])
        elif lenp == 5:
            p[0] = AST.FunCall(p[1], p[3])


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 1:
            p[0] = AST.Epsilon()
        else:
            p[0] = p[1]



    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 2:
            p[0] = AST.ExprList()
            p[0].addExpr(p[1])
        else:
            p[0] = p[1]
            p[0].addExpr(p[3])


    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        ret = p[1]
        name = p[2]
        args = p[4]
        compound = p[6]
        p[0] = AST.Fundef(ret, name, args, compound)


    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Epsilon()

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            p[0] = p[1]
            p[0].appendArg(p[3])
        else:
            p[0] = AST.ArgsList()
            p[0].appendArg(p[1])


    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2])
Пример #37
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens
    
    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )
    

    error_encountered = False
    


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')

    
    
    def p_program(self, p):
        """program : declarations fundefs instructions"""
        
        p[0] = Program(p[1], p[2], p[3])
        #if self.error_encountered == False:
        #    p[0].accept(TypeChecker(), SymbolTable(None))
        p[0].error_encountered = self.error_encountered
    
    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if (len(p) == 3):
            p[1].append(p[2])
            p[0] = p[1]
        else:
            p[0] = list()
    
    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            p[0] = Declaration(p[1], p[2])
        else:
            print "Bad declaration at line", p.lineno(1)
            self.error_encountered = True
            

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[1].append(p[3])
            p[0] = p[1]
        else:
            p[0] = list()
            p[0].append(p[1])


    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3], p.lineno(1))

    
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[1].append(p[2])
            p[0] = p[1]
        else:
            p[0] = list()
            p[0].append(p[1])
    
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]
    
    
    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        if isinstance(p[2], Node):
            p[0] = PrintInstr(p[2])
        else:
            print "Bad expression in print instruction at line", p.lineno(1)
            self.error_encountered = True
    
    
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = p[3]
        
    
    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = Assignment(p[1], p[3], p.lineno(1))
    
    
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if isinstance(p[3], Node) == False:
            print "Bad condition in choice instruction at line", p.lineno(1)
            self.error_encountered = True  
        elif len(p) == 6:
            p[0] = ChoiceInstr(p[3], p[5])
        else:
            p[0] = ChoiceInstr(p[3], p[5], p[7])
    
    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        if isinstance(p[3], Node) == False:
            print "Bad condition in while instruction at line", p.lineno(1)
            self.error_encountered = True
        else:  
            p[0] = WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = RepeatInstr(p[2], p[4])
    
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = RetInstr(p[2])
    
    
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = ContinueInstr()
    
    
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = BreakInstr()
    
    
    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = CompoundInstr(p[2], p[3])

    
    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]


    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        try:
            p[0] = Integer(int(p[1]), p.lineno(1))
        except ValueError:
            try:
                p[0] = Float(float(p[1]), p.lineno(1))
            except ValueError:
                p[0] = String(p[1], p.lineno(1))
        '''
        if isinstance(p[1], int):
            p[0] = Integer(p[1], p.lineno(1))
        elif isinstance(p[1], float):
            p[0] = Float(p[1], p.lineno(1))
        else:
            p[0] = String(p[1], p.lineno(1))
        '''
    
    
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        
        if len(p) == 5:
            if isinstance(p[3], list):
                p[0] = FunCall(p[1], p[3], p.lineno(1))
            else:
                print "Bad function call at line", p.lineno(1)
                self.error_encountered = True
        elif len(p) == 4 and p[1] == '(':
            if isinstance(p[2], Node) == False:
                print "Bad expression at line", p.lineno(1)
                self.error_encountered = True
            else:  
                p[0] = p[2]
        elif len(p) == 2:
            if type(p[1]) is str:
                p[0] = Variable(p[1], p.lineno(1))
            else:
                p[0] = p[1]
        else:
            p[0] = BinExpr(p[1], p[2], p[3], p.lineno(2))
    
    
    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = list()    
    
    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[1].append(p[3])
            p[0] = p[1]
        else:
            p[0] = list()
            p[0].append(p[1])
    
    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[2].append(p[1])
            p[0] = p[2]
        else:
            p[0] = list()        

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = FunDef(p[1], p[2], p[4], p[6], p.lineno(1))
    
    
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]     #at least one element in list
        else:
            p[0] = list()   #empty list        
    
    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[1].append(p[3])
            p[0] = p[1]
        else:
            p[0] = list()
            p[0].append(p[1])
    
    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Arg(p[1], p[2], p.lineno(1))
Пример #38
0
class Cparser(object):

    palka = ''

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    error = 0

    def p_error(self, p):
        Cparser.error = 1
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
            #exit(1);
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = AST.Program(p[1], p[2], p[3])
        #print(p[0].toString(0))
        p[1].line = self.scanner.lexer.lineno
        p[1].line = self.scanner.lexer.lineno

    def p_declarations(self, p):
        """declarations : declarations declaration"""
        p[0] = AST.Declarations(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_declarations_1(self, p):
        """declarations : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_declaration(self, p):
        """declaration : TYPE inits ';' """
        p[0] = AST.Declaration(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_declaration_error(self, p):
        """declaration : error ';' """
        self.p_error(p[1])

    def p_inits(self, p):
        """inits : inits ',' init"""
        p[0] = AST.Inits(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_inits_1(self, p):
        """inits : init"""
        p[0] = AST.Inits(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_instructions(self, p):
        """instructions : instructions instruction"""
        p[0] = AST.Instructions(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_instructions_1(self, p):
        """instructions : instruction"""
        p[0] = AST.Instructions(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = AST.Instruction(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'"""
        p[0] = AST.Print(p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_print_instr_1(self, p):
        """print_instr : PRINT error ';' """
        self.p_error(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.Labeled(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX"""
        p[0] = AST.Choice(p[3], p[5], None)
        p[0].line = self.scanner.lexer.lineno

    def p_choice_instr_1(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction"""
        p[0] = AST.Choice(p[3], p[5], p[7])
        p[0].line = self.scanner.lexer.lineno

    def p_choice_instr_error(self, p):
        """choice_instr : IF '(' error ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX"""
        self.p_error(p[3])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction"""
        p[0] = AST.While(p[3], p[5])
        p[0].line = self.scanner.lexer.lineno

    def p_while_instr_error(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        self.p_error(p[3])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.Repeat(p[2], p[4])
        p[0].line = self.scanner.lexer.lineno

    def p_repeat_error(self, p):
        """repeat_instr : REPEAT instructions UNTIL error ';' """
        self.p_error(p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return(p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Keyword(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Keyword(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstruction(p[2], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_int(self, p):
        """const : INTEGER"""
        p[0] = AST.Integer(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_float(self, p):
        """const : FLOAT"""
        p[0] = AST.Float(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_string(self, p):
        """const : STRING"""
        p[0] = AST.String(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_const(self, p):
        """expression : const"""
        p[0] = p[1]

    def p_expression_id(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_expression(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '^' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression """
        p[0] = AST.BinExpression(p[1], p[2], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_1(self, p):
        """expression : ID '(' expr_list_or_empty ')'"""
        p[0] = AST.Funcall(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_2(self, p):
        """expression : '(' expression ')'"""
        p[0] = AST.ExpressionInParentheses(p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_error(self, p):
        """expression : '(' error ')'"""
        self.p_error(p[2])

    def p_expression_error_2(self, p):
        """expression : ID '(' error ')'"""
        self.p_error(p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list"""
        p[0] = AST.ExpressionList(p[1], None)
        p[0].line = self.scanner.lexer.lineno

    def p_expr_list_or_empty_1(self, p):
        """expr_list_or_empty : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression"""
        p[0] = AST.ExpressionList(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_expr_list_1(self, p):
        """expr_list : expression"""
        p[0] = AST.ExpressionList(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_fundefs(self, p):
        """fundefs : fundef fundefs"""
        p[0] = AST.FunctionDefinitions(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_fundefs_1(self, p):
        """fundefs : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionDefinition(p[1], p[2], p[4], p[6])
        p[0].line = self.scanner.lexer.lineno

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list"""
        p[0] = AST.ArgumentList(p[1], None)
        p[0].line = self.scanner.lexer.lineno

    def p_arg_list_or_empty_1(self, p):
        """args_list_or_empty : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_args_list(self, p):
        """args_list : args_list ',' arg"""
        p[0] = AST.ArgumentList(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_arg_list_1(self, p):
        """args_list : arg"""
        p[0] = AST.ArgumentList(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Argument(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno
Пример #39
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : declarations fundefs_opt instructions_opt"""

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """

    def p_init(self, p):
        """init : ID '=' expression """

    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """

    def p_condition(self, p):
        """condition : expression"""

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs
                       | """

    def p_fundefs(self, p):
        """fundefs : fundefs fundef
                   | fundef """

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """

    def p_arg(self, p):
        """arg : TYPE ID """
Пример #40
0
class Cparser(object):
    def __init__(self):
        self.error_occured = False
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : main_parts_interlacing"""
        #p[0] = ('program',p[1],p[2],p[3])
        p[0] = Program(p[1])

    def p_main_parts_interlacing(self, p):
        """main_parts_interlacing : main_parts_interlacing main_part
                                   | main_part
        """
        if p.__len__() == 3:
            p[0] = MainPartsInerlacing(p[1], p[2])
        else:
            p[0] = MainPartsInerlacing(None, p[1])

    def p_main_part(self, p):
        """
        main_part : declaration
                  | fundef
                  | instruction
        """
        p[0] = p[1]

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        #p[0] = ('') if p.__len__() == 1 else ('decl',p[1], p[2])
        p[0] = None if p.__len__() == 1 else Declarations(p[1], p[2])

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        #p[0] = ('declaration',p[1], p[2]) if p.__len__() == 4 else ('declaration-error',p[1])
        #p[0] = Declaration(p[1], p[2])
        if not type(p[1]) == LexToken: p[0] = Declaration(p[1], p[2])
        else: self.error_occured = True

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        #p[0] = ('inits',p[1],p[3]) if p.__len__() == 4 \
        #    else ('init',p[1])
        p[0] = Inits(p[1],p[3]) if p.__len__() == 4 \
            else p[1]

    def p_init(self, p):
        """init : ID '=' expression """
        #p[0] = ('init','=',p[1],p[3])
        p[0] = Init(p[1], p[3])

    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        #p[0] = ('instructions_opt',p[1]) if p.__len__()==2 else('empty_instr')
        p[0] = InstructionsOpt(p[1]) if p.__len__() == 2 else None

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        #p[0] = ('instructions',p[1],p[2]) if p.__len__()==3 else ('instruction', p[1])
        p[0] = Instructions(p[1], p[2]) if p.__len__() == 3 else p[1]

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        #p[0] = ('instruction-node',p[1])
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        #p[0] = ('print_instr', p[1], p[2])
        if not type(p[2]) == LexToken: p[0] = PrintInstr(p[2])
        else: self.error_occured = True

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        #p[0] = ('labeled_instr', p[1], p[3])
        p[0] = LabeledInstr(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        #p[0] = ('assignment',p[1],p[3])
        p[0] = Assignment(p[1], p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        #p[0] = ('if-cond-instr',p[3],p[5])if p.__len__() == 6 else ('if-cond-instr-else-instr',p[3],p[5],p[7])
        if not type(p[3]) == LexToken:
            p[0] = ChoiceInstr(p[3],
                               p[5]) if p.__len__() == 6 else ChoiceInstr(
                                   p[3], p[5], p[7])
        else:
            self.error_occured = True

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        #p[0] = ('while-instr',p[3],p[5])
        if not type(p[3]) == LexToken: p[0] = WhileInstr(p[3], p[5])
        else: self.error_occured = True

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        #p[0] = ('repeat',p[2],p[4])
        p[0] = RepeatInstr(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        #p[0] = ('return',p[2])
        p[0] = ReturnInstr(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        #p[0] = ('continue')
        p[0] = ContinueInstr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        #p[0] = ('break')
        p[0] = BreakInstr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        #p[0] = ('compound_instr',p[2],p[3])
        p[0] = CompoundInstr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        #p[0] = ('condition',p[1])
        p[0] = Condition(p[1])

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        #p[0] = p[1]
        p[0] = Const(p[1])  #to-do!!

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        #p[0] = (p[1]) if p.__len__() == 2 else \
        #    (p[2],p[1],p[3]) if p.__len__() == 4  and p[1]!='(' else \
        #        p[2] if p.__len__() == 4 and p[1]=='(' else (p[1],p[3])
        """
        p[0] = p[1] if p.__len__() == 2 else \
            BinExpr(p[2],p[1],p[3]) if p.__len__() == 4  and p[1]!='(' else \
                p[2] if p.__len__() == 4 and p[1]=='(' else DeclaredFunc(p[1],p[3])
        """
        if p.__len__() == 2:
            p[0] = p[1]
        elif p.__len__() == 4:
            if p[1] != '(':
                p[0] = BinExpr(p[2], p[1], p[3])
            else:
                if not type(p[2]) == LexToken: p[0] = p[2]
                else: self.error_occured = True
        else:
            if not type(p[3]) == LexToken: p[0] = DeclaredFunc(p[1], p[3])
            else: self.error_occured = True

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        #p[0] = ('expr_list',p[1]) if p.__len__()==2 else ('empty_exprlist')
        p[0] = PExprListOrEmpty(p[1]) if p.__len__() == 2 else None

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        #p[0] = ('expr_list',p[1],p[3]) if p.__len__() == 4 else ('expr',p[1])
        p[0] = PExprList(p[1], p[3]) if p.__len__() == 4 else p[1]

    def p_fundefs_opt(self, p):
        """fundefs_opt : fundefs
                       | """
        #p[0] = ('fundefs_opt',p[1]) if p.__len__() == 2 else ('no fundefs')
        p[0] = FuncDefsOpt(p[1]) if p.__len__() == 2 else None

    def p_fundefs(self, p):
        """fundefs : fundefs fundef
                   | fundef """
        #p[0] = ('fundefs',p[1],p[2]) if p.__len__() == 3 else ("fundef", p[1])
        p[0] = FuncDefs(p[1], p[2]) if p.__len__() == 3 else p[1]

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        #p[0] = ('fundef',p[2],p[1],p[4],p[6])
        p[0] = FuncDef(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        #p[0] = ('args_list_',p[1]) if p.__len__() == 2 else ("empty-args-list")
        p[0] = p[1] if p.__len__() == 2 else None

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        #p[0] = ('args_list',p[1],p[3]) if p.__len__() == 4 else ('arg', p[1])
        p[0] = ArgsList(p[1], p[3]) if p.__len__() == 4 else p[1]

    def p_arg(self, p):
        """arg : TYPE ID """
        #p[0] = ('arg',p[1],p[2])
        p[0] = Arg(p[1], p[2])
Пример #41
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : segments"""
        if len(p) == 2:
            p[0] = ast.Program(p.lineno(1), p[1])

    # list
    def p_segments(self, p):
        """segments : segments segment
                    | """
        if len(p) == 3:
            p[0] = p[1]
            p[0].append(p[2])
        elif len(p) == 1:
            p[0] = []

    # 1-1
    def p_segment(self, p):
        """segment : declaration
                   | function_definition
                   | instruction """
        if len(p) == 2:
            p[0] = p[1]

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            p[0] = ast.Declaration(p.lineno(1), p[1], p[2])

    # list
    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = p[1]
            p[0].append(p[3])
        elif len(p) == 2:
            p[0] = [p[1]]

    def p_init(self, p):
        """init : ID '=' expression """
        if len(p) == 4:
            p[0] = ast.Init(p.lineno(1), p[1], p[3])

    # list
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = p[1]
            p[0].append(p[2])
        elif len(p) == 2:
            p[0] = [p[1]]

    # 1-1
    def p_instruction(self, p):
        """instruction : print_instruction
                       | labeled_instruction
                       | assignment
                       | choice_instruction
                       | while_instruction
                       | repeat_instruction
                       | return_instruction
                       | break_instruction
                       | continue_instruction
                       | compound_instructions
                       | expression ';'"""
        if len(p) == 2 or len(p) == 3:
            p[0] = p[1]

    def p_print_instruction(self, p):
        """print_instruction : PRINT expr_list ';'
                             | PRINT error ';' """
        if len(p) == 4:
            p[0] = ast.PrintInstruction(p.lineno(1), p[2])

    def p_labeled_instruction(self, p):
        """labeled_instruction : ID ':' instruction """
        p[0] = ast.LabeledInstruction(p.lineno(1), p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        if len(p) == 5:
            identifier = ast.Identifier(p.lineno(1), p[1])
            p[0] = ast.Assignment(p.lineno(1), identifier, p[3])

    def p_choice_instruction(self, p):
        """choice_instruction : IF '(' condition ')' instruction  %prec IFX
                              | IF '(' condition ')' instruction ELSE instruction
                              | IF '(' error ')' instruction  %prec IFX
                              | IF '(' error ')' instruction ELSE instruction """
        if len(p) >= 6:
            p[0] = ast.ChoiceInstruction(p.lineno(1), p[3], p[5], None)
        if len(p) == 8:
            p[0] = ast.ChoiceInstruction(p.lineno(1), p[3], p[5], p[7])

    def p_while_instruction(self, p):
        """while_instruction : WHILE '(' condition ')' instruction
                             | WHILE '(' error ')' instruction """
        if len(p) == 6:
            p[0] = ast.WhileInstruction(p.lineno(1), p[3], p[5])

    def p_repeat_instruction(self, p):
        """repeat_instruction : REPEAT instructions UNTIL condition ';' """
        if len(p) == 6:
            p[0] = ast.RepeatInstruction(p.lineno(1), p[2], p[4])

    def p_return_instruction(self, p):
        """return_instruction : RETURN expression ';' """
        if len(p) == 4:
            p[0] = ast.ReturnInstruction(p.lineno(1), p[2])

    def p_break_instruction(self, p):
        """break_instruction : BREAK ';' """
        if len(p) == 3:
            p[0] = ast.BreakInstruction(p.lineno(1))

    def p_continue_instruction(self, p):
        """continue_instruction : CONTINUE ';' """
        if len(p) == 3:
            p[0] = ast.ContinueInstruction(p.lineno(1))

    def p_compound_instructions(self, p):
        """compound_instructions : '{' compound_segments '}' """
        if len(p) == 4:
            p[0] = ast.CompoundInstructions(p.lineno(1), p[2], p.lineno(3))

    # list
    def p_compound_segments(self, p):
        """compound_segments : compound_segments compound_segment
                             | """
        if len(p) == 3:
            p[0] = p[1]
            p[0].append(p[2])
        elif len(p) == 1:
            p[0] = []

    # 1-1
    def p_compound_segment(self, p):
        """compound_segment : declaration
                            | instruction """
        if len(p) == 2:
            p[0] = p[1]

    # 1-1
    def p_condition(self, p):
        """condition : expression"""
        if len(p) == 2:
            p[0] = p[1]

    # 1-1
    def p_const(self, p):
        """const : integer
                 | float
                 | string """
        if len(p) == 2:
            p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        if len(p) == 2:
            p[0] = ast.Integer(p.lineno(1), p[1])

    def p_float(self, p):
        """float : FLOAT"""
        if len(p) == 2:
            p[0] = ast.Float(p.lineno(1), p[1])

    def p_string(self, p):
        """string : STRING"""
        if len(p) == 2:
            p[0] = ast.String(p.lineno(1), p[1])

    def p_identifier_expression(self, p):
        """identifier_expression : ID"""
        p[0] = ast.Identifier(p.lineno(1), p[1])

    def p_function_call_expression(self, p):
        """function_call_expression : ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        p[0] = ast.FunctionCallExpression(p.lineno(1), p[1], p[3])

    # 1-1
    def p_expression(self, p):
        """expression : binary_expression
                      | '(' expression ')'
                      | '(' error ')'
                      | identifier_expression
                      | function_call_expression
                      | const """
        if len(p) == 4:
            if p[1] == '(':
                p[0] = p[2]
        else:
            p[0] = p[1]

    def p_binary_expression(self, p):
        """binary_expression : expression '+' expression
                             | expression '-' expression
                             | expression '*' expression
                             | expression '/' expression
                             | expression '%' expression
                             | expression '|' expression
                             | expression '&' expression
                             | expression '^' expression
                             | expression AND expression
                             | expression OR expression
                             | expression SHL expression
                             | expression SHR expression
                             | expression EQ expression
                             | expression NEQ expression
                             | expression '>' expression
                             | expression '<' expression
                             | expression LE expression
                             | expression GE expression """
        if len(p) == 4:
            p[0] = ast.BinExpr(p.lineno(2), p[1], p[2], p[3])

    def p_function_definition(self, p):
        """function_definition : TYPE ID '(' args_list_or_empty ')' compound_instructions """
        if len(p) == 7:
            p[0] = ast.FunctionDefinition(p.lineno(1), p[1], p[2], p[4], p[6],
                                          p[6].end_lineno)

    # list
    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            p[0] = p[1]
            p[0].append(p[3])
        elif len(p) == 2:
            p[0] = [p[1]]

    def p_arg(self, p):
        """arg : TYPE ID """
        if len(p) == 3:
            p[0] = ast.Argument(p.lineno(1), p[1], p[2])

    # list
    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = []

    # list
    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = p[1]
            p[0].append(p[3])
        elif len(p) == 2:
            p[0] = [p[1]]

    # 1-1
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 1:
            p[0] = []
Пример #42
0
class Cparser(object):

    palka = ''

    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )

    error = 0

    def p_error(self, p):
        Cparser.error = 1
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
            #exit(1);
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = AST.Program(p[1], p[2], p[3])
        #print(p[0].toString(0))
        p[1].line = self.scanner.lexer.lineno
        p[1].line = self.scanner.lexer.lineno

    def p_declarations(self, p):
        """declarations : declarations declaration"""
        p[0] = AST.Declarations(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_declarations_1(self, p):
        """declarations : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_declaration(self, p):
        """declaration : TYPE inits ';' """
        p[0] = AST.Declaration(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_declaration_error(self, p):
        """declaration : error ';' """
        self.p_error(p[1])


    def p_inits(self, p):
        """inits : inits ',' init"""
        p[0] = AST.Inits(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_inits_1(self, p):
        """inits : init"""
        p[0] = AST.Inits(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_instructions(self, p):
        """instructions : instructions instruction"""
        p[0] = AST.Instructions(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_instructions_1(self, p):
        """instructions : instruction"""
        p[0] = AST.Instructions(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = AST.Instruction(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'"""
        p[0] = AST.Print(p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_print_instr_1(self, p):
        """print_instr : PRINT error ';' """
        self.p_error(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.Labeled(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX"""
        p[0] = AST.Choice(p[3], p[5], None)
        p[0].line = self.scanner.lexer.lineno

    def p_choice_instr_1(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction"""
        p[0] = AST.Choice(p[3], p[5], p[7])
        p[0].line = self.scanner.lexer.lineno

    def p_choice_instr_error(self, p):
        """choice_instr : IF '(' error ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX"""
        self.p_error(p[3])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction"""
        p[0] = AST.While(p[3], p[5])
        p[0].line = self.scanner.lexer.lineno

    def p_while_instr_error(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        self.p_error(p[3])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.Repeat(p[2], p[4])
        p[0].line = self.scanner.lexer.lineno

    def p_repeat_error(self, p):
        """repeat_instr : REPEAT instructions UNTIL error ';' """
        self.p_error(p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return(p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Keyword(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Keyword(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstruction(p[2], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_int(self, p):
        """const : INTEGER"""
        p[0] = AST.Integer(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_float(self, p):
        """const : FLOAT"""
        p[0] = AST.Float(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_string(self, p):
        """const : STRING"""
        p[0] = AST.String(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_const(self, p):
        """expression : const"""
        p[0] = p[1]

    def p_expression_id(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_expression(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '^' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression """
        p[0] = AST.BinExpression(p[1], p[2], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_1(self, p):
        """expression : ID '(' expr_list_or_empty ')'"""
        p[0] = AST.Funcall(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_2(self, p):
        """expression : '(' expression ')'"""
        p[0] = AST.ExpressionInParentheses(p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_expression_error(self, p):
        """expression : '(' error ')'"""
        self.p_error(p[2])

    def p_expression_error_2(self, p):
        """expression : ID '(' error ')'"""
        self.p_error(p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list"""
        p[0] = AST.ExpressionList(p[1], None)
        p[0].line = self.scanner.lexer.lineno

    def p_expr_list_or_empty_1(self, p):
        """expr_list_or_empty : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression"""
        p[0] = AST.ExpressionList(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_expr_list_1(self, p):
        """expr_list : expression"""
        p[0] = AST.ExpressionList(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_fundefs(self, p):
        """fundefs : fundef fundefs"""
        p[0] = AST.FunctionDefinitions(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno

    def p_fundefs_1(self, p):
        """fundefs : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionDefinition(p[1], p[2], p[4], p[6])
        p[0].line = self.scanner.lexer.lineno

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list"""
        p[0] = AST.ArgumentList(p[1], None)
        p[0].line = self.scanner.lexer.lineno

    def p_arg_list_or_empty_1(self, p):
        """args_list_or_empty : """
        p[0] = AST.Empty()
        p[0].line = self.scanner.lexer.lineno

    def p_args_list(self, p):
        """args_list : args_list ',' arg"""
        p[0] = AST.ArgumentList(p[1], p[3])
        p[0].line = self.scanner.lexer.lineno

    def p_arg_list_1(self, p):
        """args_list : arg"""
        p[0] = AST.ArgumentList(None, p[1])
        p[0].line = self.scanner.lexer.lineno

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Argument(p[1], p[2])
        p[0].line = self.scanner.lexer.lineno
Пример #43
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : segments"""
        p[0] = AST.Program(p[1])

    def p_segments(self, p):
        """segments : segments segment
                    | segment"""

        segments = None
        segment = None

        if len(p) > 2:
            segments = p[1]
            segment = p[2]
        else:
            segment = p[1]

        p[0] = AST.Segments(segments, segment)

    # def p_declarations(self, p):
    #     """declarations : declarations declaration
    #                     | """
    #     declarations = None
    #     declaration = None
    #
    #     if len(p) == 3:
    #         declarations = p[1]
    #         declaration = p[2]
    #
    #     p[0] = AST.Declarations(p[1], p[2])

    def p_segment(self, p):
        """segment : fundef
                   | instruction
                   | declaration"""
        p[0] = p[1]

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        type = None
        inits = None
        error = None

        if len(p) > 3:
            type = p[1]
            inits = p[2]
        else:
            error = p[1]

        p[0] = AST.Declaration(type, inits, error)

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        inits = None
        init = None

        if (len(p) > 2):
            inits = p[1]
            init = p[3]
        else:
            init = p[1]

        p[0] = AST.Inits(inits, init)

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))

    # def p_instructions_opt(self, p):
    #     """instructions_opt : instructions
    #                         | """


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        instructions = None
        instruction = None

        if len(p) > 2:
            instructions = p[1]
            instruction = p[2]
        else:
            instruction = p[1]

        p[0] = AST.Instructions(instructions, instruction)

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstruction(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstruction(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3], p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        instruction = p[5]
        else_instruction = None

        if (len(p) > 7):
            else_instruction = p[7]

        p[0] = AST.ChoiceInstruction(condition, instruction, else_instruction)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstruction(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstruction(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstruction(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()

    def p_compound_instr(self, p):
        """compound_instr : '{' segments '}' """

        p[0] = AST.CompoundInstruction(p[2])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        if re.match(r"\d+(\.\d*)|\.\d+", p[1]):
            p[0] = AST.Float(p[1], p.lineno(1))
        elif re.match(r"\d+", p[1]):
            p[0] = AST.Integer(p[1], p.lineno(1))
        else:
            p[0] = AST.String(p[1], p.lineno(1))

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """

        if len(p) == 2:
            if isinstance(p[1], AST.Const):
                p[0] = p[1]
            else:
                p[0] = AST.Variable(p[1], p.lineno(1))
        elif p[1] == '(' and p[3] == ')':
            p[0] = AST.ParenExpression(p[2])
        elif p[2] == '(' and p[1] != '(':
            p[0] = AST.FunctionExpression(p[1], p[3], p.lineno(1))
        else:
            p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(2))

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        expr_list = None

        if len(p) > 1:
            expr_list = p[1]

        p[0] = AST.ExpressionList(expr_list, None)

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        expr_list = None
        expression = None

        if len(p) > 2:
            expr_list = p[1]
            expression = p[3]
        else:
            expression = p[1]

        p[0] = AST.ExpressionList(expr_list, expression)

    # def p_fundefs_opt(self, p):
    #     """fundefs_opt : fundefs
    #                    | """
    #
    # def p_fundefs(self, p):
    #     """fundefs : fundefs fundef
    #                | fundef """
    #     # gramatyka?
    #


    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        args_list = None

        if len(p) > 1:
            args_list = p[1]

        p[0] = AST.ArgumentsList(args_list, None)

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """

        args_list = None
        arg = None

        if len(p) > 2:
            args_list = p[1]
            arg = p[3]
        else:
            arg = p[1]

        p[0] = AST.ArgumentsList(args_list, arg)

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Argument(p[1], p[2], p.lineno(1))
Пример #44
0
class Cparser(object):

    # Upon creatinon we create a user-defined scanner (scanner.py)
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    # We get a list of tokens
    tokens = Scanner.tokens

    # We decide precedence of operators 
    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        #  p[0]   :  p[1]         p[2]    p[3]
        if len(p[1].declarations) == 0:
          declarations = None
        else:
          declarations = p[1]

        if len(p[2].fundefs) == 0:
          fundefs = None
        else:
          fundefs = p[2]

        if len(p[3].instructions) == 0:
          instructions = None
        else:
          instructions = p[3]

        print AST.Program(declarations, fundefs, instructions)

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        #  p[0]           p[1]         p[2]

        # If the it's the first production
        if len(p) == 3:
          # If there is only one declaration omit p[1]
          if p[1] is None:
            p[0] = AST.DeclarationList()
          # If there are more make them p[0] to recursively process
          else:
            p[0] = p[1]
          # Store the declaration from p[2]
          p[0].addDeclaration(p[2])
        # If it's the second production
        else:
            p[0] = AST.DeclarationList()
                     
    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
          # p[0]         p[1]  p[2] ;
        
        # If the declaration is written properly
        if len(p) == 4:
          type = p[1]
          inits = p[2]
          p[0] = AST.Declaration(type, inits)

    # Multiple inits
    def p_inits(self, p):
        """inits : inits ',' init
                 | init """

        # If it's the first production
        if len(p) == 4:
          if p[1] is None:
            p[0] = None
          else:
            p[0] = p[1]
          p[0].addInit(p[3])
        # If it's the second production
        else:
            p[0] = AST.InitList()
            p[0].addInit(p[1])

    # Signel init
    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        expr = p[3]
        p[0] = AST.Init(id, expr)
    
    # Block of instructions
    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        
        # if the first production
        if len(p) == 3:
          if p[1] is None:
            p[0] = AST.InstructionList
          else:
            p[0] = p[1]
          p[0].addInstruction(p[2])
        # If the second productio
        else:
            p[0] = AST.InstructionList()
            p[0].addInstruction(p[1])
    
    # A single instruction, here we have all different types of instructions
    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""

        # We just assign the proper one and let next functions handle it
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        expr = p[2]
        p[0] = AST.PrintInstruction(expr)
    
    # What is a laveled instruction?
    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        instruction = p[3]
        p[0] = AST.LabeledInstruction(id, instruction)

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        expr = p[3]
        p[0] = AST.AssignmentInstruction(id, expr)
    
    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        if_instruction = p[5]
        if len(p) < 8:
          else_instruction = None
        else:
          else_instruction = p[7]

        p[0] = AST.ChoiceInstruction(condition, if_instruction, else_instruction)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileInstruction(condition, instruction)

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        instructions = p[2]
        condition = p[4]
        p[0] = AST.RepeatInstruction(instructions, condition)
    
    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        expression = p[2]
        p[0] = AST.ReturnInstruction(expression)
    
    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()
    
    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()
 
    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        if len(p[2].declarations) == 0:
            p[0] = AST.CompoundInstruction(None, p[3])
        else:
            p[0] = AST.CompoundInstruction(p[2], p[3])
        
    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        p[0] = p[1]
    
    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            value = p[1]
            p[0] = AST.Const(value)
        elif p[2] == "(" and p[1] != "(":
            funcName = p[1]
            args = p[3]
            p[0] = AST.InvocationExpression(funcName, args)
        elif p[1] == "(":
            p[0] = p[2]

        else:
            lhs = p[1]
            op = p[2]
            rhs = p[3]
            p[0] = AST.BinExpr(lhs, op, rhs)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = AST.ExpressionList() if p[1] is None else p[1]
            p[0].addExpression(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].addExpression(p[1])
    
    
    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[0] = p[2]
            p[0].addFunction(p[1])
        else:
            p[0] = AST.FunctionExpressionList()

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionExpression(p[1], p[2], p[4], p[6])
    
    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = None if len(p) == 0 else p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[0] = AST.ArgumentList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ArgumentList()
            p[0].addArgument(p[1])
            
    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        name = p[2]
        p[0] = AST.Argument(type, name)
Пример #45
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : podprogramy"""
        p[0] = AST.Program(p[1])

    def p_podprogramy(self, p):
        """podprogramy : podprogramy podprogram
                        | """
        if len(p) == 3:
            podprogram = p[2]
            if p[1] == None:
                p[0] = AST.Podprogramy()
            else:
                p[0] = p[1]
            p[0].addPodprogram(podprogram)
        else:
            p[0] = AST.Podprogramy()

    def p_podprogram(self, p):
        """podprogram : declaration
                        | fundef
                        | instruction
                        | """
        p[0] = AST.Podprogram(p[1])

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            type = p[1]
            inits = p[2]
            p[0] = AST.Declaration(type, inits)
        else:
            p[0] = AST.Error(p[1])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            if p[1] == None:
                p[0] = AST.InitList(p[3])
            else:
                p[0] = p[1]
                p[0].addInit(p[3])
        else:
            p[0] = AST.InitList(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        exp = p[3]
        p[0] = AST.Init(id, exp, p.lineno(1))

    def p_instructions(self, p):
        """instructions : instruction instructions
                        | instruction """

        if len(p) == 3:
            if p[2] == None:
                p[0] = AST.InstList(p[1])
            else:
                p[0] = p[2]
                p[0].addInst(p[1])
        else:
            p[0] = AST.InstList(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        data = p[2]
        p[0] = AST.PrtInst(data, p.lineno(1))

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        inst = p[3]
        p[0] = AST.LabInst(id, inst, p.lineno(1))

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        exp = p[3]
        p[0] = AST.AsgInst(id, exp, p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        cond = p[3]
        inst = p[5]
        if len(p) >= 8:
            alt = p[7]
        else:
            alt = None
        p[0] = AST.ChoiInst(cond, inst, alt)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        cond = p[3]
        inst = p[5]
        p[0] = AST.WhiInst(cond, inst)

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        inst = p[3]
        cond = p[5]
        p[0] = AST.RepInst(inst, cond)

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        exp = p[2]
        p[0] = AST.RetInst(exp, p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Continue(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Break(p.lineno(1))

    #Przypilnowac by instruction nie zawieral fundefu
    #stworzyc unit -> declaration | instruction
    #i jeszcze stworzyc kolejna co by miala liste unitow.
    #poczatek zmian

    def p_units(self, p):
        """units : units unit
                 | """
        if len(p) == 3:
            unit = p[2]
            if p[1] == None:
                p[0] = AST.Units()
            else:
                p[0] = p[1]
            p[0].addUnit(unit)
        else:
            p[0] = AST.Units()

    def p_unit(self, p):
        """unit : declaration
                | instruction 
                | """
        p[0] = AST.Unit(p[1])

    #koniec zmian
    def p_compound_instr(self, p):
        """compound_instr : '{' units '}' """
        if len(p[2].children) == 0:
            p[0] = AST.CompInst(None, p.lineno(3))
        else:
            p[0] = AST.CompInst(p[2], p.lineno(3))

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : integer
                 | float
                 | string"""
        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        p[0] = AST.Integer(p[1], p.lineno(1))

    def p_float(self, p):
        """float : FLOAT"""
        p[0] = AST.Float(p[1], p.lineno(1))

    def p_string(self, p):
        """string : STRING"""
        p[0] = AST.String(p[1], p.lineno(1))

    def p_expression_id(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p.lineno(1), p[1])
#H4X10R5K1 sposob na odronienie ID od const

    def p_expression(self, p):
        """expression : const
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            p[0] = p[1]
        elif p[2] == '(' and p[1] != '(':
            function_name = p[1]
            parameters = p[3]
            p[0] = AST.CallExp(function_name, parameters, p.lineno(1))
        elif p[1] == '(':
            p[0] = p[2]
        else:
            left = p[1]
            operator = p[2]
            right = p[3]
            p[0] = AST.BinExpr(left, operator, right, p.lineno(2))

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = None

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            if p[1] == None:
                p[0] = AST.ExpList(p[3])
            else:
                p[0] = p[1]
                p[0].addExp(p[3])
        else:
            p[0] = AST.ExpList(p[1])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        type = p[1]
        name = p[2]
        parameters = p[4]
        body = p[6]
        p[0] = AST.Function(type, name, parameters, body, p.lineno(1))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = None

    def p_args_list(self, p):
        """args_list : arg ',' args_list 
                     | arg """
        if len(p) == 4:
            if p[3] == None:
                p[0] = AST.ArgList(p[1])
            else:
                p[0] = p[3]
                p[0].addArgToList(p[1])
        else:
            p[0] = AST.ArgList(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        name = p[2]
        p[0] = AST.Parameter(type, name, p.lineno(1))
Пример #46
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()
        self.errorsOccured = False

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno,
                                                                                      self.scanner.find_tok_column(p),
                                                                                      p.type, p.value))

        else:
            print('At end of input')
        self.errorsOccured = True

    def p_program(self, p):
        """program : classdefs declarations fundefs instructions"""
        p[0] = AST.Program(p[1], p[2], p[3], p[4])

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) > 1:
            p[1].list.append(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.Declarations()


    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | id classinits ';'
                       | error ';' """
        if len(p) > 2:
            p[0] = AST.Declaration(p[1], p[2])
        else:
            p[0] = p[1]


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) > 2:
            p[1].list.append(p[3])
            p[0] = p[1]
        else:
            inits = AST.Inits()
            inits.list.append(p[1])
            p[0] = inits


    def p_init(self, p):
        """init : id '=' expression """
        p[0] = AST.Init(p[1], p[3])

    def p_classinits(self, p):
        """classinits : classinits ',' classinit
                      | classinit """
        if len(p) > 2:
            p[1].list.append(p[3])
            p[0] = p[1]
        else:
            classinits = AST.Classinits()
            classinits.list.append(p[1])
            p[0] = classinits

    def p_classinit(self, p):
        """classinit : id """
        p[0] = AST.Classinit(p[1])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 2:
            instructions = AST.Instructions()
            instructions.list.append(p[1])
            p[0] = instructions
        else:
            p[1].list.append(p[2])
            p[0] = p[1]


    def p_instruction(self, p):
        """instruction : expression ';'
                       | print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]


    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p[2])


    def p_labeled_instr(self, p):
        """labeled_instr : id ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3])

    def p_assignment(self, p):
        """assignment : access '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3])

    def p_access(self, p):
        """access : id
                  | id '.' id """

        if len(p) == 2:
            access = AST.Access(p.lineno(1))
            access.list.append(p[1])
            p[0] = access
        else:
            access = AST.Access(p.lineno(1))
            access.list.append(p[1])
            access.list.append(p[3])
            p[0] = access

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 6:
            p[0] = AST.ChoiceInstr(p[3], p[5], None)
        else:
            p[0] = AST.ChoiceInstr(p[3], p[5], p[7])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4])


    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Continue()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Break()


    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}'"""
        p[0] = AST.CompoundInstr(p[2], p[3])


    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])

    def p_const(self, p):
        """const : integer
                 | float
                 | string"""
        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        p[0] = AST.Integer(p[1], p.lineno(1))

    def p_float(self, p):
        """float : FLOAT"""
        p[0] = AST.Float(p[1], p.lineno(1))

    def p_string(self, p):
        """string : STRING"""
        p[0] = AST.String(p[1][1:-1], p.lineno(1))

    def p_id(self, p):
        """id : ID"""
        p[0] = AST.Id(p[1], p.lineno(1))

    def p_expression(self, p):
        """expression : const
                      | access
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | access '(' expr_list_or_empty ')'
                      | access '(' error ')' """
        if len(p) == 2:
            p[0] = p[1]
        elif p[1] == '(':
            p[0] = AST.ParExpr(p[2])
        elif len(p) == 4:
            p[0] = AST.BinExpr(p[1], p[2], p[3])
        else:
            p[0] = AST.FunExpr(p[1], p[3])


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 1:
            p[0] = AST.ExprList()
        else:
            p[0] = p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[1].list.append(p[3])
            p[0] = p[1]
        else:
            toReturn = AST.ExprList()
            toReturn.list.append(p[1])
            p[0] = toReturn


    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.FunDefs()

    def p_fundef(self, p):
        """fundef : TYPE id '(' args_list_or_empty ')' compound_instr
                  | id id '(' args_list_or_empty ')' compound_instr"""
        p[0] = AST.FunDef(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 1:
            p[0] = AST.ArgList()
        else:
            p[0] = p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 2:
            argList = AST.ArgList()
            argList.list.append(p[1])
            p[0] = argList
        else:
            p[1].list.append(p[3])
            p[0] = p[1]

    def p_arg(self, p):
        """arg : TYPE id
               | id id"""
        p[0] = AST.Arg(p[1], p[2])

    def p_classdefs(self, p):
        """classdefs : classdef classdefs
                   |  """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.ClassDefs()

    def p_classdef(self, p):
        """classdef : accessmodificator CLASS id classcontent
                  | accessmodificator CLASS id EXTENDS id classcontent"""
        if len(p) < 7:
            p[0] = AST.ClassDef(p[1], p[3], None, p[4])
        else:
            p[0] = AST.ClassDef(p[1], p[3], p[5], p[6])

    def p_classcontent(self, p):
        """classcontent : '{' fielddefs ';' methoddefs '}' """
        p[0] = AST.Classcontent(p[2], p[4])

    def p_fielddefs(self, p):
        """fielddefs : fielddef fielddefs
                     | """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.Fielddefs()

    def p_fielddef(self, p):
        """fielddef : accessmodificator declaration """
        p[0] = AST.Fielddef(p[1], p[2])

    def p_methoddefs(self, p):
        """methoddefs : methoddef methoddefs
                     | """
        if len(p) == 3:
            p[2].list.reverse()
            p[2].list.append(p[1])
            p[2].list.reverse()
            p[0] = p[2]
        else:
            p[0] = AST.Methoddefs()

    def p_methoddef(self, p):
        """methoddef : accessmodificator fundef"""
        p[0] = AST.Methoddef(p[1], p[2])

    def p_accessmodificator(self,p):
        """accessmodificator : PRIVATE
                             | PROTECTED
                             | PUBLIC"""
        p[0] = p[1]
Пример #47
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", "IFX"),
        ("nonassoc", "ELSE"),
        ("right", "="),
        ("left", "OR"),
        ("left", "AND"),
        ("left", "|"),
        ("left", "^"),
        ("left", "&"),
        ("nonassoc", "<", ">", "EQ", "NEQ", "LE", "GE"),
        ("left", "SHL", "SHR"),
        ("left", "+", "-"),
        ("left", "*", "/", "%"),
    )

    def p_error(self, p):
        if p:
            print(
                "Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(
                    p.lineno, self.scanner.find_tok_column(p), p.type, p.value
                )
            )
        else:
            print("At end of input")

    def p_program(self, p):
        """program : parts """
        p[0] = Program(p[1])

    def p_parts(self, p):
        """parts : part parts
                 | part """
        if len(p) == 3:
            result = []
            result.append(p[1])
            result.extend(p[2].parts)
            p[0] = Parts(result)
        else:
            p[0] = Parts([p[1]])

    def p_part(self, p):
        """part : fundef
                | instruction
                | declaration """
        p[0] = p[1]

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            result = []
            result.extend(p[1].declarations)
            result.append(p[2])
            p[0] = Declarations(result)
        else:
            p[0] = Declarations([])

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            p[0] = Declaration(p[1], p[2])
        else:
            p[0] = Error(p[1])

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            result = []
            result.extend(p[1].inits)
            result.append(p[3])
            p[0] = Inits(result)
        else:
            p[0] = Inits([p[1]])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3])

    def p_instruction_opt(self, p):
        """instructions_opt : instructions
                            | """
        if len(p) == 2:
            p[0] = InstructionsOpt(p[1])
        else:
            p[0] = InstructionsOpt([])

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            result = []
            result.extend(p[1].instructions)
            result.append(p[2])
            p[0] = Instructions(result)
        else:
            p[0] = Instructions([p[1]])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'"""
        p[0] = PrintInstruction(p[2])

    def p_print_error_instr(self, p):
        """print_instr : PRINT error ';' """
        p[0] = PrintInstruction(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = LabeledInstruction(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AssignementInstr(p[1], p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction """
        if p[6] == "else":
            p[0] = IfElseInstruction(p[3], p[5], p[7])
        else:
            p[0] = IfInstruction(p[3], p[5])

    def p_choice_error(self, p):
        """choice_instr : IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        p[0] = Error(p[3])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction """
        # todo: what does it mean error?
        p[0] = WhileInstruction(p[3], p[5])

    def p_while_error(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        p[0] = Error(p[3])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = RepeatInstr(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = ReturnInstr(p[2])

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = ContinueInstr()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = BreakInstr()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        p[0] = CompoundInstr(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = Condition(p[1])

    def p_const_integer(self, p):
        """const : INTEGER"""
        p[0] = Integer(p[1])

    def p_const_float(self, p):
        """const : FLOAT"""
        p[0] = Float(p[1])

    def p_const_string(self, p):
        """const : STRING"""
        p[0] = String(p[1])

    def p_expression_const(self, p):
        """expression : const"""
        p[0] = ConstExpression(p[1])

    def p_expression_id(self, p):
        """expression : ID"""
        p[0] = IdExpression(p[1])

    def p_expression_mathop(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression"""
        if p[2] == "+":
            p[0] = AddExpression(p[1], p[3])
        elif p[2] == "-":
            p[0] = SubtractExpression(p[1], p[3])
        elif p[2] == "*":
            p[0] = MultiplyExpression(p[1], p[3])
        elif p[2] == "/":
            p[0] = DivideExpression(p[1], p[3])
        elif p[2] == "%":
            p[0] = ModuloExpression(p[1], p[3])

    def p_expression_bitwise(self, p):
        """expression : expression '|' expression
                      | expression '&' expression
                      | expression '^' expression"""
        if p[2] == "|":
            p[0] = BinOrExpression(p[1], p[3])
        elif p[2] == "&":
            p[0] = BinAndExpression(p[1], p[3])
        elif p[2] == "^":
            p[0] = BinXorExpression(p[1], p[3])

    def p_expression_bool(self, p):
        """expression : expression AND expression
                      | expression OR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""
        if p[2] == "&&":
            p[0] = AndExpression(p[1], p[3])
        elif p[2] == "||":
            p[0] = OrExpression(p[1], p[3])
        elif p[2] == "==":
            p[0] = EqualExpression(p[1], p[3])
        elif p[2] == "!=":
            p[0] = NotEqualExpression(p[1], p[3])
        elif p[2] == "<":
            p[0] = LowerExpression(p[1], p[3])
        elif p[2] == ">":
            p[0] = GreaterExpression(p[1], p[3])
        elif p[2] == "<=":
            p[0] = LowerEqualExpression(p[1], p[3])
        elif p[2] == ">=":
            p[0] = GreaterEqualExpression(p[1], p[3])

    def p_expression_bracket(self, p):
        """expression : '(' expression ')'"""
        p[0] = BracketExpression(p[2])

    def p_expression_error_bracket(self, p):
        """expression : '(' error ')'"""
        p[0] = Error(p[2])

    def p_funcall_expression(self, p):
        """expression : ID '(' expr_list_or_empty ')' """
        p[0] = FuncallExpression(p[1], p[3])

    def p_funcall_error(self, p):
        """expression : ID '(' error ')' """
        p[0] = Error(p[3])

    def p_shift_expression(self, p):
        """expression : expression SHL expression
                      | expression SHR expression"""
        if p[2] == ">>":
            p[0] = SHRExpression(p[1], p[3])
        elif p[2] == "<<":
            p[0] = SHLExpression(p[1], p[3])

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = ExpressionListOrEmpty(p[1])
        else:
            p[0] = Node()

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            result = []
            result.extend(p[1].expressions)
            result.append(p[3])
            p[0] = ExpressionList(result)
        else:
            p[0] = ExpressionList([p[1]])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = FunDef(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = ArgListOrEmpty(p[1])
        else:
            p[0] = ArgListOrEmpty([])

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            result = []
            result.extend(p[1].args)
            result.append(p[3])
            p[0] = ArgList(result)
        else:
            p[0] = ArgList([p[1]])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Argument(p[1], p[2])
Пример #48
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : constructions
                   | """
        p[0] = AST.Program(p[1])

    def p_constructions(self, p):
        """constructions : constructions construction
                         | construction"""
        if len(p) > 1:
            if isinstance(p[1], AST.ConstructionList):
                p[1].add_to_list(p[2])
                p[0] = p[1]
            else:
                p[0] = AST.ConstructionList()
                p[0].add_to_list(p[1])

    def p_construction(self, p):
        """construction : declaration
                        | fundef
                        | instruction """
        p[0] = AST.Construction(p[1])

    def p_declarations(self, p):
        """declarations : declarations declaration
                       | """

        if len(p) > 1:
            if p[1] == None:
                p[1] = AST.DeclarationList()

            p[0] = p[1]
            if len(p) > 2:
                p[1].add_to_list(p[2])
        else:
            p[0] = AST.DeclarationList()

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        p[0] = AST.Declaration(p[1], p[2], p.lineno(1))

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) > 2:
            if p[1] == None:
                p[0] = AST.InitList()
            else:
                p[0] = p[1]
            p[0].add_to_list(p[3])

        else:
            p[0] = AST.InitList()
            p[0].add_to_list(p[1])

    def p_init(self, p):
        """init : ID '=' expression
                """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) > 2:
            if p[1] == None:
                p[1] = AST.InstructionList()

            p[1].add_to_list(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.InstructionList(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = AST.Instruction(p[1])

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr("PRINT", p[2], p.lineno(1))

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3], p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """

        if len(p) == 6:
            p[0] = AST.ChoiceInstr(p[3], p[5])
        elif len(p) > 6:
            p[0] = AST.ChoiceInstr(p[3], p[5], p[7])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p[2], p[4], p.lineno(1))

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstr(p[2], p[3], p.lineno(4))

    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p[1])

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        if re.match(r"\d+(\.\d*)|\.\d+", p[1]):
            p[0] = AST.Float(p[1], p.lineno(1))
        elif re.match(r"\d+", p[1]):
            p[0] = AST.Integer(p[1], p.lineno(1))
        elif re.match(r'\"([^\\\n]|(\\.))*?\"', p[1]):
            p[0] = AST.String(p[1], p.lineno(1))

    def p_expression_id(self, p):
        """expression_id : ID"""
        p[0] = AST.Variable(p[1], p.lineno(1))

    def p_expression(self, p):
        """expression : const
                      | expression_id
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """

        if len(p) == 2:
            p[0] = p[1]

        elif p[2] == "(" and p[1] != "(":
            p[0] = AST.Funcall(p[1], p[3], p.lineno(1))

        elif len(p) == 4:
            if p[1] != '(':
                p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(2))
            else:
                p[0] = p[2]

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = p[1] if len(p) >= 2 else AST.ExpressionList()

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) > 2:
            if p[1] is None:
                p[1] = AST.ExpressionList()
            p[0] = p[1]
            p[0].add_to_list(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].add_to_list(p[1])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.Fundef(p[2], p[4], p[6], p[1], p.lineno(1))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = p[1] if len(p) > 1 else AST.ArgList(line=p.lineno(0))

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) > 2:
            if p[1] is None:
                p[1] = AST.ArgList()
            p[0] = p[1]
            p[0].add_to_list(p[3])
        else:
            p[0] = AST.ArgList()
            p[0].add_to_list(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[2], p[1], p.lineno(2))
Пример #49
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print("Unexpected end of input")

    def p_program(self, p):
        """program : blocks"""
        p[0] = p[1]

    def p_blocks(self, p):
        """blocks : blocks block
                  | """
        if len(p) == 3:
            p[1].children.append(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.Blocks()

    def p_block(self, p):
        """block : declaration
                 | fundef
                 | instruction"""
        p[0] = p[1]

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            p[1].children.append(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.Declarations()

    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            p[0] = AST.Declaration(p[1], p[2])
        # else:
        #     p[0] = p[1]


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[1].children.append(p[3])
            p[0] = p[1]
        else:
            p[0] = AST.Inits()
            p[0].children.append(p[1])


    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p[1], p[3], p.lineno(1))


    def p_instructions_opt(self, p):
        """instructions_opt : instructions
                            | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.Instructions()


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[1].children.append(p[2])
            p[0] = p[1]
        else:
            p[0] = AST.Instructions()
            p[0].children.append(p[1])


    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr
                       | expression ';' """
        p[0] = p[1]


    def p_print_instr(self, p):
        """print_instr : PRINT expr_list ';'
                       | PRINT error ';' """
        if len(p) == 4:
            p[0] = AST.InstructionPrint(p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """


    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p[1], p[3], p.lineno(1))


    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 8:
            p[0] = AST.InstructionIf(p[3], p[5], p[7])
        else:
            p[0] = AST.InstructionIf(p[3], p[5], None)


    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.InstructionWhile(p[3], p[5])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.Repeat(p[2], p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.Return(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.Continue(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.Break(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions_opt '}' """
        p[0] = AST.CompoundInstruction(p[2], p[3])


    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]


    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""

        if re.match(r"\d+(\.\d*)|\.\d+", p[1]):
            p[0] = AST.Float(p[1])
        elif re.match(r"\d+", p[1]):
            p[0] = AST.Integer(p[1])
        else:
            p[0] = AST.String(p[1])

    def p_expression(self, p):
        """expression : const
                      | ID
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            if isinstance(p[1], AST.Const):
                p[0] = p[1]
            else:
                p[0] = AST.Variable(p[1], p.lineno(1))

        elif p[1] == '(':
            p[0] = p[2]
        elif p[2] == '(':
            p[0] = AST.FunCall(p[1], p[3], p.lineno(1))
        else:
            p[0] = AST.BinExpr(p[2], p[1], p[3], p.lineno(2))


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.ExpressionList()

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[1].children.append(p[3])
            p[0] = p[1]
        else:
            p[0] = AST.ExpressionList()
            p[0].children.append(p[1])


    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunDef(p[1], p[2], p[4], p[6], p.lineno(1))


    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        else:
            p[0] = AST.ArgList()

    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            p[1].children.append(p[3])
            p[0] = p[1]
        else:
            p[0] = AST.ArgList()
            p[0].children.append(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p[1], p[2], p.lineno(1))
Пример #50
0
class Cparser(object):


    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens


    precedence = (
       ("nonassoc", 'IFX'),
       ("nonassoc", 'ELSE'),
       ("right", '='),
       ("left", 'OR'),
       ("left", 'AND'),
       ("left", '|'),
       ("left", '^'),
       ("left", '&'),
       ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
       ("left", 'SHL', 'SHR'),
       ("left", '+', '-'),
       ("left", '*', '/', '%'),
    )


    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(p.lineno, self.scanner.find_tok_column(p), p.type, p.value))
        else:
            print('At end of input')


    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = AST.Program(p.lineno(1), p[1], p[2], p[3])


    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            p[0] = p[1] + [p[2]]
        elif len(p) == 1:
            p[0] = []


    def p_declaration(self, p):
        """declaration : TYPE inits ';'
                       | error ';' """
        if len(p) == 4:
            p[0] = [AST.Declaration(p.lineno(1), p[1], p[2])]
        elif len(p) == 3:
            pass


    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        elif len(p) == 2:
            p[0] = [p[1]]


    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = AST.Init(p.lineno(1), p[1], p[3])


    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = p[1] + [p[2]]
        elif len(p) == 2:
            p[0] = [p[1]]


    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr
                       | repeat_instr
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]


    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = AST.PrintInstr(p.lineno(1), p[2])


    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = AST.LabeledInstr(p.lineno(1), p[1], p[3])


    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = AST.Assignment(p.lineno(1), p[1], p[3])


    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' error ')' instruction  %prec IFX """
        p[0] = AST.ChoiceInstr(p.lineno(1), p[3], p[5])


    def p_choice_with_else_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction ELSE instruction """
        p[0] = AST.ChoiceInstr(p.lineno(1), p[3], p[5], p[7])


    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = AST.WhileInstr(p.lineno(1), p[3], p[5])


    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = AST.RepeatInstr(p.lineno(1), p[4], p[2])


    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = AST.ReturnInstr(p.lineno(1), p[2])


    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstr(p.lineno(1))


    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstr(p.lineno(1))


    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = AST.CompoundInstr(p.lineno(1), p[2], p[3])


    def p_condition(self, p):
        """condition : expression"""
        p[0] = AST.Condition(p.lineno(1), p[1])


    def p_const_int(self, p):
      """const : INTEGER"""
      p[0] = AST.Integer(p.lineno(1), p[1])


    def p_const_float(self, p):
      """const : FLOAT"""
      p[0] = AST.Float(p.lineno(1), p[1])


    def p_const_string(self, p):
      """const : STRING"""
      p[0] = AST.String(p.lineno(1), p[1])


    def p_expr_binop(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""
        p[0] = AST.BinExpr(p.lineno(1), p[2], p[1], p[3])


    def p_expr_group(self, p):
      """expression : '(' expression ')'
                    | '(' error ')' """
      p[0] = p[2]


    def p_expr_const(self, p):
      """expression : const"""
      p[0] = p[1]


    def p_expr_id(self, p):
      """expression : ID"""
      p[0] = AST.Variable(p.lineno(1), None, p[1])


    def p_expr_funcall(self, p):
        """expression : ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        p[0] = AST.Funcall(p.lineno(1), p[1], p[3])


    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 1:
            p[0] = []


    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        elif len(p) == 2:
            p[0] = [p[1]]


    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[0] = [p[1]] + p[2]
        elif len(p) == 1:
            p[0] = []


    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = [AST.Fundef(p.lineno(1), p[1], p[2], p[4], p[6])]


    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 2:
            p[0] = p[1]
        elif len(p) == 1:
            p[0] = []


    def p_args_list(self, p):
        """args_list : args_list ',' arg
                     | arg """
        if len(p) == 4:
            p[0] = p[1] + [p[3]]
        elif len(p) == 2:
            p[0] = [p[1]]


    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = AST.Arg(p.lineno(1), p[1], p[2])
Пример #51
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", 'IFX'),
        ("nonassoc", 'ELSE'),
        ("right", '='),
        ("left", 'OR'),
        ("left", 'AND'),
        ("left", '|'),
        ("left", '^'),
        ("left", '&'),
        ("nonassoc", '<', '>', 'EQ', 'NEQ', 'LE', 'GE'),
        ("left", 'SHL', 'SHR'),
        ("left", '+', '-'),
        ("left", '*', '/', '%'),
    )

    def p_error(self, p):
        if p:
            print("Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".
                  format(p.lineno, self.scanner.find_tok_column(p), p.type,
                         p.value))
        else:
            print('At end of input')

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        p[0] = Program(p[1], p[2], p[3], p.lineno(1))

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 1:
            p[0] = []
        else:
            p[0] = p[1] + [p[2]]

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        p[0] = Declaration(p[1], p[2], p.lineno(1))

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3], p.lineno(1))

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[2]]

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        p[0] = Print(p[2], p.lineno(1))

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = Labeled(p[1], p[3], p.lineno(1))

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        p[0] = Assignment(p[1], p[3], p.lineno(1))

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        if len(p) == 8:
            p[0] = IfElse(p[3], p[5], p[7], p.lineno(1))
        else:
            p[0] = If(p[3], p[5], p.lineno(1))

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        p[0] = While(p[3], p[5], p.lineno(1))

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = Repeat(p[2], p[4], p.lineno(1))

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = Return(p[2], p.lineno(1))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = Continue(p.lineno(1))

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = Break(p.lineno(1))

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = CompoundInstructions(p[2], p[3], p.lineno(1))

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : integer
                 | float
                 | string"""
        p[0] = p[1]

    def p_integer(self, p):
        """integer : INTEGER"""
        p[0] = Integer(p[1], p.lineno(1))

    def p_float(self, p):
        "float : FLOAT"
        p[0] = Float(p[1], p.lineno(1))

    def p_string(self, p):
        "string : STRING"
        p[0] = String(p[1], p.lineno(1))

    def p_binary_expression(self, p):
        """binary_expression : expression '+' expression
                             | expression '-' expression
                             | expression '*' expression
                             | expression '/' expression
                             | expression '%' expression
                             | expression '|' expression
                             | expression '&' expression
                             | expression '^' expression
                             | expression AND expression
                             | expression OR expression
                             | expression SHL expression
                             | expression SHR expression
                             | expression EQ expression
                             | expression NEQ expression
                             | expression '>' expression
                             | expression '<' expression
                             | expression LE expression
                             | expression GE expression"""
        p[0] = BinExpr(p[2], p[1], p[3], p.lineno(2))

    def p_funcall(self, p):
        """funcall : ID '(' expr_list_or_empty ')'
                   | ID '(' error ')' """
        p[0] = Funcall(p[1], p[3], p.lineno(1))

    def p_expression(self, p):
        """expression : const
                      | name
                      | binary_expression
                      | '(' expression ')'
                      | '(' error ')'
                      | funcall"""
        if len(p) == 4:
            p[0] = p[2]
        elif len(p) == 2:
            p[0] = p[1]

    def p_name(self, p):
        """name : ID"""
        p[0] = Variable(p[1], p.lineno(1))

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        if len(p) == 1:
            p[0] = []
        else:
            p[0] = p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 1:
            p[0] = []
        else:
            p[0] = [p[1]] + p[2]

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = Fundef(p[2], p[1], p[4], p[6], p.lineno(1))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if len(p) == 1:
            p[0] = []
        else:
            p[0] = p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 2:
            p[0] = [p[1]]
        else:
            p[0] = p[1] + [p[3]]

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Argument(p[1], p[2], p.lineno(1))
Пример #52
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", "IFX"),
        ("nonassoc", "ELSE"),
        ("right", "="),
        ("left", "OR"),
        ("left", "AND"),
        ("left", "|"),
        ("left", "^"),
        ("left", "&"),
        ("nonassoc", "<", ">", "EQ", "NEQ", "LE", "GE"),
        ("left", "SHL", "SHR"),
        ("left", "+", "-"),
        ("left", "*", "/", "%"),
    )

    def p_error(self, p):
        if p:
            print(
                "Syntax error at line {0}, column {1}: LexToken({2}, '{3}')".format(
                    p.lineno, self.scanner.find_tok_column(p), p.type, p.value
                )
            )
        else:
            print("At end of input")

    def p_program(self, p):
        """program : declarations fundefs instructions"""
        declarations = None if len(p[1].children) == 0 else p[1]
        fundefs = None if len(p[2].children) == 0 else p[2]
        p[0] = AST.Program(declarations, fundefs, p[3])

    def p_declarations(self, p):
        """declarations : declarations declaration
                        | """
        if len(p) == 3:
            p[0] = AST.DeclarationList() if p[1] is None else p[1]
            p[0].addDeclaration(p[2])
        else:
            p[0] = AST.DeclarationList()

    def p_declaration(self, p):
        """declaration : TYPE inits ';' 
                       | error ';' """
        if len(p) == 4:
            type = p[1]
            inits = p[2]
            p[0] = AST.Declaration(type, inits)

    def p_inits(self, p):
        """inits : inits ',' init
                 | init """
        if len(p) == 4:
            p[0] = AST.InitList() if p[1] is None else p[1]
            p[0].addInit(p[3])
        else:
            p[0] = AST.InitList()
            p[0].addInit(p[1])

    def p_init(self, p):
        """init : ID '=' expression """
        id = p[1]
        expr = p[3]
        p[0] = AST.Init(p.lineno(1), id, expr)

    def p_instructions(self, p):
        """instructions : instructions instruction
                        | instruction """
        if len(p) == 3:
            p[0] = AST.InstructionList() if p[1] is None else p[1]
            p[0].addInstruction(p[2])
        else:
            p[0] = AST.InstructionList()
            p[0].addInstruction(p[1])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';'
                       | PRINT error ';' """
        expr = p[2]
        p[0] = AST.PrintInstruction(p.lineno(1), expr)

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        id = p[1]
        instruction = p[3]
        p[0] = AST.LabeledInstruction(p.lineno(1), id, instruction)

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        id = p[1]
        expr = p[3]
        p[0] = AST.AssignmentInstruction(p.lineno(1), id, expr)

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX
                        | IF '(' condition ')' instruction ELSE instruction
                        | IF '(' error ')' instruction  %prec IFX
                        | IF '(' error ')' instruction ELSE instruction """
        condition = p[3]
        action = p[5]
        alternateAction = None if len(p) < 8 else p[7]
        p[0] = AST.ChoiceInstruction(condition, action, alternateAction)

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction
                       | WHILE '(' error ')' instruction """
        condition = p[3]
        instruction = p[5]
        p[0] = AST.WhileInstruction(condition, instruction)

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        instructions = p[2]
        condition = p[4]
        p[0] = AST.RepeatInstruction(instructions, condition)

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        expression = p[2]
        p[0] = AST.ReturnInstruction(p.lineno(1), expression)

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = AST.ContinueInstruction()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = AST.BreakInstruction()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        if len(p[2].children) == 0:
            p[0] = AST.CompoundInstruction(p[2], p[3])
        else:
            p[0] = AST.CompoundInstruction(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const(self, p):
        """const : INTEGER
                 | FLOAT
                 | STRING"""
        if re.match(r"\d+(\.\d*)|\.\d+", p[1]):
            p[0] = AST.Float(p.lineno(1), p[1])
        elif re.match(r"\d+", p[1]):
            p[0] = AST.Integer(p.lineno(1), p[1])
        else:
            p[0] = AST.String(p.lineno(1), p[1])

    def p_expression_id(self, p):
        """expression : ID"""
        p[0] = AST.Variable(p.lineno(1), p[1])

    def p_expression(self, p):
        """expression : const
                      | expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression
                      | '(' expression ')'
                      | '(' error ')'
                      | ID '(' expr_list_or_empty ')'
                      | ID '(' error ')' """
        if len(p) == 2:
            p[0] = p[1]
        elif p[1] == "(":
            interior = p[2]
            p[0] = AST.GroupedExpression(interior)
        elif p[2] == "(":
            funcName = p[1]
            args = p[3]
            p[0] = AST.InvocationExpression(p.lineno(1), funcName, args)
        else:
            lhs = p[1]
            op = p[2]
            rhs = p[3]
            p[0] = AST.BinExpr(p.lineno(2), lhs, op, rhs)

    def p_expr_list_or_empty(self, p):
        """expr_list_or_empty : expr_list
                              | """
        p[0] = None if len(p) == 1 else p[1]

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression
                     | expression """
        if len(p) == 4:
            p[0] = AST.ExpressionList() if p[1] is None else p[1]
            p[0].addExpression(p[3])
        else:
            p[0] = AST.ExpressionList()
            p[0].addExpression(p[1])

    def p_fundefs(self, p):
        """fundefs : fundef fundefs
                   |  """
        if len(p) == 3:
            p[0] = p[2]
            p[0].addFunction(p[1])
        else:
            p[0] = AST.FunctionExpressionList()

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = AST.FunctionExpression(p[1], p[2], p[4], p[6])

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        p[0] = None if len(p) == 0 else p[1]

    def p_args_list(self, p):
        """args_list : args_list ',' arg 
                     | arg """
        if len(p) == 4:
            p[0] = AST.ArgumentList() if p[1] is None else p[1]
            p[0].addArgument(p[3])
        else:
            p[0] = AST.ArgumentList()
            p[0].addArgument(p[1])

    def p_arg(self, p):
        """arg : TYPE ID """
        type = p[1]
        name = p[2]
        p[0] = AST.Argument(p.lineno(1), type, name)
Пример #53
0
class Cparser(object):
    def __init__(self):
        self.scanner = Scanner()
        self.scanner.build()

    tokens = Scanner.tokens

    precedence = (
        ("nonassoc", "IFX"),
        ("nonassoc", "ELSE"),
        ("right", "="),
        ("left", "OR"),
        ("left", "AND"),
        ("left", "|"),
        ("left", "^"),
        ("left", "&"),
        ("nonassoc", "<", ">", "EQ", "NEQ", "LE", "GE"),
        ("left", "SHL", "SHR"),
        ("left", "+", "-"),
        ("left", "*", "/", "%"),
    )

    def handle_error(self, where, p):
        print (
            "Syntax error in %s at line %d, column %d, at token LexToken(%s, '%s')"
            % (where, p.lineno, self.scanner.find_tok_column(p), p.type, p.value)
        )

    def p_error(self, p):
        if not p:
            print "Unexpected end of input"
        else:
            # let the productions handle the error on their own
            pass

    def p_program(self, p):
        """program : ext_declarations fundefs instructions"""
        p[0] = Program(p[1], p[2], p[3], pos(p))
        p[0].printTree(0)

    def p_ext_declarations(self, p):
        """ext_declarations : declarations"""
        p[0] = p[1]

    def p_declarations(self, p):
        """declarations : declarations declaration"""
        if p[2]:
            p[0] = DeclarationList(p[1].decls + [p[2]])
        else:  # error
            p[0] = p[1]

    def p_declarations_single(self, p):
        """declarations : declaration"""
        if p[1]:
            p[0] = DeclarationList([p[1]])
        else:  # error
            p[0] = DeclarationList([])

    def p_declaration_blank(self, p):
        """declarations : """
        p[0] = DeclarationList([])

    def p_declaration_fundef(self, p):
        """declaration : fundefs"""
        p[0] = p[1]

    def p_declaration(self, p):
        """declaration : TYPE inits ';' """
        p[0] = Declaration(p[1], p[2], pos(p))

    def p_declaration_error(self, p):
        """declaration : error ';' """
        self.handle_error("declaration", p[1])

    def p_inits(self, p):
        """inits : inits ',' init"""
        p[0] = InitList(p[1].inits + [p[3]])

    def p_inits_single(self, p):
        """inits : init"""
        p[0] = InitList([p[1]])

    def p_init(self, p):
        """init : ID '=' expression """
        p[0] = Init(p[1], p[3])

    def p_instructions(self, p):
        """instructions : instructions instruction"""
        if p[2]:
            p[0] = InstructionList(p[1].instrs + [p[2]])
        else:
            p[0] = p[1]

    def p_instructions_single(self, p):
        """instructions : instruction """
        if p[1]:
            p[0] = InstructionList([p[1]])
        else:
            p[0] = InstructionList([])

    def p_instruction(self, p):
        """instruction : print_instr
                       | labeled_instr
                       | assignment
                       | choice_instr
                       | while_instr 
                       | repeat_instr 
                       | return_instr
                       | break_instr
                       | continue_instr
                       | compound_instr"""
        p[0] = p[1]

    def p_print_instr(self, p):
        """print_instr : PRINT expression ';' """
        p[0] = PrintInstruction(p[2])

    def p_print_error(self, p):
        """print_instr : PRINT error ';' """
        self.handle_error("print instruction", p[2])

    def p_labeled_instr(self, p):
        """labeled_instr : ID ':' instruction """
        p[0] = LabeledInstruction(p[1], p[3])

    def p_assignment(self, p):
        """assignment : ID '=' expression ';' """
        if p[3]:
            p[0] = Assignment(p[1], p[3], pos(p))
        else:  # error
            pass

    def p_assignment_error(self, p):
        """assignment : ID '=' error ';' """
        self.handle_error("assignment", p[3])

    def p_choice_instr(self, p):
        """choice_instr : IF '(' condition ')' instruction  %prec IFX"""
        p[0] = ChoiceInstruction(p[3], p[5])

    def p_choice_instr_else(self, p):
        """choice_instr : IF '(' condition ')' instruction ELSE instruction"""
        p[0] = ChoiceInstruction(p[3], p[5], p[7])

    def p_choice_instr_error(self, p):
        """choice_instr : IF '(' error ')' instruction  %prec IFX"""
        self.handle_error("if condition", p[3])

    def p_choice_instr_else_error(self, p):
        """choice_instr : IF '(' error ')' instruction ELSE instruction"""
        self.handle_error("if condition", p[3])

    def p_while_instr(self, p):
        """while_instr : WHILE '(' condition ')' instruction"""
        p[0] = WhileInstruction(p[1], p[3], p[5])

    def p_while_error(self, p):
        """while_instr : WHILE '(' error ')' instruction """
        self.handle_error("while instruction", p[3])

    def p_repeat_instr(self, p):
        """repeat_instr : REPEAT instructions UNTIL condition ';' """
        p[0] = RepeatInstruction(p[1], p[2], p[3], p[4])

    def p_repeat_error(self, p):
        """repeat_instr : REPEAT instructions UNTIL error ';' """
        self.handle_error("repeat instruction", p[4])

    def p_return_instr(self, p):
        """return_instr : RETURN expression ';' """
        p[0] = ReturnInstruction(p[2], pos(p))

    def p_continue_instr(self, p):
        """continue_instr : CONTINUE ';' """
        p[0] = ContinueInstruction()

    def p_break_instr(self, p):
        """break_instr : BREAK ';' """
        p[0] = BreakInstruction()

    def p_compound_instr(self, p):
        """compound_instr : '{' declarations instructions '}' """
        p[0] = CompoundInstructions(p[2], p[3])

    def p_condition(self, p):
        """condition : expression"""
        p[0] = p[1]

    def p_const_integer(self, p):
        """const : INTEGER"""
        p[0] = Integer(p[1])

    def p_const_float(self, p):
        """const : FLOAT"""
        p[0] = Float(p[1])

    def p_const_string(self, p):
        """const : STRING"""
        p[0] = String(p[1])

    def p_expression_const(self, p):
        """expression : const"""
        p[0] = p[1]

    def p_expression_id(self, p):
        "expression : ID"
        p[0] = Variable(p[1], pos(p))

    def p_expression_brackets(self, p):
        "expression : '(' expression ')'"
        p[0] = p[2]

    def p_expression_brackets_error(self, p):
        "expression : '(' error ')'"
        self.handle_error("expression (bracket)", p[2])

    def p_expression_fun_call(self, p):
        "expression : ID '(' expr_list_or_empty ')'"
        p[0] = FunctionCall(p[1], p[3], pos(p))

    def p_expression_fun_call_error(self, p):
        "expression : ID '(' error ')'"
        self.handle_error("function call", p[3])

    def p_expression_binary_op(self, p):
        """expression : expression '+' expression
                      | expression '-' expression
                      | expression '*' expression
                      | expression '/' expression
                      | expression '%' expression
                      | expression '|' expression
                      | expression '&' expression
                      | expression '^' expression
                      | expression AND expression
                      | expression OR expression
                      | expression SHL expression
                      | expression SHR expression
                      | expression EQ expression
                      | expression NEQ expression
                      | expression '>' expression
                      | expression '<' expression
                      | expression LE expression
                      | expression GE expression"""

        p[0] = BinExpr(p[1], p[2], p[3], pos(p))

    def p_expr_list_non_empty(self, p):
        """expr_list_or_empty : expr_list"""
        p[0] = p[1]

    def p_expr_list_empty(self, p):
        """expr_list_or_empty : """
        p[0] = ExprList([])

    def p_expr_list(self, p):
        """expr_list : expr_list ',' expression"""
        p[0] = ExprList(p[1].exprs + [p[3]])

    def p_expr_list_single(self, p):
        """expr_list : expression"""
        p[0] = ExprList([p[1]])

    # def p_fundefs(self, p):
    #     """fundefs : fundefs fundef
    #                | fundef """
    #     if p[2]:
    #         p[0] = FunctionDefList(p[1].fundefs + [ p[2] ])
    #     else:
    #         p[0] = FunctionDefList([ p[1] ])

    def p_fundefs(self, p):
        """fundefs : fundefs fundef"""
        p[0] = FunctionDefList(p[1].fundefs + [p[2]])

    def p_fundefs_single(self, p):
        """fundefs : fundef"""
        p[0] = FunctionDefList([p[1]])

    def p_fundefs_empty(self, p):
        """fundefs : """
        p[0] = FunctionDefList([])

    def p_fundef(self, p):
        """fundef : TYPE ID '(' args_list_or_empty ')' compound_instr """
        p[0] = FunctionDef(p[1], p[2], p[4], p[6], pos(p))

    def p_args_list_or_empty(self, p):
        """args_list_or_empty : args_list
                              | """
        if p[1]:
            p[0] = p[1]
        else:
            p[0] = ArgsList([])

    # def p_args_list(self, p):
    #     """args_list : args_list ',' arg
    #                  | arg """
    #     if p[3]:
    #         p[0] = ArgsList(p[1].args + [ p[3] ])
    #     else:
    #         p[0] = ArgsList([ p[1] ])

    def p_args_list(self, p):
        """args_list : args_list ',' arg"""
        p[0] = ArgsList(p[1].args + [p[3]])

    def p_args_list_single(self, p):
        """args_list : arg"""
        p[0] = ArgsList([p[1]])

    def p_arg(self, p):
        """arg : TYPE ID """
        p[0] = Arg(p[1], p[2])