예제 #1
0
파일: parser.c 프로젝트: shunting1986/scc
// parse init declarator util meeting a ';'
static struct init_declarator_list *parse_init_declarator_list(struct parser *parser) {
	// need check for empty init_declarator_list here
	union token tok = lexer_next_token(parser->lexer);
	if (tok.tok_tag == TOK_SEMICOLON) {
		return NULL;
	}
	lexer_put_back(parser->lexer, tok);
	return parse_init_declarator_list_with_la(parser, 
		parse_declarator(parser));
}
예제 #2
0
파일: parser.c 프로젝트: shunting1986/scc
static struct direct_declarator *parse_direct_declarator(struct parser *parser) {
	struct direct_declarator *dd = direct_declarator_init();
	union token tok = lexer_next_token(parser->lexer);
	if (tok.tok_tag == TOK_IDENTIFIER) {
		dd->id = tok.id.s;	
	} else if (tok.tok_tag == TOK_LPAREN) { 
		union token nxtok = lexer_next_token(parser->lexer);
		if (nxtok.tok_tag == TOK_RPAREN || initiate_declaration_specifiers(nxtok)) {
			lexer_put_back(parser->lexer, nxtok);
			lexer_put_back(parser->lexer, tok);
			goto parse_suffix;
		}
		lexer_put_back(parser->lexer, nxtok);
		dd->declarator = parse_declarator(parser);
		expect(parser->lexer, TOK_RPAREN);
	} else {
		// pass thru
		lexer_put_back(parser->lexer, tok);
	}

parse_suffix:
	while (1) {
		tok = lexer_next_token(parser->lexer);
		if (tok.tok_tag == TOK_LBRACKET) {
			tok = lexer_next_token(parser->lexer);
			struct direct_declarator_suffix *suff = mallocz(sizeof(*suff));
			if (tok.tok_tag == TOK_RBRACKET) {
				suff->empty_bracket = 1;
			} else {
				lexer_put_back(parser->lexer, tok);
				struct constant_expression *expr = parse_constant_expression(parser);
				expect(parser->lexer, TOK_RBRACKET);
				suff->const_expr = expr;
			}
			dynarr_add(dd->suff_list, suff);
		} else if (tok.tok_tag == TOK_LPAREN) {
			tok = lexer_next_token(parser->lexer);
			struct direct_declarator_suffix *suff = mallocz(sizeof(*suff));
			if (tok.tok_tag == TOK_RPAREN) {
				suff->empty_paren = 1;
			} else {
				lexer_put_back(parser->lexer, tok);
				struct parameter_type_list *param_type_list = parse_parameter_type_list(parser);
				expect(parser->lexer, TOK_RPAREN);
				suff->param_type_list = param_type_list;
			}
			dynarr_add(dd->suff_list, suff);
		} else {
			lexer_put_back(parser->lexer, tok);	
			break;
		}
	}
	return dd;
}
예제 #3
0
파일: parser.c 프로젝트: shunting1986/scc
struct type_name *parse_type_name(struct parser *parser) {
	struct specifier_qualifier_list *sqlist = parse_specifier_qualifier_list(parser);
	union token tok = lexer_next_token(parser->lexer);
	struct declarator *declarator = NULL;
	lexer_put_back(parser->lexer, tok);
	if (initiate_abstract_declarator(tok)) {
		declarator = parse_declarator(parser);
		if (!is_abstract_declarator(declarator)) {
			panic("require abstract declarator");
		}
	} 
	return type_name_init(sqlist, declarator);
}
예제 #4
0
파일: cdcl.c 프로젝트: DeadDork/learning_c
int main(void) {
	char input_buffer[MAX_STRING];
	char type[MAX_SUBSTRING];
	char declarator[MAX_SUBSTRING];
	char identifier[MAX_SUBSTRING];

	while (get_string(input_buffer)) {
		type[0] = identifier[0] = declarator[0] = '\0';
		parse_type(type, input_buffer);
		parse_declarator(identifier, declarator, input_buffer);
		printf("Declare %s as %s %s\n", identifier, declarator, type);
	}

	return 0;
}
예제 #5
0
파일: parser.c 프로젝트: shunting1986/scc
// assume no EOF found; 
static struct external_declaration *parse_external_decl(struct parser *parser) {
	struct declaration_specifiers *decl_specifiers = parse_declaration_specifiers(parser);
	struct external_declaration *external_decl = external_declaration_init(decl_specifiers);
	struct declarator *declarator = NULL;

	// compound statement case
	struct compound_statement *compound_stmt = NULL;
	// declaration case
	struct init_declarator_list *init_declarator_list = NULL;

	// check for empty init_declarator_list case, similar to what we do in
	// parse_init_declarator_list
	union token tok = lexer_next_token(parser->lexer);
	if (tok.tok_tag == TOK_SEMICOLON) {
	} else {
		lexer_put_back(parser->lexer, tok);
		declarator = parse_declarator(parser);

		tok = lexer_next_token(parser->lexer);	
		if (tok.tok_tag == TOK_LBRACE) {
			lexer_push_typedef_tab(parser->lexer);
			register_func_parameters_for_typedef(parser, declarator);

			lexer_put_back(parser->lexer, tok);
			compound_stmt = parse_compound_statement(parser);

	 		lexer_pop_typedef_tab(parser->lexer);
		
			// set external decl
			external_decl->func_def_declarator = declarator;
			external_decl->compound_stmt = compound_stmt;
		} else {
			lexer_put_back(parser->lexer, tok);
			init_declarator_list = parse_init_declarator_list_with_la(parser, declarator);

			// set external decl
			external_decl->init_declarator_list = init_declarator_list;

			register_potential_typedefs(parser, decl_specifiers, init_declarator_list);
		}
	}

	return external_decl;
}
예제 #6
0
struct struct_declarator *parse_struct_declarator(struct parser *parser) {
	struct declarator *declarator = NULL;
	struct constant_expression *const_expr = NULL;
	union token tok = lexer_next_token(parser->lexer);

	if (tok.tok_tag != TOK_COLON) {
		lexer_put_back(parser->lexer, tok);
		declarator = parse_declarator(parser);
		tok = lexer_next_token(parser->lexer);
	}
	
	if (tok.tok_tag == TOK_COLON) {
		const_expr = parse_constant_expression(parser);
	} else {
		lexer_put_back(parser->lexer, tok);
	}

	return struct_declarator_init(declarator, const_expr);
}
예제 #7
0
파일: parser.c 프로젝트: shunting1986/scc
// TODO support abstract_declarator
static struct parameter_declaration *parse_parameter_declaration(struct parser *parser) {
	int old_disable_typedef = lexer_push_config(parser->lexer, disable_typedef, 0);
	struct declaration_specifiers *decl_specifiers = parse_declaration_specifiers(parser);

	// to support item *item, which item is a type name
	// we need disable typedef after we get decl specifiers
	//
	// To support the case that the declarator recursively contains type (func ptr as 
	// parameter), we enable typedef at the beginning

	(void) lexer_push_config(parser->lexer, disable_typedef, 1);
	union token tok = lexer_next_token(parser->lexer);

	struct declarator *declarator = NULL;
	if (initiate_declarator(tok)) {
		lexer_put_back(parser->lexer, tok);
		declarator = parse_declarator(parser);
	} else {
		lexer_put_back(parser->lexer, tok);
	}

	lexer_pop_config(parser->lexer, disable_typedef, old_disable_typedef);
	return parameter_declaration_init(decl_specifiers, declarator);
}
예제 #8
0
파일: parser.c 프로젝트: shunting1986/scc
static struct init_declarator *parse_init_declarator(struct parser *parser) {
	struct declarator *declarator = parse_declarator(parser);	
	return parse_init_declarator_with_la(parser, declarator);	
}