示例#1
0
    def test_duplicate_precedence(self):
        pg = ParserGenerator([], precedence=[
            ("left", ["term", "term"])
        ])

        with py.test.raises(ParserGeneratorError):
            pg.build()
示例#2
0
    def test_invalid_associativity(self):
        pg = ParserGenerator([], precedence=[
            ("to-the-left", ["term"]),
        ])

        with py.test.raises(ParserGeneratorError):
            pg.build()
示例#3
0
    def test_production_terminal_overlap(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("VALUE :")
        def x(p):
            pass

        with py.test.raises(ParserGeneratorError):
            pg.build()
示例#4
0
    def test_nonexistant_precedence(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : VALUE", precedence="abc")
        def main(p):
            pass

        with py.test.raises(ParserGeneratorError):
            pg.build()
示例#5
0
    def test_unused_tokens(self):
        pg = ParserGenerator(["VALUE", "OTHER"])

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        with self.assert_warns(ParserGeneratorWarning, "Token 'OTHER' is unused"):
            pg.build()
示例#6
0
    def test_error_symbol(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : VALUE")
        def main(p):
            pass

        @pg.production("main : error")
        def main_error(p):
            pass

        pg.build()
示例#7
0
    def test_unused_production(self):
        pg = ParserGenerator(["VALUE", "OTHER"])

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        @pg.production("unused : OTHER")
        def unused(p):
            pass

        with self.assert_warns(ParserGeneratorWarning, "Production 'unused' is not reachable"):
            pg.build()
示例#8
0
    def test_simple_caching(self):
        pg = ParserGenerator(["VALUE"], cache_id="simple")

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        pg.build()
        parser = pg.build()

        assert parser.parse(iter([
            Token("VALUE", "3")
        ])) == Token("VALUE", "3")
示例#9
0
    def test_simple_caching(self):
        # Generate a random cache_id so that every test run does both the cache
        # write and read paths.
        pg = ParserGenerator(["VALUE"], cache_id=str(uuid.uuid4()))

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        pg.build()
        parser = pg.build()

        assert parser.parse(iter([
            Token("VALUE", "3")
        ])) == Token("VALUE", "3")
示例#10
0
    def test_arithmetic(self):
        pg = ParserGenerator(["NUMBER", "PLUS"])

        @pg.production("main : expr")
        def main(p):
            return p[0]

        @pg.production("expr : expr PLUS expr")
        def expr_op(p):
            return BoxInt(p[0].getint() + p[2].getint())

        @pg.production("expr : NUMBER")
        def expr_num(p):
            return BoxInt(int(p[0].getstr()))

        with self.assert_warns(
            ParserGeneratorWarning, "1 shift/reduce conflict"
        ):
            parser = pg.build()

        assert parser.parse(iter([
            Token("NUMBER", "1"),
            Token("PLUS", "+"),
            Token("NUMBER", "4")
        ])) == BoxInt(5)
示例#11
0
    def test_precedence(self):
        pg = ParserGenerator(["NUMBER", "PLUS", "TIMES"], precedence=[
            ("left", ["PLUS"]),
            ("left", ["TIMES"]),
        ])

        @pg.production("main : expr")
        def main(p):
            return p[0]

        @pg.production("expr : expr PLUS expr")
        @pg.production("expr : expr TIMES expr")
        def expr_binop(p):
            return BoxInt({
                "+": operator.add,
                "*": operator.mul
            }[p[1].getstr()](p[0].getint(), p[2].getint()))

        @pg.production("expr : NUMBER")
        def expr_num(p):
            return BoxInt(int(p[0].getstr()))

        parser = pg.build()

        assert parser.parse(iter([
            Token("NUMBER", "3"),
            Token("TIMES", "*"),
            Token("NUMBER", "4"),
            Token("PLUS", "+"),
            Token("NUMBER", "5")
        ])) == BoxInt(17)
示例#12
0
    def test_state(self):
        pg = ParserGenerator(["NUMBER", "PLUS"], precedence=[
            ("left", ["PLUS"]),
        ])

        @pg.production("main : expression")
        def main(state, p):
            state.count += 1
            return p[0]

        @pg.production("expression : expression PLUS expression")
        def expression_plus(state, p):
            state.count += 1
            return BoxInt(p[0].getint() + p[2].getint())

        @pg.production("expression : NUMBER")
        def expression_number(state, p):
            state.count += 1
            return BoxInt(int(p[0].getstr()))

        parser = pg.build()

        state = ParserState()
        assert parser.parse(iter([
            Token("NUMBER", "10"),
            Token("PLUS", "+"),
            Token("NUMBER", "12"),
            Token("PLUS", "+"),
            Token("NUMBER", "-2"),
        ]), state=state) == BoxInt(20)
        assert state.count == 6
示例#13
0
    def test_basic_parser(self):
        pg = ParserGenerator(["NUMBER", "PLUS"])

        @pg.production("main : expr")
        def main(p):
            return p[0]

        @pg.production("expr : expr PLUS expr")
        def expr_op(p):
            return BoxInt(p[0].getint() + p[2].getint())

        @pg.production("expr : NUMBER")
        def expr_num(p):
            return BoxInt(int(p[0].getstr()))

        with self.assert_warns(
            ParserGeneratorWarning, "1 shift/reduce conflict"
        ):
            parser = pg.build()

        def f(n):
            return parser.parse(iter([
                Token("NUMBER", str(n)),
                Token("PLUS", "+"),
                Token("NUMBER", str(n))
            ])).getint()

        assert self.run(f, [12]) == 24
示例#14
0
文件: test_both.py 项目: DasIch/rply
    def test_arithmetic(self):
        lg = LexerGenerator()
        lg.add("NUMBER", r"\d+")
        lg.add("PLUS", r"\+")
        lg.add("TIMES", r"\*")

        pg = ParserGenerator(["NUMBER", "PLUS", "TIMES"], precedence=[
            ("left", ["PLUS"]),
            ("left", ["TIMES"]),
        ])

        @pg.production("main : expr")
        def main(p):
            return p[0]

        @pg.production("expr : expr PLUS expr")
        @pg.production("expr : expr TIMES expr")
        def expr_binop(p):
            return BoxInt({
                "+": operator.add,
                "*": operator.mul
            }[p[1].getstr()](p[0].getint(), p[2].getint()))

        @pg.production("expr : NUMBER")
        def expr_num(p):
            return BoxInt(int(p[0].getstr()))

        lexer = lg.build()
        parser = pg.build()

        assert parser.parse(lexer.lex("3*4+5"))
示例#15
0
    def test_null_production(self):
        pg = ParserGenerator(["VALUE", "SPACE"])

        @pg.production("main : values")
        def main(p):
            return p[0]

        @pg.production("values : none")
        def values_empty(p):
            return []

        @pg.production("values : VALUE")
        def values_value(p):
            return [p[0].getstr()]

        @pg.production("values : values SPACE VALUE")
        def values_values(p):
            return p[0] + [p[2].getstr()]

        @pg.production("none :")
        def none(p):
            return None

        parser = pg.build()
        assert parser.parse(iter([
            Token("VALUE", "abc"),
            Token("SPACE", " "),
            Token("VALUE", "def"),
            Token("SPACE", " "),
            Token("VALUE", "ghi"),
        ])) == ["abc", "def", "ghi"]

        assert parser.parse(iter([])) == []
示例#16
0
    def test_per_rule_precedence(self):
        pg = ParserGenerator(["NUMBER", "MINUS"], precedence=[
            ("right", ["UMINUS"]),
        ])

        @pg.production("main : expr")
        def main_expr(p):
            return p[0]

        @pg.production("expr : expr MINUS expr")
        def expr_minus(p):
            return BoxInt(p[0].getint() - p[2].getint())

        @pg.production("expr : MINUS expr", precedence="UMINUS")
        def expr_uminus(p):
            return BoxInt(-p[1].getint())

        @pg.production("expr : NUMBER")
        def expr_number(p):
            return BoxInt(int(p[0].getstr()))

        with self.assert_warns(
            ParserGeneratorWarning, "1 shift/reduce conflict"
        ):
            parser = pg.build()

        assert parser.parse(iter([
            Token("MINUS", "-"),
            Token("NUMBER", "4"),
            Token("MINUS", "-"),
            Token("NUMBER", "5"),
        ])) == BoxInt(-9)
示例#17
0
    def test_reduce_reduce(self):
        pg = ParserGenerator(["NAME", "EQUALS", "NUMBER"])

        @pg.production("main : assign")
        def main(p):
            pass

        @pg.production("assign : NAME EQUALS expression")
        @pg.production("assign : NAME EQUALS NUMBER")
        def assign(p):
            pass

        @pg.production("expression : NUMBER")
        def expression(p):
            pass

        with self.assert_warns(ParserGeneratorWarning, "1 reduce/reduce conflict"):
            pg.build()
示例#18
0
    def test_simple(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        parser = pg.build()

        assert parser.parse(iter([Token("VALUE", "abc")])) == Token("VALUE", "abc")
示例#19
0
文件: parser.py 项目: flynnwang/dive
def build():
    pg = ParserGenerator(TOKENS, cache_id="sql_parser")
    for prod, cls in gen_productions(select_bnf, node_classes):
        pg.production(prod)(cls.production)
        # print prod

    @pg.error
    def error_handler(token):
        raise ValueError("Ran into a %s(%s) where it wasn't expected"
                         % (token.gettokentype(), token.getstr()))
    return pg.build()
示例#20
0
    def test_shift_reduce(self):
        pg = ParserGenerator([
            "NAME", "NUMBER", "EQUALS", "PLUS", "MINUS", "TIMES", "DIVIDE",
            "LPAREN", "RPAREN"
        ])

        @pg.production("statement : NAME EQUALS expression")
        def statement_assign(p):
            pass

        @pg.production("statement : expression")
        def statement_expression(p):
            pass

        @pg.production("expression : expression PLUS expression")
        @pg.production("expression : expression MINUS expression")
        @pg.production("expression : expression TIMES expression")
        @pg.production("expression : expression DIVIDE expression")
        def expression_binop(p):
            pass

        @pg.production("expression : MINUS expression")
        def expression_uminus(p):
            pass

        @pg.production("expression : LPAREN expression RPAREN")
        def expression_group(p):
            pass

        @pg.production("expression : NUMBER")
        def expression_number(p):
            pass

        @pg.production("expression : NAME")
        def expression_name(p):
            pass

        with self.assert_warns(
            ParserGeneratorWarning, "20 shift/reduce conflicts"
        ):
            pg.build()
示例#21
0
文件: test_parser.py 项目: rlamy/rply
    def test_parse_error(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        parser = pg.build()

        with py.test.raises(ParsingError) as exc_info:
            parser.parse(FakeLexer([Token("VALUE", "hello"), Token("VALUE", "world", SourcePosition(5, 10, 2))]))

        assert exc_info.value.getsourcepos().lineno == 10
示例#22
0
    def test_simple(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        parser = pg.build()

        assert parser.lr_table.lr_action == {
            0: {"VALUE": 2},
            1: {"$end": 0},
            2: {"$end": -1},
        }
示例#23
0
    def test_default_reductions(self):
        pg = ParserGenerator(
            ["INTEGER_START", "INTEGER_VALUE", "COMPARE"],
            precedence=[
                ("nonassoc", ["COMPARE"])
            ]
        )
        record = []

        @pg.production("main : expr")
        def main(p):
            record.append("main")
            return p[0]

        @pg.production("expr : expr COMPARE expr")
        def expr_compare(p):
            record.append("expr:compare")
            return BoxInt(p[0].getint() - p[2].getint())

        @pg.production("expr : INTEGER_START INTEGER_VALUE")
        def expr_int(p):
            record.append("expr:int")
            return BoxInt(int(p[1].getstr()))

        parser = pg.build()

        assert parser.parse(RecordingLexer(record, [
            Token("INTEGER_START", ""),
            Token("INTEGER_VALUE", "10"),
            Token("COMPARE", "-"),
            Token("INTEGER_START", ""),
            Token("INTEGER_VALUE", "5")
        ])) == BoxInt(5)

        assert record == [
            "token:INTEGER_START",
            "token:INTEGER_VALUE",
            "expr:int",
            "token:COMPARE",
            "token:INTEGER_START",
            "token:INTEGER_VALUE",
            "expr:int",
            "expr:compare",
            "token:None",
            "main",
        ]
示例#24
0
def parser_from_lexer(lexer, mapping):
    pg = ParserGenerator(
        [rule.name for rule in lexer.rules],
        cache_id="cache",

        # NOTE: This is pretty arbitrary at the moment
        precedence=[
            ('right', ['NOT']),
            ('left', ['PARENT', 'CHILD', 'OR']),
            ('left', ['AND', 'TYPE']),
            ('left', ['L_PAREN', 'R_PAREN', 'EQUAL']),
        ])

    @pg.production("expr : L_PAREN expr R_PAREN")
    def expr(p):
        return p[1]

    @pg.production("expr : expr AND expr")
    @pg.production("expr : expr OR expr")
    @pg.production("expr : expr CHILD expr")
    @pg.production("expr : expr PARENT expr")
    def binary_operation(p):
        return [p[1], p[0], p[2]]

    @pg.production("expr : expr EQUAL DATA")
    @pg.production("expr : expr TYPE DATA")
    def equal(p):
        p[2].value = p[2].value.strip("/")
        return p

    @pg.production("expr : expr NOT CHILD expr")
    @pg.production("expr : expr NOT PARENT expr")
    def not_expr(p):
        # This is a hack
        op = p[2]
        op.name = "NOT_" + op.name
        op.value = "!" + op.value
        return [op, p[0], p[3]]

    for kind in mapping.keys():
        @pg.production("expr : " + kind)
        def kind(p):
            return mapping[p[0].name]

    parser = pg.build()
    return parser
示例#25
0
文件: test_parser.py 项目: rlamy/rply
    def test_parse_error_handler(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : VALUE")
        def main(p):
            return p[0]

        @pg.error
        def error_handler(token):
            raise ValueError(token)

        parser = pg.build()

        token = Token("VALUE", "world")

        with py.test.raises(ValueError) as exc_info:
            parser.parse(FakeLexer([Token("VALUE", "hello"), token]))

        assert exc_info.value.args[0] is token
示例#26
0
    def test_error_handler_state(self):
        pg = ParserGenerator([])

        @pg.production("main :")
        def main(state, p):
            pass

        @pg.error
        def error(state, token):
            raise ValueError(state, token)

        parser = pg.build()

        state = ParserState()
        token = Token("VALUE", "")
        with py.test.raises(ValueError) as exc_info:
            parser.parse(iter([token]), state=state)

        assert exc_info.value.args[0] is state
        assert exc_info.value.args[1] is token
示例#27
0
    def test_empty_production(self):
        pg = ParserGenerator(["VALUE"])

        @pg.production("main : values")
        def main(p):
            return p[0]

        @pg.production("values : VALUE values")
        def values_value(p):
            return [p[0]] + p[1]

        @pg.production("values :")
        def values_empty(p):
            return []

        parser = pg.build()
        assert parser.lr_table.lr_action == {
            0: {"$end": -3, "VALUE": 3},
            1: {"$end": 0},
            2: {"$end": -1},
            3: {"$end": -3, "VALUE": 3},
            4: {"$end": -2},
        }
示例#28
0
class Parser:
    def __init__(self):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            [
                'ADDVV',
                'ADDVS',
                'SUBVV',
                'SUBVS',
                'SUBSV',
                'MULVV',
                'MULVS',
                'DIVVV',
                'DIVVS',
                'DIVSV',
                'LV',
                'LVWS',
                'SV',
                'SVWS',
                'CVI',
                'SLEVV',
                'SLEVS',
                'SREVV',
                'SREVS',
                'XOREVV',
                'XOREVS',
                'OWNEP',
                'SLDVV',
                'SLDVS',
                'SRDVV',
                'SRDVS',
                'XORDVV',
                'XORDVS',
                'OWNDP',
                'COLON',
                'SEMI_COLON',
                'OPEN_PAREN',
                'CLOSE_PAREN',
                'NUMBER',
                'VEC1',
                'VEC2',
                'VEC3',
                'S0',
                'S1',
                'S2',
                'S3',
                'S4',
                'S5',
                'S6',
                'S7',
                'S8',
                'S9',
                'S10',
                'S11',
                'S12',
                'S13',
                'S14',
                'S15',
            ])

    def parse(self):
        @self.pg.production(
            'expression : ADDVV VEC1 COLON VEC2 COLON VEC3 SEMI_COLON')
        @self.pg.production(
            'expression : ADDVV VEC1 COLON VEC3 COLON VEC2 SEMI_COLON')
        @self.pg.production(
            'expression : ADDVV VEC2 COLON VEC1 COLON VEC3 SEMI_COLON')
        @self.pg.production(
            'expression : ADDVV VEC2 COLON VEC3 COLON VEC1 SEMI_COLON')
        @self.pg.production(
            'expression : ADDVV VEC3 COLON VEC1 COLON VEC2 SEMI_COLON')
        @self.pg.production(
            'expression : ADDVV VEC3 COLON VEC2 COLON VEC1 SEMI_COLON')
        def expression(p):
            print("ADDVV 1")
            return 0

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#29
0
class Parser:
    def __init__(self):

        self.pg = ParserGenerator([
            'NUMBER', 'PRINT', 'OPEN_PAREN', 'CLOSE_PAREN', 'SEMI_COLON',
            'SUM', 'SUB', 'MULT', 'DIV', 'POT', 'RESTO'
        ],
                                  precedence=[
                                      ('left', ['SUM', 'SUB']),
                                      ('left', ['MULT', 'DIV', 'RESTO']),
                                      ('left', ['POT']),
                                  ])
        self.file = open("codigo.asm", "w")
        self.file.write(".data\n")
        self.file.write(".text\n")
        self.file.write(".global main\n")
        self.file.write("main:\n")
        print("\"codigo\" compilado com sucesso para \"./".__add__(
            self.file.name).__add__("\""))

    def parse(self):
        @self.pg.production(
            'program : PRINT OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def program(p):
            self.file.write("\tmove $a0, $t1\n")
            self.file.write("\tli $v0, 1\n")
            self.file.write("\tsyscall\n")
            self.file.write("\tli $v0, 10\n")
            self.file.write("\tsyscall\n")
            self.file.write(".end main")

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MULT expression')
        @self.pg.production('expression : expression DIV expression')
        @self.pg.production('expression : expression POT expression')
        @self.pg.production('expression : expression RESTO expression')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                flag = 0
                if left:
                    if right:
                        self.file.write("\tli $t1, ".__add__(
                            str(left)).__add__("\n"))
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))
                        flag = 1

                if flag == 0:
                    if left:
                        self.file.write("\tli $t2, ".__add__(
                            str(left)).__add__("\n"))
                    if right:
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))

                self.file.write("\tadd $t1, $t1, $t2\n")

            elif operator.gettokentype() == 'SUB':
                flag = 0
                if left:
                    if right:
                        self.file.write("\tli $t1, ".__add__(
                            str(left)).__add__("\n"))
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))
                        flag = 1

                if flag == 0:
                    if left:
                        self.file.write("\tli $t2, ".__add__(
                            str(left)).__add__("\n"))
                    if right:
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))

                self.file.write("\tsub $t1, $t1, $t2\n")

            elif operator.gettokentype() == 'MULT':
                flag = 0
                if left:
                    if right:
                        self.file.write("\tli $t1, ".__add__(
                            str(left)).__add__("\n"))
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))
                        flag = 1

                if flag == 0:
                    if left:
                        self.file.write("\tli $t2, ".__add__(
                            str(left)).__add__("\n"))
                    if right:
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))

                self.file.write("\tmul $t1, $t1, $t2\n")

            elif operator.gettokentype() == 'DIV':
                flag = 0
                if left:
                    if right:
                        self.file.write("\tli $t1, ".__add__(
                            str(left)).__add__("\n"))
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))
                        flag = 1

                if flag == 0:
                    if left:
                        self.file.write("\tli $t2, ".__add__(
                            str(left)).__add__("\n"))
                    if right:
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))

                self.file.write("\tdiv $t1, $t1, $t2\n")

            elif operator.gettokentype() == 'POT':  # Not finished
                aux_x = left
                aux_y = int(right) - 1
                while aux_y > 0:
                    self.file.write("\tli $t2, ".__add__(
                        str(aux_x)).__add__("\n"))
                    self.file.write("\tmul $t1, $t2, $t2\n")
                    aux_y = aux_y - 1

            elif operator.gettokentype() == 'RESTO':
                flag = 0
                interator = 1
                if left:
                    if right:
                        self.file.write("\tli $t1, ".__add__(
                            str(left)).__add__("\n"))
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))
                        flag = 1

                if flag == 0:
                    if left:
                        self.file.write("\tli $t2, ".__add__(
                            str(left)).__add__("\n"))
                    if right:
                        self.file.write("\tli $t2, ".__add__(
                            str(right)).__add__("\n"))

                self.file.write("\tmove $t3, $t1 \n")
                self.file.write("\tmove $t4, $t2\n")
                self.file.write("\tli $t5, 0\n")

                self.file.write("\tloop:\n")
                self.file.write("\t\tli $t6, 1\n")
                self.file.write(
                    "\t\tadd $t5, $t5, $t6\n")  # incrementando contador
                self.file.write("\t\tsub $t3, $t3, $t4\n")
                self.file.write("\t\tbgt $t3, $t4, loop\n")
                self.file.write("\tmul $t3, $t5, $t2\n")
                self.file.write("\tsub $t1, $t1, $t3\n")

        @self.pg.production('expression : NUMBER')
        def number(p):
            return p[0].value

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#30
0
@pg.production("hashtags : hashtags HASHTAG")
@pg.production("hashtags : HASHTAG")
def hashtags(p):
    if len(p) == 1:
        return p
    else:
        return list(flattened(p))

@pg.production("topics : FOR hashtags")
@pg.production("topics : ")
def topics(p):
    if len(p) == 0:
        return { u'topics': [] }
    else:
        topics = [tok.value.strip('#') for tok in p[1]]
        return { u'topics': topics }

@pg.error
def error_handler(token):
    pos = token.getsourcepos()
    if pos:
        offset = "offset {}".format(pos.idx)
    else:
        offset = u"end of stream"
    raise ValueError("Ran into a {0} where it wasn't expected at {1}".format(token.gettokentype(), offset))

TweetLexer = lex.build()
TweetParser = pg.build()

示例#31
0
文件: parser.py 项目: fineans/Vython
class Parser:
    def __init__(self, tokens):
        self.pg = ParserGenerator(
            tokens,
            precedence=[('left', ['NEWLINE']), ('left', ['EGAL']),
                        ('left', ['AND', 'OR', 'NOT']),
                        ('left', ['IS', 'LESS', 'MORE', 'LESSE', 'MOREE']),
                        ('left', ['SUMAFF', 'SUBAFF']),
                        ('left', ['MULAFF', 'DIVAFF', 'DIVEUAFF', 'MODAFF']),
                        ('left', ['POWAFF']), ('left', ['SUM', 'SUB']),
                        ('left', ['MUL', 'DIV', 'DIVEU', 'MOD']),
                        ('left', ['POW'])])
        self.var = Variables()

    def parse(self):
        @self.pg.production('program : statementlist')
        def program(p):
            return p[0].eval()

        @self.pg.production('statementlist : statementlist NEWLINE statement')
        @self.pg.production(
            'statementlist : statementlist NEWLINE loop_statement')
        @self.pg.production(
            'statementlist : statementlist NEWLINE if_statement')
        def statementlistexp(p):
            return StatementList(p[2], p[0])

        @self.pg.production('statementlist : statement')
        @self.pg.production('statementlist : loop_statement')
        @self.pg.production('statementlist : if_statement')
        @self.pg.production('statementlist : statementlist NEWLINE')
        def statementlist(p):
            if p[0].gettokentype() == 'statement':
                return StatementList(p[0])
            else:
                return StatementList(None, p[0])

        @self.pg.production(
            'loop_statement : LOOP INTEGER OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def loop(p):
            return Loop(int(p[1].value), p[4])

        @self.pg.production(
            'loop_statement : LOOP INTEGER NEWLINE OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def loop2(p):
            return Loop(int(p[1].value), p[5])

        @self.pg.production(
            'loop_statement : WHILE expression OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def whileexp(p):
            return While(p[1], p[4])

        @self.pg.production(
            'loop_statement : WHILE expression NEWLINE OPEN_CRO NEWLINE statementlist NEWLINE '
            'CLOSE_CRO')
        def whileexp2(p):
            return While(p[1], p[5])

        @self.pg.production(
            'if_statement : IF expression OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def ifexp(p):
            return If(p[1], p[4])

        @self.pg.production(
            'if_statement : IF expression NEWLINE OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def ifexp2(p):
            return If(p[1], p[5])

        @self.pg.production(
            'else_statement : ELSE OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def elseexp(p):
            return Else(p[3])

        @self.pg.production(
            'else_statement : ELSE NEWLINE OPEN_CRO NEWLINE statementlist NEWLINE CLOSE_CRO'
        )
        def elseexp2(p):
            return Else(p[4])

        @self.pg.production(
            'elseif_statement : ELSEIF expression OPEN_CRO NEWLINE statementlist NEWLINE '
            'CLOSE_CRO')
        def elseif(p):
            return ElseIfs(ElseIf(p[1], p[4]))

        @self.pg.production(
            'elseif_statement : ELSEIF expression NEWLINE OPEN_CRO NEWLINE statementlist NEWLINE '
            'CLOSE_CRO')
        def elseif2(p):
            return ElseIfs(ElseIf(p[1], p[5]))

        @self.pg.production(
            'elseif_statement : elseif_statement elseif_statement')
        def elseif3(p):
            return p[0].add(p[1])

        @self.pg.production('if_statement : if_statement else_statement')
        def ifelse(p):
            if type(p[0]) == IfElse:
                error(errors.UNEXPECTEDSYNTAX, "Alone Else", {"type": ""})
                sys.exit(1)
            elif type(p[0]) == IfElseIf:
                return IfElseIfElse(If(p[0].ifcondition, p[0].ifstatementlist),
                                    p[0].elseifs, p[1])
            else:
                return IfElse(p[0], p[1])

        @self.pg.production('if_statement : if_statement elseif_statement')
        def ifelseif(p):
            if type(p[0]) == IfElse:
                error(errors.UNEXPECTEDSYNTAX, "Alone ElseIf", {"type": ""})
                sys.exit(1)
            return IfElseIf(p[0], p[1])

        @self.pg.production('statement : expression COMMENT')
        @self.pg.production('statement : expression')
        def statement(p):
            return Statement(p[0])

        @self.pg.production('statement : COMMENT')
        def statement(p):
            return Nothing()

        @self.pg.production('expression : IDENTIFIER EGAL expression')
        def programvar(p):
            if type(p[2]) == List:
                error(errors.EXPECTEDSYNTAX, "Expected hook around List.", {
                    "type": "token",
                    "token": p[0]
                })
                sys.exit(1)
            var = self.var.get(p[0].value)
            if var is not None:
                if type(var) == ListVar:
                    error(errors.INVALIDTYPE, "Cannot have basic type.", {
                        "type": "token",
                        "token": p[0]
                    })
                    sys.exit(1)
                return AffectionVar(var, p[2])
            else:
                var = Variable(p[0].value, p[2])
                self.var.add(var)
            return var

        @self.pg.production('expression : IDENTIFIER EGAL CRO_OPEN CRO_CLOSE')
        def programvar2(p):
            var = self.var.get(p[0].value)
            if var is not None:
                if type(var) == Variable:
                    error(errors.INVALIDTYPE, "Cannot have complex type.", {
                        "type": "token",
                        "token": p[0]
                    })
                    sys.exit(1)
                return AffectionVar(var, List())
            else:
                var = ListVar(p[0].value, List())
                self.var.add(var)
            return var

        @self.pg.production(
            'expression : IDENTIFIER EGAL CRO_OPEN expression CRO_CLOSE')
        def programvar3(p):
            var = self.var.get(p[0].value)
            if var is not None:
                if type(var) == Variable:
                    error(errors.INVALIDTYPE, "Cannot have complex type.", {
                        "type": "token",
                        "token": p[0]
                    })
                    sys.exit(1)
                return AffectionVar(var, List(p[3]))
            else:
                var = ListVar(p[0].value, List(p[3]))
                self.var.add(var)
            return var

        @self.pg.production(
            'expression : IDENTIFIER POINT IDENTIFIER OPEN_PAREN CLOSE_PAREN')
        def membervar(p):
            var = self.var.get(p[0].value)
            if var is not None:
                return MemberType(p[2].value, var)
            else:
                error(errors.NOTDECLARED, "Variable is not declared.", {
                    "type": "token",
                    "token": p[0]
                })
                sys.exit(1)

        @self.pg.production(
            'expression : IDENTIFIER POINT IDENTIFIER OPEN_PAREN expression CLOSE_PAREN'
        )
        def membervar2(p):
            var = self.var.get(p[0].value)
            if var is not None:
                return MemberType(p[2].value, var, [p[4]])
            else:
                error(errors.NOTDECLARED, "Variable is not declared.", {
                    "type": "token",
                    "token": p[0]
                })
                sys.exit(1)

        @self.pg.production('expression : expression VIRGULE expression')
        def list(p):
            return List(p[0], p[2])

        @self.pg.production(
            'expression : CANBE OPEN_PAREN expression VIRGULE STRING CLOSE_PAREN'
        )
        def programfunc2(p):
            func = p[0]
            exp = p[2]
            if func.gettokentype() == 'CANBE':
                return CanBe(exp, p[4].value[1:-1])

        @self.pg.production(
            'expression : INT OPEN_PAREN expression CLOSE_PAREN')
        @self.pg.production(
            'expression : FLOATF OPEN_PAREN expression CLOSE_PAREN')
        @self.pg.production(
            'expression : BOOL OPEN_PAREN expression CLOSE_PAREN')
        @self.pg.production(
            'expression : STR OPEN_PAREN expression CLOSE_PAREN')
        @self.pg.production(
            'expression : TYPE OPEN_PAREN expression CLOSE_PAREN')
        @self.pg.production(
            'expression : PRINT OPEN_PAREN expression CLOSE_PAREN')
        @self.pg.production('expression : ENTER OPEN_PAREN STRING CLOSE_PAREN')
        def programfunc1(p):
            func = p[0]
            exp = p[2]
            if func.gettokentype() == "INT":
                return Int(exp)
            elif func.gettokentype() == "FLOATF":
                return Float(exp)
            elif func.gettokentype() == "BOOL":
                return Boolean(exp)
            elif func.gettokentype() == "STR":
                return Str(exp)
            elif func.gettokentype() == "TYPE":
                return Type(exp)
            elif func.gettokentype() == "PRINT":
                return Print(exp)
            else:
                return Input(exp.value)

        @self.pg.production('expression : EXIT OPEN_PAREN CLOSE_PAREN')
        @self.pg.production('expression : ENTER OPEN_PAREN CLOSE_PAREN')
        @self.pg.production('expression : PRINT OPEN_PAREN CLOSE_PAREN')
        def programfunc0(p):
            func = p[0]
            if func.gettokentype() == "EXIT":
                sys.exit(0)
            elif func.gettokentype() == "ENTER":
                return Input()
            else:
                return Print()

        @self.pg.production('expression : OPEN_PAREN expression CLOSE_PAREN')
        def expressionparen(p):
            return p[1]

        @self.pg.production('expression : IDENTIFIER INCREMENT')
        @self.pg.production('expression : IDENTIFIER DECREMENT')
        def uniqueop(p):
            var = self.var.get(p[0].value)
            if var is not None:
                if p[1].gettokentype() == "INCREMENT":
                    return Increment(var)
                else:
                    return Decrement(var)
            else:
                error(errors.NOTDECLARED, "Variable is not declared.", {
                    "type": "token",
                    "token": p[0]
                })
                sys.exit(1)

        @self.pg.production('expression : IDENTIFIER SUMAFF expression')
        @self.pg.production('expression : IDENTIFIER SUBAFF expression')
        @self.pg.production('expression : IDENTIFIER MULAFF expression')
        @self.pg.production('expression : IDENTIFIER DIVAFF expression')
        @self.pg.production('expression : IDENTIFIER MODAFF expression')
        @self.pg.production('expression : IDENTIFIER POWAFF expression')
        @self.pg.production('expression : IDENTIFIER DIVEUAFF expression')
        def affectionop(p):
            var = self.var.get(p[0].value)
            op = p[1]
            if var is not None:
                if op.gettokentype() == 'SUMAFF':
                    return SumAffector(var, p[2])
                elif op.gettokentype() == 'SUBAFF':
                    return SubAffector(var, p[2])
                elif op.gettokentype() == 'MULAFF':
                    return MulAffector(var, p[2])
                elif op.gettokentype() == 'MODAFF':
                    return ModAffector(var, p[2])
                elif op.gettokentype() == 'POWAFF':
                    return PowAffector(var, p[2])
                elif op.gettokentype() == 'DIVEUAFF':
                    return DivEuAffector(var, p[2])
                else:
                    return DivAffector(var, p[2])
            else:
                error(errors.NOTDECLARED, "Variable is not declared.", {
                    "type": "token",
                    "token": p[0]
                })
                sys.exit(1)

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        @self.pg.production('expression : expression MOD expression')
        @self.pg.production('expression : expression POW expression')
        @self.pg.production('expression : expression DIVEU expression')
        def binaryop(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                return Sum(left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(left, right)
            elif operator.gettokentype() == 'MUL':
                return Mul(left, right)
            elif operator.gettokentype() == 'MOD':
                return Mod(left, right)
            elif operator.gettokentype() == 'POW':
                return Pow(left, right)
            elif operator.gettokentype() == 'DIVEU':
                return DivEu(left, right)
            else:
                return Div(left, right)

        @self.pg.production('expression : expression AND expression')
        @self.pg.production('expression : expression OR expression')
        def logicoperators2(p):
            op = p[1]
            e1 = p[0]
            e2 = p[2]
            if op.gettokentype() == "AND":
                return And(e1, e2)
            else:
                return Or(e1, e2)

        @self.pg.production('expression : NOT expression')
        def logicoperator1(p):
            return ExpressionBase(Not(p[1]).eval(), "boolean")

        @self.pg.production('expression : expression IS expression')
        @self.pg.production('expression : expression LESS expression')
        @self.pg.production('expression : expression LESSE expression')
        @self.pg.production('expression : expression MORE expression')
        @self.pg.production('expression : expression MOREE expression')
        def comparators(p):
            c = p[1]
            e1 = p[0]
            e2 = p[2]
            if c.gettokentype() == "IS":
                return Egal(e1, e2)
            elif c.gettokentype() == "LESS":
                return Less(e1, e2)
            elif c.gettokentype() == "MORE":
                return More(e1, e2)
            elif c.gettokentype() == "LESSE":
                return LessOrEgal(e1, e2)
            else:
                return MoreOrEgal(e1, e2)

        @self.pg.production('expression : SUB expression')
        @self.pg.production('expression : SUM expression')
        def uniqueop(p):
            ope = p[0]
            exp = p[1]
            if ope.gettokentype() == 'SUM':
                return Sum(ExpressionBase(0, "integer"), exp)
            else:
                return Sub(ExpressionBase(0, "integer"), exp)

        @self.pg.production(
            'expression : IDENTIFIER CRO_OPEN INTEGER CRO_CLOSE')
        def expressionlist(p):
            var = self.var.get(p[0].value)
            if var is not None:
                return var.get(int(p[2].value))
            else:
                error(errors.NOTDECLARED, "Variable is not declared.", {
                    "type": "token",
                    "token": p[0]
                })
                sys.exit(1)

        @self.pg.production('expression : FLOAT')
        @self.pg.production('expression : INTEGER')
        @self.pg.production('expression : STRING')
        @self.pg.production('expression : BOOLEAN')
        @self.pg.production('expression : IDENTIFIER')
        def expression(p):
            if p[0].gettokentype() == 'FLOAT':
                return ExpressionBase(float(p[0].value), "float")
            elif p[0].gettokentype() == 'STRING':
                return ExpressionBase(str(p[0].value)[1:-1], "string")
            elif p[0].gettokentype() == 'BOOLEAN':
                if p[0].value == "false":
                    return ExpressionBase(False, "boolean")
                return ExpressionBase(True, "boolean")
            elif p[0].gettokentype() == 'IDENTIFIER':
                var = self.var.get(p[0].value)
                if var is not None:
                    return ExpressionBase(var.value, var.kind, var)
                else:
                    error(errors.NOTDECLARED, "Variable is not declared.", {
                        "type": "token",
                        "token": p[0]
                    })
                    sys.exit(1)
            else:
                return ExpressionBase(int(p[0].value), "integer")

        @self.pg.error
        def error_handle(token):
            print("Syntax unexcepted : \n - Position :", token.getsourcepos(),
                  "\n - Token : Valeur =", token.getstr(), "| Type =",
                  token.gettokentype())
            sys.exit(1)

    def get_parser(self):
        parser = self.pg.build()
        return parser
示例#32
0
class Parser():
    def __init__(self, module, builder, printf):
        self.pg = ParserGenerator([
            'PROG', 'BEGIN', 'END', 'OP', 'CP', 'TZ', 'TT', 'Z', 'FUNC', 'VAR',
            'INT', 'REAL', 'NUMBER', 'ID', 'ASSIGN', 'EQUAL', 'NOT_EQUAL',
            'AND', 'NOT', 'OR', 'MORE', 'LESS', 'SUM', 'SUB', 'MUL', 'DIV',
            'IF', 'ELSE', 'WHILE', 'DO', 'BREAKCONTINUE', 'PRINT'
        ],
                                  precedence=[("left", ['MUL', 'DIV']),
                                              ("left", ['SUM', 'SUB'])])

        self.module = module
        self.builder = builder
        self.printf = printf

    def parse(self):
        @self.pg.production(
            'program : PROG ID TZ var functions BEGIN statements END')
        def program(p):
            return p[6]

        @self.pg.production('var : VAR variable TT type TZ')
        def var(p):
            return p[1]

        @self.pg.production('var : VAR variable TT type TZ var')
        def var2(p):
            return p[1], p[5]

        @self.pg.production('variable : ID')
        def variable(p):
            return p[0]

        @self.pg.production('variable : ID Z variable')
        def variable2(p):
            return p[0], p[2]

        @self.pg.production('type : INT')
        @self.pg.production('type : REAL')
        def type(p):
            return p[0]

        @self.pg.production('functions : function')
        def functions(p):
            return p[0].eval()

        @self.pg.production('functions : function functions')
        def functions2(p):
            return Eval_(self.builder, self.module, p[0], p[2])

        @self.pg.production(
            'function : FUNC ID OP var CP TT type TZ BEGIN statements END')
        def function(p):
            return Func_(self.builder, self.module, p[1], p[3], p[9])

        @self.pg.production('expression : OP expression CP')
        def expression(p):
            return p[1]

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        def expression(p):
            if p[1].gettokentype() == 'SUM':
                return Sum(self.builder, self.module, p[0], p[2])
            elif p[1].gettokentype() == 'SUB':
                return Sub(self.builder, self.module, p[0], p[2])
            elif p[1].gettokentype() == 'MUL':
                return Mul(self.builder, self.module, p[0], p[2])
            elif p[1].gettokentype() == 'DIV':
                return Div(self.builder, self.module, p[0], p[2])

        @self.pg.production('expression : NUMBER')
        def number(p):
            return Number(self.builder, self.module, p[0].value)

        @self.pg.production('expression : ID')
        def expression_id(p):
            return Id_load(self.builder, self.module, p[0])

        @self.pg.production('expression : ID OP variable CP')
        def function3(p):
            return Call_(self.builder, self.module, p[0], p[2])

        @self.pg.production('statements : statement TZ')
        def statements(p):
            return p[0]

        @self.pg.production('statements : statement TZ statements')
        def statements2(p):
            return Eval_(self.builder, self.module, p[0], p[2])

        @self.pg.production('statement : type ID ASSIGN expression')
        def assign(p):
            print(p[0].value)
            return Id_save(self.builder, self.module, p[0], p[1], p[3])

        @self.pg.production(
            'statement : IF OP bool CP BEGIN statements END ELSE BEGIN statements END'
        )
        def if_(p):
            return If_else(self.builder, self.module, p[2], p[5], p[9])

        @self.pg.production('statement : IF OP bool CP BEGIN statements END')
        def if_2(p):
            return If_(self.builder, self.module, p[2], p[5])

        @self.pg.production(
            'statement : WHILE OP bool CP DO BEGIN statements END')
        def while_(p):
            return While_(self.builder, self.module, p[2], p[6])

        @self.pg.production('statement : BREAKCONTINUE ')
        def breakcontinue(p):
            global goto
            goto = p[0].getstr()
            return

        @self.pg.production('statement : PRINT OP expression CP')
        def print_(p):
            return Print(self.builder, self.module, self.printf, p[2])

        @self.pg.production('bool : OP bool CP')
        def bool_(p):
            return p[1]

        @self.pg.production('bool : expression EQUAL expression')
        @self.pg.production('bool : expression MORE expression')
        @self.pg.production('bool : expression LESS expression')
        @self.pg.production('bool : expression NOT_EQUAL expression')
        def bool_2(p):
            if p[1].gettokentype() == 'EQUAL':
                return Equal(self.builder, self.module, p[0], p[2])
            elif p[1].gettokentype() == 'MORE':
                return More(self.builder, self.module, p[0], p[2])
            elif p[1].gettokentype() == 'LESS':
                return Less(self.builder, self.module, p[0], p[2])
            elif p[1].gettokentype() == 'NOT_EQUAL':
                return Not_equal(self.builder, self.module, p[0], p[2])

        @self.pg.production('bool : bool AND bool')
        def and_(p):
            return And_(self.builder, self.module, p[0], p[2])

        @self.pg.production('bool : bool OR bool')
        def or_(p):
            return Or_(self.builder, self.module, p[0], p[2])

        @self.pg.production('bool : NOT bool')
        def not_(p):
            return Not_(self.builder, self.module, p[1])

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#33
0
class Parser():
    def __init__(self, module, builder, printf):
        self.pg = ParserGenerator(
            # A list of all token names, accepted by the parser.
            ['SUM', 'SUB', 'MUL', 'DIV',
             'OPEN_PAREN', 'CLOSE_PAREN', 'SEMI_COLON',
             'NUMBER',
             'PRINT',

             ],
            # A list of precedence rules with ascending precedence, to
            # disambiguate ambiguous production rules.
            precedence=[
                ('left', ['SUM', 'SUB', ]),
                ('left', ['MUL', 'DIV', ]),
            ]
        )

        self.module = module
        self.builder = builder
        self.printf = printf

    def parse(self):

        @self.pg.production('program : PRINT OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def program(p):
            return Print(self.builder, self.module, self.printf, p[2])

        @self.pg.production('expression : OPEN_PAREN expression CLOSE_PAREN')
        def expression_parens(p):
            expression = p[1]
            return expression

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                return Sum(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'MUL':
                return Mul(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'DIV':
                return Div(self.builder, self.module, left, right)

        @self.pg.production('expression : expression expression', precedence='MUL')
        def implicit_multiplication(p):
            left = p[0]
            right = p[1]
            return Mul(self.builder, self.module, left, right)

        @self.pg.production('expression : NUMBER')
        def number(p):
            return Number(self.builder, self.module, p[0].value)

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#34
0
class Parser():
    def __init__(self):
        self.pg = ParserGenerator([
            'NUMBER',
            'STRING',
            'IDENT',
            'PRINT',
            'READ',
            'INT',
            'IF',
            'THEN',
            'ELSE',
            'END_IF',
            'FOR',
            'UNTIL',
            'STEP',
            'END_FOR',
            'OPEN_PAREN',
            'CLOSE_PAREN',
            'END_STATEMENT',
            'DECLARE_TYPE',
            'ADD',
            'SUB',
            'MULT',
            'DIV',
            'LESS',
            'MORE',
            'LESS_EQ',
            'MORE_EQ',
        ],
                                  precedence=[('left', ['ADD', 'SUB']),
                                              ('left', ['MUL', 'DIV'])])
        self.vars = {}
        self.flags = {"for": False, "while": False, "if": False}

    def parse(self):
        @self.pg.production("main : expression")
        def main(p):

            return p[0]

        @self.pg.production(
            "expression : PRINT OPEN_PAREN expression CLOSE_PAREN END_STATEMENT"
        )
        def imprime(p):
            if isinstance(p[2], Identificador):
                if p[2].nome in self.vars.keys():
                    return Imprime(self.vars[p[2].nome])

            return Imprime(p[2])

        @self.pg.production(
            "expression : READ OPEN_PAREN expression CLOSE_PAREN END_STATEMENT"
        )
        def read_input(p):
            new_ident, new_value = Leia(p[2]).eval()
            self.vars[new_ident.nome].value = new_value

            return new_ident

        @self.pg.production('expression : IF expression THEN expression END_IF'
                            )
        @self.pg.production(
            'expression : IF expression THEN expression ELSE expression END_IF'
        )
        def expression_conditional_complete(p):
            if len(p) > 5:
                return p[3] if p[1].eval() else p[5]
            return p[3] if p[1].eval() else Nulo()

        @self.pg.production(
            'expression : FOR expression UNTIL expression STEP expression expression END_FOR'
        )
        def expression_control_loop(p):
            if isinstance(p[1], Identificador):
                if p[1].nome in self.vars.keys():
                    base = self.vars[p[1].nome]

            if isinstance(p[3], Identificador):
                if p[3].nome in self.vars.keys():
                    limite = self.vars[p[3].nome]

            if isinstance(base, Identificador) and isinstance(
                    limite, Identificador):
                return ForLoop(base, limite, p[5], p[6])

            return ForLoop(p[1], p[3], p[5], p[6])

        @self.pg.production(
            'expression : expression DECLARE_TYPE expression END_STATEMENT')
        def expression_attr(p):
            type_ident = p[0]
            ident = p[2]

            atrib = Atribuicao(type_ident, ident)
            ident_to_be_stored = atrib.right.tipo.value

            self.vars[ident_to_be_stored] = atrib.right

            return atrib

        @self.pg.production('expression : expression LESS expression')
        @self.pg.production('expression : expression MORE expression')
        @self.pg.production('expression : expression LESS_EQ expression')
        @self.pg.production('expression : expression MORE_EQ expression')
        def expression_bool(p):
            left = p[0]
            right = p[2]
            operator = p[1]

            if isinstance(p[0], Identificador):
                if p[0].nome in self.vars.keys():
                    left = self.vars[p[0].nome]

            if isinstance(p[2], Identificador):
                if p[2].nome in self.vars.keys():
                    right = self.vars[p[2].nome]

            if operator.gettokentype() == 'LESS':
                return Less(left, right)
            elif operator.gettokentype() == 'MORE':
                return More(left, right)
            elif operator.gettokentype() == 'LESS_EQ':
                return LessEqual(left, right)
            elif operator.gettokentype() == 'MORE_EQ':
                return MoreEqual(left, right)

        @self.pg.production('expression : expression ADD expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MULT expression')
        @self.pg.production('expression : expression DIV expression')
        def expression_arg(p):
            left = p[0]
            right = p[2]
            operator = p[1]

            if isinstance(p[0], Identificador):
                if p[0].nome in self.vars.keys():
                    left = self.vars[p[0].nome]

            if isinstance(p[2], Identificador):
                if p[2].nome in self.vars.keys():
                    right = self.vars[p[2].nome]

            if operator.gettokentype() == 'ADD':
                return Add(left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(left, right)
            elif operator.gettokentype() == 'MULT':
                return Mult(left, right)
            elif operator.gettokentype() == 'DIV':
                return Div(left, right)

        @self.pg.production('expression : IDENT')
        def identifier(p):

            return Identificador(p[0].value, p[0])

        @self.pg.production('expression : NUMBER')
        def number(p):

            return Numero(p[0].value)

        @self.pg.production('expression : STRING')
        def string(p):

            return String(p[0].value)

        @self.pg.production('expression : INT')
        def tipo(p):

            return Tipo(p[0].value)

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):

        return self.pg.build()
示例#35
0
class Parser():
    def __init__(self, token_names):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            token_names)

    def parse(self):
        @self.pg.production(
            'statement : IDENTIFIER parameter_list_specifier block_specifier quantity_specifier SEMI_COLON'
        )
        @self.pg.production('statement : empty')
        def statement(p):
            # logic
            pass

        @self.pg.production(
            'parameter_list_specifier : OPEN_PAREN parameter_list CLOSE_PAREN')
        @self.pg.production('parameter_list_specifier : empty')
        def parameter_list_specifier(p):
            # logic
            pass

        @self.pg.production(
            'block_specifier : OPEN_CURLY statement_list CLOSE_CURLY')
        @self.pg.production('block_specifier : empty')
        def block_specifier(p):
            # logic
            pass

        @self.pg.production('statement_list : statement')
        @self.pg.production('statement_list : statement_list statement')
        @self.pg.production('statement_list : plain_text')
        def statement_list(p):
            # logic
            pass

        @self.pg.production('parameter_list : parameter_declaration')
        @self.pg.production(
            'parameter_list : parameter_list COMMA parameter_declaration')
        def parameter_list(p):
            # logic
            pass

        @self.pg.production('parameter_declaration : STRING EQU STRING')
        @self.pg.production('parameter_declaration : empty')
        def parameter_declaration(p):
            # logic
            pass

        @self.pg.production('quantity_specifier : MUL NUMBER')
        @self.pg.production('quantity_specifier : empty')
        def quantity_specifier(p):
            # logic
            pass

        @self.pg.production('plain_text : STRING')
        @self.pg.production('plain_text : empty')
        def plain_text(p):
            # logic
            pass

        # success area begins here:
        @self.pg.production('quantity_specifier : MUL NUMBER')
        def quantity_specifier(p):
            return Number(p[0].value)

        @self.pg.production('empty :')
        def empty(p):
            pass

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#36
0
class Parser():
    def __init__(self):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            ['NUMBER', 'PRINTTOLCD', 'OPEN_PAREN', 'CLOSE_PAREN',
             'SEMI_COLON', 'SUM', 'SUB', 'STRING', 'SLEEP', 'OUTPUT', 'PINON', 'PINOFF', 'EQUAL', 'VAR','VARNAME','GETVAR','IF','ENDIF','THEN','EQUAL']
        )

    def parse(self):
        
        @self.pg.production('program : PRINTTOLCD OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def program(p):
            return Print(p[2])
        @self.pg.production('program : SLEEP OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def sleep(p):
            return Sleep(p[2])
        @self.pg.production('program : OUTPUT OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def output(p):
            return Output(p[2])
        @self.pg.production('program : PINON OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def pinon(p):
            return PinOn(p[2])
        @self.pg.production('program : PINOFF OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def pinoff(p):
            return PinOff(p[2])
        @self.pg.production('program : VAR expression EQUAL expression SEMI_COLON')
        def var(p):
            return setVar(p[1],p[3])
        @self.pg.production('program : IF expression EQUAL expression THEN program ENDIF')
        def ifstatement(p):
            return IfStatement(p[1],p[3],p[5])
        
        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                return Sum(left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(left, right)
        
        @self.pg.production('expression : STRING')
        def string(p):
            return String(p[0].value)
        @self.pg.production('expression : VARNAME')
        def varname(p):
            s = p[0].value
            return Letter(s)
        # @self.pg.production('expression : GETVAR')
        # def getvar(p):
        #     s = p[0].value
        #     return getVar(s)

        @self.pg.production('expression : NUMBER')
        def number(p):
            return Number(p[0].value)
        
        @self.pg.error
        def error_handle(token):
            raise ValueError("Ran into a %s where it wasn't expected" + token.gettokentype)

        
    def get_parser(self):
        return self.pg.build()
示例#37
0
class Parser():
    def __init__(self, verbose=False):
        self.verbose = str(verbose).lower()
        self.setup_verbosity()
        self.parser_generator = ParserGenerator([
            '$end', 'OPENQASM', 'INCLUDE', 'OPAQUE', 'BARRIER', 'IF',
            'MEASURE', 'RESET', 'QREG', 'CREG', 'GATE', 'PAREN_OPEN',
            'PAREN_CLOSE', 'STRING', 'OPEN_BRACKET', 'CLOSE_BRACKET',
            'OPEN_BRACE', 'CLOSE_BRACE', 'SEMI_COLON', 'COLON', 'DASH',
            'UNDER_SCORE', 'COMMA', 'QUOTE', 'U', 'CX', 'PLUS', 'MINUS', 'MUL',
            'DIV', 'POW', 'PI', 'SIN', 'COS', 'TAN', 'EXP', 'LN', 'SQRT',
            'ASSIGN_TO', 'EQU', 'ID', 'INT', 'REAL'
        ])

    def setup_verbosity(self):
        global V
        V = getattr(importlib.import_module("qeda.verbose", self.verbose),
                    self.verbose)
        V("Verbosity setup complete")

    def parse(self):
        @self.parser_generator.production(
            'main : OPENQASM real SEMI_COLON program')
        @self.parser_generator.production(
            'main : OPENQASM real SEMI_COLON include program')
        def main(p):
            V("Creating Main")
            V("QCODE: {}".format(QCODE))
            return QCODE

        @self.parser_generator.production('include : INCLUDE STRING SEMI_COLON'
                                          )
        def include(p):
            V("Including file {}".format(p[1]))
            return p[0]

        @self.parser_generator.production('program : statement')
        @self.parser_generator.production('program : program statement')
        def program(p):
            V("Creating program!")
            pass

        @self.parser_generator.production('statement : decl')
        @self.parser_generator.production(
            'statement : gatedecl goplist CLOSE_BRACE')
        @self.parser_generator.production('statement : gatedecl CLOSE_BRACE')
        @self.parser_generator.production(
            'statement : OPAQUE id idlist SEMI_COLON')
        @self.parser_generator.production(
            'statement : OPAQUE id PAREN_OPEN PAREN_CLOSE idlist SEMI_COLON')
        @self.parser_generator.production(
            'statement : OPAQUE id PAREN_OPEN idlist PAREN_CLOSE idlist SEMI_COLON'
        )
        @self.parser_generator.production('statement : qop')
        @self.parser_generator.production(
            'statement : IF PAREN_OPEN id EQU EQU int PAREN_CLOSE qop')
        @self.parser_generator.production(
            'statement : BARRIER anylist SEMI_COLON')
        def statement(p):
            V("Creating statement!")
            pass

        @self.parser_generator.production(
            'decl : QREG id OPEN_BRACKET int CLOSE_BRACKET SEMI_COLON')
        @self.parser_generator.production(
            'decl : CREG id OPEN_BRACKET int CLOSE_BRACKET SEMI_COLON')
        def decl(p):
            V("Declaring register {} id {}".format(p[0].name, p[1].value))
            if p[0].name == 'QREG':
                V("Creating quantum register")
            elif p[0].name == 'CREG':
                V("Creating classical register")
            pass

        @self.parser_generator.production(
            'gatedecl : GATE id idlist OPEN_BRACE')
        @self.parser_generator.production(
            'gatedecl : GATE id PAREN_OPEN PAREN_CLOSE idlist OPEN_BRACE')
        @self.parser_generator.production(
            'gatedecl : GATE id PAREN_OPEN idlist PAREN_CLOSE idlist OPEN_BRACE'
        )
        def gatedecl(p):
            V([x for x in p])
            V('Declaring GATE: {}'.format(p[1].value))
            if 'list' in str(type(p[2])):
                return GateDecl(p[1].value, args=p[2])
            elif p[2].value == 'PAREN_OPEN':
                if len(p) == 7:
                    return GateDecl(p[1].value, args=p[3])
                return GateDecl(p[1].value, control=p[3])

        @self.parser_generator.production('goplist : uop')
        @self.parser_generator.production('goplist : BARRIER idlist SEMI_COLON'
                                          )
        @self.parser_generator.production('goplist : goplist uop')
        @self.parser_generator.production(
            'goplist : goplist BARRIER idlist SEMI_COLON')
        def goplist(p):
            pass

        @self.parser_generator.production('qop : uop')
        @self.parser_generator.production(
            'qop : MEASURE argument ASSIGN_TO argument SEMI_COLON')
        @self.parser_generator.production('qop : RESET argument SEMI_COLON')
        def qop(p):
            if "Token" in str(type(p[0])):
                V("Token")
                if p[0].name == 'MEASURE':
                    V("MEASURE: {}, {}".format(p[1], p[3]))
                    Measure(p[1])
                    V("Measure complete")
                elif p[0].name == 'RESET':
                    V("RESET")
            else:
                return p[0]

        @self.parser_generator.production(
            'uop : U PAREN_OPEN explist PAREN_CLOSE argument SEMI_COLON')
        @self.parser_generator.production(
            'uop : CX argument COMMA argument SEMI_COLON')
        @self.parser_generator.production('uop : CX anylist SEMI_COLON')
        @self.parser_generator.production('uop : int anylist SEMI_COLON')
        @self.parser_generator.production(
            'uop : int PAREN_OPEN PAREN_CLOSE anylist SEMI_COLON')
        @self.parser_generator.production(
            'uop : int PAREN_OPEN explist PAREN_CLOSE anylist SEMI_COLON')
        @self.parser_generator.production(
            'uop : id anylist SEMI_COLON'
        )  # Adds support for custom gates: ccx a,b,c;
        @self.parser_generator.production('uop : id id SEMI_COLON'
                                          )  # supports: y b;
        @self.parser_generator.production(
            'uop : id id OPEN_BRACKET int CLOSE_BRACKET SEMI_COLON'
        )  # supports X a[1];
        @self.parser_generator.production(
            'uop : id PAREN_OPEN int PAREN_CLOSE SEMI_COLON')  # Supports X(0);
        def uop(p):
            V('uop', p)
            if p[0].name in ('U', 'u'):
                V('U gate!')
                return p
            elif p[0].name in ('cx', 'CX'):
                V("CX Gate")
                if len(p) == 5:
                    return CX(p[1], p[3])
                else:
                    return CX(p[0][0], p[0][1])
            elif p[0].name == 'ID':
                V('a', p)
                if p[0].value.lower() == 'h':
                    V("Hadamard!")
                    return H(p[2])
                elif p[0].value.lower() == 'i':
                    V("Identity!")
                    return I(p[2])
                elif p[0].value.lower() == 's':
                    V("S Gate")
                    return S(p[2])
                elif p[0].value.lower() == 'sdg':
                    V("SDG Gate")
                    return SDG(p[2])
                elif p[0].value.lower() == 't':
                    V("T Gate")
                    return T(p[2])
                elif p[0].value.lower() == 'tdg':
                    V("TDG Gate")
                    return TDG(p[2])
                elif p[0].value.lower() == 'x':
                    V("X Gate")
                    return X(p[2])
                elif p[0].value.lower() == 'y':
                    V("Y Gate")
                    return Y(p[2])
                elif p[0].value.lower() == 'z':
                    V("Z Gate")
                    return Z(p[2])
                elif p[0].value.lower() == 'rx':
                    V("RX Gate")
                    return RX(p[2])
                elif p[0].value.lower() == 'ry':
                    V("RY Gate")
                    return RY(p[2])
                elif p[0].value.lower() == 'rz':
                    V("RZ Gate")
                    return RZ(p[2])
                else:
                    V(p[0])
                return p
            pass

        @self.parser_generator.production('anylist : idlist')
        @self.parser_generator.production('anylist : mixedlist')
        def anylist(p):
            x = []
            if type(p[0]) == list:
                V("anylist list", p[0])
                x = [x for x in p[0]]
                V("anylist list res", x)
            elif 'token' in str(type(p[0])):
                V('anylist token', p[0])
                x = [x for x in p]
            return x

        @self.parser_generator.production('idlist : id COMMA id')
        @self.parser_generator.production('idlist : idlist COMMA id')
        def idlist(p):
            x = []
            if type(p[0]) == list:
                V("idlist list", p[0])
                x = [x for x in p[0]]
                x.append(p[2])
                V('idlist list res', x)
            elif 'token' in str(type(p[0])):
                V('idlist token', p[0])
                x = [p[0], p[2]]
                V('idlist token res', x)
            return x

        @self.parser_generator.production(
            'mixedlist : id OPEN_BRACKET int CLOSE_BRACKET')
        @self.parser_generator.production('mixedlist : mixedlist COMMA id')
        @self.parser_generator.production(
            'mixedlist : mixedlist COMMA id OPEN_BRACKET int CLOSE_BRACKET')
        @self.parser_generator.production(
            'mixedlist : idlist COMMA id OPEN_BRACKET int CLOSE_BRACKET')
        def mixedlist(p):
            if 'token' in str(type(p[0])):
                x = [{'name': p[0], 'val': p[2]}]
            elif type(p[0]) == list:
                if len(p) == 3:
                    x = [x for x in p[0]]
                    x.append(p[2])
                else:
                    x = [x for x in p[0]]
                    x.append({'name': [2], 'val': [4]})
            V('mixedlist', x)
            return x

        @self.parser_generator.production('argument : id')
        @self.parser_generator.production('argument : real')
        @self.parser_generator.production('argument : int')
        @self.parser_generator.production('argument : anylist')
        def argument(p):
            V('arg', p)
            return p[0]

        @self.parser_generator.production('explist : expression')
        @self.parser_generator.production('explist : explist COMMA expression')
        def explist(p):
            if 'expression' in type(p[0]):
                x = [x for x in p]
            elif type(p[0]) == list:
                x = p[0]
                x.append(p[2])
            return x

        @self.parser_generator.production('expression : real')
        @self.parser_generator.production('expression : int')
        @self.parser_generator.production('expression : PI')
        @self.parser_generator.production('expression : id')
        @self.parser_generator.production(
            'expression : expression PLUS expression')
        @self.parser_generator.production(
            'expression : expression MINUS expression')
        @self.parser_generator.production(
            'expression : expression MUL expression')
        @self.parser_generator.production(
            'expression : expression DIV expression')
        @self.parser_generator.production(
            'expression : expression POW expression')
        @self.parser_generator.production(
            'expression : PAREN_OPEN expression PAREN_CLOSE')
        @self.parser_generator.production(
            'expression : unaryop PAREN_OPEN expression PAREN_CLOSE')
        def expression(p):
            V('expression', p)
            return p
            pass

        @self.parser_generator.production('unaryop : SQRT ')
        @self.parser_generator.production('unaryop : SIN ')
        @self.parser_generator.production('unaryop : COS ')
        @self.parser_generator.production('unaryop : TAN ')
        @self.parser_generator.production('unaryop : EXP ')
        @self.parser_generator.production('unaryop : LN ')
        def unaryop(p):
            V('unaryop', p)
            return p[0]

        @self.parser_generator.production('id : ID ')
        def id(p):
            V([p[x].value for x in range(len(p))])
            V('setting id', p[0].value)
            return p[0]

        @self.parser_generator.production('int : INT')
        def nnint(p):
            V('setting int', p[0].value)
            return Int(p[0].value)

        @self.parser_generator.production('real : REAL')
        def real(p):
            V('setting float', p[0].value)
            return p[0]

        @self.parser_generator.error
        def error_handle(token):
            '''"Dirty" error handling'''
            V(token)
            raise ValueError(token)

    def get_parser(self):
        '''Returns a parser generator object'''
        return self.parser_generator.build()
示例#38
0
class Pars():

    def __init__(self):
        self.pg = ParserGenerator(
            ['INCLUDE', 'LIBstdio.h', 'MAIN', 'NUMBER', 'STR', 'PRINT', 'START', 'FINISH', 'OPEN_PARENS', 'CLOSE_PARENS', 'SEMI_COLON', 'SUM', 'SUB'],
            precedence=[('left', ['SUM', 'SUB']), ]
             )

    def parse(self):

        @self.pg.production('expression : NUMBER')
        def number(p):
            return Number(int(p[0].value))

        @self.pg.production('expression : STR')
        def strings(p):
            return String(p[0].value[1:-1])

        @self.pg.production('expression : INCLUDE expression')
        def include(p):
            return p[1]

        @self.pg.production('expression : LIBstdio.h expression')
        def include(p):
            return p[1]

        @self.pg.production('expression : MAIN expression')
        def cmainc(p):
            return p[1]

        @self.pg.production('expression : START expression FINISH')
        def expression_start_finish(p):
            return p[1]

        @self.pg.production('expression : START OPEN_PARENS expression FINISH')
        def expression_open_parens(p):
            return p[1]

        @self.pg.production('expression : OPEN_PARENS expression CLOSE_PARENS')
        def expression_close_parens(p):
            return p[1]

        @self.pg.production('expression : START expression SEMI_COLON FINISH')
        def expression_semicolon(p):
            return p[1]

        @self.pg.production('expression : START expression SUM expression FINISH')
        @self.pg.production('expression : START expression SUB expression FINISH')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                return Sum(left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(left, right)

        @self.pg.production('expression : PRINT OPEN_PARENS expression CLOSE_PARENS SEMI_COLON')
        def expression(p):
            return Print(p[2])

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
            return self.pg.build()
示例#39
0
class ParserBuilder(object):
    # A list of all token names accepted by the parser.
    ACCEPTED_TOKENS = (
        'FROM',
        'IMPORT',
        'AS',
        'LET',

        'OPEN_CURLY_BRACKET',
        'CLOSE_CURLY_BRACKET',

        'FORWARD_SLASH',

        'OPEN_PAREN',
        'CLOSE_PAREN',

        'OPEN_BRACKET',
        'CLOSE_BRACKET',
        'COLON',
        'SEMICOLON',
        'COMMA',
        'PERIOD',
        'NUMBER',
        'IDENTIFIER',
        'AMINO_ACID_SEQUENCE',
        'EQUAL',
        'TILDE',
        'EXCLAMATION',
    )

    def __init__(self):
        self.pg = ParserGenerator(self.ACCEPTED_TOKENS)
        self.build_parser()

    def build_parser(self):
        """Define the parser rules."""

        # rply has it's own style which does not conform to pylint's expectations.
        # pylint: disable=W0613,C0103,W0612,C0301

        @self.pg.production('program : import_list definition_list')
        @self.pg.production('program : import_list')
        @self.pg.production('program : definition_list')
        def program(state, p):
            imports = []
            definition_list = None
            if len(p) == 2:
                # we have at least one import
                imports = p[0]
                definition_list = p[1]
            else:
                if isinstance(p[0], ast.DefinitionList):
                    definition_list = p[0]
                else:
                    imports = p[0]

            return ast.Program(imports, definition_list)

        @self.pg.production('import_list : import_list import')
        @self.pg.production('import_list : import')
        def program_import_list(state, p):
            if len(p) == 2:
                p[0].append(p[1])
                return p[0]

            return [p[0]]

        @self.pg.production('import : FROM import_module IMPORT OPEN_PAREN import_identifiers CLOSE_PAREN')
        @self.pg.production('import : FROM import_module IMPORT import_identifiers')
        def program_import(state, p):
            if len(p) == 6:
                import_module = p[1]
                import_identifiers = p[4]
            if len(p) == 4:
                import_module = p[1]
                import_identifiers = p[3]

            return ast.Import(import_module, import_identifiers)

        @self.pg.production('import_module : import_module PERIOD IDENTIFIER')
        @self.pg.production('import_module : IDENTIFIER')
        def program_import_module(state, p):
            if len(p) == 3:
                return p[0] + [p[2].value]

            return [p[0].value]

        @self.pg.production('import_identifiers : import_identifiers COMMA import_identifier')
        @self.pg.production('import_identifiers : import_identifier')
        def program_import_identifiers(state, p):
            if len(p) == 3:
                p[0].append(p[2])
                return p[0]

            return [p[0]]

        @self.pg.production('import_identifier : IDENTIFIER AS IDENTIFIER')
        @self.pg.production('import_identifier : IDENTIFIER')
        def import_identifier(state, p):
            import_identifier = p[0].value
            if len(p) == 3:
                alias_identifier = p[2].value
            else:
                alias_identifier = None

            return ast.ImportIdentifier(import_identifier, alias_identifier)

        @self.pg.production('definition_list : definition_list definition')
        @self.pg.production('definition_list : definition')
        def definition_list(state, p):
            if len(p) == 2:
                p[0].add_definition(p[1])
                return p[0]

            return ast.DefinitionList([p[0]])

        @self.pg.production('definition : variable_definition')
        @self.pg.production('definition : function_invoke')
        @self.pg.production('definition : assembly')
        def definition(state, p):
            return p[0]

        @self.pg.production('variable_definition : LET IDENTIFIER EQUAL definition_item')
        @self.pg.production('variable_definition : LET IDENTIFIER EQUAL function_invoke')
        @self.pg.production('variable_definition : LET IDENTIFIER EQUAL list_declaration')
        @self.pg.production('variable_definition : LET IDENTIFIER type_declaration EQUAL list_declaration')
        def variable_definition(state, p):
            variable_identifier = p[1].value
            if len(p) == 4:
                variable_type = None
                definition = p[3]
            elif len(p) == 5:
                variable_type = p[2]
                definition = p[4]

            return ast.VariableDeclaration(variable_identifier, variable_type, definition)

        @self.pg.production('type_declaration : OPEN_BRACKET IDENTIFIER CLOSE_BRACKET')
        def type_declaration(state, p):
            return ast.TypeDeclaration(p[1].value)

        @self.pg.production('list_declaration : OPEN_BRACKET list_items CLOSE_BRACKET')
        def list_declaration(state, p):
            return ast.ListDeclaration(p[1])

        @self.pg.production('list_items : definition_item')
        @self.pg.production('list_items : definition_item COMMA list_items')
        def list_items(state, p):
            new_list = [p[0]]
            if len(p) == 3:
                new_list.extend(p[2])
            return new_list

        @self.pg.production('definition_item : symbol_reference')
        @self.pg.production('definition_item : nucleotide_constant')
        @self.pg.production('definition_item : amino_acid_constant')
        @self.pg.production('definition_item : number_constant')
        def definition_item(state, p):
            return p[0]

        @self.pg.production('function_name_and_label : IDENTIFIER')
        @self.pg.production('function_name_and_label : IDENTIFIER COLON IDENTIFIER')
        def function_name_and_label(state, p):
            if len(p) == 3:
                # return Name and label
                return p[2].value, p[0].value

            return p[0].value, None

        @self.pg.production('function_invoke : function_name_and_label function_parameter_block')
        @self.pg.production('function_invoke : function_name_and_label OPEN_CURLY_BRACKET definition_list CLOSE_CURLY_BRACKET')
        def function_invoke(state, p):
            if len(p) == 2:
                return ast.FunctionInvocation(p[0][0], None, p[1], p[0][1])

            return ast.FunctionInvocation(p[0][0], p[2], None, p[0][1])


        @self.pg.production('function_parameter_block : OPEN_PAREN function_parameters CLOSE_PAREN')
        @self.pg.production('function_parameter_block : OPEN_PAREN CLOSE_PAREN')
        def function_param_block(state, p):
            if len(p) == 2:
                return None

            return p[1]

        @self.pg.production('function_parameters : definition_item')
        @self.pg.production('function_parameters : definition_item COMMA function_parameters')
        def function_parameters(state, p):
            x = [p[0]]
            if len(p) == 3:
                x.extend(p[2])
            return x

        @self.pg.production('assembly : assembly_list')
        @self.pg.production('assembly : IDENTIFIER COLON assembly_list')
        def assembly(state, p):
            if len(p) == 1:
                return ast.Assembly(p[0])
            elif len(p) == 3:
                return ast.Assembly(p[2], label=p[0].value)

        @self.pg.production('assembly_list : assembly_list SEMICOLON definition_item')
        @self.pg.production('assembly_list : definition_item')
        def assembly_list(state, p):
            if len(p) == 1:
                return [p[0]]
            elif len(p) == 3:
                p[0].append(p[2])
                return p[0]

        @self.pg.production('number_constant : NUMBER')
        def number_constant(state, p):
            return ast.Constant(p[0].value, NUMBER_CONSTANT)

        @self.pg.production('nucleotide_constant : FORWARD_SLASH IDENTIFIER FORWARD_SLASH')
        def nucleotide_constant(state, p):
            return ast.SequenceConstant(p[1].value, UNAMBIGUOUS_DNA_SEQUENCE)

        @self.pg.production('amino_acid_constant : FORWARD_SLASH AMINO_ACID_SEQUENCE FORWARD_SLASH')
        def protein_constant(state, p):
            return ast.SequenceConstant(p[1].value[1:], UNAMBIGUOUS_PROTEIN_SEQUENCE)

        @self.pg.production('symbol_reference : symbol_identifier OPEN_BRACKET slice_index CLOSE_BRACKET')
        @self.pg.production('symbol_reference : symbol_identifier')
        def symbol_reference(state, p):
            identifier, invert = p[0]
            part_slice = None
            if len(p) == 4:
                part_slice = p[2]

            return ast.SymbolReference(identifier, part_slice, invert)

        @self.pg.production('symbol_identifier : EXCLAMATION IDENTIFIER')
        @self.pg.production('symbol_identifier : IDENTIFIER')
        def symbol_identifier(state, p):
            if len(p) == 2:
                invert = True
                identifier = p[1].value
            else:
                invert = False
                identifier = p[0].value

            return (identifier, invert)

        @self.pg.production('slice_index : slice_position COLON slice_position')
        def index_slice(state, p):
            return ast.Slice(p[0], p[2])

        @self.pg.production('slice_position : TILDE slice_coordinates')
        @self.pg.production('slice_position : slice_coordinates')
        def slice_position(state, p):
            if len(p) == 2:
                approximate = True
                position_index, postfix = p[1]
            else:
                approximate = False
                position_index, postfix = p[0]

            return ast.SlicePosition(position_index, postfix, approximate)

        @self.pg.production('slice_coordinates : NUMBER')
        @self.pg.production('slice_coordinates : NUMBER IDENTIFIER')
        def slice_coordinates(state, p):
            position_index = int(p[0].value)
            postfix = None
            if len(p) == 2:
                postfix = p[1].value
                if postfix not in ['S', 'E']:
                    raise ParsingError('Slice postfix can only be "S" or "E"')

            return (position_index, postfix)

        @self.pg.error
        def error_handle(state, lookahead):
            raise ParsingError(
                'An error occurred parsing source document at %s' % lookahead.source_pos)

    def parse(self, tokens):
        parser = self.pg.build()

        parser_state = ParserState()
        return parser.parse(tokens, state=parser_state)
示例#40
0
    def __init__(self):
        # define the parser
        pg = ParserGenerator(
            [
                "NUMBER", "PLUS", "MINUS", "MULTIPLY", "DIVIDE", "SEMICOLON",
                "PRINT", "PRINTLN", "STRING", "EQUAL", "IDENTIFIER", "BOOLEAN",
                "LBRACE", "RBRACE", "LPAREN", "RPAREN", "IF", "ELSE",
                "BOOLEAN_AND", "BOOLEAN_OR", "EQUAL_EQUAL", "NOT_EQUAL",
                "GREATER", "LESS", "GREATER_EQUAL", "LESS_EQUAL", "WHILE",
                "FOR"
            ],
            # A list of precedence rules with ascending precedence, to
            # disambiguate ambiguous production rules.
            precedence=[
                ('left', ['LPAREN', 'RPAREN']),
                ('left', ['PLUS', 'MINUS']),
                ('left', ['MUL', 'DIV']),
                ('right', ['EQUAL']),
            ])

        # parser definition

        # top-level statements
        @pg.production("main : statements")
        def main(s):
            # return the statement block
            return s[0]

        # multiple statement statements
        @pg.production("statements : statements statement")
        def statements(s):
            return ast.Block(s[0].getASTList() + [s[1]])

        # single statement statements
        @pg.production("statements : statement")
        def statements_statement(s):
            return ast.Block([s[0]])

        # single expression statement
        @pg.production("statement : expr SEMICOLON")
        def statement_expr(s):
            return ast.Statement(s[0])

        # print/println statements
        @pg.production("statement : PRINT expr SEMICOLON")
        @pg.production("statement : PRINTLN expr SEMICOLON")
        def statement_print(s):
            return ast.PrintStatement(s[0].getstr(), s[1])

        # while statement
        # can end with semicolon or not
        @pg.production(
            "statement : WHILE LPAREN expr RPAREN LBRACE statements RBRACE SEMICOLON"
        )
        @pg.production(
            "statement : WHILE LPAREN expr RPAREN LBRACE statements RBRACE")
        def statement_while(s):
            return ast.WhileStatement(s[2], s[5])

        # for statement
        # can end with semicolon or not
        @pg.production(
            "statement : FOR LPAREN statement expr SEMICOLON statement RPAREN LBRACE statements RBRACE SEMICOLON"
        )
        @pg.production(
            "statement : FOR LPAREN statement expr SEMICOLON statement RPAREN LBRACE statements RBRACE"
        )
        def statement_for(s):
            return ast.ForStatement(s[2], s[3], s[5], s[8])

        # parenthese support for expressions
        # not working
        @pg.production("val : LPAREN expr RPAREN")
        def expr_parens(s):
            return ast.ParentheseValue(s[1])

        # assignment expression
        @pg.production("expr : expr EQUAL expr")
        def expr_assignment(s):
            return ast.AssignmentExpression(s[0], s[2])

        # binary operator expressions
        # algebratic operations -> return number
        @pg.production("expr : expr PLUS expr")
        @pg.production("expr : expr MINUS expr")
        @pg.production("expr : expr MULTIPLY expr")
        @pg.production("expr : expr DIVIDE expr")
        # boolean operations -> return boolean
        @pg.production("expr : expr BOOLEAN_OR expr")
        @pg.production("expr : expr BOOLEAN_AND expr")
        # number operations -> return boolean
        @pg.production("expr : expr GREATER_EQUAL expr")
        @pg.production("expr : expr LESS_EQUAL expr")
        @pg.production("expr : expr GREATER expr")
        @pg.production("expr : expr LESS expr")
        # for both number and booleans -> return boolean
        @pg.production("expr : expr EQUAL_EQUAL expr")
        @pg.production("expr : expr NOT_EQUAL expr")
        def expr_binop(s):
            return ast.BinaryOperator(s[1].getstr(), s[0], s[2])

        # single value/identifier expression
        @pg.production("expr : val")
        def expr_val(s):
            return ast.Expr(s[0])

        # single identifier expression
        @pg.production("expr : IDENTIFIER")
        def expr_id(s):
            return ast.Expr(ast.Identifier(s[0].getstr()))

        # single if expression, body of if expression can be either statements or expression
        # if expression is evaluated to Null if the body are statements
        # body must be consistent, which means all the clause has to be either expressions or statements
        # don't forget semicolor at the end of the if block
        @pg.production("expr : IF LPAREN expr RPAREN LBRACE expr RBRACE ")
        @pg.production("expr : IF LPAREN expr RPAREN LBRACE statements RBRACE")
        def expr_if(s):
            return ast.IfExpression(s[2], s[5])

        # if - else if - else expression. Else - if is optional
        @pg.production(
            "expr : IF LPAREN expr RPAREN LBRACE expr RBRACE else-if-body-list else-body"
        )
        @pg.production(
            "expr : IF LPAREN expr RPAREN LBRACE statements RBRACE else-if-body-list else-body"
        )
        def expr_if_elseif_else(s):
            return ast.IfElseIfElseExpression(s[2], s[5], s[7], s[8])

        # if - else expression. DO NOT INCLUDE else if body lists (put placeholder empty else if body list)
        @pg.production(
            "expr : IF LPAREN expr RPAREN LBRACE expr RBRACE else-body")
        @pg.production(
            "expr : IF LPAREN expr RPAREN LBRACE statements RBRACE else-body")
        def expr_if_else(s):
            return ast.IfElseIfElseExpression(s[2], s[5],
                                              ast.ElseIfBodyList([]), s[7])

        # define the else if body in the case of multiple (one or more) else - if expressions
        @pg.production("else-if-body-list : else-if-body-list else-if-body")
        @pg.production("else-if-body-list : else-if-body-list else-if-body")
        def expr_else_if_body_list(s):
            return ast.ElseIfBodyList(s[0].getASTList() + [s[1]])

        # define a single else-if-body as a else-if-body-list
        @pg.production("else-if-body-list : else-if-body")
        def expr_else_if_body_list__else_if_body(s):
            return ast.ElseIfBodyList([s[0]])

        @pg.production(
            "else-if-body : ELSE IF LPAREN expr RPAREN LBRACE expr RBRACE")
        @pg.production(
            "else-if-body : ELSE IF LPAREN expr RPAREN LBRACE statements RBRACE"
        )
        def expr_else_if_body(s):
            return ast.ElseIfBody(s[3], s[6])

        # define the else body
        @pg.production("else-body : ELSE LBRACE expr RBRACE")
        @pg.production("else-body : ELSE LBRACE statements RBRACE")
        def expr_else_body(s):
            return ast.ElseBody(s[2])

        # number value
        @pg.production("val : NUMBER")
        def val_number(s):
            return ast.Number(float(s[0].getstr()))

        # string value
        @pg.production("val : STRING")
        def val_string(s):
            return ast.String(s[0].getstr())

        # boolean value
        @pg.production("val : BOOLEAN")
        def val_boolean(s):
            return ast.Boolean(s[0].getstr())

        # build the parser
        self.parser = pg.build()
示例#41
0
class Parser():
    def __init__(self, state):
        self.state = state
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            [
                'NUMBER', 'DOT', 'COMMA', 'HYPHEN', 'OPEN_PAREN',
                'CLOSE_PAREN', 'ATHOM', 'DEF_BASE', 'DEF_NOT', 'NOT', 'IFF',
                'IMPLIE', 'AND', 'OR', 'DEF_IFF', 'DEF_IMPLIE', 'DEF_AND',
                'DEF_OR'
            ],
            precedence=[('left', ['NOT', 'AND', 'OR', 'IMPLIE', 'IFF'])])
        self.variables = {}
        self.formule_latex = ''
        self.error = {'messages': []}

    def parse(self):
        @self.pg.production('program : steps')
        def program(p):
            data = {}

            if len(self.error['messages']):
                firstMessage = 'Os seguintes erros foram encontrados:'

                data["status"] = "error"
                data["firstMessage"] = firstMessage

                error_number = 1
                errorList = []

                for error_message in self.error['messages']:
                    errorList.append('Erro {}: {}'.format(
                        error_number, error_message))
                    error_number += 1

                data["errorList"] = errorList
                data["errorNumber"] = error_number
            else:
                firstMessage = 'Fórmulas estão corretas. Código látex:'

                data["status"] = 'ok'
                data["firstMessage"] = firstMessage

                latex = '\\[\n' + self.variables[list(
                    self.variables)[-1]][0].toLatex() + '\\]\n'

                data["latex"] = latex

            fileHandle(data)

        @self.pg.production('steps : steps step')
        @self.pg.production('steps : step')
        def steps(p):
            return self.variables

        @self.pg.production('step : NUMBER DOT ATHOM athoms DEF_BASE')
        def step_base(p):
            number_line = p[0].value
            athoms = [p[2].value] + p[3]

            if number_line in self.variables:
                for athom in athoms:
                    self.variables[number_line].append(
                        BinaryFormule(key=athom))
                source_position = p[0].getsourcepos()
                line_error = source_position.lineno
                self.set_error(1, line_error, number_line)
                return

            self.variables[number_line] = []
            for athom in athoms:
                self.variables[number_line].append(BinaryFormule(key=athom))

        @self.pg.production('step : NUMBER DOT formule DEF_NOT NUMBER')
        def step_negation(p):
            number_line = p[0].value
            formule = p[2]

            source_position = p[0].getsourcepos()
            line_error = source_position.lineno

            if isinstance(formule, BinaryFormule):
                self.variables[number_line] = [formule]
                self.set_error(3, line_error, formule.toString())
                return

            if number_line in self.variables:
                self.variables[number_line] = self.variables[number_line] + [
                    formule
                ]

                self.set_error(1, line_error, number_line)
                return

            if not (p[4].value in self.variables):
                self.variables[number_line] = [formule]
                self.set_error(2, line_error, p[4].value)
                return

            self.variables[number_line] = [formule]
            if not (negationDef().eval(formule, p[4].value, self.variables)):
                self.set_error(4, line_error, formule.toString())

        @self.pg.production(
            'step : NUMBER DOT formule DEF_AND NUMBER HYPHEN NUMBER')
        @self.pg.production(
            'step : NUMBER DOT formule DEF_OR NUMBER HYPHEN NUMBER')
        @self.pg.production(
            'step : NUMBER DOT formule DEF_IMPLIE NUMBER HYPHEN NUMBER')
        @self.pg.production(
            'step : NUMBER DOT formule DEF_IFF NUMBER HYPHEN NUMBER')
        def step(p):
            formule = p[2]
            operator = formule.key

            line_error = p[0].getsourcepos().lineno

            number_line = p[0].value

            used_formule1_line = p[4].value
            used_formule2_line = p[6].value

            if number_line in self.variables:
                self.variables[number_line] = self.variables[number_line] + [
                    formule
                ]
                self.set_error(1, line_error, number_line)
                return

            if not (used_formule1_line in self.variables):
                self.variables[number_line] = [formule]
                self.set_error(2, line_error, used_formule1_line)
                return

            if not (used_formule2_line in self.variables):
                self.variables[number_line] = [formule]
                self.set_error(2, line_error, used_formule2_line)
                return

            self.variables[number_line] = [formule]
            result = binaryDef().eval(p[2], operator, used_formule1_line,
                                      used_formule2_line, self.variables)
            if result == 0:
                self.set_error(0, line_error, formule.left.toString())
            elif result == 1:
                self.set_error(0, line_error, formule.right.toString())

        @self.pg.production('formule : NOT formule')
        @self.pg.production('formule : ATHOM')
        @self.pg.production('formule : formule AND formule')
        @self.pg.production('formule : formule OR formule')
        @self.pg.production('formule : formule IMPLIE formule')
        @self.pg.production('formule : formule IFF formule')
        def formule(p):
            if len(p) < 3:
                if p[0].gettokentype() == 'ATHOM':
                    return BinaryFormule(key=p[0].value)
                if p[0].gettokentype() == 'NOT':
                    return UnaryFormule(key=p[1])
            else:
                return BinaryFormule(key=p[1].value, left=p[0], right=p[2])

        @self.pg.production('formule : OPEN_PAREN formule CLOSE_PAREN')
        def paren_formule(p):
            return p[1]

        @self.pg.production('athoms : COMMA ATHOM athoms')
        @self.pg.production('athoms : ')
        def athoms(p):
            if (len(p) == 0):
                return []
            else:
                return [p[1].value] + p[2]

        @self.pg.error
        def error_handle(token):
            productions = self.state.splitlines()
            error = ''
            if (productions == ['']):
                error = 'Nenhuma demonstração foi recebida, verifique a entrada.'
            if token.gettokentype() == '$end':
                error = 'Uma das definições não está completa, verifica se todas regras foram aplicadas corretamente.'
            else:
                source_position = token.getsourcepos()
                line = source_position.lineno
                error = "token {} não esperado na linha {}: {}".format(
                    token.value, line, productions[line - 1])

            data = {
                'status': 'error',
                'firstMessage': 'O seguinte erro foi encontrado',
                'error': error
            }

            fileHandle(data)

            raise ValueError(error)

    def set_error(self, type, line_error, token_error):
        productions = self.state.splitlines()
        if type == 0:
            self.error['messages'].append(
                "A fórmula {} não foi definido anteriormente, na linha {}: {}".
                format(token_error, line_error, productions[line_error - 1]))
        elif type == 1:
            self.error['messages'].append(
                "Número {} já foi definido antes da linha {}: {}".format(
                    token_error, line_error, productions[line_error - 1]))
        elif type == 2:
            self.error['messages'].append(
                "linha não definida {} referenciado na linha {}: {}".format(
                    token_error, line_error, productions[line_error - 1]))
        elif type == 3:
            self.error['messages'].append(
                "Fórmula {} é binaria, quando o esperado é uma negação, na linha {}: {}"
                .format(token_error, line_error, productions[line_error - 1]))
        else:
            self.error['messages'].append(
                "Fórmula {} utilizado na linha {} não foi definido anteriormente: {}"
                .format(token_error[1:], line_error,
                        productions[line_error - 1]))

    def get_parser(self):
        return self.pg.build()
示例#42
0
@PG.production("charge : + DIGIT")
def charge_production_plus_many(p):
    "+D"
    return +int_from_digit(p[1])


##### ATOM CLASS #####


# class ::= ':' NUMBER
# class :: int
@PG.production("class : colon NUMBER")
def class_production(p):
    "return :: int."
    return p[1]


@PG.error
def error_handler(token, expected=None):
    "Handle parser errors."
    if DEBUG:
        raise ValueError(("Ran into a %s (%s) where it wasn't expected."+\
            "At %s. Instead expected: %s.") % (repr(token.name), \
            repr(token.value), dictof(token.source_pos), repr(expected)))
    else:
        print "Warning: parser error"


LEXER = LG.build()
PARSER = PG.build()
示例#43
0
class Parserr():
    def __init__(self, module, builder, printf , name):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            ['DECLARE', 'EQUAL', 'NUMBER', 'INC', 'DEC', 'OPEN_PAREN',
             'CLOSE_PAREN', 'SEMI_COLON', 'COMMA', 'COMMENT', 'TEXT', 'INCLI',
             'CALL', 'PROCEDURE', 'BEGIN', 'END', 'BRIGHT', 'VIB', 'MOV',
             'FOR', 'FEND', 'TIMES', 'TEMP', 'OBJ', 'SOUND', 'CASE',
             'WHEN', 'THEN','ELSE', 'END_CASE','DOW', 'ENDDO']
        )
        self.module = module
        self.builder = builder
        self.printf = printf
        
        self.comment = ""
        self.case = ""
        self.dow = ""
        self.procedures = []
        self.token = 0
        self.arguments = []
        self.declarations = []
        self.fort = ""
        self.whenDec = []
        
        self.name = name

    def parse(self):
        @self.pg.production('x : ')
        @self.pg.production('x : x program')
        @self.pg.production('program : program  y')
        def program(p):
            return [self.declarations,self.procedures, self.name]
        
        @self.pg.production('program : ')
        def programE(p):
            return 
        
        # Declare
        @self.pg.production('y : DECLARE TEXT EQUAL NUMBER SEMI_COLON')
        def declare(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                if len(p[1].value) > 10:
                    raise SystemExit("Supera las 10 posiciones")
                    return
                if (p[1].value).islower() == True:
                    dCopy = self.declarations
                    for i in dCopy:
                        if(i.name == p[1].value): 
                            raise SystemExit("Ya existe una variable con ese nombre")
                            return
                    self.declarations.append(Variable(p[1].value, p[3].value))
                    self.token = 2
            elif self.token == 2:
                if len(p[1].value) > 10:
                    raise SystemExit("Supera las 10 posiciones")
                    return
                if (p[1].value).islower() == True:
                    dCopy = self.declarations
                    for i in dCopy:
                        if(i.name == p[1].value): 
                            raise SystemExit("Ya existe una variable con ese nombre")
                            return
                    self.declarations.append(Variable(p[1].value, p[3].value))
            elif self.token == -3:
                if len(p[1].value) > 10:
                    raise SystemExit("Supera las 10 posiciones")
                    return
                if (p[1].value).islower() == True:
                    dCopy = self.declarations
                    for i in dCopy:
                        if(i.name == p[1].value): 
                            raise SystemExit("Ya existe una variable con ese nombre")
                            return
                    (self.procedures[len(self.procedures) - 1]).declaration.append(Variable(p[1].value, p[3].value))
            elif self.token == 4:
                raise SystemExit("DECLARE esta fuera de un procedimiento")
                return
            elif self.token == 6:
                if self.fort.token == 3:
                    raise SystemExit("No se pueden hacer declaraciones en el For")
                    return
            
        @self.pg.production('y : DECLARE TEXT SEMI_COLON')
        def emptyDeclare(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                if len(p[1].value) > 10:
                    raise SystemExit("Supera las 10 posiciones")
                    return
                if (p[1].value).islower() == True:
                    dCopy = self.declarations
                    for i in dCopy:
                        if(i.name == p[1].value): 
                            raise SystemExit("Ya existe una variable con ese nombre")
                            return
                    self.declarations.append(Variable(p[1].value))
                    self.token = 2
            elif self.token == 2:
                if len(p[1].value) > 10:
                    raise SystemExit("Supera las 10 posiciones")
                    return
                if (p[1].value).islower() == True:
                    dCopy = self.declarations
                    for i in dCopy:
                        if(i.name == p[1].value): 
                            raise SystemExit("Ya existe una variable con ese nombre")
                            return
                    self.declarations.append(Variable(p[1].value))
            
            elif self.token == -3:
                if len(p[1].value) > 10:
                    raise SystemExit("Supera las 10 posiciones")
                    return
                if (p[1].value).islower() == True:
                    dCopy = (self.procedures[len(self.procedures) - 1]).declaration
                    for i in dCopy:
                        if(i.name == p[1].value): 
                            raise SystemExit("Ya existe una variable con ese nombre")
                            return
                    (self.procedures[len(self.procedures) - 1]).declaration.append(Variable(p[1].value))
            elif self.token == 4:
                raise SystemExit("DECLARE esta fuera de un procedimiento")
                return
            elif self.token == 6:
                if self.fort.token == 3:
                    raise SystemExit("No se pueden hacer declaraciones en el For")
                    return

        @self.pg.production('y : TEXT EQUAL NUMBER SEMI_COLON')
        def reDeclare(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("DECLARE esta fuera de un procedimiento")
                return
            elif self.token == -3:
                (self.procedures[len(self.procedures) - 1]).array.append(Variable(p[0].value,p[2].value))
                self.token = 3
                return
            elif self.token == 3:
                (self.procedures[len(self.procedures) - 1]).array.append(Variable(p[0].value,p[2].value))
                return
            elif self.token == 4:
                raise SystemExit("DECLARE esta fuera de un procedimiento")
                return
            elif self.token == 6:
                (self.fort.cycle).append(Variable(p[0].value,p[2].value))
                return
            elif self.token == -6:
                (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Variable(p[0].value,p[2].value))
                return
        
        # Case
        @self.pg.production('y : CASE')
        def case(p):
            if(self.token == 8):
                self.case.whenDec[len(self.case.whenDec) - 1].function.append(Case(self.token))
                self.token = -8
            else:
                if(self.token == 3 or self.token == -3):
                    self.case = Case(3)
                    self.token = 7
            return

        @self.pg.production('y : WHEN TEXT EQUAL NUMBER THEN')
        def caseWhen(p):
            if(self.token == -8):
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec.append(When(p[1].value, p[3].value))
            else:   
                self.case.whenDec.append(When(p[1].value, p[3].value))
                self.token = 8
            return

        @self.pg.production('y : ELSE')
        def caseElse(p): 
            if(self.token == -8):
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec.append(When(None, None))
            else:
                self.case.whenDec.append(When(None, None))
                self.token = 8
            return

        @self.pg.production('y : END_CASE SEMI_COLON')
        def caseEnd(p):
            if(self.case.cToken == 3):                
                self.procedures[len(self.procedures) - 1].array.append(self.case)
                self.token = 3

            elif(self.token == -8):
                self.token = 8

            print("END")
            return
        
        # Incremento
        @self.pg.production('y : INC OPEN_PAREN TEXT COMMA NUMBER CLOSE_PAREN SEMI_COLON')
        def IncP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Inc() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                left = p[2].value
                right = Number(p[4].value)
                self.token = 3
                self.name = self.name + "r"
                return (self.procedures[len(self.procedures) - 1]).array.append(Inc(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 3:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Inc(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 4:
                raise SystemExit("Inc() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Inc(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == -6:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Inc(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 8:
                left = p[2].value
                right = Number(p[4].value)
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Inc(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == -8:
                left = p[2].value
                right = Number(p[4].value)
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Inc(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 9:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r"
                return (self.dow.function.append(Inc(self.builder, self.module,self.printf,left, right, self.name)))
            elif self.token == -9:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Inc(self.builder, self.module,self.printf,left, right, self.name)))
            
        # Decremento
        @self.pg.production('y : DEC OPEN_PAREN TEXT COMMA NUMBER CLOSE_PAREN SEMI_COLON')
        def DecP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Dec() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                left = p[2].value
                right = Number(p[4].value)
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Dec(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 3:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Dec(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 4:
                raise SystemExit("Dec() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Dec(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == -6:
                left = p[2].value
                right = Number(p[4].value)
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Dec(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 8:
                left = p[2].value
                right = Number(p[4].value)
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Dec(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == -8:
                left = p[2].value
                right = Number(p[4].value)
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Dec(self.builder, self.module,self.printf,left, right, self.name))
            elif self.token == 9:
                left = Number(p[2].value)
                right = Number(p[4].value)
                self.name = self.name + "r"
                return (self.dow.function.append(Dec(self.builder, self.module,self.printf,left, right, self.name)))
            elif self.token == -9:
                left = Number(p[2].value)
                right = Number(p[4].value)
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Dec(self.builder, self.module,self.printf,left, right, self.name)))
            
        # Comentario
        @self.pg.production('y : COMMENT z')
        def CommentP(p):
            print("Comment: " + self.comment[1:len(self.comment)])
            self.comment = ""
            if self.token == 0:
                self.token = 1
            return 
         
        @self.pg.production('z : z TEXT')
        def CommentPI(p):
            self.comment += " " + str(p[1].value)
            return
         
        @self.pg.production('z : ')
        def CommentPE(p):
             return 
        
        # Inclinacion
        @self.pg.production('y : INCLI OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def InclinationP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Inclination() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Inclination(self.builder,self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Inclination() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Inclination(self.builder, self.module,self.printf,p[2].value,self.name)))
            
        # Object
        @self.pg.production('y : OBJ OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def ObjectP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Object() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Object(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Object(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Object() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Object(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Object(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                self.name = self.name + "r"
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Object(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                self.name = self.name + "r"
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Object(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Object(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Object(self.builder, self.module,self.printf,p[2].value,self.name)))
        
        # Sounds
        @self.pg.production('y : SOUND OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def SoundsP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Sounds() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Sounds() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                self.name = self.name + "r"
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                self.name = self.name + "r"
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Sounds(self.builder, self.module,self.printf,p[2].value,self.name)))
            
        
        #Iluminacion
        @self.pg.production('y : BRIGHT OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def BrightnessP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Brightness() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Brightness(self.builder,self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Brightness() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                self.name = self.name + "r"
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                self.name = self.name + "r"
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Brightness(self.builder, self.module,self.printf,p[2].value,self.name)))
            
        # Temperature
        @self.pg.production('y : TEMP OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def TemperatureP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Temperature() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Temperature() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                self.name = self.name + "r"
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                self.name = self.name + "r"
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Temperature(self.builder, self.module,self.printf,p[2].value,self.name)))
            
        #Vibracion
        @self.pg.production('y : VIB OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def VibrationP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Vibration() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Vibration(self.builder,self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Vibration() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                self.name = self.name + "r"
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                self.name = self.name + "r"
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Vibration(self.builder, self.module,self.printf,p[2].value,self.name)))
            
        #Movimientos
        @self.pg.production('y : MOV OPEN_PAREN TEXT CLOSE_PAREN SEMI_COLON')
        def MoveP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Move() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Move(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 3:
                self.name = self.name + "r" 
                return (self.procedures[len(self.procedures) - 1]).array.append(Move(self.builder,self.module,self.printf,p[2].value,self.name))
            elif self.token == 4:
                raise SystemExit("Move() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                self.name = self.name + "r" 
                return (self.fort.cycle).append(Move(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -6:
                self.name = self.name + "r" 
                return (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Move(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 8:
                self.name = self.name + "r"
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Move(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == -8:
                self.name = self.name + "r"
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Move(self.builder, self.module,self.printf,p[2].value,self.name))
            elif self.token == 9:
                self.name = self.name + "r"
                return (self.dow.function.append(Move(self.builder, self.module,self.printf,p[2].value,self.name)))
            elif self.token == -9:
                self.name = self.name + "r"
                return (self.dow.function[len(self.dow.function)-1].function.append(Move(self.builder, self.module,self.printf,p[2].value,self.name)))
            
        # Call
        @self.pg.production('y : CALL TEXT SEMI_COLON')
        def CallNP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Call esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                return (self.procedures[len(self.procedures) - 1]).array.append(Call(p[1].value))
            elif self.token == 3:
                return (self.procedures[len(self.procedures) - 1]).array.append(Call(p[1].value))
            elif self.token == 4:
                raise SystemExit("Call esta fuera de un procedimiento")
                return
            elif self.token == 6:
                return (self.fort.cycle).append(Call(p[1].value))
            elif self.token == -6:
                (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Call(p[1].value))
                return
            elif self.token == 8:
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Call(p[1].value))
            elif self.token == -8:
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                return (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Call(p[1].value))
            elif self.token == 9:
                return (self.dow.function.append(Call(p[1].value)))
            elif self.token == -9:
                return (self.dow.function[len(self.dow.function)-1].function.append(Call(p[1].value)))
            
        @self.pg.production('y : CALL TEXT OPEN_PAREN args CLOSE_PAREN SEMI_COLON')
        def CallEP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("Call() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.token = 3
                (self.procedures[len(self.procedures) - 1]).array.append(Call(p[1].value, self.arguments))
                self.arguments = []
                return
            elif self.token == 3:
                (self.procedures[len(self.procedures) - 1]).array.append(Call(p[1].value, self.arguments))
                self.arguments = []
                return
            elif self.token == 4:
                raise SystemExit("Call() esta fuera de un procedimiento")
                return
            elif self.token == 6:
                (self.fort.cycle).append(Call(p[1].value, self.arguments))
                self.arguments = []
                return
            elif self.token == -6:
                (self.fort.cycle[len(self.fort.cycle) -1]).cycle.append(Call(p[1].value, self.arguments))
                self.arguments = []
                return
            elif self.token == 8:
                (self.case.whenDec[len(self.case.whenDec) - 1]).function.append(Call(p[1].value, self.argument))
                self.arguments = []
                return
            elif self.token == -8:
                i = len(self.case.whenDec[len(self.case.whenDec) - 1].function) - 1
                j = len(self.case.whenDec[len(self.case.whenDec) - 1].function[i].whenDec) - 1
                (self.case.whenDec[len(self.case.whenDec) - 1]).function[i].whenDec[j].function.append(Call(p[1].value, self.argument))
                self.arguments = []
                return 
            elif self.token == 9:
                return (self.dow.function.append(Call(p[1].value, self.argument)))
            elif self.token == -9:
                return (self.dow.function[len(self.dow.function)-1].function.append(Call(p[1].value, self.argument)))
            
        # For
        @self.pg.production('y : FOR NUMBER TIMES')
        def ForP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                raise SystemExit("For() esta fuera de un procedimiento")
                return
            elif self.token == -3:
                self.fort = For(p[1].value,3)
                (self.procedures[len(self.procedures) - 1]).array.append(self.fort)
                self.token = 6
                return
            elif self.token == 3:
                self.fort = For(p[1].value,self.token)
                (self.procedures[len(self.procedures) - 1]).array.append(self.fort)
                self.token = 6
                return
            elif self.token == 4:
                raise SystemExit("For() esta fuera de un procedimiento")
                return
            # revisar
            elif self.token == 6:
                (self.fort.cycle).append(For(p[1].value,self.token))
                self.token == -6
                return
            
        #FEnd
        @self.pg.production('y : FEND SEMI_COLON')
        def FEndP(p):
            if self.token == -6:
                self.token = (self.fort.cycle[len(self.fort.cycle) -1]).token
            elif self.token == 6:
                if self.fort.token == 3:
                    self.token = self.fort.token
            return
        
        # Procedure Begin
        @self.pg.production('y : PROCEDURE TEXT OPEN_PAREN args CLOSE_PAREN BEGIN')
        def prodNP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                self.procedures.append(Procedure(p[1].value, self.arguments))
                self.token = -3;
                self.arguments = []
                return
            elif self.token == 3:
                raise SystemExit("No se puede crear un procedimiento dentro de otro")
                return
            elif self.token == 4:
                self.procedures.append(Procedure(p[1].value, self.arguments))
                self.token = -3;
                self.arguments = []
                return
            elif self.token == 6:
                raise SystemExit("No se puede hacer un procedimiento dentro de un For")
                return
        
        @self.pg.production('y : PROCEDURE TEXT OPEN_PAREN CLOSE_PAREN BEGIN')
        def prodP(p):
            if self.token == 0:
                raise SystemExit("No se ha puesto un comentario al inicio")
                return
            elif self.token == 1:
                raise SystemExit("No se han declarado variables")
                return
            elif self.token == 2:
                self.procedures.append(Procedure(p[1].value))
                self.token = -3;
                return
            elif self.token == 3:
                raise SystemExit("No se puede crear un procedimiento dentro de otro")
                return
            elif self.token == 4:
                self.procedures.append(Procedure(p[1].value))
                self.token = -3;
                return
            elif self.token == 6:
                raise SystemExit("No se puede hacer un procedimiento dentro de un For")
                return
        
        # Procedure End
        @self.pg.production('y : END SEMI_COLON')
        def prodEP(p):
            if self.token == 3:
                self.token = 4;
                return (self.procedures[len(self.procedures) - 1])
            elif self.token == -3:
                self.token = 4;
                return (self.procedures[len(self.procedures) - 1])
            
        # Dow
        @self.pg.production('y : DOW OPEN_PAREN TEXT COMMA NUMBER COMMA NUMBER COMMA NUMBER CLOSE_PAREN')
        def dowN(p):
            miVar = p[2].value
            valIni = (p[4].value)
            increment = (p[6].value)
            valFin = (p[8].value)
            if self.token == 9:
                self.dow.function.append(Dow(miVar,valIni,increment,valFin,self.token))
                self.token = -9
            else:
                self.dow = Dow(miVar,valIni,increment,valFin,self.token)
                self.token=9
                return 

        @self.pg.production('y : ENDDO SEMI_COLON')
        def dowe(p):
            if self.token == -9:
                self.token = 9
            elif self.dow.token == -3:
                self.token = 3
                self.procedures[len(self.procedures) - 1].array.append(self.dow)
        
        # Argumentos
        @self.pg.production('args : TEXT COMMA args')
        def argsC(p):
            self.arguments.append(p[0].value)
            return
        
        @self.pg.production('args : TEXT')
        def args(p):
            self.arguments.append(p[0].value)
            return
        
        # Error
        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#44
0
文件: parser.py 项目: cdinu/StackVM
@pg.production('expr : NUMBER')
def expression_number(p):
    return ast.Number(int(p[0].getstr()))


@pg.production('expr : LPAREN expr RPAREN')
def expression_parens(p):
    return p[1]


@pg.production('expr : ADD expr expr')
@pg.production('expr : SUBSTRACT expr expr')
@pg.production('expr : MULTIPLY expr expr')
@pg.production('expr : DIVIDE expr expr')
def expression_binop(p):
    left = p[1]
    right = p[2]
    if p[0].gettokentype() == 'ADD':
        return ast.Add(left, right)
    elif p[0].gettokentype() == 'SUBSTRACT':
        return ast.Substract(left, right)
    elif p[0].gettokentype() == 'MULTIPLY':
        return ast.Multiply(left, right)
    elif p[0].gettokentype() == 'DIVIDE':
        return ast.Divide(left, right)
    else:
        raise AssertionError('Oops, this should not be possible!')


parser = pg.build()
示例#45
0
class Parser():
    def __init__(self, module, builder, printf, scanf, definations = {}):
        self.pg = ParserGenerator(
            # Tokens that can be accepted by our parser
            ['NUMBER', 'WRITE', 'WRITELN', 'OPEN_PAREN', 'CLOSE_PAREN',
             'SEMI_COLON', 'SUM', 'SUB','MUL','DIV','MOD', 'VAR', 'ASSIGN',
             'AND', 'OR', 'NOT', 'TRUE', 'FALSE',
             'EQUALS', 'LESS', 'GREATER', 'LESS_EQ', 'GREAT_EQ', 'NOT_EQUALS',
             'COMMA', 'STRING', 'IF', 'ELSE', 'OPEN_CURLY', 'CLOSE_CURLY',
             'NOPS','FUNCTION', 'RETURN', 'FOR', 'INPUT', 'WHILE'
             ],
            
             
             ## Defining the precedence of operators in language
             precedence = [
                ('left', ['SUM', 'SUB']),
                ('left', ['MUL', 'DIV']),
                ('left', ['MOD'])
            ]
        )

        ## Setting the module, builder and printf system call reference
        self.module = module
        self.builder = builder
        self.printf = printf
        self.scanf = scanf

        ## Initializing the defaults constructs for our language
        ## Like a global string called True, False etc.
        initialize(builder, module, definations)

        self.constants = {}
        self.constants['false'] = self.builder.bitcast(globalFalse, globalVoidPtr)
        self.constants['true'] = self.builder.bitcast(globalTrue, globalVoidPtr)
        self.constants['int'] = self.builder.bitcast(globalInt, globalVoidPtr)




    '''
        Method that does the actual parsing
    '''
    def parse(self):
        ## a program is a list of statements
        @self.pg.production('program : statements')
        def program(p):
            return Statements(self.builder, self.module, p)


        ## statements is either onestatemnt or statements followed by onestatemnt
        @self.pg.production('statements : onestatement')
        @self.pg.production('statements : statements onestatement')
        def statements(p):
            return Line(self.builder, self.module, p)

        
        ## onestatement represents every single line possible in our code
        ## onestatement consist of two type of constructs
        ##          for and if statement which don't end with semicolon
        ##          semicolon statement followed by SEMI_COLON token. ';'
        @self.pg.production('onestatement : forstatement')
        @self.pg.production('onestatement : ifelsestatement')
        @self.pg.production('onestatement : whilestatement')
        @self.pg.production('onestatement : semicolon SEMI_COLON')
        def onestatement(p):
            return Line(self.builder, self.module, p[0])


        ## These are the group of statemetns that actually require to end with semi colon
        ## Consist of 
        ##          list of all the statemnets constructs in our language
        @self.pg.production('semicolon : noopsstatement')
        @self.pg.production('semicolon : functiondefination')
        @self.pg.production('semicolon : returnstatement')
        @self.pg.production('semicolon : inputstatement')
        @self.pg.production('semicolon : functioncall')
        @self.pg.production('semicolon : writestatement')
        @self.pg.production('semicolon : writelnstatement')
        @self.pg.production('semicolon : assignmentstatement')
        def semicolonstatement(p):
            return p[0]





        '''
        ------- All Statements in the language -----------
        '''

        ## There is a keyword called 'nothing' in our language
        ## The need for this is that sometimes make a if condition 
        ## but don't know what to do as of now. Leaving a block empty throws error.
        ## So, you can write 'nothing;' which is a valid construct and also 
        ## as the name suggests does nothing :)
        @self.pg.production('noopsstatement : NOPS')
        def noopsstatement(p):
            ## Passing empty list thus adding no construct to the code
            return Line(self.builder, self.module, [])
            


        ## Function defination is supposed to be a prototype. 
        ##          it is supposed to be like 
        ##          function name(args*)
        @self.pg.production('functiondefination : FUNCTION VAR OPEN_PAREN argslist CLOSE_PAREN')
        @self.pg.production('functiondefination : FUNCTION VAR OPEN_PAREN CLOSE_PAREN')
        def functiondefination(p):
            if len(p) == 4:
                ## If len is 4 that means we have no arguments in the function
                ## p[1].value is the name of the function
                return DefineFunction(self.builder, self.module, self.printf, self.scanf, p[1].value, [])
            else:
                ## p[3] is supposed to give argslist in the next case
                return DefineFunction(self.builder, self.module, self.printf, self.scanf, p[1].value, p[3])


        
        ## arglist is collection of variable names separated by ,
        ## like a, b, c
        @self.pg.production('argslist : VAR')
        @self.pg.production('argslist : argslist COMMA VAR')
        def argslist(p):
            if len(p) == 1:
                return p[0].value
            
            else:
                ## Flattening the args list
                ## It is used because in case of multpile args the array can be recursive
                ## So, it picks every element to same depth
                values = p[:-1:2]
                if type(values[0]) == list:
                    values[0].append(p[-1].value)
                    return values[0]
                else:
                    values.append(p[-1].value)
                    return values

        
        ## The return statement can be used to return an evaluated expression
        @self.pg.production('returnstatement : RETURN expression')
        def returnstatement(p):
            return ReturnValue(self.builder, self.module, p[1])


        ## assignment statements can be used to assign a value to a variable
        ## Also, not that our language can detect if the variable is declared on not
        ## and declare it for you automatically :)
        @self.pg.production('assignmentstatement : VAR ASSIGN expression')
        @self.pg.production('assignmentstatement : VAR ASSIGN functioncall')
        def assignmentstatement(p):
            return Assign(self.builder, self.module, p[0].value, p[2])





        ## write takes a list of printable statements and prints it one by one
        ## Eg : write(2, 2 == 2, "Rahul")
        ## should print 2 True Rahul in console
        @self.pg.production('writestatement : WRITE OPEN_PAREN printstatement CLOSE_PAREN')
        def writestatement(p):
            return Line(self.builder, self.module, p[2])

        ## writeln is same as write but adds a newline after all values have been printed
        @self.pg.production('writelnstatement : WRITELN OPEN_PAREN printstatement CLOSE_PAREN')
        def writelnstatement(p):
            withnewline = p[2].value
            ## Append a Write commant to print \n at the end of previous list
            withnewline.append(Write(self.builder, self.module, self.printf, String("\n", trim = False), self.constants))
            return Line(self.builder, self.module, withnewline)


        @self.pg.production('inputstatement : INPUT OPEN_PAREN VAR CLOSE_PAREN')
        def inputstatement(p):
            return Input(self.builder, self.module, self.scanf, p[2].value, self.constants)

        ## printstatement is a list of printable statements comma separated
        @self.pg.production('printstatement : oneprintstatement')
        @self.pg.production('printstatement : printstatement COMMA oneprintstatement')
        def printstatement(p):
            return Line(self.builder, self.module, p[::2])


        ## oneprintstatemnet can be any expression or a STRING kind
        @self.pg.production('oneprintstatement : allexpression')
        @self.pg.production('oneprintstatement : STRING')
        def oneprintstatement(p):
            try:
                isString = p[0].gettokentype()
                return Write(self.builder, self.module, self.printf, String(p[0].value), self.constants)
            except AttributeError:
                return Write(self.builder, self.module, self.printf, p[0], self.constants)
            return Write(self.builder, self.module, self.printf, p[0], self.constants)



        ## Function call is when you call a function but don't store the return value
        ## it takes an optional comma separated expression list
        @self.pg.production('functioncall : VAR OPEN_PAREN CLOSE_PAREN')
        @self.pg.production('functioncall : VAR OPEN_PAREN expresslist CLOSE_PAREN')
        def functincall(p):
            if len(p) == 3:
                return CallFunction(self.builder, self.module, p[0].value, [])
            else:
                return CallFunction(self.builder, self.module, p[0].value, p[2])     


        ## Return list of expressions
        @self.pg.production('expresslist : expression')
        @self.pg.production('expresslist : expresslist COMMA expression')
        def expresslist(p):
            if len(p) == 1:
                return p[0]
            
            else:
                values = p[:-1:2]
                if type(values[0]) == list:
                    values[0].append(p[-1])
                    return values[0]
                else:
                    values.append(p[-1])
                    return values   

    

        ## If statement can be a if followed by logical expression then optional else 
        ## each if and else takes a block as next parameter which is the set of statemnets
        @self.pg.production('ifelsestatement : IF log_expression block ELSE block')
        @self.pg.production('ifelsestatement : IF log_expression block')
        def ifelsestatement(p):
            if len(p) == 3:
                return If(self.builder, self.module, p[1], p[2])
            else:
                return IfElse(self.builder, self.module, p[1], p[2], p[4])


        ## For has the syntax like 
        ## for (assignment; logical_expression; assignment2) block
        @self.pg.production('forstatement : FOR OPEN_PAREN assignmentstatement SEMI_COLON log_expression SEMI_COLON assignmentstatement CLOSE_PAREN block')
        def forstatement(p):
            return For(self.builder, self.module, p[2], p[4], p[6], p[8])

        ## While has the syntax like 
        ## while(logical_expression) block
        @self.pg.production('whilestatement : WHILE OPEN_PAREN log_expression CLOSE_PAREN block')
        def whilestatement(p):
            return While(self.builder,self.module,p[2],p[4])

        ## A block is a single statement
        ## In case you need multiple statements you need to enclose it in curly braces
        @self.pg.production('block : onestatement')
        @self.pg.production('block : OPEN_CURLY statements CLOSE_CURLY')
        def block(p):
            if len(p) == 1:
                return Line(self.builder, self.module, p[0])
            else:
                return Line(self.builder, self.module, p[1])





        '''
        ------- All Expressions in the language -----------
        '''

        ## allexpression consist of expression or logical expression
        @self.pg.production('allexpression : expression')
        @self.pg.production('allexpression : log_expression')
        def allexpression(p):
            return Line(self.builder, self.module, p[0])

        

        ## Logical Expressions
        ## logical expressions when operated with and, or, not also give logical expression
        @self.pg.production('log_expression : log_expression OR log_expression')
        @self.pg.production('log_expression : log_expression AND log_expression')
        @self.pg.production('log_expression : NOT log_expression')
        def log_expression(p):

            if len(p) == 3:
                # And Or case
                left = p[0]
                right = p[2]
                operator = p[1]

                if operator.gettokentype() == 'OR':
                    return Or(self.builder, self.module, left, right)
                else:
                    return And(self.builder, self.module, left, right)
            else:
                return Not(self.builder, self.module, p[1])


        
        ## The keyword True, False are logical expression itself
        ## Also, we can enclose a logical expression in () and it is still logical expression
        @self.pg.production('log_expression : TRUE')
        @self.pg.production('log_expression : FALSE')
        @self.pg.production('log_expression : OPEN_PAREN log_expression CLOSE_PAREN')
        def log_expression_value(p):
            if p[0].gettokentype() == 'TRUE':
                return Bool(self.builder, self.module, True)
            elif p[0].gettokentype() == "FALSE":
                return Bool(self.builder, self.module, False)
            else:
                return Line(self.builder, self.module, p[1])


        ## This is the tricky part
        ## Since relational operators give either true or false 
        ## We have wrapped it within logical expression
        @self.pg.production('log_expression : rel_expression')
        def log_expression_relation(p):
            return Line(self.builder, self.module, p[0])


        

        ## Relational expressions
        @self.pg.production('rel_expression : expression EQUALS expression')
        @self.pg.production('rel_expression : expression LESS expression')
        @self.pg.production('rel_expression : expression GREATER expression')
        @self.pg.production('rel_expression : expression LESS_EQ expression')
        @self.pg.production('rel_expression : expression GREAT_EQ expression')
        @self.pg.production('rel_expression : expression NOT_EQUALS expression')
        def arithmatic_relations(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'EQUALS':
                return Equals(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'LESS':
                return Less(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'GREATER':
                return Greater(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'LESS_EQ':
                return LessEq(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'GREAT_EQ':
                return GreatEq(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'NOT_EQUALS':
                return NotEquals(self.builder, self.module, left, right)


        ## Arithmatic Expressions
        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        @self.pg.production('expression : expression MOD expression')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                return Sum(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'MUL':
                return Mul(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'DIV':
                return Div(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'MOD':
                return Mod(self.builder, self.module, left, right)


        ## A function call is also a valid expression
        @self.pg.production('expression : functioncall')
        def callexpression(p):            
            return p[0]        


        ## A number, variable or (expression) are also expression
        @self.pg.production('expression : NUMBER')
        @self.pg.production('expression : VAR')
        @self.pg.production('expression : OPEN_PAREN expression CLOSE_PAREN')
        def stopexpression(p):
            if p[0].gettokentype() == 'NUMBER':
                return Number(self.builder, self.module, p[0].value)

            elif p[0].gettokentype() == 'VAR':
                return Var(self.builder, self.module, p[0].value)
            
            elif p[0].gettokentype() == 'OPEN_PAREN':
                return Line(self.builder, self.module, p[1])

        
        

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#46
0
class Parser():
    def __init__(self, state):
        self.state = state
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            ['NUM', 'DOT', 'COMMA', 'OPEN_PAREN', 'CLOSE_PAREN', 'NOT', 'IMPLIE',
             'AND', 'OR', 'IMP_INTROD', 'AND_INTROD', 'BOTTOM', 'OPEN_BRACKET',
             'NEG_INTROD', 'NEG_ELIM', 'HYPOTESIS', 'PREMISE', 'ATHOM', 'CLOSE_BRACKET'],
            precedence=[
                ('left', ['NOT','AND', 'OR', 'IMPLIE']),
            ]
        )
        self.symbol_table = SymbolTable()

    def parse(self):
        @self.pg.production('program : steps')
        def program(p):
            formules = p[0]
            for i in range(0, len(formules)):
                formule = formules[i]
                rule = self.symbol_table.get_rule(formule.toString())
                if(isinstance(rule, PremisseDef) ):
                    pass
                elif(isinstance(rule, HypotesisDef)):
                    pass
                elif(isinstance(rule, NegationEliminationDef)):
                    formule1 = self.symbol_table.lookup_formule_by_line(rule.formule, rule.reference1)
                    formule2 = self.symbol_table.lookup_formule_by_line(rule.formule, rule.reference2)
                    if(rule.eval(formule1, formule2) == 4):
                        print('Deu certo')
                    else:
                        print('Algo deu errado')
                

        @self.pg.production('steps : steps step')
        @self.pg.production('steps : step')
        def steps(p):
            if len(p) == 1:
                return [p[0]]
            else:
                p[0].append(p[1])
                return p[0]

        @self.pg.production('step : NUM DOT formule PREMISE')
        def Premisse(p):
            formule = p[2]
            premisse = PremisseDef(p[0].value, formule)
            self.symbol_table.insert(premisse)
            return formule

        @self.pg.production('step : NUM DOT formule HYPOTESIS')
        @self.pg.production('step : NUM DOT formule HYPOTESIS OPEN_BRACKET')
        def Hypotesis(p):
            if len(p) > 4:
                self.symbol_table.add_scope()
            
            formule = p[2]
            hypotesis = HypotesisDef(p[0].value, formule)
            self.symbol_table.insert(hypotesis)
            return formule

        @self.pg.production('step : NUM DOT formule NEG_ELIM NUM COMMA NUM')
        @self.pg.production('step : NUM DOT formule NEG_ELIM NUM COMMA NUM CLOSE_BRACKET')
        def Negation_elim(p):
            formule = p[2]
            negationElimination = NegationEliminationDef(p[0].value, formule, p[4].value, p[6].value)
            self.symbol_table.insert(negationElimination)
            if len(p) == 8:
                self.symbol_table.end_scope()
            return formule

        @self.pg.production('formule : NOT formule')
        @self.pg.production('formule : ATHOM')
        @self.pg.production('formule : BOTTOM')
        @self.pg.production('formule : formule AND formule')
        @self.pg.production('formule : formule OR formule')
        @self.pg.production('formule : formule IMPLIE formule')
        def formule(p):
            if len(p) < 3:
                if p[0].gettokentype() == 'ATHOM':
                    return AthomFormule(key=p[0].value)
                elif p[0].gettokentype() == 'BOTTOM':
                    return AthomFormule(key=p[0].value)
                elif p[0].gettokentype() == 'NOT':
                    return NegationFormule(key=p[1])
            else:
                return BinaryFormule(key=p[1].value, left=p[0], right=p[2])

        @self.pg.production('formule : OPEN_PAREN formule CLOSE_PAREN')
        def paren_formule(p):
            return p[1]

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
        
示例#47
0
class Parser:
    def __init__(self, syntax=False):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            [
                'STRING', 'INTEGER', 'FLOAT', 'BOOLEAN', 'PI', 'E', 'PRINT',
                'ABSOLUTE', 'SIN', 'COS', 'TAN', 'POWER', 'CONSOLE_INPUT', '(',
                ')', ';', ',', '{', '}', 'LET', 'AND', 'OR', 'NOT', 'IF',
                'ELSE', '=', '==', '!=', '>=', '>', '<', '<=', 'SUM', 'SUB',
                'MUL', 'DIV', 'IDENTIFIER', 'FUNCTION'
            ],
            # A list of precedence rules with ascending precedence, to
            # disambiguate ambiguous production rules.
            precedence=(('left', ['FUNCTION']), ('left', ['LET']),
                        ('left', ['=']), ('left', ['IF', 'ELSE', ';']),
                        ('left', ['AND', 'OR']), ('left', ['NOT']),
                        ('left', ['==', '!=', '>=', '>', '<',
                                  '<=']), ('left', ['SUM',
                                                    'SUB']), ('left',
                                                              ['MUL', 'DIV']),
                        ('left',
                         ['STRING', 'INTEGER', 'FLOAT', 'BOOLEAN', 'PI',
                          'E'])))
        self.syntax = syntax
        self.parse()
        pass  # End Parser's constructor !

    def parse(self):
        @self.pg.production("main : program")
        def main_program(state, p):
            if self.syntax is True:
                return [Node("program", p[0])]
            return Main(p[0])

        @self.pg.production('program : statement_full')
        def program_statement(state, p):
            if self.syntax is True:
                return [Node("statement_full", p[0])]
            return Program(p[0], None, state)

        @self.pg.production('program : statement_full program')
        def program_statement_program(state, p):
            if self.syntax is True:
                return [Node("statement_full", p[0]), Node("program", p[1])]
            return Program(p[0], p[1], state)

        @self.pg.production('expression : ( expression )')
        def expression_parenthesis(state, p):
            # In this case we need parenthesis only for precedence
            # so we just need to return the inner expression
            if self.syntax is True:
                return [Node("("), Node("expression", p[1]), Node(")")]
            return ExpressParenthesis(p[1])

        @self.pg.production('statement_full : IF ( expression ) { block }')
        def expression_if(state, p):
            if self.syntax is True:
                return [
                    Node("IF"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")"),
                    Node("{"),
                    Node("block", p[5]),
                    Node("}")
                ]
            return If(condition=p[2], body=p[5], state=state)

        @self.pg.production(
            'statement_full : IF ( expression ) { block } ELSE { block }')
        def expression_if_else(state, p):
            if self.syntax is True:
                return [
                    Node("IF"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")"),
                    Node("{"),
                    Node("block", p[5]),
                    Node("}"),
                    Node("ELSE"),
                    Node("{"),
                    Node("block", p[9]),
                    Node("}")
                ]
            return If(condition=p[2], body=p[5], else_body=p[9], state=state)

        @self.pg.production('block : statement_full')
        def block_expr(state, p):
            if self.syntax is True:
                return [Node("statement_full", p[0])]
            return Block(p[0], None, state)

        @self.pg.production('block : statement_full block')
        def block_expr_block(state, p):
            if self.syntax is True:
                return [Node("statement_full", p[0]), Node("block", p[1])]
            return Block(p[0], p[1], state)

        @self.pg.production('statement_full : statement ;')
        def statement_full(state, p):
            if self.syntax is True:
                return [Node("statement", p[0]), Node(";")]
            return StatementFull(p[0])

        @self.pg.production('statement : expression')
        def statement_expr(state, p):
            if self.syntax is True:
                return [Node("expression", p[0])]
            return Statement(p[0])

        @self.pg.production('statement : LET IDENTIFIER = expression')
        def statement_assignment(state, p):
            if self.syntax is True:
                return [
                    Node("LET"),
                    Node("IDENTIFIER", p[1]),
                    Node("="),
                    Node("expression", p[3])
                ]
            return Assignment(Variable(p[1].getstr(), state), p[3], state)

        @self.pg.production(
            'statement_full : FUNCTION IDENTIFIER ( ) { block }')
        def statement_func_noargs(state, p):
            if self.syntax is True:
                return [
                    Node("FUNCTION"),
                    Node("IDENTIFIER", p[1]),
                    Node("("),
                    Node(")"),
                    Node("{"),
                    Node("block", p[5]),
                    Node("}")
                ]
            return FunctionDeclaration(name=p[1].getstr(),
                                       args=None,
                                       block=p[5],
                                       state=state)

        @self.pg.production('expression : NOT expression')
        def expression_not(state, p):
            if self.syntax is True:
                return [Node("NOT"), Node("expression", p[1])]
            return Not(p[1], state)

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        def expression_binary_operator(state, p):
            if p[1].gettokentype() == 'SUM':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("+"),
                        Node("expression", p[2])
                    ]
                return Sum(p[0], p[2], state)
            elif p[1].gettokentype() == 'SUB':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("-"),
                        Node("expression", p[2])
                    ]
                return Sub(p[0], p[2], state)
            elif p[1].gettokentype() == 'MUL':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("*"),
                        Node("expression", p[2])
                    ]
                return Mul(p[0], p[2], state)
            elif p[1].gettokentype() == 'DIV':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("/"),
                        Node("expression", p[2])
                    ]
                return Div(p[0], p[2], state)
            else:
                raise LogicError('Oops, this should not be possible!')

        @self.pg.production('expression : expression != expression')
        @self.pg.production('expression : expression == expression')
        @self.pg.production('expression : expression >= expression')
        @self.pg.production('expression : expression <= expression')
        @self.pg.production('expression : expression > expression')
        @self.pg.production('expression : expression < expression')
        @self.pg.production('expression : expression AND expression')
        @self.pg.production('expression : expression OR expression')
        def expression_equality(state, p):
            if p[1].gettokentype() == '==':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("=="),
                        Node("expression", p[2])
                    ]
                return Equal(p[0], p[2], state)
            elif p[1].gettokentype() == '!=':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("!="),
                        Node("expression", p[2])
                    ]
                return NotEqual(p[0], p[2], state)
            elif p[1].gettokentype() == '>=':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node(">="),
                        Node("expression", p[2])
                    ]
                return GreaterThanEqual(p[0], p[2], state)
            elif p[1].gettokentype() == '<=':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("<="),
                        Node("expression", p[2])
                    ]
                return LessThanEqual(p[0], p[2], state)
            elif p[1].gettokentype() == '>':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node(">"),
                        Node("expression", p[2])
                    ]
                return GreaterThan(p[0], p[2], state)
            elif p[1].gettokentype() == '<':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("<"),
                        Node("expression", p[2])
                    ]
                return LessThan(p[0], p[2], state)
            elif p[1].gettokentype() == 'AND':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("AND"),
                        Node("expression", p[2])
                    ]
                return And(p[0], p[2], state)
            elif p[1].gettokentype() == 'OR':
                if self.syntax is True:
                    return [
                        Node("expression", p[0]),
                        Node("OR"),
                        Node("expression", p[2])
                    ]
                return Or(p[0], p[2], state)
            else:
                raise LogicError("Shouldn't be possible")

        @self.pg.production('expression : CONSOLE_INPUT ( )')
        def program(state, p):
            if self.syntax is True:
                return [Node("CONSOLE_INPUT"), Node("("), Node(")")]
            return Input()

        @self.pg.production('expression : CONSOLE_INPUT ( expression )')
        def program(state, p):
            if self.syntax is True:
                return [
                    Node("CONSOLE_INPUT"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")")
                ]
            return Input(expression=p[2], state=state)

        @self.pg.production('statement : PRINT ( )')
        def program(state, p):
            if self.syntax is True:
                return [Node("PRINT"), Node("("), Node(")")]
            return Print()

        @self.pg.production('statement : PRINT ( expression )')
        def program(state, p):
            if self.syntax is True:
                return [
                    Node("PRINT"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")")
                ]
            return Print(expression=p[2], state=state)

        @self.pg.production('expression : ABSOLUTE ( expression )')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node("ABSOLUTE"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")")
                ]
            return Absolute(p[2], state)

        @self.pg.production('expression : SIN ( expression )')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node("SIN"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")")
                ]
            return Sin(p[2], state)

        @self.pg.production('expression : COS ( expression )')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node("COS"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")")
                ]
            return Cos(p[2], state)

        @self.pg.production('expression : TAN ( expression )')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node("TAN"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(")")
                ]
            return Tan(p[2], state)

        @self.pg.production('expression : POWER ( expression , expression )')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node("POWER"),
                    Node("("),
                    Node("expression", p[2]),
                    Node(","),
                    Node("expression", p[4]),
                    Node(")")
                ]
            return Pow(p[2], p[4], state)

        @self.pg.production('expression : IDENTIFIER')
        def expression_variable(state, p):
            # Cannot return the value of a variable if it isn't yet defined
            if self.syntax is True:
                return [Node("IDENTIFIER", p[0])]
            return Variable(p[0].getstr(), state)

        @self.pg.production('expression : IDENTIFIER ( )')
        def expression_call_noargs(state, p):
            # Cannot return the value of a function if it isn't yet defined
            if self.syntax is True:
                return [Node("IDENTIFIER", p[0]), Node("("), Node(")")]
            return CallFunction(name=p[0].getstr(), args=None, state=state)

        @self.pg.production('expression : const')
        def expression_const(state, p):
            if self.syntax is True:
                return [Node("const", p[0])]
            return p[0]

        @self.pg.production('const : FLOAT')
        def constant_float(state, p):
            if self.syntax is True:
                return [Node("FLOAT", p[0])]
            return Float(p[0].getstr(), state)

        @self.pg.production('const : BOOLEAN')
        def constant_boolean(state, p):
            if self.syntax is True:
                return [Node("BOOLEAN", p[0])]
            return Boolean(p[0].getstr(), state)

        @self.pg.production('const : INTEGER')
        def constant_integer(state, p):
            if self.syntax is True:
                return [Node("INTEGER", p[0])]
            return Integer(p[0].getstr(), state)

        @self.pg.production('const : STRING')
        def constant_string(state, p):
            if self.syntax is True:
                return [Node("STRING", p[0])]
            return String(p[0].getstr().strip('"\''), state)

        @self.pg.production('const : PI')
        def constant_pi(state, p):
            if self.syntax is True:
                return [Node("PI", p[0])]
            return ConstantPI(p[0].getstr(), state)

        @self.pg.production('const : E')
        def constant_e(state, p):
            if self.syntax is True:
                return [Node("E", p[0])]
            return ConstantE(p[0].getstr(), state)

        @self.pg.error
        def error_handle(state, token):
            raise ValueError(token)

    def build(self):
        return self.pg.build()
示例#48
0
class Parser():
    def __init__(self):
        # The list of tokens from the lexer file
        self.pg = ParserGenerator([token for token in operators.keys()],
                                  precedence=[
                                      ("left", ["ADD", "SUBTRACT"]),
                                      ("left", ["MULTIPLY", "DIVIDE"]),
                                  ])

    def parse(self):
        @self.pg.production('program : expression')
        def program(p):
            return Program(p[0])

        @self.pg.production('expression : expression expression')
        def expression(p):
            return Expression(p)

        @self.pg.production('expression : PRINT expression')
        def print_(p):
            return Print(p[1])

        # Binary operations

        @self.pg.production('expression : ADD expression WITH expression')
        def add(p):
            return Add(p[1], p[3])

        @self.pg.production('expression : SUBTRACT expression FROM expression')
        def subtract(p):
            return Subtract(p[1], p[3])

        @self.pg.production('expression : MULTIPLY expression BY expression')
        def multiply(p):
            return Multiply(p[1], p[3])

        @self.pg.production('expression : DIVIDE expression BY expression')
        def divide(p):
            return Divide(p[1], p[3])

        # Handle assinging
        @self.pg.production('expression : ASSIGN variable_name TO expression')
        def assign(p):
            return Assign(p[1], p[3])

        # defining expressions
        @self.pg.production('variable_name : IDENTIFIER')
        def identifier(p):
            return Identifier(p[0].value)

        @self.pg.production('expression : NUMBER')
        def number(p):
            return Number(p[0].value)

        @self.pg.production('expression : STRING')
        def string(p):
            return String(p[0].value)

        @self.pg.production('expression : RPN')
        def rpn(p):
            return Rpn(p[0].value)

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#49
0
class Parser():
    def __init__(self):
        self.pg = ParserGenerator(
            TOKENS,
            precedence=[
                ('left', ['ADD', 'SUB']),
                ('left', ['MOD']),
                ('left', ['NOT_EQ']),
            ]
        )

    def parse(self):
        @self.pg.production('fsm : fsm_pre LBRACE fsm_rules RBRACE')
        def fsm(p) -> FSM:
            (start, dones) = p[0]
            rules = {k: v for (k, v) in p[2]}
            return FSM(start.val, [n.val for n in dones], rules)

        @self.pg.production('number : NUMBER')
        @self.pg.production('expr : number')
        def number(p) -> SynthExpr:
            if isinstance(p[0], Num):
                return p[0]
            return Num(int(p[0].value))

        @self.pg.production('id : ID')
        @self.pg.production('expr : id')
        def id(p) -> SynthExpr:
            if isinstance(p[0], RegRef):
                return p[0]
            return RegRef(p[0].value)

        @self.pg.production('expr : expr ADD expr')
        @self.pg.production('expr : expr SUB expr')
        @self.pg.production('expr : expr MOD expr')
        @self.pg.production('expr : expr NOT_EQ expr')
        def expr(p) -> SynthExpr:
            left = p[0]
            right = p[2]
            operator = p[1]
            return Binop(operator.value, left, right)

        @self.pg.production('number_rep : number COMMA number_rep')
        @self.pg.production('number_rep : number')
        def number_rep(p) -> List[SynthExpr]:
            if len(p) == 1:
                return [p[0]]
            else:
                return [p[0]] + [p[2]]

        @self.pg.production('next : NEXT LPAREN number RPAREN')
        def direct_next(p) -> NextState:
            return DirectNext(p[2].val)

        @self.pg.production('next : NEXT LPAREN id COMMA number COMMA number RPAREN')
        def cond_next(p) -> NextState:
            return CondNext(p[2], p[4].val, p[6].val)

        @self.pg.production('next : DONE')
        def done_next(p) -> NextState:
            return Done()

        @self.pg.production('update : id LEFT_ARROW expr')
        def update(p) -> Update:
            return Update(p[0], p[2])

        @self.pg.production('updates : update SEMI updates')
        @self.pg.production('updates : update SEMI')
        def updates(p) -> List[Update]:
            if len(p) == 2:
                return [p[0]]
            else:
                return [p[0]] + p[2]

        @self.pg.production('action : LBRACE updates next RBRACE')
        @self.pg.production('action : LBRACE next RBRACE')
        def action(p) -> Action:
            if len(p) == 3:
                return Action([], p[1])
            else:
                return Action(p[1], p[2])

        @self.pg.production('fsm_pre : LPAREN START EQUAL number COMMA DONE EQUAL LBRACKET number_rep RBRACKET RPAREN')
        def fsm_pre(p):
            return (p[3], p[8])

        @self.pg.production('fsm_rule : number COLON action')
        def fsm_rule(p):
            return (p[0].val, p[2])

        @self.pg.production('fsm_rules : fsm_rule fsm_rules')
        @self.pg.production('fsm_rules : fsm_rule')
        def fsm_rules(p):
            if len(p) == 1:
                return [p[0]]
            else:
                return [p[0]] + p[1]

        @self.pg.error
        def error_handle(token):
            pos = token.getsourcepos()
            raise ValueError(
                "Failed to parse `%s' on line %s, column %s." % (token.value, pos.lineno, pos.colno))

    def get_parser(self):
        return self.pg.build()
示例#50
0
class Parser:
    def __init__(self, state):
        self.pg = ParserGenerator(tokens=[
            "FN", "LET", "RET", "(", ")", "=", ";", "{", "}", ",", "NUMBER",
            "FLOAT", "FALSE", "TRUE", "TO", "REF", "DEREF", "ADDR", "PTR",
            "IDENTIFIER"
        ],
                                  precedence=[
                                      ("left", ["NUMBER", "FLOAT"]),
                                      ("left", ["IDENTIFIER"]),
                                      ("left", [",", ";"]),
                                      ("left", ["FN", "LET", "RET"]),
                                      ("left", ["="]),
                                      ("right", ["REF", "DEREF", "ADDR"]),
                                      ("left", ["TO"]),
                                      ("left", ["{", "}"]),
                                      ("left", ["(", ")"]),
                                  ],
                                  cache_id="soda_cache")

        self.state = state

    def build(self):
        # bug poop
        @self.pg.production("program : definitions")
        def program_definitions(p):
            return ProgramNode(p[0])

        @self.pg.production("definitions : definitions definitions")
        @self.pg.production("definitions : definition")
        def definitions_all(p):
            return DefinitionsNode(p)

        @self.pg.production("definition : statements")
        @self.pg.production("definition : functions")
        def definition_all(p):
            return p[0]

        @self.pg.production("functions : functions functions")
        @self.pg.production("functions : function")
        def functions_all(p):
            return FunctionsNode(p)

        @self.pg.production("function : FN type IDENTIFIER arguments closure")
        def function_def(p):
            return FunctionNode(p[0], p[1], p[2], p[3], p[4])

        @self.pg.production("closure : { statements }")
        @self.pg.production("closure : { }")
        def closure_all(p):
            if len(p) == 3:
                return ClosureNode([p[1]])
            else:
                return ClosureNode([])

        @self.pg.production("arguments : ( internal_arguments )")
        @self.pg.production("arguments : ( )")
        def arguments_paren_internal(p):
            if len(p) == 3:
                return ArgumentsNode([p[1]])
            else:
                return ArgumentsNode([])

        @self.pg.production(
            "internal_arguments : internal_arguments , internal_argument")
        @self.pg.production(
            "internal_arguments : internal_argument , internal_argument")
        @self.pg.production("internal_arguments : internal_argument")
        def internal_arguments(p):
            tmp = []
            for tok in p:
                if not hasattr(tok, "gettokentype"):
                    tmp.append(tok)
            return ArgumentsNode(tmp)

        @self.pg.production("internal_argument : IDENTIFIER type")
        def internal_argument(p):
            return ArgumentNode(p[0], p[1])

        @self.pg.production("statements : statements statements")
        @self.pg.production("statements : statement")
        def statements_all(p):
            return StatementsNode(p)

        @self.pg.production("statement : IDENTIFIER call")
        @self.pg.production("expr : IDENTIFIER call")
        def statements_call(p):
            return CallNode(p[0], p[1])

        @self.pg.production("call : ( )")
        @self.pg.production("call : ( call_arguments )")
        def call_op(p):
            if len(p) == 2:
                return CallOpNode([])
            else:
                return CallOpNode([p[1]])

        @self.pg.production("call_arguments : call_arguments , call_arguments")
        @self.pg.production("call_arguments : expr , expr")
        @self.pg.production("call_arguments : expr")
        def call_arguments(p):
            temp = []
            for tok in p:
                if not isinstance(tok, Token):
                    temp.append(tok)

            return CallArgumentsNode(temp)

        @self.pg.production("statement : RET expr ;")
        def statement_return(p):
            return ReturnNode(p[0], p[1])

        @self.pg.production("statement : LET IDENTIFIER type = expr ;")
        def statements_let(p):
            return LetNode(p[1], p[2], p[4])

        @self.pg.production("statement : LET IDENTIFIER = expr ;")
        def statements_let(p):
            return LetNode(p[1], None, p[3])

        @self.pg.production("statement : LET IDENTIFIER type ;")
        def statements_let(p):
            return LetNode(p[1], p[2], None)

        @self.pg.production("expr : expr TO type")
        def expr_casting(p):
            return CastNode(p[1], p[0], p[2])

        @self.pg.production("expr : REF expr")
        def expr_refrence(p):
            return RefNode(p[0], p[1])

        @self.pg.production("expr : DEREF expr")
        def expr_derefrence(p):
            return DerefNode(p[0], p[1])

        @self.pg.production("expr : ADDR expr")
        def expr_refrence(p):
            return AddressNode(p[0], p[1])

        @self.pg.production("expr : ( expr )")
        def expr_paren_expr(p):
            return p[1]

        @self.pg.production("expr : IDENTIFIER")
        def expr_identifier(p):
            return VariableNode(p[0])

        @self.pg.production("expr : TRUE")
        @self.pg.production("expr : FALSE")
        def expr_boolean(p):
            return BoolNode(p[0])

        @self.pg.production("expr : NUMBER")
        def expr_number(p):
            return NumberNode(p[0])

        @self.pg.production("expr : FLOAT")
        def expr_number(p):
            return FloatNode(p[0])

        @self.pg.production("expr : FLOAT")
        def expr_number(p):
            return FloatNode(p[0])

        @self.pg.production("type : ( IDENTIFIER )")
        def type_identifier(p):
            return TypeNode(p[1])

        @self.pg.production("type : ( ptrs IDENTIFIER )")
        def ptrtype_identifier(p):
            return TypeNode(p[2], is_ptr=p[1])

        @self.pg.production("ptrs : ptrs ptrs")
        @self.pg.production("ptrs : PTR")
        def ptrs_count(p):
            if len(p) != 1:
                return PtrNode(p)
            else:
                return PtrNode([])

        @self.pg.error
        def error_handler(token):
            self.state.error_handler("Came across unexpected token.",
                                     token.getsourcepos())

        warnings.filterwarnings("ignore", category=ParserGeneratorWarning)
        return self.pg.build()
示例#51
0
        constr = state.tagged[tag_name]
        return constr(p[1])
    elif state.accept_unknown_tags:
        return TaggedValue(tag_name, p[1])
    else:
        raise KeyError("No registered constructor for tag '{}'".format(tag_name))

@pg.production("value : tag value")
def value_tagged(state, p):
    return handle_tagged_value(state, p)

@pg.production("value : ns_tag value")
def value_tagged_ns(state, p):
    return handle_tagged_value(state, p)

parser = pg.build()

def loads(code, tagged=None, accept_unknown_tags=False):
    state = State(tagged, accept_unknown_tags)
    return parser.parse(lexer.lex(code), state)

CHARS = {
    '\t': 'tab',
    '\n': 'newline',
    '\r': 'return',
    ' ': 'space'
}

ESCAPE = re.compile(r'[\x00-\x1f\\"\b\f\n\r\t]')
ESCAPE_DCT = {
    '\\': '\\\\',
示例#52
0
class Parser():
    def __init__(self):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            [
                'INT', 'PRINT', 'OPENPAR', 'CLOSEPAR', 'PLUS', 'MINUS', 'MULT',
                'DIV', 'ASSIGN', 'BREAKLINE', 'IDENT', 'IF', 'END', 'ELSE',
                'GREATERTHAN', 'LESSTHAN', 'COMMA', 'COLON', 'AND', 'OR',
                'NOT', 'DEF', 'VOID', 'INTEGER', 'BOOLEAN', 'TRUE', 'FALSE',
                'WHILE', 'WEND', 'INPUT', 'AS', 'CALL', 'EQUAL'
            ])

    def parse(self):
        @self.pg.production('program : expression')
        def program(p):
            return

        @self.pg.production(
            'program : expression PRINT OPENPAR expression CLOSEPAR')
        def program(p):
            return Print(p[3])

        @self.pg.production('program : PRINT OPENPAR expression CLOSEPAR')
        def program(p):
            return Print(p[2])

        @self.pg.production('expression : expression PLUS expression')
        @self.pg.production('expression : expression MINUS expression')
        @self.pg.production('expression : expression MULT expression')
        @self.pg.production('expression : expression DIV expression')
        @self.pg.production('expression : expression ASSIGN expression')
        @self.pg.production('expression : expression GREATERTHAN expression')
        @self.pg.production('expression : expression LESSTHAN expression')
        @self.pg.production('expression : expression EQUAL expression')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'PLUS':
                return Sum(left, right)
            elif operator.gettokentype() == 'MINUS':
                return Sub(left, right)
            elif operator.gettokentype() == 'MULT':
                return Mult(left, right)
            elif operator.gettokentype() == 'DIV':
                return Div(left, right)
            elif operator.gettokentype() == 'ASSIGN':
                return Assign(left, right)
            elif operator.gettokentype() == 'GREATERTHAN':
                return GreaterThan(left, right)
            elif operator.gettokentype() == 'LESSTHAN':
                return LessThan(left, right)
            elif operator.gettokentype() == 'EQUAL':
                return Equal(left, right)

        @self.pg.production('expression : INT')
        def number(p):
            return Number(p[0].value)

        @self.pg.production('expression : IDENT')
        def ident(p):
            return Ident(p[0].value)

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#53
0
    def create_parser(tokens):
        pg = ParserGenerator(
            tokens,
            precedence=[
                ("left", ["OR"]),
                ("left", ["AND"]),
                ("right", ["NOT"]),
                ("left", ["EQ", "NE", "LE", "GE", "LT", "GT"]),
                ("left", ["ADD", "SUB"]),
                ("left", ["MUL", "DIV", "MOD"]),
                ("right", ["MINUS"]),
                ("right", ["POW"]),
                ("nonassoc", ["LPAREN", "RPAREN"]),
            ],
            cache_id="lang",
        )

        @pg.production("program : block")
        def program(p):
            return ast.Program(p[0])

        @pg.production("scope : LBRACE block RBRACE")
        def scope(p):
            return ast.Block(p[1].block)

        @pg.production("scope : LBRACE RBRACE")
        def scope_empty(p):
            return ast.Block(None)

        @pg.production("block : block stmt")
        def block(p):
            return ast.Block(p[0].block + [p[1]])

        @pg.production("block : stmt")
        def block_stmt(p):
            return ast.Block([p[0]])

        @pg.production("stmt : FN SYMBOL LPAREN fn_args RPAREN scope")
        def stmt_fn(p):
            return ast.Fn(p[1].getstr(), p[3], p[5])

        @pg.production("fn_args : fn_args COMMA def_arg")
        def fn_args(p):
            return ast.FnArgs(p[0].args + [p[2]])

        @pg.production("fn_args : def_arg")
        def def_args_arg(p):
            return ast.FnArgs([p[0]])

        @pg.production("fn_args :")
        def def_args_empty(p):
            return ast.FnArgs([])

        @pg.production("def_arg : SYMBOL COLON type")
        def def_arg(p):
            return ast.FnArg(p[0].getstr(), p[2])

        @pg.production("stmt : SYMBOL DEFINE expr")
        def stmt_define(p):
            return ast.Define(p[0].getstr(), p[2])

        @pg.production("stmt : SYMBOL ASSIGN expr")
        def stmt_assign(p):
            return ast.Assign(p[0].getstr(), p[2])

        @pg.production("stmt : PRINTLN LPAREN expr RPAREN")
        @pg.production("stmt : PRINT LPAREN expr RPAREN")
        def stmt_print(p):
            if p[0].gettokentype() == "PRINTLN":
                return ast.Print(p[2], True)
            elif p[0].gettokentype() == "PRINT":
                return ast.Print(p[2], False)

        @pg.production("stmt : expr")
        def stmt_expr(p):
            return ast.Statement(p[0])

        @pg.production("expr : scope")
        def expr_scope(p):
            return p[0]

        @pg.production("expr : SYMBOL LPAREN args RPAREN")
        def expr_call(p):
            return ast.Call(p[0].getstr(), p[2])

        @pg.production("args : args COMMA expr")
        def args(p):
            return ast.Args(p[0].args + [p[2]])

        @pg.production("args : expr")
        def args_expr(p):
            return ast.Args([p[0]])

        @pg.production("args :")
        def args_empty(p):
            return ast.Args([])

        @pg.production("expr : IF expr scope ELSE scope")
        def expr_if_else(p):
            return ast.IfElse(p[1], p[2], p[4])

        @pg.production("expr : IF expr scope")
        def expr_if(p):
            return ast.If(p[1], p[2])

        @pg.production("expr : WHILE expr scope")
        def expr_while(p):
            return ast.While(p[1], p[2])

        @pg.production("expr : FOR stmt SC expr SC stmt scope")
        def expr_for(p):
            return ast.For(p[1], p[3], p[5], p[6])

        @pg.production("expr : NOT expr")
        def expr_not(p):
            return ast.Not(p[1])

        @pg.production("expr : SYMBOL")
        def expr_symbol(p):
            return ast.ValueSymbol(p[0].getstr())

        @pg.production("expr : CAST LPAREN type COMMA expr RPAREN")
        def expr_cast(p):
            return ast.Cast(p[2], p[4])

        @pg.production("type : INT")
        @pg.production("type : FLOAT")
        @pg.production("type : STR")
        @pg.production("type : BOOL")
        def expr_type(p):
            return ast.Type(p[0].gettokentype())

        @pg.production("expr : VALUE_INT")
        def expr_number_int(p):
            return ast.ValueInt(int(p[0].getstr()))

        @pg.production("expr : VALUE_FLOAT")
        def expr_number_float(p):
            return ast.ValueFloat(float(p[0].getstr()))

        @pg.production("expr : VALUE_STR")
        def expr_str(p):
            return ast.ValueStr(p[0].getstr())

        @pg.production("expr : TRUE")
        def expr_true(p):
            return ast.ValueTrue()

        @pg.production("expr : FALSE")
        def expr_false(p):
            return ast.ValueFalse()

        @pg.production("expr : LPAREN expr RPAREN")
        def expr_parens(p):
            return p[1]

        @pg.production("expr : expr ADD expr")
        @pg.production("expr : expr SUB expr")
        @pg.production("expr : expr MUL expr")
        @pg.production("expr : expr DIV expr")
        @pg.production("expr : expr POW expr")
        @pg.production("expr : expr MOD expr")
        @pg.production("expr : expr EQ expr")
        @pg.production("expr : expr NE expr")
        @pg.production("expr : expr LE expr")
        @pg.production("expr : expr GE expr")
        @pg.production("expr : expr LT expr")
        @pg.production("expr : expr GT expr")
        @pg.production("expr : expr AND expr")
        @pg.production("expr : expr OR expr")
        def expr_binop(p):
            left = p[0]
            op = p[1].gettokentype()
            right = p[2]

            def is_number(x):
                return isinstance(x, ast.ValueInt) or isinstance(
                    x, ast.ValueFloat)

            # Mathematical identities optimziation
            if op == "ADD":
                if is_number(left) and left.value == 0:  # 0 + x = x
                    return right
                elif is_number(right) and right.value == 0:  # x + 0 = x
                    return left
            elif op == "SUB":
                if is_number(left) and left.value == 0:  # 0 - x = -x
                    return ast.Minus(right)
                elif is_number(right) and right.value == 0:  # x - 0 = x
                    return left
            elif op == "MUL":
                if is_number(left) and left.value == 1:  # 1 * x = x
                    return right
                elif is_number(left) and left.value == 2:  # 2 * x = x + x
                    return ast.BinaryOp(operator.add, right, right)
                elif is_number(right) and right.value == 1:  # x * 1 = x
                    return left
                elif is_number(right) and right.value == 2:  # x * 2 = x + x
                    return ast.BinaryOp(operator.add, left, left)
            elif op == "DIV":
                if is_number(right) and right.value == 1:  # x / 1 = x
                    return left
                elif is_number(right) and right.value == 2:  # x / 2 = x * 0.5
                    return ast.BinaryOp(operator.mul, left,
                                        ast.ValueFloat(0.5))
            elif op == "POW":
                if is_number(right) and right.value == 2:  # x ^ 2 = x * x
                    return ast.BinaryOp(operator.mul, left, left)

            methods = {
                "ADD": operator.add,
                "SUB": operator.sub,
                "MUL": operator.mul,
                "DIV": operator.truediv,
                "POW": operator.pow,
                "MOD": operator.mod,
                "EQ": operator.eq,
                "NE": operator.ne,
                "LE": operator.le,
                "GE": operator.ge,
                "LT": operator.lt,
                "GT": operator.gt,
                "AND": operator.and_,
                "OR": operator.or_,
            }

            assert op in methods
            return ast.BinaryOp(methods[op], left, right)

        return pg.build()
示例#54
0
class Parser:
    class Number:
        """
        Number data type that represent an 8 bit integer
        """

        def __init__(self, value):
            self.value = value

        def eval(self):
            """ evaluate """
            return int(self.value)

        def generate(self):
            return [

            ]
    class String:
        """
        String data type
        """
        def __init__(self, value):
            self.value = value

        def eval(self):
            """ evaluate """
            return int(self.value)

        def generate(self):
            return [

            ]
    class Boolean:
        """
        Boolean data type
        """
        def __init__(self, value):
            self.value = value

        def eval(self):
            """ evaluate """
            return int(self.value)

        def generate(self):
            return [

            ]
    class BinaryOp():
        """
        Base class for any binary operations
        """
        def __init__(self, left, right):
            self.left = left
            self.right = right
    class Sum(BinaryOp):
        def eval(self):
            return self.left.eval() + self.right.eval()
    class Sub(BinaryOp):
        def eval(self):
            return self.left.eval() - self.right.eval()
    class Mult(BinaryOp):
        def eval(self):
            return self.left.eval() * self.right.eval()
    class LeftDiv(BinaryOp):
        def eval(self):
            return self.left.eval() / self.right.eval()
    class RightDiv(BinaryOp):
        def eval(self):
            return self.right.eval() / self.left.eval()
    class Print():
        def __init__(self, value):
            self.value = value

        def eval(self):
            print(self.value.eval())

    def __init__(self, tokens):
        self.pg = ParserGenerator(tokens)

    def parse(self):
        @self.pg.production('letter : "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" \
       | "O" | "P" | "Q" | "R" | "S" | "T" | "U" \
       | "V" | "W" | "X" | "Y" | "Z" | "a" | "b" \
       | "c" | "d" | "e" | "f" | "g" | "h" | "i" \
       | "j" | "k" | "l" | "m" | "n" | "o" | "p" \
       | "q" | "r" | "s" | "t" | "u" | "v" | "w" \
       | "x" | "y" | "z" ')
        def letter(p):
            """ evaluate letters """
            pass

        @self.pg.production('digit : "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ')
        def digit(p):
            pass

        @self.pg.production('symbol : "[" | "]" | "{" | "}" | "(" | ")" | "<" | ">" \
       | "'" | '"' | "=" | "|" | "." | "," | ";" ')
        def symbol(p):
            pass

        @self.pg.production('program : PRINT OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def program(p):
            return self.Print(p[2])

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        def expression(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SUM':
                return self.Sum(left, right)
            elif operator.gettokentype() == 'SUB':
                return self.Sub(left, right)

        @self.pg.production('expression : NUMBER')
        def number(p):
            return self.Number(p[0].value)

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    @property
    def getParser(self):
        return self.pg.build()
示例#55
0
class Parser():
    def __init__(self, dic_variables, dic_etiquetas):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            ['LODD','STOD','ADDD','SUBD','JPOS','JZER','JUMP','LOCO','LODL','STOL','ADDL','SUBL','JNEG','JNZE','CALL','PUSHI','POPI','PUSH','POP','RETN','SWAP','INSP','DESP','INPAC', 'OUTAC','HALT','DIRECCION', 'NUMERO', 'VARIABLE', 'ETIQUETA']
        )
        self.dic_variables=dic_variables
        self.dic_etiquetas=dic_etiquetas
        
    def parse(self):
    
        @self.pg.production('expression : LODD expression')
        @self.pg.production('expression : STOD expression')
        @self.pg.production('expression : ADDD expression')
        @self.pg.production('expression : SUBD expression')
        @self.pg.production('expression : JPOS expression')
        @self.pg.production('expression : JZER expression')
        @self.pg.production('expression : JUMP expression')
        @self.pg.production('expression : LOCO expression')
        @self.pg.production('expression : LODL expression')
        @self.pg.production('expression : STOL expression')
        @self.pg.production('expression : ADDL expression')
        @self.pg.production('expression : SUBL expression')
        @self.pg.production('expression : JNEG expression')
        @self.pg.production('expression : JNZE expression')
        @self.pg.production('expression : CALL expression')
        @self.pg.production('expression : INSP expression')
        @self.pg.production('expression : DESP expression')
        def expression(p):
            if p[0].gettokentype() == 'LODD':
                return Lodd(p[1])
            elif p[0].gettokentype() == 'STOD':
                return Stod(p[1])
            elif p[0].gettokentype() == 'ADDD':
                return Addd(p[1])
            elif p[0].gettokentype() == 'SUBD':
                return Subd(p[1])
            elif p[0].gettokentype() == 'JPOS':
                return Jpos(p[1])
            elif p[0].gettokentype() == 'JZER':
                return Jzer(p[1])
            elif p[0].gettokentype() == 'JUMP':
                return Jump(p[1])
            elif p[0].gettokentype() == 'LOCO':
                return Loco(p[1])
            elif p[0].gettokentype() == 'LODL':
                return Lodl(p[1])
            elif p[0].gettokentype() == 'STOL':
                return Stol(p[1])
            elif p[0].gettokentype() == 'ADDL':
                return Addl(p[1])
            elif p[0].gettokentype() == 'SUBL':
                return Subl(p[1])
            elif p[0].gettokentype() == 'JNEG':
                return Jneg(p[1])
            elif p[0].gettokentype() == 'JNZE':
                return Jnze(p[1])
            elif p[0].gettokentype() == 'CALL':
                return Call(p[1])
            elif p[0].gettokentype() == 'INSP':
                return Insp(p[1])
            elif p[0].gettokentype() == 'DESP':
                return Desp(p[1])
        
        @self.pg.production('expression : PUSHI')
        @self.pg.production('expression : POPI')
        @self.pg.production('expression : PUSH')
        @self.pg.production('expression : POP')
        @self.pg.production('expression : RETN')
        @self.pg.production('expression : SWAP')
        @self.pg.production('expression : INPAC')
        @self.pg.production('expression : OUTAC')
        @self.pg.production('expression : HALT')
        def expression(p):
            if p[0].gettokentype() == 'PUSHI':
                return Pushi()
            elif p[0].gettokentype() == 'POPI':
                return Popi()
            elif p[0].gettokentype() == 'PUSH':
                return Push()
            elif p[0].gettokentype() == 'POP':
                return Pop()
            elif p[0].gettokentype() == 'RETN':
                return Retn()
            elif p[0].gettokentype() == 'SWAP':
                return Swap()
            elif p[0].gettokentype() == 'INPAC':
                return Inpac()
            elif p[0].gettokentype() == 'OUTAC':
                return Outac()
            elif p[0].gettokentype() == 'HALT':
                return Halt()
        
                  
        @self.pg.production('expression : DIRECCION')
        def expression(p):
            return Direccion(p[0])
            
        @self.pg.production('expression : VARIABLE')    
        def expression(p):
            return Variable(p[0].value, self.dic_variables)
            
        @self.pg.production('expression : NUMERO') 
        def expression(p):
            return NumeroUnsigned(p[0].value)
            
        @self.pg.production('expression : ETIQUETA expression')
        def expression(p):
            return Etiqueta_Inicial(p[1])
            
        @self.pg.production('expression : ETIQUETA')
        def expression(p):
            return Etiqueta(p[0].value, self.dic_etiquetas)
        
        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#56
0
class Parser:
    def __init__(self):
        self.pg = ParserGenerator(
            [
                'NUMBER', '(', ')', 'SUM', 'SUB', 'MUL', 'DIV', 'PRINT', '=',
                'NEWLINE', 'IDENTIFIER', 'STRING', '$end', 'IF', '==', '!=',
                '>=', '<=', '<', '>', 'COLON', 'ELSE', 'ELIF', 'DEF', 'END',
                'SLEEP', ',', 'open', 'read', '.', 'return', 'import', '{',
                '}', 'AND', 'await', '@', 'from', '[', ']'
            ],
            precedence=[('left', ['SUM', 'SUB']), ('left', ['MUL', 'DIV']),
                        ('left', ['DEF', 'END', 'return', 'IDENTIFIER']),
                        ('left', ['IF', 'COLON', 'ELIF', 'ELSE', 'NEWLINE']),
                        ('left', [
                            '==',
                            '!=',
                            '>=',
                            '>',
                            '<',
                            '<=',
                        ]), ('left', ['=']), ('left', ['{', '}'])])
        self.build()

    def build(self):
        @self.pg.production("main : program")
        def main_program(env, p):
            return p[0]

        @self.pg.production('program : statement_full')
        def program_statement(env, p):
            return Program(p[0])

        @self.pg.production('program : statement_full program')
        def program_statement_program(env, p):
            if type(p[1]) is Program:
                program = p[1]
            else:
                program = Program(p[-1])

            program.add_statement(p[0])
            return p[1]

        @self.pg.production('statement_full : statement NEWLINE')
        @self.pg.production('statement_full : statement $end')
        def statement_full(env, p):
            try:
                p[0].gettokentype()
                return p[1]
            except AttributeError:
                return p[0]

        @self.pg.production('statement : IDENTIFIER = expression')
        def assignment(env, p):
            if isinstance(p[2], Function):
                return Assignment(Variable(p[0].value), p[2])
            return Assignment(Variable(p[0].value), p[2])

        @self.pg.production('expression : IDENTIFIER')
        def variable(env, p):
            return Variable(p[0].value)

        @self.pg.production('statement : expression')
        def statement_expr(env, p):
            return p[0]

        @self.pg.production('expression : IDENTIFIER [ expression ]')
        def index(env, p):
            return Index(Variable(p[0].value), p[2].value)

        @self.pg.production('statement : PRINT ( expression )')
        def printsw(env, p):
            return Print(p[2])

        @self.pg.production('statement : SLEEP ( NUMBER )')
        def sleep(env, p):
            return Sleep(int(p[2].value))

        @self.pg.production('expression : NUMBER')
        def number(env, p):
            return Number(int(p[0].value))

        @self.pg.production('expression : STRING')
        def string(env, p):
            return String(str(p[0].value))

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        def binop(env, p):
            left = p[0]
            right = p[2]
            if p[1].gettokentype() == 'SUM':
                return Sum(left, right)
            elif p[1].gettokentype() == 'SUB':
                return Sub(left, right)
            elif p[1].gettokentype() == 'MUL':
                return Mul(left, right)
            elif p[1].gettokentype() == 'DIV':
                return Div(left, right)
            else:
                raise AssertionError('Oops, this should not be possible!')

        @self.pg.production(
            'expression : IF expression COLON NEWLINE block END')
        def expression_if(env, p):
            return If(condition=p[1], body=p[4])

        @self.pg.production(
            'expression : IF expression COLON NEWLINE block ELSE COLON NEWLINE block END'
        )
        def expression_if_else(env, p):
            return If(condition=p[1], body=p[4], else_body=p[8])

        @self.pg.production(
            'expression : IF expression COLON NEWLINE block ELIF expression COLON NEWLINE block END'
        )
        def expression_if_elif(env, p):
            return If(condition=p[1],
                      body=p[4],
                      elif_condition=p[6],
                      elif_body=p[9])

        @self.pg.production(
            'expression : IF expression COLON NEWLINE block ELIF expression COLON NEWLINE block ELSE COLON NEWLINE block END'
        )
        def expression_if_elif_else(env, p):
            return If(condition=p[1],
                      body=p[4],
                      elif_condition=p[6],
                      elif_body=p[9],
                      else_body=p[13])

        @self.pg.production('expression : expression != expression')
        @self.pg.production('expression : expression == expression')
        @self.pg.production('expression : expression >= expression')
        @self.pg.production('expression : expression <= expression')
        @self.pg.production('expression : expression > expression')
        @self.pg.production('expression : expression < expression')
        def expression_equality(env, p):
            left = p[0]
            right = p[2]
            check = p[1]

            if check.gettokentype() == '==':
                return Equal(left, right)
            elif check.gettokentype() == '!=':
                return NotEqual(left, right)
            elif check.gettokentype() == '>=':
                return GreaterThanEqual(left, right)
            elif check.gettokentype() == '<=':
                return LessThanEqual(left, right)
            elif check.gettokentype() == '>':
                return GreaterThan(left, right)
            elif check.gettokentype() == '<':
                return LessThan(left, right)
            else:
                raise ValueError("Shouldn't be possible")

        @self.pg.production('block : statement_full')
        def block_expr(env, p):
            return Block(p[0])

        @self.pg.production('block : statement_full block')
        def block_expr_block(env, p):
            if type(p[1]) is Block:
                b = p[1]
            else:
                b = Block(p[1])

            b.add_statement(p[0])
            return b

        @self.pg.production("function : IDENTIFIER ( )")
        def function_call(env, p):
            return Function(p[0].value)

        @self.pg.production("function : IDENTIFIER ( args )")
        def function_callargs(env, p):
            have = list(p[2].statements)
            env.args[1] = have
            return Function(p[0].value, Array(p[2]))

        @self.pg.production('function : IDENTIFIER . IDENTIFIER ( ) ')
        def importedfunc(env, p):
            return ImportedFunction(p[0].value, p[2].value)

        @self.pg.production('function : IDENTIFIER . IDENTIFIER ( args ) ')
        def importedfuncargs(env, p):
            return ImportedFunction(p[0].value, p[2].value, p[4])

        @self.pg.production(
            'function : IDENTIFIER . IDENTIFIER ( args AND kwargs ) ')
        def importedfuncboth(env, p):
            return ImportedFunction(p[0].value, p[2].value, p[4], p[6])

        @self.pg.production('function : IDENTIFIER . IDENTIFIER ( kwargs ) ')
        def importedfunckwargs(env, p):
            return ImportedFunction(p[0].value, p[2].value, None, p[4])

        @self.pg.production('expression : function')
        def function(env, p):
            return p[0]

        @self.pg.production('expression : await function')
        def awaitfunction(env, p):
            return Await(p[1])

        @self.pg.production(
            'funcstatement : defstatement ( ) COLON NEWLINE block END')
        def funcstate(env, p):
            return AssignmentFunction(p[0], p[5], None)

        @self.pg.production(
            'statement : @ IDENTIFIER . IDENTIFIER NEWLINE funcstatement')
        def blank_deco(env, p):
            return DecoratedFunction(p[1].value, p[3].value, p[5], False, None,
                                     None)

        @self.pg.production(
            'statement : @ IDENTIFIER . IDENTIFIER ( ) NEWLINE funcstatement')
        def none_deco(env, p):
            return DecoratedFunction(p[1].value, p[3].value, p[7], True, None,
                                     None)

        @self.pg.production(
            'statement : @ IDENTIFIER . IDENTIFIER ( args AND kwargs ) NEWLINE funcstatement'
        )
        def both_deco(env, p):
            return DecoratedFunction(p[1].value, p[3].value, p[10], True, p[5],
                                     p[7])

        @self.pg.production(
            'statement : @ IDENTIFIER . IDENTIFIER ( kwargs ) NEWLINE funcstatement'
        )
        def kwargs_deco(env, p):
            return DecoratedFunction(p[1].value, p[3].value, p[8], True, None,
                                     p[5])

        @self.pg.production(
            'statement : @ IDENTIFIER . IDENTIFIER ( args ) NEWLINE funcstatement'
        )
        def args_deco(env, p):
            return DecoratedFunction(p[1].value, p[3].value, p[8], True, p[5],
                                     None)

        @self.pg.production("defstatement : DEF IDENTIFIER")
        def defstatement(env, p):
            return p[1].value

        @self.pg.production("statement : funcstatement")
        def function_assign(env, p):
            return p[0]

        @self.pg.production(
            "funcstatement : defstatement ( args ) COLON NEWLINE block END")
        def function_assign(env, p):
            need = list(x.name for x in p[2].statements)
            env.args[0] = need
            func = AssignmentFunction(p[0], p[6], Array(p[2]))
            return func

        @self.pg.production('args : IDENTIFIER')
        @self.pg.production('args : IDENTIFIER ,')
        def arglist_single(env, p):
            return InnerArray([Variable(p[0].value)])

        @self.pg.production('args : IDENTIFIER , args')
        def arglist(env, p):
            p[2].append(Variable(p[0].value))
            return p[2]

        @self.pg.production('args : expression')
        @self.pg.production('args : expression ,')
        def args_single(env, p):
            return InnerArray([p[0]])

        @self.pg.production('args : expression , args')
        def arglist(env, p):
            p[2].append(p[0])
            return p[2]

        @self.pg.production('expression : open ( STRING )')
        @self.pg.production('openfile : open ( STRING )')
        def openfile(env, p):
            return Open(p[2].value)

        @self.pg.production('expression : openfile . read ( )')
        @self.pg.production('expression : IDENTIFIER . read ( )')
        def readfile(env, p):
            if type(p[0]) == Open:
                return Read(Open(p[0].filepath))
            else:
                return Read(Variable(p[0].value))

        @self.pg.production('statement : returning')
        def returning(env, p):
            return p[0]

        @self.pg.production('returning : return expression')
        def returnz(env, p):
            return Return(p[1])

        @self.pg.production('statement : import idlist')
        def importing(env, p):
            return Import(p[1], None)

        @self.pg.production('idlist : IDENTIFIER')
        @self.pg.production('idlist : IDENTIFIER . idlist')
        def importz(env, p):
            try:
                return p[0].value + "." + p[2]
            except IndexError:
                return p[0].value

        @self.pg.production('statement : from idlist import IDENTIFIER')
        def imported(env, p):
            return Import(p[3].value, p[1])

        @self.pg.production('expression : IDENTIFIER . IDENTIFIER')
        def importez(env, p):
            return GetAttr(p[0].value, p[2].value)

        @self.pg.production('kwargs : IDENTIFIER = expression')
        @self.pg.production('kwargs : IDENTIFIER = expression ,')
        def kwargs_single(state, p):
            return InnerDict({p[0].value: p[2]})

        @self.pg.production('kwargs : IDENTIFIER = expression , kwargs')
        def arglist(state, p):
            p[4].update(p[0].value, p[2])
            return p[4]

        @self.pg.production('dict : expression COLON expression')
        @self.pg.production('dict : expression COLON expression ,')
        def kwargs_single(state, p):
            return InnerDict({p[0]: p[2]})

        @self.pg.production('dict : expression COLON expression , dict')
        def arglist(state, p):
            p[4].update(p[0], p[2])
            return p[4]

        @self.pg.production('expression : { dict }')
        def expression_dict(state, p):
            return Dict(p[1])

        @self.pg.error
        def error_handler(env, token):
            if token.gettokentype() == "$end":
                raise SyntaxError(
                    "Ran into EoF while still parsing. Check to make sure you have end after every if/def"
                )
            print(token.getsourcepos())
            raise ValueError("Ran into a %s where it wasn't expected" %
                             token.gettokentype())

    def get_parser(self):
        return self.pg.build()
示例#57
0
文件: parser.py 项目: snim2/naulang
    return ast.UnaryNot(p[1], p[0].getsourcepos())

@pg.production("expression : expression IS expression")
@pg.production("expression : expression DOUBLE_EQ expression")
def expression_equality(p):
    return ast.Equals(p[0], p[2], p[1].getsourcepos())

@pg.production("expression : expression NOT_EQ expression")
def expression_notequals(p):
    return ast.NotEquals(p[0], p[2], p[1].getsourcepos())

@pg.production("expression : IDENTIFIER")
def expression_identifier(p):
    return ast.IdentifierExpression(p[0].getstr(), p[0].getsourcepos())

@pg.production("none : ")
def none(p):
    return None

@pg.error
def error_handler(token):
    raise ParsingError("Ran into a '%s' where it was't expected" % token.getstr(), token.getsourcepos())

PARSER = pg.build()

def create_parser():
    return PARSER

def create_lexer():
    return get_lexer()
示例#58
0
class Parser():
    def __init__(self, module, builder, printf):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            [
                'NUMERO',
                'ESCREVA',
                'APAR',
                'FPAR',
                'PONTO_VIRGULA',
                'SOMA',
                'SUB',
                'MUL',
                'DIV',
            ],
            precedence=[
                ('left', [
                    'SOMA',
                    'SUB',
                ]),
                ('left', [
                    'MUL',
                    'DIV',
                ]),
            ],
        )
        self.module = module
        self.builder = builder
        self.printf = printf

    def parse(self):
        @self.pg.production(
            'programa : ESCREVA APAR expressao FPAR PONTO_VIRGULA')
        def programa(p):
            return Print(self.builder, self.module, self.printf, p[2])

        @self.pg.production('expressao : expressao SOMA expressao')
        @self.pg.production('expressao : expressao SUB expressao')
        @self.pg.production('expressao : expressao MUL expressao')
        @self.pg.production('expressao : expressao DIV expressao')
        def expressao(p):
            left = p[0]
            right = p[2]
            operator = p[1]
            if operator.gettokentype() == 'SOMA':
                return Sum(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'SUB':
                return Sub(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'MUL':
                return Mul(self.builder, self.module, left, right)
            elif operator.gettokentype() == 'DIV':
                return Div(self.builder, self.module, left, right)

        @self.pg.production('expressao : NUMERO')
        def number(p):
            return Number(self.builder, self.module, p[0].value)

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()
示例#59
0
class Parser:
    def __init__(self, syntax=False):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            get_all_tokens_name(),
            # A list of precedence rules with ascending precedence, to
            # disambiguate ambiguous production rules.
            precedence=((AppConstant.LEFT, [TokenEnum.FUNCTION.name]),
                        (AppConstant.LEFT, [TokenEnum.LET.name]),
                        (AppConstant.LEFT,
                         [TokenEnum.ASSIGN.name]), (AppConstant.LEFT, [
                             TokenEnum.IF.name, TokenEnum.ELSE.name,
                             TokenEnum.SEMI_COLON.name
                         ]), (AppConstant.LEFT,
                              [TokenEnum.AND.name, TokenEnum.OR.name
                               ]), (AppConstant.LEFT, [TokenEnum.NOT.name]),
                        (AppConstant.LEFT, [
                            TokenEnum.EQ.name, TokenEnum.NEQ.name,
                            TokenEnum.GTEQ.name, TokenEnum.GT.name,
                            TokenEnum.LT.name, TokenEnum.LTEQ.name
                        ]), (AppConstant.LEFT,
                             [TokenEnum.SUM.name, TokenEnum.SUB.name]),
                        (AppConstant.LEFT,
                         [TokenEnum.MUL.name,
                          TokenEnum.DIV.name]), (AppConstant.LEFT, [
                              TokenEnum.STRING.name, TokenEnum.INTEGER.name,
                              TokenEnum.FLOAT.name, TokenEnum.BOOLEAN.name,
                              TokenEnum.PI.name, TokenEnum.E.name
                          ])))
        self.syntax = syntax
        self.parse()
        pass  # End Parser's constructor !

    def parse(self):
        @self.pg.production("main : program")
        def main_program(state, p):
            if self.syntax is True:
                return [Node(AppConstant.PROGRAM_NODE_NAME, p[0])]
            return Main(p[0])

        @self.pg.production('program : statement_full')
        def program_statement(state, p):
            if self.syntax is True:
                return [Node(AppConstant.STATEMENT_FULL_NODE_NAME, p[0])]
            return Program(p[0], None, state)

        @self.pg.production('program : statement_full program')
        def program_statement_program(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.STATEMENT_FULL_NODE_NAME, p[0]),
                    Node(AppConstant.PROGRAM_NODE_NAME, p[1])
                ]
            return Program(p[0], p[1], state)

        @self.pg.production('expression : LEFT_PARENT expression RIGHT_PARENT')
        def expression_parenthesis(state, p):
            if self.syntax is True:
                return [
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[1]),
                    Node('}')
                ]
            return ExpressParenthesis(p[1])

        @self.pg.production(
            'statement_full : IF LEFT_PARENT expression RIGHT_PARENT LEFT_BRACKET block RIGHT_BRACKET'
        )
        def expression_if(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.IF_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}'),
                    Node('{'),
                    Node(AppConstant.BLOCK_NODE_NAME, p[5]),
                    Node('}')
                ]
            return If(condition=p[2], body=p[5], state=state)

        @self.pg.production(
            'statement_full : IF LEFT_PARENT expression RIGHT_PARENT LEFT_BRACKET'
            ' block '
            'RIGHT_BRACKET ELSE LEFT_BRACKET'
            ' block '
            'RIGHT_BRACKET')
        def expression_if_else(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.IF_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}'),
                    Node('{'),
                    Node(AppConstant.BLOCK_NODE_NAME, p[5]),
                    Node('}'),
                    Node(AppConstant.ELSE_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.BLOCK_NODE_NAME, p[9]),
                    Node('}')
                ]
            return If(condition=p[2], body=p[5], else_body=p[9], state=state)

        @self.pg.production('block : statement_full')
        def block_expr(state, p):
            if self.syntax is True:
                return [Node("statement_full", p[0])]
            return Block(p[0], None, state)

        @self.pg.production('block : statement_full block')
        def block_expr_block(state, p):
            if self.syntax is True:
                return [
                    Node("statement_full", p[0]),
                    Node(AppConstant.BLOCK_NODE_NAME, p[1])
                ]
            return Block(p[0], p[1], state)

        @self.pg.production('statement_full : statement ' +
                            TokenEnum.SEMI_COLON.name)
        def statement_full(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.STATEMENT_NODE_NAME, p[0]),
                    Node(AppConstant.SEMI_COLON_SIGN)
                ]
            return StatementFull(p[0])

        @self.pg.production('statement : expression')
        def statement_expr(state, p):
            if self.syntax is True:
                return [Node(AppConstant.EXPRESSION_NODE_NAME, p[0])]
            return Statement(p[0])

        @self.pg.production('statement : LET IDENTIFIER ASSIGN expression')
        def statement_assignment(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.LET_NODE_NAME),
                    Node(AppConstant.IDENTIFIER_NODE_NAME, p[1]),
                    Node(AppConstant.EQUAL_SIGN),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[3])
                ]
            return Assignment(Variable(p[1].getstr(), state), p[3], state)

        @self.pg.production(
            'statement_full : FUNCTION IDENTIFIER LEFT_PARENT RIGHT_PARENT LEFT_BRACKET block RIGHT_BRACKET'
        )
        def statement_func_noargs(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.FUNCTION_NODE_NAME),
                    Node(AppConstant.IDENTIFIER_NODE_NAME, p[1]),
                    Node('{'),
                    Node('}'),
                    Node('{'),
                    Node(AppConstant.BLOCK_NODE_NAME, p[5]),
                    Node('}')
                ]
            return FunctionDeclaration(name=p[1].getstr(),
                                       args=None,
                                       block=p[5],
                                       state=state)

        @self.pg.production('expression : NOT expression')
        def expression_not(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.NOT_NODE_NAME),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[1])
                ]
            return Not(p[1], state)

        @self.pg.production('expression : expression SUM expression')
        @self.pg.production('expression : expression SUB expression')
        @self.pg.production('expression : expression MUL expression')
        @self.pg.production('expression : expression DIV expression')
        def expression_binary_operator(state, p):
            if p[1].gettokentype() == TokenEnum.SUM.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.SUM_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return Sum(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.SUB.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.SUM_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return Sub(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.MUL.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.MUL_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return Mul(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.DIV.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.DIV_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return Div(p[0], p[2], state)
            else:
                raise LogicError('Oops, this should not be possible!')

        @self.pg.production('expression : expression NEQ expression')
        @self.pg.production('expression : expression EQ expression')
        @self.pg.production('expression : expression GTEQ expression')
        @self.pg.production('expression : expression LTEQ expression')
        @self.pg.production('expression : expression GT expression')
        @self.pg.production('expression : expression LT expression')
        @self.pg.production('expression : expression AND expression')
        @self.pg.production('expression : expression OR expression')
        def expression_equality(state, p):
            if p[1].gettokentype() == TokenEnum.EQ.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.EQUAL_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return Equal(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.NEQ.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.NOT_EQUAL_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return NotEqual(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.GTEQ.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.GREATER_THAN_EQUAL_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return GreaterThanEqual(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.LTEQ.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.LESS_THAN__EQUAL_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return LessThanEqual(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.GT.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.GREATER_THAN_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return GreaterThan(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.LT.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.LESS_THAN_SIGN),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return LessThan(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.AND.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.AND_NODE_NAME),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return And(p[0], p[2], state)
            elif p[1].gettokentype() == TokenEnum.OR.name:
                if self.syntax is True:
                    return [
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[0]),
                        Node(AppConstant.OR_NODE_NAME),
                        Node(AppConstant.EXPRESSION_NODE_NAME, p[2])
                    ]
                return Or(p[0], p[2], state)
            else:
                raise LogicError("Shouldn't be possible")

        @self.pg.production('expression : INPUTTER LEFT_PARENT RIGHT_PARENT')
        def program(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.INPUTTER_NODE_NAME),
                    Node('{'),
                    Node('}')
                ]
            return Input()

        @self.pg.production(
            'expression : INPUTTER LEFT_PARENT expression RIGHT_PARENT')
        def program(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.INPUTTER_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Input(expression=p[2], state=state)

        @self.pg.production('statement : PRINT LEFT_PARENT RIGHT_PARENT')
        def program(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.PRINT_NODE_NAME),
                    Node('{'),
                    Node('}')
                ]
            return Print()

        @self.pg.production(
            'statement : PRINT LEFT_PARENT expression RIGHT_PARENT')
        def program(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.PRINT_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Print(first_expression=p[2], state=state)

        @self.pg.production(
            'statement : PRINT LEFT_PARENT expression COMMA expression RIGHT_PARENT'
        )
        def program(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.PRINT_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Print(first_expression=p[2],
                         second_expression=p[4],
                         state=state)

        @self.pg.production(
            'expression : ABSOLUTE LEFT_PARENT expression RIGHT_PARENT')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.MATH_ABS_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Absolute(p[2], state)

        @self.pg.production(
            'expression : SIN LEFT_PARENT expression RIGHT_PARENT')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.MATH_SIN_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Sin(p[2], state)

        @self.pg.production(
            'expression : COS LEFT_PARENT expression RIGHT_PARENT')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.MATH_COS_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Cos(p[2], state)

        @self.pg.production(
            'expression : TAN LEFT_PARENT expression RIGHT_PARENT')
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.MATH_TAN_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node('}')
                ]
            return Tan(p[2], state)

        @self.pg.production(
            'expression : POWER LEFT_PARENT expression COMMA expression RIGHT_PARENT'
        )
        def expression_absolute(state, p):
            if self.syntax is True:
                return [
                    Node(AppConstant.MATH_POW_NODE_NAME),
                    Node('{'),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[2]),
                    Node(AppConstant.COMMA_SIGN),
                    Node(AppConstant.EXPRESSION_NODE_NAME, p[4]),
                    Node('}')
                ]
            return Pow(p[2], p[4], state)

        @self.pg.production('expression : IDENTIFIER')
        def expression_variable(state, p):
            # Cannot return the value of a variable if it isn't yet defined
            if self.syntax is True:
                return [Node(AppConstant.IDENTIFIER_NODE_NAME, p[0])]
            return Variable(p[0].getstr(), state)

        @self.pg.production('expression : IDENTIFIER LEFT_PARENT RIGHT_PARENT')
        def expression_call_noargs(state, p):
            # Cannot return the value of a function if it isn't yet defined
            if self.syntax is True:
                return [
                    Node(AppConstant.IDENTIFIER_NODE_NAME, p[0]),
                    Node('{'),
                    Node('}')
                ]
            return CallFunction(name=p[0].getstr(), args=None, state=state)

        @self.pg.production('expression : const')
        def expression_const(state, p):
            if self.syntax is True:
                return [Node(AppConstant.CONSTANT_NODE_NAME, p[0])]
            return p[0]

        @self.pg.production('const : FLOAT')
        def constant_float(state, p):
            if self.syntax is True:
                return [Node(AppConstant.FLOAT_NODE_NAME, p[0])]
            return Float(p[0].getstr(), state)

        @self.pg.production('const : BOOLEAN')
        def constant_boolean(state, p):
            if self.syntax is True:
                return [Node(AppConstant.BOOLEAN_NODE_NAME, p[0])]
            return Boolean(p[0].getstr(), state)

        @self.pg.production('const : INTEGER')
        def constant_integer(state, p):
            if self.syntax is True:
                return [Node(AppConstant.INTEGER_NODE_NAME, p[0])]
            return Integer(p[0].getstr(), state)

        @self.pg.production('const : STRING')
        def constant_string(state, p):
            if self.syntax is True:
                return [Node(AppConstant.STRING_NODE_NAME, p[0])]
            return String(p[0].getstr().strip('"\''), state)

        @self.pg.production('const : PI')
        def constant_pi(state, p):
            if self.syntax is True:
                return [Node(AppConstant.MATH_CONST_PI_NODE_NAME, p[0])]
            return MathConstPI(p[0].getstr(), state)

        @self.pg.production('const : E')
        def constant_e(state, p):
            if self.syntax is True:
                return [Node(AppConstant.MATH_CONST_E_NODE_NAME, p[0])]
            return MathConstE(p[0].getstr(), state)

        @self.pg.error
        def error_handle(state, token):
            raise ValueError(token)

    def build(self):
        return self.pg.build()
示例#60
0
class Parser():
    def __init__(self):
        self.pg = ParserGenerator(
            # A list of all token names accepted by the parser.
            [
                'NUMBER', 'PRINT', 'SCANF', 'OPEN_KEY', 'CLOSE_KEY',
                'OPEN_PAR', 'CLOSE_PAR', 'SEMI_COLON', 'DOTS', 'COMMA', 'SUM',
                'SUB', 'MULT', 'DIV', 'OR', 'AND', 'NOT', 'BIGGER_THAN',
                'SMALLER_THAN', 'EQUAL_TO', 'DIFF', 'INT', 'CHAR', 'VOID',
                'WHILE', 'IF', 'ELSE', 'FUNC', 'QUOTE'
            ],
            precedence=[('left', ['PLUS', 'MINUS']), ('left', ['MULT', 'DIV']),
                        ('left', ['AND', 'OR'])])
#___________PROGRAM___________________________________________

    def parse(self):
        @self.pg.production('program : statement')
        def program(p):
            return p[0]

#_____________FUNCTION___________________________________________
# funct
#     : 'f', variable , "(", variable, {",", variable} ,")" ,':'
#     |'{',statement ,'}'
#     ;

        @self.pg.production(
            'statement : FUNC variable OPEN_PAREN variable OPEN_KEY COMMA variable CLOSE_KEY CLOSE_PAREN DOTS'
        )
        def function(p):
            return Function(p[1], p[3], p[5])
    # @self.pg.production('statement : OPEN_KEY statement CLOSE_KEY')

#_____________STATEMENT___________________________________________
#     statement
#    : 'if', paren_expr, '{',statement,'}' ,':'
#    | 'if', paren_expr ,'{',statement,'}' ,'else' ,'{',statement,'}' ,':'
#    | 'while', paren_expr, '{',statement,'}' ,':'
#    | 'print', paren_expr, ';'
#    | atribution
#    ;''

        @self.pg.production(
            'statement : IF paren_expression OPEN_KEY statement CLOSE_KEY DOTS'
        )
        def statement_if(p):
            return If(p[1], p[3])

        @self.pg.production(
            'statement : IF paren_expression OPEN_KEY statement CLOSE_KEY ELSE  OPEN_KEY statement CLOSE_KEY DOTS'
        )
        def statement_if_else(p):
            return IfElse(p[1], p[3], p[7])

        @self.pg.production(
            'statement : WHILE paren_expression OPEN_KEY statement CLOSE_KEY DOTS'
        )
        def statement_while(p):
            return IfElse(p[1], p[3])

        @self.pg.production('statement : PRINT paren_expression SEMI_COLON')
        def statement_print(p):
            return Print(p[1])

        # @self.pg.production('statement : attribution')
        # def atribution(p):

    #_____________PAREN_EXPRESSION__________________________________________
    # paren_expression
    #     : '(', expression, ')'
    #     | '(' ,bools, ')'
    #     | '(' ,relats, ')'
    #     ;

        @self.pg.production('paren_expression : OPEN_PAR expression CLOSE_PAR')
        @self.pg.production('paren_expression : OPEN_PAR booleans CLOSE_PAR')
        @self.pg.production(
            'paren_expression : OPEN_PAR relational_expression CLOSE_PAR')
        def paren_expression(p):
            return p[1]

    #_____________BOOLEANS__________________________________________
    # bools
    #     : expression, '//', expression
    #     | expression, '&&', expression
    #     | expression, '!',  expression
    #     ;

        @self.pg.production('booleans : expression OR expression',
                            precedence='OR')
        @self.pg.production('booleans : expression AND expression',
                            precedence='AND')
        @self.pg.production('booleans : expression NOT expression')
        def booleans(p):
            left = p[0]
            right = p[2]
            bool_operator = p[1]
            if bool_operator.gettokentype() == 'OR':
                return Or(left, right)
            elif bool_operator.gettokentype() == 'AND':
                return And(left, right)
            elif bool_operator.gettokentype() == 'NOT':
                return Not(left)

    #_____________RELATIONAL_EXPRESSION___________________________________________
    # relats
    #     : expression, '>',  expression
    #     | expression, '<',  expression
    #     | expression, '==', expression
    #     | expression, '!=', expression
    #     ;

        @self.pg.production(
            'relational_expression : expression BIGGER_THAN expression')
        @self.pg.production(
            'relational_expression : expression SMALLER_THAN expression')
        @self.pg.production(
            'relational_expression : expression EQUAL_TO EQUAL_TO expression')
        @self.pg.production(
            'relational_expression : expression DIFF expression')
        def relational_expression(p):
            left = p[0]
            right = p[2]
            relat_operator = p[1]
            if relat_operator.gettokentype() == 'BIGGER_THAN':
                return Bigger(left, right)
            elif relat_operator.gettokentype() == 'SMALLER_THAN':
                return Smaller(left, right)
            elif relat_operator.gettokentype() == 'EQUAL_TO':
                return Equal(left, right)
            elif relat_operator.gettokentype() == 'DIFF':
                return Different(left, right)

    #_____________EXPRESSION___________________________________________
    # expression
    #    :term
    #    |term, '+', term
    #    |term, '-', term
    #    ;

            @self.pg.production('expression : term')
            @self.pg.production('expression : term SUM term',
                                precedence='PLUS')
            @self.pg.production('expression : term SUB term',
                                precedence='MINUS')
            def expression(p):
                left = p[0]
                right = p[2]
                operator = p[1]
                if operator.gettokentype() == 'SUM':
                    return Sum(left, right)
                elif operator.gettokentype() == 'SUB':
                    return Sub(left, right)
                elif operator.gettokentype() == None:
                    return left

    #_____________TERM___________________________________________
    # term
    #    : factor, '*', factor
    #    | factor, '/', factor
    #    ;

        @self.pg.production('term : factor MULT factor', precedence='MULT')
        @self.pg.production('term : factor DIV factor', precedence='DIV')
        def term(p):
            left = p[0]
            right = p[2]
            t_operator = p[1]
            if t_operator.gettokentype() == 'MULT':
                return Multiply(left, right)
            elif t_operator.gettokentype() == 'DIV':
                return Divide(left, right)

    #_____________FACTOR___________________________________________
    # factor
    #    : '+', factor
    #    | '-', factor
    #    | number
    #    | '(',expression,')'
    #    | variable
    #    ;

        @self.pg.production('factor : SUM factor')
        @self.pg.production('factor : SUB factor')
        @self.pg.production('factor : number')
        @self.pg.production('factor : OPEN_PAR expression CLOSE_PAR')
        @self.pg.production('factor : variable')
        def factor(p):
            left = p[0]
            right = p[2]
            middle = p[1]
            if left.gettokentype() == 'SUM':
                return Plus(middle)
            elif left.gettokentype() == 'SUB':
                return Minus(middle)
            elif left.gettokentype() == 'number':
                return left
            elif middle.gettokentype() == 'expression':
                return middle
            elif left.gettokentype() == 'variable':
                return left

    #_____________ATTRIBUTION___________________________________________
    # attribution
    #     : variable, '=', expression
    #     ;

        @self.pg.production('attribution : variable EQUAL_TO expression')
        def attribution(p):
            return

    #_____________VARIABLE___________________________________________
    # variable
    #    : STRING, {STRING, INT, '_'}
    #    ;

        @self.pg.production('expression : STRING')
        @self.pg.production('expression : STRINGINT')
        @self.pg.production('expression : STRING_')
        @self.pg.production('expression : STRING_STRING')
        @self.pg.production('expression : STRING_INT')
        def variable(p):
            return String(p[0].value)
    #_____________NUMBER___________________________________________
    # number
    #    : FLOAT
    #    ;

        @self.pg.production('expression : NUMBER')
        def number(p):
            return Number(p[0].value)
    #____________STRING__________________________________________
    # STRING
    #    :  "A" | "B" | "C" | "D" | "E" | "F" | "G"
    #     | "H" | "I" | "J" | "K" | "L" | "M" | "N"
    #     | "O" | "P" | "Q" | "R" | "S" | "T" | "U"
    #     | "V" | "W" | "X" | "Y" | "Z"
    #     | "a" | "b"| "c" | "d" | "e" | "f" | "g"
    #     | "h" | "i"| "j" | "k" | "l" | "m" | "n"
    #     | "o" | "p"| "q" | "r" | "s" | "t" | "u"
    #     | "v" | "w"| "x" | "y" | "z" ;
    #    ;

        @self.pg.production('expression : STRING')
        def string(p):
            return String(p[0].value)
    #_____________FLOAT___________________________________________
    # FLOAT
    #    : INT, ['.', INT]
    #    ;

        @self.pg.production('expression : FLOAT')
        @self.pg.production('expression : INT.INT')
        def float(p):
            return Number(p[0].value)

    #_____________INTEGER___________________________________________
    # INT
    #    : "0"|"1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
    #    ;

        @self.pg.production('expression : INT')
        def integer(p):
            return Number(p[0].value)

# _____________TEXT___________________________________________

        @self.pg.production('text : QUOTE IDENTIFIER QUOTE')
        def text(p):
            return p[1]

        @self.pg.error
        def error_handle(token):
            raise ValueError(token)

    def get_parser(self):
        return self.pg.build()