def parse_id_expr(): id_name = GLOBALS["CUR_VALUE"] match(TK.ID) # check if it is a variable if GLOBALS["CUR_TOKEN"] != TK.LPAREN: sym = GLOBALS["SYMBOL_TABLE"].lookup(id_name) if sym: var_ast = VariableExprAST(sym) # check for postfix operators if is_prepost_token(): postfix_op = GLOBALS["CUR_TOKEN"] get_token() return UnaryExprAST(postfix_op, var_ast, True) else: return var_ast else: processing_error("'{}' undeclared".format(id_name)) # else it is a function call match(TK.LPAREN) args = [] if GLOBALS["CUR_TOKEN"] != TK.RPAREN: while True: arg = parse_expression() args.append(arg) if GLOBALS["CUR_TOKEN"] != TK.RPAREN: match(TK.COMMA) else: break match(TK.RPAREN) return CallExprAST(id_name, args)
def main_loop(): ast = BodyAST() while True: get_token() # our scanner if GLOBALS["CUR_TOKEN"] == TK.EOF: return ast else: expr = parse_id_decl() ast.insert(expr)
def parse_type_flags(): flags = set() storage = None while is_typemod_token(): if GLOBALS["CUR_TOKEN"] in TYPE_FLAG_TOKENS: flags.add(GLOBALS["CUR_TOKEN"]) elif GLOBALS["CUR_TOKEN"] in TYPE_STORAGE_TOKENS: if storage: processing_error("multiple storage classes in declaration") flags.add(GLOBALS["CUR_TOKEN"]) storage = GLOBALS["CUR_TOKEN"] get_token() return list(flags)
def Program(): global fi global instructions #import pdb; pdb.set_trace() sc.get_token(fi) #import pdb; pdb.set_trace() if sc.__CURRENT_TOKEN__ == ["keyword","program"]: match(["keyword","program"]) match(["identifier",""]) #import pdb; pdb.set_trace() match(["semicolon",";"]) declarations() #import pdb; pdb.set_trace() match(["keyword","begin"])#program begins statements() match(["keyword","end"])#program ends match(["dot","."]) addNewInstruction(["halt",""])#produce opcode to halt the program write_instructions_to_file()
def parse_binop_rhs(expr_prec, lhs): while True: tok_prec = get_token_precedence() if tok_prec < expr_prec: return lhs binop = GLOBALS["CUR_TOKEN"] get_token() rhs = parse_unary() if not rhs: return None next_prec = get_token_precedence() if tok_prec < next_prec: # a binop (b binop unparsed) in this case rhs = parse_binop_rhs(expr_prec+1, rhs) if not rhs: return None lhs = BinaryExprAST(binop, lhs, rhs)
def parse_unary(): UNARY_OPERATORS = [ TK.NOT, TK.BIT_NOT, TK.INCR, TK.DECR, ] if GLOBALS["CUR_TOKEN"] not in UNARY_OPERATORS: return parse_primary() else: prefix_op = GLOBALS["CUR_TOKEN"] if is_prepost_token(): get_token() var_ast = parse_id_expr() if type(var_ast) is VariableExprAST: return UnaryExprAST(prefix_op, var_ast) else: processing_error("Expected variable after {}".format(prefix_op)) get_token() operand = parse_unary() if operand: return UnaryExprAST(prefix_op, operand) return None
def parse_id_decl(params=None): if not params: flags = [] if is_typemod_token(): flags = parse_type_flags() typ, signed = parse_type_dec() else: flags, typ, signed = params id_name = GLOBALS["CUR_VALUE"] match(TK.ID) # check if it is a variable if GLOBALS["CUR_TOKEN"] != TK.LPAREN: if typ == TYPE.VOID: processing_error("variable '{}' declared void".format(id_name)) symb = make_symbol(id_name, TK.VAR, flags, typ, signed) GLOBALS["SYMBOL_TABLE"].insert_symbol(symb) return VariableExprAST(symb,True) # else it is a function prototype symb = GLOBALS["SYMBOL_TABLE"].lookup(id_name) if not symb: symb = GLOBALS["SYMBOL_TABLE"].insert(id_name, TK.FUNC, flags, typ, signed) proto = parse_prototype(symb) if GLOBALS["CUR_TOKEN"] == TK.SEMICOLON: get_token() return proto match(TK.LBRACE) GLOBALS["SYMBOL_TABLE"].enter_scope() for arg in proto.args: GLOBALS["SYMBOL_TABLE"].insert_symbol(arg.symbol) body = parse_body() match(TK.RBRACE) GLOBALS["SYMBOL_TABLE"].exit_scope() return FunctionAST(proto, body)
def match(token): global fi if token == ["dot","."]: if sc.__CURRENT_TOKEN__ == token: return else: print("an error occured") if token[0] == "identifier" and sc.__CURRENT_TOKEN__[0] == "identifier": sc.get_token(fi) return if token[0] == "unsigned int" and sc.__CURRENT_TOKEN__[0] == "unsigned int": sc.get_token(fi) return if sc.__CURRENT_TOKEN__ != token: print("an error occured") return else: sc.get_token(fi)
def parse_type_dec(): # (TYPE, True/False) for signed type_tuple = None if GLOBALS["CUR_TOKEN"] == TK.SIGNED: get_token() type_tuple = (basic_type_dec(), True) elif GLOBALS["CUR_TOKEN"] == TK.UNSIGNED: get_token() type_tuple = (basic_type_dec(), False) elif GLOBALS["CUR_TOKEN"] == TK.VOID: get_token() type_tuple = (TYPE.VOID, None) else: type_tuple = (basic_type_dec(), True) if type_tuple[0] == TYPE.CHAR: type_tuple = (TYPE.CHAR, False) elif type_tuple[0] == TYPE.FLOAT: type_tuple = (TYPE.FLOAT, None) elif type_tuple[0] == TYPE.DOUBLE: type_tuple = (TYPE.DOUBLE, None) return type_tuple
def parse_number_expr(typ, signed=None): result = NumberExprAST(GLOBALS["CUR_VALUE"], typ, signed) get_token() return result
def optional_match(token): if GLOBALS["CUR_TOKEN"] == token: get_token()
def match(token): if GLOBALS["CUR_TOKEN"] != token: processing_error("Expected {}, but got {}".format(token, GLOBALS["CUR_TOKEN"])) else: get_token()
def basic_type_dec(): basic_type = TYPE.INT ending_int = True if GLOBALS["CUR_TOKEN"] == TK.CHAR: get_token() basic_type = TYPE.CHAR ending_int = False elif GLOBALS["CUR_TOKEN"] == TK.SHORT: get_token() basic_type = TYPE.SHORT elif GLOBALS["CUR_TOKEN"] == TK.INT: get_token() basic_type = TYPE.INT ending_int = False elif GLOBALS["CUR_TOKEN"] == TK.LONG: get_token() optional_match(TK.LONG) basic_type = TYPE.LONG elif GLOBALS["CUR_TOKEN"] == TK.FLOAT: get_token() basic_type = TYPE.FLOAT elif GLOBALS["CUR_TOKEN"] == TK.DOUBLE: get_token() basic_type = TYPE.DOUBLE if ending_int: optional_match(TK.INT) return basic_type
from scanner import get_token # scanner from Pascal_Helper_Files.pascal_reader import PascalFile from parse import Parser # parser from emulator import Emulator # emulator if __name__ == '__main__': pretty_printer = pprint.PrettyPrinter() # UNCOMMENT the below statements one at a time # tokens = get_token(PascalFile(input_file_location='array_example.pas', output_location='')) # tokens = get_token(PascalFile(input_file_location='assignment_example.pas', output_location='')) # tokens = get_token(PascalFile(input_file_location='for_example.pas', output_location='')) # tokens = get_token(PascalFile(input_file_location='if_example.pas', output_location='')) tokens = get_token( PascalFile(input_file_location='while_example.pas', output_location='')) # UNCOMMENT THE LINE BELOW TO TEST THE SCANNER --> YOU WILL SEE THE TOKENS # pretty_printer.pprint(tokens) print '----------------------------------' # UNCOMMENT THE LINE BELOW TO TEST THE PARSER # parser = Parser(token_list=tokens, verbose=True) parser = Parser(token_list=tokens) byte_array = parser.parse() # This prints the byte array, uncomment to see the bytearray # pretty_printer.pprint(byte_array) print '----------------------------------' emulator = Emulator(byte_array)