예제 #1
0
 def mult(self):
     expr = self.unary()
     while (self.match_val('/', '*', '%')):
         op = self.pop().val
         rhs = self.unary()
         expr = ast.Binary(expr, op, rhs)
     return expr
예제 #2
0
 def add(self):
     expr = self.mult()
     while (self.match_val('+', '-')):
         op = self.pop().val
         rhs = self.mult()
         expr = ast.Binary(expr, op, rhs)
     return expr
예제 #3
0
 def compare(self):
     expr = self.add()
     while (self.match_val('>', '<', '<=', '>=')):
         op = self.pop().val
         rhs = self.add()
         expr = ast.Binary(expr, op, rhs)
     return expr
예제 #4
0
 def expr(self):
     expr = self.compare()
     while (self.match_val('==', '!=')):
         op = self.pop().val
         rhs = self.compare()
         expr = ast.Binary(expr, op, rhs)
     return expr
예제 #5
0
    def _parse_array_offset(self, expr, env):
        """
        Parses the array offset.

        """
        self._match('[')
        num = self._parse_logical_expression(env)
        self._match(']')
        of_type = expr.get_type().get_of_type()
        width = ast.Constant(lexer.Num(of_type.get_width()), ty.Type.Int)
        expr_id = expr
        offset = ast.Binary(lexer.Token('*'), num, width)
        if type(expr) is ast.Access:
            expr_id = expr.get_access_id()
            offset = ast.Binary(lexer.Token('+'), expr.get_offset(), offset)
        return ast.Access(lexer.Word('[]', lexer.Tag.INDEX), of_type, expr_id,
                          offset)
예제 #6
0
    def _parse_and_expression(self, env):
        """ <and_expression>

        Parses the <and_expression> language structure.

            and_expression -> and_expression '&' equality_expression
                                    |   equality_expression

        """
        eqexp = self._parse_equality_expression(env)
        while self._look.tag == '&':
            tok = self._look.tag
            self._match('&')
            eqexp = ast.Binary(tok, eqexp, self._parse_and_expression(env))
        return eqexp
예제 #7
0
    def _parse_exclusive_or_expression(self, env):
        """ <exclusive_or_expression>

        Parses the <exclusive_or_expression> language structure.

            exclusive_or_expression -> exclusive_or_expression '^' and_expression
                                    |   and_expression

        """
        andexp = self._parse_and_expression(env)
        while self._look.tag == '^':
            tok = self._look
            self._match('^')
            andexp = ast.Binary(tok, andexp,
                                self._parse_exclusive_or_expression(env))
        return andexp
예제 #8
0
    def _parse_inclusive_or_expression(self, env):
        """ <inclusive_or_expression>

        Parses the <inclusive_or_expression> language structure.

            inclusive_or_expression -> inclusive_or_expression '|' exclusive_or_expression
                                    |   exclusive_or_expression

        """
        exclor = self._parse_exclusive_or_expression(env)
        while self._look.tag == '|':
            tok = self._look
            self._match('|')
            exclor = ast.Binary(tok, exclor,
                                self._parse_inclusive_or_expression(env))
        return exclor
예제 #9
0
    def _parse_shift_expression(self, env):
        """ <shift_expression>

        Parses the <shift_expression> language structure.

            shift_expression -> shift_expression '<<' additive_expression
                            |   shift_expression '>>' additive_expression
                            |   additive_expression

        """
        addexp = self._parse_additive_expression(env)
        while self._look.tag == lexer.Tag.LS or self._look.tag == lexer.Tag.RS:
            tok = self._look
            if self._look.tag == lexer.Tag.LS:
                self._match(lexer.Tag.LS)
            else:
                self._match(lexer.Tag.RS)
            addexp = ast.Binary(tok, addexp, self._parse_shift_expression(env))
        return addexp
예제 #10
0
    def _parse_multiplicative_expression(self, env):
        """ <multiplicative_expression>

        Parses the <multiplicative_expression> language structure.

            multiplicative_expression -> multiplicative_expression '*' cast_expression
                                    |   multiplicative_expression '/' cast_expression
                                    |   cast_expression

        """
        castexp = self._parse_cast_expression(env)
        while self._look.tag == '*' or self._look.tag == '/':
            tok = self._look
            if self._look.tag == '*':
                self._match('*')
            else:
                self._match('/')
            castexp = ast.Binary(tok, castexp,
                                 self._parse_multiplicative_expression(env))
        return castexp
예제 #11
0
    def _parse_additive_expression(self, env):
        """ <additive_expression>

        Parses the <additive_expression> language structure.

            additive_expression -> additive_expression '+' multiplicative_expression
                            |   additive_expression '-' multiplicative_expression
                            |   multiplicative_expression

        """
        mulexp = self._parse_multiplicative_expression(env)
        while self._look.tag == '+' or self._look.tag == '-':
            tok = self._look
            if self._look.tag == '+':
                self._match('+')
            else:
                self._match('-')
            mulexp = ast.Binary(tok, mulexp,
                                self._parse_additive_expression(env))
        return mulexp
예제 #12
0
    def statement(self):
        if self.match("let"):
            line = self.pop().line

            ty = self.type()
            if self.match_val("="):
                name = ty[1]
                ty = None
                #this is where more complete type parsing would happen
                #for the time being, just error out
            elif self.match("ident"):
                name = self.pop().val
            else:
                raise ValueError(
                    f"expected type in var declaration on line {line}, saw {self.tl[0].val}"
                )
            self.consume(
                "=",
                f"expected '=' in let declaration on line {line}, saw {self.tl[0].val}"
            )
            ex = self.expr()
            if ty != None:
                return ast.Let(name, (ty, None), ex)
            else:
                return ast.Let(name, None, ex)

        elif self.match("var"):
            line = self.pop().line
            ty = self.type()
            if self.match_val("="):
                name = ty[0]
                ty = None
                #this is where more complete type parsing would happen
                #for the time being, just error out
            elif self.match("ident"):
                name = self.pop().val
            else:
                raise ValueError(
                    f"expected type in var declaration on line {line}, saw {self.tl[0].val}"
                )

            self.consume(
                "=",
                f"expected '=' in var declaration on line {line}, saw {self.tl[0].val}"
            )
            ex = self.expr()
            return ast.Var(name, ty, ex)
        elif self.match("if"):
            line = self.pop().line
            ex = self.expr()
            thenstmnts = self.statementlist("if statement", line)
            if not self.match("else"):
                elsestmnts = None
            else:
                line = self.pop().line
                elsestmnts = self.statementlist("else statement", line)
            return ast.If(ex, thenstmnts, elsestmnts)
        elif self.match('return'):
            self.pop()
            returning = self.expr()
            return ast.Return(returning)
        elif self.match('while'):
            line = self.pop().line
            condition = self.expr()
            body = self.statementlist("while body", line)
            return ast.While(condition, body)
        else:
            lhs = self.expr()
            if self.match_val('=') or self.match_val('+=') or self.match_val(
                    '-=') or self.match_val('*=') or self.match_val(
                        '/=') or self.match_val('%='):
                op = self.pop().val
                rhs = self.expr()
                if (op[0] != '='):
                    rhs = ast.Binary(lhs, op[0], rhs)
                return ast.Assign(lhs, rhs)
            else:
                return lhs