def parse_function(self, declr): func = declr.typ return ast.Declaration( typ=ast.Function( ret=func.ret, args=func.args, body=self.block()), name=declr.name)
def arg_list(self): self.expect('(') args = [] while not self.accept(')'): typ = self.ctype() name = self.name() args.append(ast.Declaration(name, typ)) if not self.accept(')'): self.expect(',') self.expect(')') return args
def type(self): """ Type ⇒ int | bool | float""" # Check to see if current token is # a keyword int, keyword bool, or keyword Float if self.currtok[0] in [lexer.Lexer.KWDINT, lexer.Lexer.KWDBOOL, lexer.Lexer.KWDFLOAT]: temptype = self.currtok[1] self.currtok = next(self.tokens) tempid = self.currtok[1] self.currtok = next(self.tokens) return ast.Declaration(temptype, tempid)
def declarations(self): """ Declarations ⇒ { Declaration } Declaration ⇒ Type Identifier ; Type ⇒ int | bool | float """ # Look for declarations to store in the Program object. The first token in a declaration is # a variable keyword. while self.currToken[0] in (lexer.Lexer.KWDBOOL, lexer.Lexer.KWDINT, lexer.Lexer.KWDFLOAT): # Capture the token representation to create a Declaration object. type = self.currToken[0] # Move to the next token. self.currToken = next(self.tokens) # Check for an identifier. if self.currToken[0] == lexer.Lexer.ID: # Capture the Id value to create a Declaration object. identify = self.currToken[2] # Check whether the variable has already been defined. # The variable has already been defined; raise an exception. if identify in self.parseTree.declarations.keys(): raise CLiteSyntaxError( self.currToken, 'N/A', 'The variable has been previously declared') # Variable has not been defined yet. else: # Create a Declaration object. declare = ast.Declaration(type, identify) # Move to the next token. self.currToken = next(self.tokens) # Check for ';'. if self.currToken[0] == lexer.Lexer.SEMICOLON: # Move to the next token. self.currToken = next(self.tokens) # Add the declaration to the Program object. self.parseTree.addDecl(declare) # Unexpected token encountered. else: raise CLiteSyntaxError(self.currToken, 'a semicolon') # Unexpected token encountered. else: raise CLiteSyntaxError(self.currToken, 'Identifier')
def type(self): if self.curr_tok[0] in Parser.type_first: tp = self.curr_tok[0] self.curr_tok = next(self.lex) else: print("Error: 'int', 'bool', or 'float' expected: found", self.curr_tok[1], "on line", self.curr_tok[2]) sys.exit(1) # we should be at an identifier if self.curr_tok[0] != lexer.Lexer.ID: print("Error: identifier expected: found", self.curr_tok[1], "on line", self.curr_tok[2]) sys.exit(1) tmp = self.curr_tok self.curr_tok = next(self.lex) return ast.Declaration(tp, tmp[1])
def parse_initialize(self, val): name = '' while True: self.loc += 1 char = self.source[self.loc] name += char if self.isalone(): if not isname(name): print("Parse Error: 'var' or 'val' not followed by a name at location " + str(self.loc) + ': \n' + self.source[self.loc:self.loc+20]) sys.exit(1) self.skip_whitespace() if self.source[self.loc] != '=': return ast.Declaration(val, name) # TODO: Type self.loc += 1 self.skip_whitespace() expr = self.parse_expr() ast.index[name] = expr ast.vals[name] = val return ast.Initialization(val, name, expr)
def parse_declr_expr(self, typ, e): ''' parse an expression as declaration; e.g. "int *x[8]" when treated as expression will be parsed as `PrefixExpr(op='*', expr=Index(array='x', index=8))`, which we want to transform into this: `Array(Pointer(typ='int'), cap=8)` ''' while is_type_modifier(e): if type(e) == ast.Index: cap = int(e.index.val) if e.index is not None else None typ = ast.Array(typ=typ, cap=cap) e = e.array else: typ = ast.Pointer(typ=typ) e = e.expr if type(e) == ast.CallExpr: return self.parse_declr_expr( ast.Function(ret=typ or 'void', args=e.args, body=None), e.func) else: return ast.Declaration(typ=typ, name=e)