Beispiel #1
0
    def term(self):
        """
        T -> F | F + T | F - T 
        """
        left = self.factor()
        peek = self.peek()
        if peek.token == "plus":
            plus = self.match("plus")
            right = self.term()
            return ast.ASTNode("plus_exp", plus, [left, right])
        elif peek.token == "minus":
            minus = self.match("minus")
            right = self.term()
            return ast.ASTNode("minus_exp", minus, [left, right])

        return left
Beispiel #2
0
 def return_statement(self):
     """
     R -> return E
     """
     r = self.match("return")
     e = self.expr()
     self.match("semicolon")
     return ast.ASTNode("return", r, [e])
Beispiel #3
0
 def var_decl_statement(self):
     """
     Let -> let id = E; | let id: Ty;
     """
     self.match("let")
     i = self.match("id")
     # let id = E
     if self.peek().token == "assign":
         self.match("assign")
         e = self.expr()
         self.match("semicolon")
         return ast.ASTNode("var_decl_assign", i, [e])
     # let id: Ty
     self.match("colon")
     ty = self.type_decl()
     self.match("semicolon")
     return ast.ASTNode("var_decl", i, [ty])
Beispiel #4
0
 def fn(self):
     self.match("function def")
     f = self.match("id")
     self.match("left paren")
     self.match("right paren")
     self.match("left brace")
     s = self.statement_list()
     self.match("right brace")
     return ast.ASTNode("main", f, [s])
Beispiel #5
0
 def assign_statement(self):
     """
     Ass -> id = E
     """
     lhs = self.var()
     e = self.match("assign")
     ex = self.expr()
     self.match("semicolon")
     return ast.ASTNode("assignment", e, [lhs, ex])
Beispiel #6
0
 def type_decl(self):
     """
     Ty -> i32 | bool | <id>
     """
     peek = self.peek()
     valid_type_tokens = ["i32", "bool", "id"]
     if peek.token in valid_type_tokens:
         t = self.match(peek.token)
         return ast.ASTNode(peek.token, t, None)
     self.error(f"Expected a type found: {peek}")
Beispiel #7
0
 def statement_list(self):
     """
     L -> S L | S
     assume all statement lists must end if next token is }
     """
     statements = []
     s = self.statement()
     statements.append(s)
     while self.peek().token != "right brace":
         statements.append(self.statement())
     return ast.ASTNode("statement_list", s.symbol, statements)
Beispiel #8
0
    def factor(self):
        """
        F -> P | P * F
        """
        left = self.paren()
        peek = self.peek()
        if peek.token == "times":
            times = self.match("times")
            right = self.factor()
            return ast.ASTNode("times_exp", times, [left, right])

        return left
Beispiel #9
0
 def expr(self):
     """
     E -> T
     E -> T == T
     """
     t = self.term()
     peek = self.peek()
     if peek.token == "equality":
         e = self.match("equality")
         t2 = self.term()
         return ast.ASTNode("equality_exp", e, [t, t2])
     return t
Beispiel #10
0
def test_parse1():
    prog = ["3 * (2 + 8) - 9 * 11;"]
    tokens = scanner.scan(prog, lexing_rules.RULES)
    p = parser.Parser(tokens)
    root = p.expr()

    a3 = ast.ASTNode("int_literal", scanner.Symbol("int literal", "3", 3, 1, 1), None)
    a2 = ast.ASTNode("int_literal", scanner.Symbol("int literal", "2", 2, 1, 6), None)
    a8 = ast.ASTNode("int_literal", scanner.Symbol("int literal", "8", 8, 1, 10), None)
    a9 = ast.ASTNode("int_literal", scanner.Symbol("int literal", "9", 9, 1, 15), None)
    a11 = ast.ASTNode("int_literal", scanner.Symbol("int literal", "11", 11, 1, 19), None)

    plus = ast.ASTNode("plus_exp", scanner.Symbol("plus", "+", None, 1,  8), [a2, a8])
    times1 = ast.ASTNode("times_exp", scanner.Symbol("times", "*", None, 1,  3), [a3, plus])
    times2 = ast.ASTNode("times_exp", scanner.Symbol("times", "*", None, 1,  17), [a9, a11])
    minus = ast.ASTNode("minus_exp", scanner.Symbol("minus", "-", None, 1,  13), [times1, times2])

    assert root == minus
Beispiel #11
0
    def if_statement(self):
        """
        If -> if (E) { L } | if (E) { L } else { L }
        """
        i = self.match("if")
        self.match("left paren")
        e = self.expr()
        self.match("right paren")
        self.match("left brace")
        l1 = self.statement_list()
        self.match("right brace")
        if self.peek().token == "else":
            self.match("else")
            self.match("left brace")
            l2 = self.statement_list()
            self.match("right brace")
            # children are:
            #  expression condition, if statement list, else statment list
            return ast.ASTNode("if_statement", i, [e, l1, l2])

        # children are:
        #  expression condition, if statement list
        return ast.ASTNode("if_statement", i, [e, l1])
Beispiel #12
0
    def paren(self):
        """
        P -> I | (E) | input | bool | Var
        """
        peek = self.peek()
        if peek.token == "left paren":
            self.match("left paren")
            ex = self.term()
            self.match("right paren")
            return ex
        elif peek.token == "int literal":
            return self.int_literal()
        elif peek.token == "input":
            i = self.match("input")
            self.match("left paren")
            self.match("right paren")
            return ast.ASTNode("input_exp", i, None)
        elif peek.token == "bool_literal":
            return self.bool_literal()
        elif peek.token == "id":
            return self.var()

        self.error(f"unexpected {peek}")
Beispiel #13
0
 def bool_literal(self):
     s = self.match("bool_literal")
     return ast.ASTNode("bool_literal", s, None)
Beispiel #14
0
 def int_literal(self):
     sym = self.match("int literal")
     return ast.ASTNode("int_literal", sym, None)
Beispiel #15
0
 def var(self):
     """
     Var -> id
     """
     i = self.match("id")
     return ast.ASTNode("var", i, None)