handle multiple strings in a row
authorMatthias Braun <matze@braunis.de>
Sat, 8 Sep 2007 11:21:29 +0000 (11:21 +0000)
committerMatthias Braun <matze@braunis.de>
Sat, 8 Sep 2007 11:21:29 +0000 (11:21 +0000)
[r18346]

lexer.c
lexer.h
parser.c
tokens.inc

diff --git a/lexer.c b/lexer.c
index ce964fa..7732c9d 100644 (file)
--- a/lexer.c
+++ b/lexer.c
@@ -405,6 +405,23 @@ int parse_escape_sequence(void)
        }
 }
 
+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)
 {
diff --git a/lexer.h b/lexer.h
index f266a90..3a3ea1f 100644 (file)
--- a/lexer.h
+++ b/lexer.h
@@ -16,4 +16,6 @@ void exit_lexer(void);
 
 void lexer_open_stream(FILE *stream, const char *input_name);
 
+const char *concat_strings(const char *string1, const char *string2);
+
 #endif
index 66d44c2..58045f3 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -14,6 +14,7 @@
 #include "adt/array.h"
 
 //#define PRINT_TOKENS
+//#define ABORT_ON_ERROR
 #define MAX_LOOKAHEAD 2
 
 struct environment_entry_t {
@@ -87,7 +88,7 @@ static inline
 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];
 }
 
@@ -104,6 +105,9 @@ void parser_print_error_prefix_pos(const source_position_t source_position)
     fputc(':', stderr);
     fprintf(stderr, "%d", source_position.linenr);
     fputs(": error: ", stderr);
+#ifdef ABORT_ON_ERROR
+       abort();
+#endif
 }
 
 void parser_print_error_prefix(void)
@@ -860,7 +864,7 @@ void parse_parameters(method_type_t *type)
                return;
        }
 
-       declaration_t *declaration;
+       declaration_t           *declaration;
        method_parameter_type_t *parameter_type;
        method_parameter_type_t *last_parameter_type = NULL;
 
@@ -897,31 +901,69 @@ void parse_parameters(method_type_t *type)
 }
 
 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;
@@ -941,6 +983,9 @@ declarator_part *parse_inner_declarator(declaration_t *declaration,
 
        part->pointers = parse_pointers();
 
+       /* TODO: find out if this is correct */
+       parse_attributes();
+
        switch(token.type) {
        case T_IDENTIFIER:
                if(declaration == NULL) {
@@ -1226,9 +1271,7 @@ expression_t *parse_string_const(void)
        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;
 }
@@ -1898,7 +1941,7 @@ statement_t *parse_compound_statement(void)
 
        statement_t *last_statement = NULL;
 
-       while(token.type != '}') {
+       while(token.type != '}' && token.type != T_EOF) {
                statement_t *statement = parse_statement();
 
                if(last_statement != NULL) {
index a5f0348..ff8b237 100644 (file)
@@ -22,7 +22,6 @@ S(float)
 S(for)
 S(goto)
 S(if)
-S(inline)
 S(int)
 S(long)
 S(register)
@@ -51,6 +50,10 @@ T(const,               "__const",)
 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,                 "++",)