def parse_str(): ''' 解析字符串 ''' if get_next_token().type == 'STR': rnode = TreeNode('STR') rnode.line = tokens[tokens_index].pos[0] rnode.value = get_next_token().name skip_next_token() return rnode else: raise ParseException('Line %d: token should be a string ' % get_next_token().pos[0])
def parse_id(): ''' 解析标识符 ''' id_token = get_next_token() if id_token.type != 'ID': raise ParseException('Line %d: token should be a identifier' % id_token.pos[0]) skip_next_token() rnode = TreeNode('ID') rnode.line = tokens[tokens_index].pos[0] rnode.value = id_token.name return rnode
def parse_factor(): ''' 解析项中单个因子 ''' node = TreeNode('FACTOR') node.line = tokens[tokens_index].pos[0] token = get_next_token() if token.type == 'NUM': rnode = TreeNode('NUM') rnode.line = tokens[tokens_index].pos[0] rnode.value = token.name node.add_child(rnode) skip_next_token() elif token.name == '(': check_next_token('(') node.add_child(parse_expr()) check_next_token(')') else: node.add_child(parse_var()) return node
def parse_decl_stmt(): ''' 解析声明语句 ''' type_token = get_next_token() decl_node = TreeNode('VARDECL') type_node = TreeNode('TYPE') decl_node.line = tokens[tokens_index].pos[0] type_node.line = tokens[tokens_index].pos[0] decl_node.add_child(type_node) type_node.add_child(check_next_token(type_token.name)) next_token = get_next_token() if next_token.name == '[': #判断声明是否为数组 check_next_token('[') num_token = get_next_token() if num_token.type != 'NUM' or '.' in num_token.name: #声明数组长度时需为正整数 raise ParseException( 'Line %d: length of array should be a positive constant number' % num_token.pos[0]) num_node = TreeNode('NUM') num_node.line = tokens[tokens_index].pos[0] num_node.value = num_token.name type_node.add_child(num_node) skip_next_token() check_next_token(']') id = parse_id() decl_node.add_child(id) next_name = get_next_token().name assfunc = parse_str if type_token.name == 'string' else parse_expr while next_name in [',', '=']: if next_name == '=': check_next_token('=') id.add_child(assfunc()) else: check_next_token(',') id = parse_id() decl_node.add_child(id) next_name = get_next_token().name check_next_token(';') return decl_node