aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ast.c1
-rw-r--r--ast.h1
-rw-r--r--cibic.l17
-rw-r--r--cibic.y5
4 files changed, 20 insertions, 4 deletions
diff --git a/ast.c b/ast.c
index e65f2c2..9ac5fcb 100644
--- a/ast.c
+++ b/ast.c
@@ -256,6 +256,7 @@ char *cnode_debug_type_repr(CNode *ast) {
aptr += sprintf(abuff, "\"%s\"", ast->rec.strval);
break;
case FIELD: type = "field"; break;
+ case FIELDS: type = "fields"; break;
case NOP: type = "nop"; break;
case EXP:
case INITR:
diff --git a/ast.h b/ast.h
index eaed761..5324cda 100644
--- a/ast.h
+++ b/ast.h
@@ -37,6 +37,7 @@ typedef struct CNode {
INITR, /* initializer */
TYPE_SPEC,
FIELD, /* struct-or-union field */
+ FIELDS,
PLAIN_DECL,
DECLS,
FUNCS,
diff --git a/cibic.l b/cibic.l
index 75244a0..e616325 100644
--- a/cibic.l
+++ b/cibic.l
@@ -10,6 +10,9 @@ int yycolumn = 1;
letter [a-zA-Z_$]
digit [0-9]
+string ((\\.|[^\n\"\\])*)
+char ([^'\\]|\\.|\\[0-7][0-7]?[0-7]?|\\[xX][0-9a-fA-F]+)
+
%s IN_BLOCK_COMMENT IN_INLINE_COMMENT IN_DIRECTIVE
%option yylineno
%%
@@ -72,16 +75,26 @@ digit [0-9]
return INT_CONST;
}
-'([^\'\\]|\\.|\\[0-7][0-7]?[0-7]?|\\[xX][0-9a-fA-F]+)' {
+'{char}' {
yylval.strval = strdup(yytext);
return CHAR_CONST;
}
-\"[^\n\"]*\" {
+'{char} {
+ yyerror("missing terminating ' character\n");
+ exit(1);
+}
+
+\"{string}\" {
yylval.strval = strndup(yytext + 1, strlen(yytext) - 2);
return STR_CONST;
}
+\"{string} {
+ yyerror("missing terminating \" character\n");
+ exit(1);
+}
+
"||" { return OPT_OR; }
"&&" { return OPT_AND; }
"==" { return OPT_EQ; }
diff --git a/cibic.y b/cibic.y
index 3cfdad9..6f3fc13 100644
--- a/cibic.y
+++ b/cibic.y
@@ -1,5 +1,6 @@
%{
#include <stdio.h>
+#include <stdlib.h>
#include "ast.h"
%}
%union {
@@ -83,10 +84,10 @@ type_specifier
| KW_CHAR { $$ = cnode_add_loc(cnode_create_type_spec(KW_CHAR, 0), @$); }
| KW_INT { $$ = cnode_add_loc(cnode_create_type_spec(KW_INT, 0), @$); }
| struct_or_union identifier '{' struct_fields '}' {
- $$ = cnode_add_loc(cnode_create_type_spec($1, 2, $2, cnode_add_loc($4, @4)), @$);
+ $$ = cnode_add_loc(cnode_create_type_spec($1, 2, $2, cnode_add_loc(cnode_list_wrap(FIELDS, $4), @4)), @$);
}
| struct_or_union '{' struct_fields '}' {
- $$ = cnode_add_loc(cnode_create_type_spec($1, 2, cnode_create_nop(), cnode_add_loc($3, @3)), @$);
+ $$ = cnode_add_loc(cnode_create_type_spec($1, 2, cnode_create_nop(), cnode_add_loc(cnode_list_wrap(FIELDS, $3), @3)), @$);
}
| struct_or_union identifier {
$$ = cnode_add_loc(cnode_create_type_spec($1, 2, $2, cnode_create_nop()), @$);