Ejemplo n.º 1
0
    def parse_pri_expr(self):
        """ primary-Expression ::= Integer-Literal
                    |   V-name (or identifier)
                    |   Operator primary-Expression
                    |   '(' Expression ')' """

        token = self.token_current()

        if (token.type == scanner.TK_INTLITERAL):
            self.token_accept(scanner.TK_INTLITERAL)
            return ast.IntegerExpression(token.val)

        if (token.type == scanner.TK_IDENTIFIER):
            v = ast.Vname(token.val)
            self.token_accept(scanner.TK_IDENTIFIER)
            return ast.VnameExpression(v)

        if (token.type == scanner.TK_LPAREN):
            self.token_accept(scanner.TK_LPAREN)
            e1 = self.parse_expr()
            self.token_accept(scanner.TK_RPAREN)
            return e1

        else:  #just added
            raise ParserError(self.curtoken.pos, self.curtoken.type)
Ejemplo n.º 2
0
    def parse_single_command(self):
        """single-Command ::=  Identifier ( ':=' Expression | '(' Expression ')')
                           |   if Expression then single-Command
                               else single-Command
                           |   while Expression do single-Command
                           |   let Declaration in single-Command
                           |   begin Command end
                           |   return Expression
        """

        token = self.token_current()

        if token.type == scanner.TK_IDENTIFIER:
            self.token_accept_any()
            token_next = self.token_current()
            if token_next.type == scanner.TK_BECOMES:
                self.token_accept_any()
                expr = self.parse_expression()
                cmd = ast.AssignCommand(ast.Vname(token.val), expr)
            elif token_next.type == scanner.TK_LPAREN:
                self.token_accept_any()
                expr = self.parse_arg_expr()
                self.token_accept(scanner.TK_RPAREN)
                cmd = ast.CallCommand(token.val, expr)
            self.token_accept(scanner.TK_SEMICOLON)
        elif token.type == scanner.TK_IF:
            self.token_accept_any()
            expr = self.parse_expression()
            self.token_accept(scanner.TK_THEN)
            sc1 = self.parse_single_command()
            self.token_accept(scanner.TK_ELSE)
            sc2 = self.parse_single_command()
            cmd = ast.IfCommand(expr, sc1, sc2)
        elif token.type == scanner.TK_WHILE:
            self.token_accept_any()
            expr = self.parse_expression()
            self.token_accept(scanner.TK_DO)
            sc1 = self.parse_single_command()
            cmd = ast.WhileCommand(expr, sc1)
        elif token.type == scanner.TK_LET:
            self.token_accept_any()
            decl = self.parse_declaration()
            self.token_accept(scanner.TK_IN)
            sc1 = self.parse_single_command()
            cmd = ast.LetCommand(decl, sc1)
        elif token.type == scanner.TK_BEGIN:
            self.token_accept_any()
            cmd = self.parse_command()
            self.token_accept(scanner.TK_END)
        elif token.type == scanner.TK_RETURN:
            self.token_accept_any()
            expr = self.parse_expression()
            cmd = ast.ReturnCommand(expr)
            self.token_accept(scanner.TK_SEMICOLON)
        else:
            raise ParserError(self.curtoken.pos, self.curtoken.type)
        return cmd
    def parse_parameter_list(self):
        """ Identifier ':' 'Type-denoter' ( ',' Identifier : Type-denoter )*
        Returns a list of tuples with the format [(Vname(var_name), TypeDenoter(var_type)),...]
        """

        param_list = []
        var_name = self.token_current().val
        self.token_accept(scanner.TK_IDENTIFIER)
        self.token_accept(scanner.TK_COLON)
        var_type = self.token_current().val
        self.token_accept(scanner.TK_IDENTIFIER)
        param_list.append((ast.Vname(var_name), ast.TypeDenoter(var_type)))

        while self.curtoken.type == scanner.TK_COMMA:
            self.token_accept_any()
            var_name = self.token_current().val
            self.token_accept(scanner.TK_IDENTIFIER)
            self.token_accept(scanner.TK_COLON)
            var_type = self.token_current().val
            self.token_accept(scanner.TK_IDENTIFIER)
            param_list.append((ast.Vname(var_name), ast.TypeDenoter(var_type)))
        return param_list
    def parse_primary_expression(self):
        """Integer-Literal
        |  V-name
        |  Operator primary-Expression
        |  '(' Expression ')'
        |  function-call
        """

        token = self.token_current()
        # Integer-Literal
        if token.type == scanner.TK_INTLITERAL:
            e1 = ast.IntegerExpression(token.val)
            self.token_accept_any()
        # Variable name or function call
        elif token.type == scanner.TK_IDENTIFIER:
            name = self.token_current().val
            self.token_accept_any()

            # Function call
            if self.curtoken.type == scanner.TK_LPAREN:
                self.token_accept_any()
                param_list = self.parse_argument_list()
                self.token_accept(scanner.TK_RPAREN)
                e1 = ast.CallCommand(name, param_list)
            # Variable name
            else:
                e1 = ast.VnameExpression(ast.Vname(name))
        # Unary Expression
        elif token.type == scanner.TK_OPERATOR:
            oper = self.token_current()
            self.token_accept_any()
            e1 = ast.UnaryExpression(oper.val, self.parse_primary_expression())
        # ( Expression )
        elif token.type == scanner.TK_LPAREN:
            self.token_accept_any()
            e1 = self.parse_expression()
            self.token_accept(scanner.TK_RPAREN)
        # Unexpected tokens
        else:
            raise ParserException(self.curtoken.pos, self.curtoken.type)
        return e1
Ejemplo n.º 5
0
    def parse_primary_expression(self):
        """ primary-Expression ::=  Integer-Literal
                                |   Identifier ( *empty* | '(' Expression ')' )
                                |   Operator primary-Expression
                                |   '(' Expression ')' 
        """

        token = self.token_current()
        if token.type == scanner.TK_INTLITERAL:

            self.token_accept_any()
            expr = ast.IntegerExpression(token.val)

        elif token.type == scanner.TK_IDENTIFIER:
            self.token_accept_any()
            next = self.token_current()
            if next.type == scanner.TK_LPAREN:
                ident = token.val
                self.token_accept_any()
                expr = self.parse_arg_expr()
                self.token_accept(scanner.TK_RPAREN)
                expr = ast.CallExpression(ident, expr)
            else:
                expr = ast.VnameExpression(ast.Vname(token.val))
        elif token.type == scanner.TK_OPERATOR:
            oper = token.val
            self.token_accept_any()
            expr = self.parse_primary_expression()
            expr = ast.UnaryExpression(oper, expr)
        elif token.type == scanner.TK_LPAREN:
            self.token_accept_any()
            expr = self.parse_expression()
            self.token_accept(scanner.TK_RPAREN)
            return expr
        else:
            raise ParserError(self.curtoken.pos, self.curtoken.type)

        return expr
Ejemplo n.º 6
0
    def parse_single_command(self):
        """ single-Command     ::=  V-name ':=' Expression
                    |   Identifier '(' Expression ')'
                    |   if Expression then single-Command
                           else single-Command
                    |   while Expression do single-Command
                    |   let Declaration in single-Command
                    |   begin Command end """

        token = self.token_current()

        if token.type == scanner.TK_IDENTIFIER:
            temp = token.val
            self.token_accept(scanner.TK_IDENTIFIER)
            token = self.token_current()

            if token.type == scanner.TK_BECOMES:
                self.token_accept(scanner.TK_BECOMES)
                vname = ast.Vname(temp)
                e1 = self.parse_expr()
                token = self.token_current()
                return ast.AssignCommand(vname, e1)

            if token.type == scanner.TK_LPAREN:
                self.token_accept(scanner.TK_LPAREN)
                e1 = self.parse_expr()
                self.token_accept(scanner.TK_RPAREN)
                return ast.CallCommand(temp, e1)

            else:  #just added
                raise ParserError(self.curtoken.pos, self.curtoken.type)

        if token.type == scanner.TK_IF:
            self.token_accept(scanner.TK_IF)
            e1 = self.parse_expr()
            token = self.token_current()

            if token.type == scanner.TK_THEN:
                self.token_accept(scanner.TK_THEN)
                e2 = self.parse_single_command()
                token = self.token_current()

                if token.type == scanner.TK_ELSE:
                    self.token_accept(scanner.TK_ELSE)
                    e3 = self.parse_single_command()
                    token = self.token_current()
                    return ast.IfCommand(e1, e2, e3)

                else:
                    raise ParserError(self.curtoken.pos, self.curtoken.type)

            else:
                raise ParserError(self.curtoken.pos, self.curtoken.type)

        if token.type == scanner.TK_WHILE:
            self.token_accept_any()
            e1 = self.parse_expr()
            token = self.token_current()

            if token.type == scanner.TK_DO:
                self.token_accept_any()
                e2 = self.parse_single_command()
                token = self.token_current()
                return ast.WhileCommand(e1, e2)
            else:
                raise ParserError(self.curtoken.pos, self.curtoken.type)

        if token.type == scanner.TK_BEGIN:
            self.token_accept(scanner.TK_BEGIN)

            while token.type != scanner.TK_END:
                e1 = self.parse_command()
                token = self.token_current()

            if token.type == scanner.TK_END:
                self.token_accept_any()
                token = self.token_current()
            return e1

        if token.type == scanner.TK_LET:
            e1 = self.parse_let_command()
            return e1

        else:  #just added
            raise ParserError(self.curtoken.pos, self.curtoken.type)
    def parse_single_command(self):
        """V-name ':=' Expression ';'
        |  call-command ';'
        |  if Expression then single-Command else single-Command
        |  while Expression do single-Command
        |  let Declaration in single-Command
        |  begin Command end
        """
        # Assignment or Function Call
        if self.curtoken.type == scanner.TK_IDENTIFIER:
            name = self.token_current().val
            self.token_accept_any()

            # Variable Assignment
            if self.curtoken.type == scanner.TK_BECOMES:
                self.token_accept_any()
                expr = self.parse_expression()
                self.token_accept(scanner.TK_SEMICOLON)
                return ast.AssignCommand(ast.Vname(name), expr)
            # Function call
            elif self.curtoken.type == scanner.TK_LPAREN:
                self.token_accept_any()
                param_list = self.parse_argument_list()
                self.token_accept(scanner.TK_RPAREN)
                self.token_accept(scanner.TK_SEMICOLON)
                return ast.CallCommand(name, param_list)
            # Unexpected tokens
            else:
                raise ParserException(self.curtoken.pos, self.curtoken.type)
        # While Loop
        elif self.curtoken.type == scanner.TK_WHILE:
            self.token_accept_any()
            expr = self.parse_expression()
            self.token_accept(scanner.TK_DO)
            com = self.parse_single_command()
            return ast.WhileCommand(expr, com)
        # If Statement
        elif self.curtoken.type == scanner.TK_IF:
            self.token_accept_any()
            expr = self.parse_expression()
            self.token_accept(scanner.TK_THEN)
            com1 = self.parse_single_command()
            self.token_accept(scanner.TK_ELSE)
            com2 = self.parse_single_command()
            return ast.IfCommand(expr, com1, com2)
        # Let-In Statement
        elif self.curtoken.type == scanner.TK_LET:
            self.token_accept_any()
            dec = self.parse_declaration()
            self.token_accept(scanner.TK_IN)
            com = self.parse_single_command()
            return ast.LetCommand(dec, com)
        # Begin-End Statement
        elif self.curtoken.type == scanner.TK_BEGIN:
            self.token_accept_any()
            com = self.parse_command()
            self.token_accept(scanner.TK_END)
            return com
        elif self.curtoken.type == scanner.TK_RETURN:
            self.token_accept_any()
            expr = self.parse_expression()
            self.token_accept(scanner.TK_SEMICOLON)
            return ast.ReturnCommand(expr)
        # Unexpected tokens
        else:
            raise ParserException(self.curtoken.pos, self.curtoken.type)
Ejemplo n.º 8
0
 def parse_ident(self):
     """ V-name             ::=  Identifier """
     token = self.token_current()
     v = ast.Vname(token.val)
     self.token_accept_any()
     return v