def parse_vars(tokens, idx): # <id> "[" <exp> "]" old_idx = idx try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) id_name = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, '[') idx, index_expression = parse_expression(tokens, idx) idx, tok = utils.match(tokens, idx, OPERATOR, ']') return idx, ArrayVariable(id_name=id_name, index_expression=index_expression) except: idx = old_idx # <id> try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) return idx, Variable(id_name=tok.value) except: pass assert False
def parse_single_declaration(tokens, idx): # <single_declaration> ::= <id> "[" <exp>(a num) "]" | <id> [ '=' <exp> ] old_idx = idx try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) id_name = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, '[') idx, tok = utils.match_type(tokens, idx, INT) index_expression = Number(num=int(tok.value)) idx, tok = utils.match(tokens, idx, OPERATOR, ']') return idx, SingleArrayDeclaration(id_name=id_name, index_expression=index_expression) except: idx = old_idx old_idx = idx try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) id_name = tok.value try: idx, tok = utils.match(tokens, idx, OPERATOR, '=') idx, expression = parse_subexpression(tokens, idx) return idx, SingleDeclaration(id_name=id_name, expression=expression) except: pass return idx, SingleDeclaration(id_name=id_name, expression=None) except: idx = old_idx assert False
def parse_function(tokens, idx): # <function> ::= "int" <id> "(" [ "int" <id> { "," "int" <id> } ] ")" ( "{" { <block-item> } "}" | ";" ) idx, tok = utils.match(tokens, idx, RESERVED, 'int') rtype = tok.value idx, tok = utils.match_type(tokens, idx, IDENTIFIER) fname = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, '(') idx, parameters = parse_parameter_list(tokens, idx) idx, tok = utils.match(tokens, idx, OPERATOR, ')') # if it is declaration try: idx, tok = utils.match(tokens, idx, OPERATOR, ';') return idx, Function_Declaration(fname=fname, rtype=rtype, parameters=parameters, function=None) except: pass # else it is defination idx, tok = utils.match(tokens, idx, OPERATOR, '{') # sub statement idx, statement = parse_block_item(tokens, idx) function = Function(fname=fname, rtype=rtype, statement=statement, parameters=parameters, function=None) # more statement while True: if tokens[idx].value == '}': break # print(idx, tokens[idx]) idx, statement = parse_block_item(tokens, idx) function = Function(fname=fname, rtype=rtype, statement=statement, parameters=parameters, function=function) idx, tok = utils.match(tokens, idx, OPERATOR, '}') # add default return if 'astnodes.Return' not in str(type(function.statement)): function = Function(fname=fname, rtype=rtype, statement=Return(), parameters=parameters, function=function) return idx, function
def parse_parameter_list(tokens, idx): # [ "int" <id> { "," "int" <id> } ] ret = [] try: idx, tok1 = utils.match(tokens, idx, RESERVED, 'int') idx, tok2 = utils.match_type(tokens, idx, IDENTIFIER) ret.append([tok1, tok2]) old_idx = None try: while True: old_idx = idx idx, tok = utils.match(tokens, idx, OPERATOR, ',') idx, tok1 = utils.match(tokens, idx, RESERVED, 'int') idx, tok2 = utils.match_type(tokens, idx, IDENTIFIER) ret.append([tok1, tok2]) except: idx = old_idx except: pass return idx, ret
def parse_global_declaration(tokens, idx): # <declaration> ::= "int" <id> [ = <exp> ] ";" try: idx, tok = utils.match(tokens, idx, RESERVED, 'int') type_name = tok.value idx, tok = utils.match_type(tokens, idx, IDENTIFIER) id_name = tok.value try: idx, tok = utils.match(tokens, idx, OPERATOR, '=') idx, tok = utils.match_type(tokens, idx, INT) val = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, ';') return idx, GlobalDeclaration(type_name=type_name, id_name=id_name, val=val) except: pass idx, tok = utils.match(tokens, idx, OPERATOR, ';') return idx, Declaration(type_name=type_name, id_name=id_name) except: pass assert False
def parse_func_call(tokens, idx): # <function-call> ::= id "(" [ <exp> { "," <exp> } ] ")" try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) fname = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, '(') parameters = [] try: idx, exp = parse_condition_expression(tokens, idx) parameters.append(exp) while True: old_idx = idx try: old_idx = idx idx, tok = utils.match(tokens, idx, OPERATOR, ',') # idx, exp = parse_expression(tokens, idx) idx, exp = parse_condition_expression( tokens, idx) # fix bugs, no assignment action parameters.append(exp) except: idx = old_idx break except: pass # print(parameters[0]) idx, tok = utils.match(tokens, idx, OPERATOR, ')') # print(parameters) # print(fname, tok) return idx, Func_Call(fname=fname, parameters=parameters) except: pass assert False
def parse_subexpression(tokens, idx): # <exp> ::= <id> "=" <exp> old_idx = idx try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) f_name = tok.value idx, tok = utils.match_type_values(tokens, idx, OPERATOR, utils.assign_op) idx, expression = parse_subexpression(tokens, idx) # b=1,a assignment = Assignment(id_name=f_name, expression=expression, op=tok.value) return idx, assignment except: idx = old_idx # <id> "[" <exp> "]" "=" <exp> old_idx = idx try: idx, tok = utils.match_type(tokens, idx, IDENTIFIER) f_name = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, '[') idx, index_expression = parse_expression(tokens, idx) idx, tok = utils.match(tokens, idx, OPERATOR, ']') idx, tok = utils.match_type_values(tokens, idx, OPERATOR, utils.assign_op) idx, expression = parse_subexpression(tokens, idx) assignment = ArrayAssignment(id_name=f_name, expression=expression, op=tok.value, index_expression=index_expression) return idx, assignment except: idx = old_idx # <exp> ::= "*" <id> "=" <exp> old_idx = idx try: idx, tok = utils.match(tokens, idx, OPERATOR, '*') idx, tok = utils.match_type(tokens, idx, IDENTIFIER) f_name = tok.value idx, tok = utils.match_type_values(tokens, idx, OPERATOR, utils.assign_op) idx, expression = parse_subexpression(tokens, idx) # b=1,a assignment = CiteAssignment(id_name=f_name, expression=expression, op=tok.value) return idx, assignment except: idx = old_idx # <id> "*" "[" <exp> "]" "=" <exp> old_idx = idx try: idx, tok = utils.match(tokens, idx, OPERATOR, '*') idx, tok = utils.match_type(tokens, idx, IDENTIFIER) f_name = tok.value idx, tok = utils.match(tokens, idx, OPERATOR, '[') idx, index_expression = parse_expression(tokens, idx) idx, tok = utils.match(tokens, idx, OPERATOR, ']') idx, tok = utils.match_type_values(tokens, idx, OPERATOR, utils.assign_op) idx, expression = parse_subexpression(tokens, idx) assignment = ArrayAssignment(id_name=f_name, expression=expression, op=tok.value, index_expression=index_expression) return idx, assignment except: idx = old_idx # <conditional-exp> try: idx, expression = parse_condition_expression(tokens, idx) expression = Expression(logical_or_expression=expression) return idx, expression except: pass assert False
def parse_factor(tokens, idx): # <function-call> try: idx, expression = parse_func_call(tokens, idx) return idx, Factor(expression=expression) except: pass # "(" <exp> ")" old_idx = idx try: idx, tok = utils.match(tokens, idx, OPERATOR, '(') idx, expression = parse_expression(tokens, idx) idx, tok = utils.match(tokens, idx, OPERATOR, ')') return idx, Factor(expression=expression) except: idx = old_idx # <unary_op> <var> old_idx = idx try: idx, tok = utils.match_type_values(tokens, idx, OPERATOR, utils.unary_op) idx, var = parse_vars(tokens, idx) return idx, UnaryOP(op=tok.value, factor=var) except: idx = old_idx # <var> <unary_op> old_idx = idx try: idx, var = parse_vars(tokens, idx) idx, tok = utils.match_type_values(tokens, idx, OPERATOR, utils.post_unary_op) return idx, PostUnaryOP(op=tok.value, factor=var) except: idx = old_idx # <var> try: idx, var = parse_vars(tokens, idx) return idx, var except: idx = old_idx # <int> try: idx, tok = utils.match_type(tokens, idx, INT) return idx, Number(num=int(tok.value)) except: pass # <char> try: idx, tok = utils.match_type(tokens, idx, CHAR) return idx, Number(num=ord(tok.value)) except: pass # <string> try: idx, tok = utils.match_type(tokens, idx, STRING) return idx, String(string=tok.value) except: pass # print('error: parse_factor') assert False