Ejemplo n.º 1
0
 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 = {}
Ejemplo n.º 2
0
 def __init__(self,
              lexer_or_tokens: Union[Lexer, Iterable[str]],
              precedence: Optional[ParserPrecedence] = None):
     self._pg = ParserGenerator(
         lexer_or_tokens.possible_tokens if isinstance(
             lexer_or_tokens, Lexer) else lexer_or_tokens, precedence or [])
     self._pg.error(self._handle_error)
Ejemplo n.º 3
0
    def test_invalid_associativity(self):
        pg = ParserGenerator([], precedence=[
            ("to-the-left", ["term"]),
        ])

        with py.test.raises(ParserGeneratorError):
            pg.build()
Ejemplo n.º 4
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)
Ejemplo n.º 5
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(FakeLexer([
            Token("MINUS", "-"),
            Token("NUMBER", "4"),
            Token("MINUS", "-"),
            Token("NUMBER", "5"),
        ])) == BoxInt(-9)
Ejemplo n.º 6
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(FakeLexer([
            Token("NUMBER", "3"),
            Token("TIMES", "*"),
            Token("NUMBER", "4"),
            Token("PLUS",  "+"),
            Token("NUMBER", "5")
        ])) == BoxInt(17)
Ejemplo n.º 7
0
 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 !
Ejemplo n.º 8
0
 def __init__(self):
     self.pg = ParserGenerator(
         # A list of all token names accepted by the parser.
         [
             'NUMBER', 'PRINT', 'OPEN_PAREN', 'CLOSE_PAREN', 'SEMI_COLON',
             'SUM', 'SUB', 'OPEN_QUOTE', 'CLOSE_QUOTE'
         ])
Ejemplo n.º 9
0
 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"]),
                               ])
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
    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)
Ejemplo n.º 12
0
 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 !
Ejemplo n.º 13
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 == [
            {
                "$end": -3,
                "VALUE": 3
            },
            {
                "$end": 0
            },
            {
                "$end": -1
            },
            {
                "$end": -3,
                "VALUE": 3
            },
            {
                "$end": -2
            },
        ]
Ejemplo n.º 14
0
 def __init__(self):
     self.pg = ParserGenerator(
         # A list of all token names accepted by the parser.
         [
             'SCANF', 'OPEN_PAREN', 'CLOSE_PAREN', 'POINT', 'PLUS', 'COMMA',
             'SEMI_COLON', 'CONNECTION_CLASS', 'EXEC_FUNC', 'VAR', 'STRING'
         ])
Ejemplo n.º 15
0
 def __init__(self):
     self.pg = ParserGenerator([
         'NUMBER', 'OPEN_PARENS', 'CLOSE_PARENS', 'SEMI_COLON', 'SUM', 'SUB'
     ],
                               precedence=[
                                   ('left', ['SUM', 'SUB']),
                               ])
Ejemplo n.º 16
0
 def __init__(self, module, builder, printf):
     self.pg = ParserGenerator(
         # A list of all token names accepted by the parser.
         ['RESERVED', 'END', 'DIGIT', 'LETTER', 'SPECIAL'])
     self.module = module
     self.builder = builder
     self.printf = printf
Ejemplo n.º 17
0
 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
Ejemplo n.º 18
0
    def __init__(self):
        self.token_list = ["NUMBER", "PLUS", "EXIT"]
        pg = ParserGenerator(self.token_list, cache_id='wcc')

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

        @pg.production("statement : addition")
        @pg.production("statement : exit")
        def main(p):
            return p[0]

        @pg.production("exit : EXIT")
        def exit_prod(p):
            return ExitBox()

        @pg.production("number : NUMBER")
        def number(p):
            return IntBox(p[0])

        @pg.production("addition : PLUS number number")
        def addition0(p):
            return BinaryAddBox(p[1], p[2])

        @pg.production("addition : number PLUS number")
        def addition1(p):
            return BinaryAddBox(p[0], p[2])

        @pg.production("addition : number number PLUS")
        def addition2(p):
            return BinaryAddBox(p[0], p[1])

        self.parser = pg.build()
Ejemplo n.º 19
0
    def test_duplicate_precedence(self):
        pg = ParserGenerator([], precedence=[
            ("left", ["term", "term"])
        ])

        with py.test.raises(ParserGeneratorError):
            pg.build()
Ejemplo n.º 20
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(FakeLexer([
            Token("VALUE", "abc"),
            Token("SPACE", " "),
            Token("VALUE", "def"),
            Token("SPACE", " "),
            Token("VALUE", "ghi"),
        ])) == ["abc", "def", "ghi"]

        assert parser.parse(FakeLexer([])) == []
Ejemplo n.º 21
0
 def __init__(self):
     self.pg = ParserGenerator([
         'ADD', 'COLON', 'PREDICTION', 'CLUSTERING', 'FLOAT', 'STATS',
         'PLOT', 'C_PLOT', 'SENTENCE', 'PRINT', 'FORECAST', 'VAR', 'EQUAL',
         'INT', 'OPEN_BRA', 'CLOSE_BRA', 'OPEN_PAREN', 'CLOSE_PAREN',
         'SEMI_COLON', 'COMA', 'METHOD', 'BOOLEAN', 'TYPE_A'
     ])
Ejemplo n.º 22
0
    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"))
Ejemplo n.º 23
0
    def test_parser_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()

        def f():
            state = ParserState()
            return parser.parse(FakeLexer([
                Token("NUMBER", "10"),
                Token("PLUS", "+"),
                Token("NUMBER", "12"),
                Token("PLUS", "+"),
                Token("NUMBER", "-2"),
            ]),
                                state=state).getint() + state.count

        assert self.run(f, []) == 26
Ejemplo n.º 24
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(
                FakeLexer([
                    Token("NUMBER", str(n)),
                    Token("PLUS", "+"),
                    Token("NUMBER", str(n))
                ])).getint()

        assert self.run(f, [12]) == 24
Ejemplo n.º 25
0
    def __init__(self):
        self.indent_count = 0
        self.definition_list = []

        self.pg = ParserGenerator(
            # A list of all token names, accepted by the parser.
            [
                'INTEGER', 'IDENTIFIER', 'IF', 'ELSE', 'COLON', 'NOT', 'WHILE',
                'END', 'FUNCTION', 'OPENPAREN', 'CLOSEPAREN', 'NOT', 'IMPORT',
                'BEGIN', 'MOVE', 'LEFTTURN', 'PUTBEEPER', 'PICKBEEPER',
                'FACENORTH', 'FACESOUTH', 'FACEWEST', 'LEFTCLEAR',
                'RIGHTCLEAR', 'FRONTCLEAR', 'PRESENT', 'INBAG', 'FOR',
                'FACEEAST', 'INDENT', 'DEDENT'
            ],
            # A list of precedence rules with ascending precedence, to
            # disambiguate ambiguous production rules.
            precedence=[('left', [
                'FUNCTION',
            ]), ('left', ['[', ']', ',']),
                        ('left', [
                            'IF',
                            'COLON',
                            'ELSE',
                            ' ',
                            'WHILE',
                        ])])
Ejemplo n.º 26
0
 def __init__(self):
     self.pg = ParserGenerator(
         # A list of all token names accepted by the parser.
         [
             'NOMBRE', 'MON', 'PARENTESE1', 'PARENTESE2', 'POINT_VERG',
             'PLUS', 'MOINS', 'FOIS', 'DIVI', 'TERM', 'EGAL', 'QUOTE',
             'VERGULE', 'DOLLAR'
         ])
Ejemplo n.º 27
0
 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'
         ])
Ejemplo n.º 28
0
 def __init__(self):
     self.parseGen = ParserGenerator(
         # A list of all token names accepted by the parser.
         [
             'NUMBER', 'PRINT', 'LEFT_PAREN', 'RIGHT_PAREN', 'EOL', 'SUM',
             'SUB', 'MUL', 'DIV'
         ],
         precedence=[('left', ['SUM', 'SUB']), ('left', ['MUL', 'DIV'])])
Ejemplo n.º 29
0
 def __init__(self):
     self.pg = ParserGenerator(
         [
             'SELECT', 'FROM', 'WHERE', 'SEP', 'BOXPLOT', 'STR', 'GRT',
             'LSS', 'EQ'
         ]
         #Adicionar o NUM no final, agora é tudo string
     )
Ejemplo n.º 30
0
 def __init__(self, module, builder, printf):
     self.pg = ParserGenerator([
         'NUMBER', 'PRINT', 'OPEN_PAREN', 'CLOSE_PAREN', 'SEMI_COLON',
         'ADD', 'SUB'
     ])
     self.module = module
     self.builder = builder
     self.printf = printf