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)
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
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
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)
def parse_ident(self): """ V-name ::= Identifier """ token = self.token_current() v = ast.Vname(token.val) self.token_accept_any() return v