Fixed a number of bugs and conforming to the Code API

This commit is contained in:
Pierre Pronchery 2008-06-03 09:47:47 +00:00
parent eb4075fed7
commit 1ba882052d

View File

@ -33,6 +33,7 @@
/* prototypes */ /* prototypes */
static int _parse_check(C99 * c99, TokenCode code); static int _parse_check(C99 * c99, TokenCode code);
static int _parse_error(C99 * c99, char const * format, ...); static int _parse_error(C99 * c99, char const * format, ...);
static int _parse_get_code(C99 * c99);
static char const * _parse_get_string(C99 * c99); static char const * _parse_get_string(C99 * c99);
static int _parse_in_set(C99 * c99, TokenSet set); static int _parse_in_set(C99 * c99, TokenSet set);
static int _parse_is_code(C99 * c99, TokenCode code); static int _parse_is_code(C99 * c99, TokenCode code);
@ -70,7 +71,7 @@ static int _direct_abstract_declarator(C99 * c99);
static int _assignment_expr(C99 * c99); static int _assignment_expr(C99 * c99);
static int _unary_expr(C99 * c99); static int _unary_expr(C99 * c99);
static int _postfix_expr(C99 * c99); static int _postfix_expr(C99 * c99);
static int _argument_expression_list(C99 * c99); static int _argument_expr_list(C99 * c99);
static int _primary_expr(C99 * c99); static int _primary_expr(C99 * c99);
static int _type_name(C99 * c99); static int _type_name(C99 * c99);
static int _specifier_qualifier_list(C99 * c99); static int _specifier_qualifier_list(C99 * c99);
@ -90,6 +91,7 @@ static int _multiplicative_expr(C99 * c99);
static int _cast_expr(C99 * c99); static int _cast_expr(C99 * c99);
static int _declaration_list(C99 * c99); static int _declaration_list(C99 * c99);
static int _declaration(C99 * c99); static int _declaration(C99 * c99);
static int _declaration_do(C99 * c99);
static int _compound_statement(C99 * c99); static int _compound_statement(C99 * c99);
static int _block_item_list(C99 * c99); static int _block_item_list(C99 * c99);
static int _block_item(C99 * c99); static int _block_item(C99 * c99);
@ -149,6 +151,15 @@ static int _parse_error(C99 * c99, char const * format, ...)
} }
/* parse_get_code */
static int _parse_get_code(C99 * c99)
{
if(c99->token == NULL)
return TC_NULL;
return token_get_code(c99->token);
}
/* parse_get_string */ /* parse_get_string */
static char const * _parse_get_string(C99 * c99) static char const * _parse_get_string(C99 * c99)
{ {
@ -186,7 +197,9 @@ static int _translation_unit(C99 * c99)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
while(scan(c99) == 0 && c99->token != NULL) /* end of file */ if(scan(c99) != 0)
return 1;
while(c99->token != NULL) /* end of file */
ret |= _external_declaration(c99); ret |= _external_declaration(c99);
if(c99->token != NULL) if(c99->token != NULL)
ret |= 1; ret |= 1;
@ -198,34 +211,74 @@ static int _translation_unit(C99 * c99)
static int _external_declaration(C99 * c99) static int _external_declaration(C99 * c99)
/* function-definition | declaration */ /* function-definition | declaration */
{ {
/* FIXME ambiguity between function definition and declaration */ int ret;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, _parse_get_string(
c99));
#endif #endif
if(_parse_in_set(c99, c99set_function_definition)) ret = _declaration_specifiers(c99);
return _function_definition(c99); if(_parse_is_code(c99, C99_CODE_OPERATOR_SEMICOLON))
else if(_parse_in_set(c99, c99set_declaration)) {
return _declaration(c99); /* this is a declaration */
return _parse_error(c99, "Expected function definition or declaration"); ret |= scan(c99);
ret |= _declaration_do(c99);
return ret;
}
ret |= _declarator(c99);
if(_parse_is_code(c99, C99_CODE_OPERATOR_EQUALS))
{
/* this is a declaration */
ret |= scan(c99);
ret |= _initializer(c99);
while(_parse_is_code(c99, C99_CODE_COMMA))
{
ret |= scan(c99);
ret |= _init_declarator(c99);
}
ret |= _parse_check(c99, C99_CODE_OPERATOR_SEMICOLON);
ret |= _declaration_do(c99);
return ret;
}
if(_parse_in_set(c99, c99set_declaration_list))
{
/* this is a function */
ret |= _declaration_list(c99);
ret |= _function_definition(c99);
return ret;
}
if(_parse_in_set(c99, c99set_compound_statement))
{
/* this is a function */
ret |= _function_definition(c99);
return ret;
}
/* this is a declaration */
if(_parse_is_code(c99, C99_CODE_COMMA))
{
ret |= scan(c99);
ret |= _init_declarator_list(c99);
}
ret |= _parse_check(c99, C99_CODE_OPERATOR_SEMICOLON);
ret |= _declaration_do(c99);
return ret;
} }
/* function_definition */ /* function_definition */
static int _function_definition(C99 * c99) static int _function_definition(C99 * c99)
/* declaration-specifiers declarator [ declaration-list ] /* compound-statement */
* compound-statement */
{ {
int ret; int ret;
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _declaration_specifiers(c99); ret = code_function_begin(c99->code, c99->identifier);
ret |= code_set_context(c99->code, CODE_CONTEXT_FUNCTION_NAME); free(c99->identifier);
ret |= _declarator(c99); c99->identifier = NULL;
if(_parse_in_set(c99, c99set_declaration_list))
ret |= _declaration_list(c99);
ret |= _compound_statement(c99); ret |= _compound_statement(c99);
ret |= code_function_end(c99->code);
return ret; return ret;
} }
@ -259,9 +312,29 @@ static int _declaration(C99 * c99)
if(_parse_in_set(c99, c99set_init_declarator)) if(_parse_in_set(c99, c99set_init_declarator))
ret |= _init_declarator_list(c99); ret |= _init_declarator_list(c99);
ret |= _parse_check(c99, C99_CODE_OPERATOR_SEMICOLON); ret |= _parse_check(c99, C99_CODE_OPERATOR_SEMICOLON);
ret |= _declaration_do(c99);
return ret; return ret;
} }
static int _declaration_do(C99 * c99)
{
#ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif
if(c99->typedef_flag)
{
c99->typedef_flag = 0;
if(c99->identifier == NULL)
return _parse_error(c99, "%s", "DEBUG: typedef without"
" identifier");
if(code_type_add(c99->code, c99->identifier) != 0)
return _parse_error(c99, "%s", error_get());
}
else if(code_variable_add(c99->code, c99->identifier) != 0)
return _parse_error(c99, "%s", error_get());
return 0;
}
/* declaration-specifiers */ /* declaration-specifiers */
static int _declaration_specifiers(C99 * c99) static int _declaration_specifiers(C99 * c99)
@ -307,6 +380,8 @@ static int _storage_class_specifier(C99 * c99)
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
_parse_get_string(c99)); _parse_get_string(c99));
#endif #endif
if(_parse_is_code(c99, C99_CODE_KEYWORD_TYPEDEF))
c99->typedef_flag = 1;
return scan(c99); return scan(c99);
} }
@ -516,7 +591,7 @@ static int _typedef_name(C99 * c99)
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
_parse_get_string(c99)); _parse_get_string(c99));
#endif #endif
return scan(c99); return _identifier(c99);
} }
@ -604,7 +679,7 @@ static int _type_qualifier_list(C99 * c99)
static int _direct_declarator(C99 * c99) static int _direct_declarator(C99 * c99)
/* identifier /* identifier
* "(" declarator ")" * "(" declarator ")"
* direct-declarator "[" (assignment-expression | "*") "]" * direct-declarator "[" (assignment-expr | "*") "]"
* direct-declarator "(" parameter-type-list ")" * direct-declarator "(" parameter-type-list ")"
* direct-declarator "(" [ identifier-list ] ")" */ * direct-declarator "(" [ identifier-list ] ")" */
{ {
@ -653,14 +728,19 @@ static int _direct_declarator(C99 * c99)
static int _identifier(C99 * c99) static int _identifier(C99 * c99)
/* identifier-nondigit { (identifier-nondigit | identifier-digit) } */ /* identifier-nondigit { (identifier-nondigit | identifier-digit) } */
{ {
int ret; int ret = 0;
char const * str; char const * str;
char * name = NULL;
str = _parse_get_string(c99);
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, str); fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, _parse_get_string(
c99));
#endif #endif
ret = code_set_identifier(c99->code, str); free(c99->identifier);
if((str = _parse_get_string(c99)) != NULL
&& (name = strdup(str)) == NULL)
ret = _parse_error(c99, "%s", strerror(errno));
c99->identifier = name;
ret |= scan(c99); ret |= scan(c99);
return ret; return ret;
} }
@ -681,7 +761,6 @@ static int _identifier_list(C99 * c99)
ret |= scan(c99); ret |= scan(c99);
ret |= _identifier(c99); ret |= _identifier(c99);
} }
ret |= code_set_context(c99->code, CODE_CONTEXT_UNDEFINED);
return ret; return ret;
} }
@ -719,6 +798,10 @@ static int _parameter_declaration(C99 * c99)
ret = _declaration_specifiers(c99); ret = _declaration_specifiers(c99);
if(_parse_in_set(c99, c99set_abstract_or_declarator)) if(_parse_in_set(c99, c99set_abstract_or_declarator))
ret |= _abstract_or_declarator(c99); ret |= _abstract_or_declarator(c99);
#ifdef DEBUG
if(c99->identifier != NULL)
fprintf(stderr, "DEBUG: parameter \"%s\"\n", c99->identifier);
#endif
return ret; return ret;
} }
@ -735,7 +818,8 @@ static int _abstract_or_declarator(C99 * c99)
if(_parse_is_code(c99, C99_CODE_IDENTIFIER)) if(_parse_is_code(c99, C99_CODE_IDENTIFIER))
return ret | _direct_declarator(c99); return ret | _direct_declarator(c99);
/* FIXME there is still an ambiguity with "(" */ /* FIXME there is still an ambiguity with "(" */
return ret | _direct_abstract_declarator(c99); ret |= _direct_abstract_declarator(c99);
return ret;
} }
@ -772,9 +856,8 @@ static int _direct_abstract_declarator(C99 * c99)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
if(c99->token == NULL) code = _parse_get_code(c99);
return _parse_error(c99, "Unexpected end of file"); if(code == C99_CODE_OPERATOR_LPAREN)
else if((code = token_get_code(c99->token)) == C99_CODE_OPERATOR_LPAREN)
{ {
ret = scan(c99); ret = scan(c99);
ret |= _abstract_declarator(c99); ret |= _abstract_declarator(c99);
@ -787,10 +870,8 @@ static int _direct_abstract_declarator(C99 * c99)
ret |= _assignment_expr(c99); ret |= _assignment_expr(c99);
ret |= _parse_check(c99, C99_CODE_OPERATOR_RBRACKET); ret |= _parse_check(c99, C99_CODE_OPERATOR_RBRACKET);
} }
while(c99->token != NULL) while((code = _parse_get_code(c99)) != TC_NULL)
{ if(code == C99_CODE_OPERATOR_LPAREN)
if((code = token_get_code(c99->token))
== C99_CODE_OPERATOR_LPAREN)
{ {
ret |= scan(c99); ret |= scan(c99);
if(_parse_in_set(c99, c99set_parameter_type_list)) if(_parse_in_set(c99, c99set_parameter_type_list))
@ -807,7 +888,6 @@ static int _direct_abstract_declarator(C99 * c99)
} }
else else
break; break;
}
return ret; return ret;
} }
@ -854,6 +934,7 @@ static int _unary_expr(C99 * c99)
#endif #endif
if(_parse_in_set(c99, c99set_postfix_expr)) if(_parse_in_set(c99, c99set_postfix_expr))
return _postfix_expr(c99); return _postfix_expr(c99);
/* FIXME use _parse_get_code() */
else if(c99->token == NULL) else if(c99->token == NULL)
return _parse_error(c99, "Unexpected end of file"); return _parse_error(c99, "Unexpected end of file");
else if((code = token_get_code(c99->token)) == C99_CODE_OPERATOR_DPLUS else if((code = token_get_code(c99->token)) == C99_CODE_OPERATOR_DPLUS
@ -887,7 +968,7 @@ static int _unary_expr(C99 * c99)
static int _postfix_expr(C99 * c99) static int _postfix_expr(C99 * c99)
/* primary-expr /* primary-expr
* postfix-expr "[" expression "]" * postfix-expr "[" expression "]"
* postfix-expr "(" argument-expression-list-opt ")" * postfix-expr "(" [ argument-expr-list ] ")"
* postfix-expr "." identifier * postfix-expr "." identifier
* postfix-expr "->" identifier * postfix-expr "->" identifier
* postfix-expr "++" * postfix-expr "++"
@ -914,9 +995,7 @@ static int _postfix_expr(C99 * c99)
ret |= scan(c99); ret |= scan(c99);
ret |= _parse_check(c99, C99_CODE_OPERATOR_RBRACE); ret |= _parse_check(c99, C99_CODE_OPERATOR_RBRACE);
} }
while(c99->token != NULL) while((code = _parse_get_code(c99)) != TC_NULL)
{
code = token_get_code(c99->token);
if(code == C99_CODE_OPERATOR_LBRACKET) if(code == C99_CODE_OPERATOR_LBRACKET)
{ {
ret |= scan(c99); ret |= scan(c99);
@ -927,8 +1006,10 @@ static int _postfix_expr(C99 * c99)
{ {
ret |= scan(c99); ret |= scan(c99);
if(!_parse_is_code(c99, C99_CODE_OPERATOR_RPAREN)) if(!_parse_is_code(c99, C99_CODE_OPERATOR_RPAREN))
ret |= _argument_expression_list(c99); ret |= _argument_expr_list(c99);
ret |= _parse_check(c99, C99_CODE_OPERATOR_RPAREN); ret |= _parse_check(c99, C99_CODE_OPERATOR_RPAREN);
if(code_function_call(c99->code, c99->identifier) != 0)
ret |= _parse_error(c99, "%s", error_get());
} }
else if(code == C99_CODE_OPERATOR_DOT else if(code == C99_CODE_OPERATOR_DOT
|| code == C99_CODE_OPERATOR_MGREATER) || code == C99_CODE_OPERATOR_MGREATER)
@ -941,13 +1022,12 @@ static int _postfix_expr(C99 * c99)
ret |= scan(c99); ret |= scan(c99);
else else
break; break;
}
return ret; return ret;
} }
/* argument-expression-list */ /* argument-expr-list */
static int _argument_expression_list(C99 * c99) static int _argument_expr_list(C99 * c99)
/* assignment-expr { "," assignment-expr } */ /* assignment-expr { "," assignment-expr } */
{ {
int ret; int ret;
@ -986,6 +1066,7 @@ static int _primary_expr(C99 * c99)
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
_parse_get_string(c99)); _parse_get_string(c99));
#endif #endif
/* FIXME use _parse_get_code() */
if(c99->token == NULL) if(c99->token == NULL)
return _parse_error(c99, "Unexpected end of file"); return _parse_error(c99, "Unexpected end of file");
else if((code = token_get_code(c99->token)) == C99_CODE_IDENTIFIER) else if((code = token_get_code(c99->token)) == C99_CODE_IDENTIFIER)
@ -1199,9 +1280,8 @@ static int _equality_expr(C99 * c99)
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _relational_expr(c99); ret = _relational_expr(c99);
while(c99->token != NULL while((code = _parse_get_code(c99)) != TC_NULL
&& ((code = token_get_code(c99->token)) && (code == C99_CODE_OPERATOR_DEQUALS
== C99_CODE_OPERATOR_DEQUALS
|| code == C99_CODE_OPERATOR_NEQUALS)) || code == C99_CODE_OPERATOR_NEQUALS))
{ {
ret |= scan(c99); ret |= scan(c99);
@ -1222,9 +1302,8 @@ static int _relational_expr(C99 * c99)
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _shift_expr(c99); ret = _shift_expr(c99);
while(c99->token != NULL while((code = _parse_get_code(c99)) != TC_NULL
&& ((code = token_get_code(c99->token)) && (code == C99_CODE_OPERATOR_LESS
== C99_CODE_OPERATOR_LESS
|| code == C99_CODE_OPERATOR_GREATER || code == C99_CODE_OPERATOR_GREATER
|| code == C99_CODE_OPERATOR_LEQUALS || code == C99_CODE_OPERATOR_LEQUALS
|| code == C99_CODE_OPERATOR_GEQUALS)) || code == C99_CODE_OPERATOR_GEQUALS))
@ -1247,9 +1326,8 @@ static int _shift_expr(C99 * c99)
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _additive_expr(c99); ret = _additive_expr(c99);
while(c99->token != NULL while((code = _parse_get_code(c99)) != TC_NULL
&& ((code = token_get_code(c99->token)) && (code == C99_CODE_OPERATOR_DLESS
== C99_CODE_OPERATOR_DLESS
|| code == C99_CODE_OPERATOR_DGREATER)) || code == C99_CODE_OPERATOR_DGREATER))
{ {
ret |= scan(c99); ret |= scan(c99);
@ -1270,9 +1348,8 @@ static int _additive_expr(C99 * c99)
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _multiplicative_expr(c99); ret = _multiplicative_expr(c99);
while(c99->token != NULL while((code = _parse_get_code(c99)) != TC_NULL
&& ((code = token_get_code(c99->token)) && (code == C99_CODE_OPERATOR_PLUS
== C99_CODE_OPERATOR_PLUS
|| code == C99_CODE_OPERATOR_MINUS)) || code == C99_CODE_OPERATOR_MINUS))
{ {
ret |= scan(c99); ret |= scan(c99);
@ -1293,9 +1370,8 @@ static int _multiplicative_expr(C99 * c99)
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _cast_expr(c99); ret = _cast_expr(c99);
while(c99->token != NULL while((code = _parse_get_code(c99)) != TC_NULL
&& ((code = token_get_code(c99->token)) && (code == C99_CODE_OPERATOR_TIMES
== C99_CODE_OPERATOR_TIMES
|| code == C99_CODE_OPERATOR_DIVIDE || code == C99_CODE_OPERATOR_DIVIDE
|| code == C99_CODE_OPERATOR_MODULO)) || code == C99_CODE_OPERATOR_MODULO))
{ {
@ -1418,6 +1494,7 @@ static int _labeled_statement(C99 * c99)
fprintf(stderr, "DEBUG: %s() %s\n", __func__, fprintf(stderr, "DEBUG: %s() %s\n", __func__,
_parse_get_string(c99)); _parse_get_string(c99));
#endif #endif
/* FIXME use _parse_get_code() */
if(c99->token == NULL) if(c99->token == NULL)
return _parse_error(c99, "Unexpected end of file"); return _parse_error(c99, "Unexpected end of file");
if((code = token_get_code(c99->token)) == C99_CODE_IDENTIFIER) if((code = token_get_code(c99->token)) == C99_CODE_IDENTIFIER)
@ -1494,6 +1571,7 @@ static int _selection_statement(C99 * c99)
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
_parse_get_string(c99)); _parse_get_string(c99));
#endif #endif
/* FIXME use _parse_get_code() */
if(c99->token == NULL) if(c99->token == NULL)
return _parse_error(c99, "Unexpected end of file"); return _parse_error(c99, "Unexpected end of file");
else if((code = token_get_code(c99->token)) == C99_CODE_KEYWORD_SWITCH) else if((code = token_get_code(c99->token)) == C99_CODE_KEYWORD_SWITCH)
@ -1527,6 +1605,7 @@ static int _iteration_statement(C99 * c99)
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
/* FIXME use _parse_get_code() */
if(c99->token == NULL) if(c99->token == NULL)
return _parse_error(c99, "Unexpected end of file"); return _parse_error(c99, "Unexpected end of file");
else if((code = token_get_code(c99->token)) == C99_CODE_KEYWORD_WHILE) else if((code = token_get_code(c99->token)) == C99_CODE_KEYWORD_WHILE)
@ -1580,6 +1659,7 @@ static int _jump_statement(C99 * c99)
fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__, fprintf(stderr, "DEBUG: %s() \"%s\"\n", __func__,
_parse_get_string(c99)); _parse_get_string(c99));
#endif #endif
/* FIXME use _parse_get_code() */
if(c99->token == NULL) if(c99->token == NULL)
return _parse_error(c99, "Unexpected end of file"); return _parse_error(c99, "Unexpected end of file");
else if((code = token_get_code(c99->token)) == C99_CODE_KEYWORD_GOTO) else if((code = token_get_code(c99->token)) == C99_CODE_KEYWORD_GOTO)
@ -1602,7 +1682,7 @@ static int _jump_statement(C99 * c99)
/* init-declarator-list */ /* init-declarator-list */
static int _init_declarator_list(C99 * c99) static int _init_declarator_list(C99 * c99)
/* init-declarator { init-declarator } */ /* init-declarator { "," init-declarator } */
{ {
int ret; int ret;
@ -1610,8 +1690,11 @@ static int _init_declarator_list(C99 * c99)
fprintf(stderr, "DEBUG: %s()\n", __func__); fprintf(stderr, "DEBUG: %s()\n", __func__);
#endif #endif
ret = _init_declarator(c99); ret = _init_declarator(c99);
while(_parse_in_set(c99, c99set_init_declarator)) while(_parse_is_code(c99, C99_CODE_COMMA))
{
ret |= scan(c99);
ret |= _init_declarator(c99); ret |= _init_declarator(c99);
}
return ret; return ret;
} }