}
}
+const char *concat_strings(const char *s1, const char *s2)
+{
+ size_t len1 = strlen(s1);
+ size_t len2 = strlen(s2);
+
+ char *concat = obstack_alloc(&symbol_obstack, len1 + len2 + 1);
+ memcpy(concat, s1, len1);
+ memcpy(concat + len1, s2, len2 + 1);
+
+ const char *result = strset_insert(&stringset, concat);
+ if(result != concat) {
+ obstack_free(&symbol_obstack, concat);
+ }
+
+ return result;
+}
+
static
void parse_string_literal(void)
{
#include "adt/array.h"
//#define PRINT_TOKENS
+//#define ABORT_ON_ERROR
#define MAX_LOOKAHEAD 2
struct environment_entry_t {
const token_t *la(int num)
{
assert(num > 0 && num <= MAX_LOOKAHEAD);
- int pos = (num-1) % MAX_LOOKAHEAD;
+ int pos = (lookahead_bufpos+num-1) % MAX_LOOKAHEAD;
return & lookahead_buffer[pos];
}
fputc(':', stderr);
fprintf(stderr, "%d", source_position.linenr);
fputs(": error: ", stderr);
+#ifdef ABORT_ON_ERROR
+ abort();
+#endif
}
void parser_print_error_prefix(void)
return;
}
- declaration_t *declaration;
+ declaration_t *declaration;
method_parameter_type_t *parameter_type;
method_parameter_type_t *last_parameter_type = NULL;
}
static
-void parse_attributes(void)
+const char *parse_string_literals(void)
{
- while(token.type == T___attribute__) {
+ assert(token.type == T_STRING_LITERAL);
+ const char *result = token.v.string;
+
+ next_token();
+
+ while(token.type == T_STRING_LITERAL) {
+ result = concat_strings(result, token.v.string);
next_token();
+ }
- expect_void('(');
- int depth = 1;
- while(depth > 0) {
- switch(token.type) {
- case T_EOF:
- parse_error("EOF while parsing attribute");
- break;
- case '(':
- next_token();
- depth++;
- break;
- case ')':
- next_token();
- depth--;
+ return result;
+}
+
+static
+void parse_attributes(void)
+{
+ while(1) {
+ switch(token.type) {
+ case T___attribute__:
+ next_token();
+
+ expect_void('(');
+ int depth = 1;
+ while(depth > 0) {
+ switch(token.type) {
+ case T_EOF:
+ parse_error("EOF while parsing attribute");
+ break;
+ case '(':
+ next_token();
+ depth++;
+ break;
+ case ')':
+ next_token();
+ depth--;
+ break;
+ default:
+ next_token();
+ }
+ }
+ break;
+ case T_asm:
+ next_token();
+ expect_void('(');
+ if(token.type != T_STRING_LITERAL) {
+ parse_error_expected("while parsing assembler attribute",
+ T_STRING_LITERAL);
+ eat_until(')');
break;
- default:
- next_token();
+ } else {
+ parse_string_literals();
}
+ expect_void(')');
+ break;
+ default:
+ goto attributes_finished;
}
}
+
+attributes_finished:
+ ;
}
typedef struct declarator_part declarator_part;
part->pointers = parse_pointers();
+ /* TODO: find out if this is correct */
+ parse_attributes();
+
switch(token.type) {
case T_IDENTIFIER:
if(declaration == NULL) {
string_literal_t *cnst = allocate_ast_zero(sizeof(cnst[0]));
cnst->expression.type = EXPR_STRING_LITERAL;
- cnst->value = token.v.string;
-
- next_token();
+ cnst->value = parse_string_literals();
return (expression_t*) cnst;
}
statement_t *last_statement = NULL;
- while(token.type != '}') {
+ while(token.type != '}' && token.type != T_EOF) {
statement_t *statement = parse_statement();
if(last_statement != NULL) {
S(for)
S(goto)
S(if)
-S(inline)
S(int)
S(long)
S(register)
T(_const, "const", = T_const)
T(restrict, "__restrict",)
T(_restrict, "restrict", = T_restrict)
+T(asm, "asm",)
+T(__asm__, "__asm__", = T_asm)
+T(inline, "inline",)
+T(__inline, "__inline", = T_inline)
T(SELECT, "->",)
T(PLUSPLUS, "++",)