aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-10-10 23:41:40 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-10-10 23:41:40 +0300
commit27e0842899c6d2a674d95d888e10d0b036e27753 (patch)
tree6f9519b8b40747aca8c505b8a7af0c3fcae6a0f5
parent250d9aab8f79ebd7a2f2535de9db60172df51598 (diff)
downloadcflow-27e0842899c6d2a674d95d888e10d0b036e27753.tar.gz
cflow-27e0842899c6d2a674d95d888e10d0b036e27753.tar.bz2
Improve parser. Allow users to declare aliases to other symbols.
The latter feature is useful for declaring reserved symbols such as __restrict or __inline, e.g. --symbol __restrict:=restrict instructs cflow to treat `__restrict' exactly as `restrict'. * src/Makefile.am: Minor fix in rule for flowgraph. * src/c.l (init_tokens): New function, separated from init_lex. Install qualifiers. * src/cflow.h (symbol_alias): New flag. (symbol)<alias>: New member. (INSTALL_DEFAULT,INSTALL_OVERWRITE) (INSTALL_CHECK_LOCAL,INSTALL_UNIT_LOCAL): New defines. * src/cflow.rc: Rewrite for use with --cpp='gcc -E' * src/main.c (symbol_override): Extend syntax to allow for defining aliases to other tokens (--symbol __inline:=inline). * src/parser.c (print_token): print qualifiers and ops. (file_error): Change signature. All uses changed. (save_token): Improve output spacing. (skip_balanced): Treat LBRACE0 and RBRACE0 as { and }. (is_function): allow for qualifiers and wrappers before defintion. (parse_function_declaration): Remove PARM_WRAPPER case: it is taken care of by the caller. (fake_struct): leave when '(' is encountered. (parse_variable_declaration): Allow for qualifiers before the identifier. (skip_struct): Use skip_balanced. (dcl): Handle wrappers. Leave if a semicolon is encountered. (dirdcl): Optimize handing of wrapper. (maybe_parm_list): Handle qualifiers. (declare): allow for wrappers. (declare_type): Pass INSTALL_UNIT_LOCAL as a flag to install. * src/symbol.c (lookup): Argument is const now. (install): Change semantics of the 2nd argument. (install_ident): Change the call to install accordingly. * tests/nfparg.at: Change spacing to reflect changes to save_token.
-rw-r--r--src/Makefile.am9
-rw-r--r--src/c.l95
-rw-r--r--src/cflow.h16
-rw-r--r--src/cflow.rc20
-rw-r--r--src/main.c45
-rw-r--r--src/parser.c175
-rw-r--r--src/symbol.c30
-rw-r--r--tests/nfparg.at2
8 files changed, 235 insertions, 157 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 05acd30..f4736d7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -44,11 +44,12 @@ AM_CPPFLAGS=-DLOCALEDIR=\"$(localedir)\"
44AM_LFLAGS=-dvp 44AM_LFLAGS=-dvp
45EXTRA_DIST=cflow.rc 45EXTRA_DIST=cflow.rc
46 46
47CFLOW=$(abs_builddir)/cflow
47CFLOW_FLAGS=-i^s --brief 48CFLOW_FLAGS=-i^s --brief
48cflow_CFLOW_INPUT=$(cflow_OBJECTS:.@OBJEXT@=.c) 49cflow_CFLOW_INPUT=$(cflow_OBJECTS:.@OBJEXT@=.c)
49cflow.cflow: $(cflow_CFLOW_INPUT) cflow.rc Makefile 50cflow.cflow: $(cflow_CFLOW_INPUT) cflow.rc Makefile
50 CFLOWRC=$(top_srcdir)/src/cflow.rc \ 51 $(AM_V_GEN)CFLOWRC=$(top_srcdir)/src/cflow.rc \
51 cflow -o$@ $(CFLOW_FLAGS) $(DEFS) \ 52 $(CFLOW) -o$@ --cpp="$(CC) -E" $(CFLOW_FLAGS) $(DEFS) \
52 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 53 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
53 $(CPPFLAGS) \ 54 $(CPPFLAGS) \
54 $(cflow_CFLOW_INPUT) 55 $(cflow_CFLOW_INPUT)
diff --git a/src/c.l b/src/c.l
index be14004..f3467e8 100644
--- a/src/c.l
+++ b/src/c.l
@@ -75,7 +75,6 @@ auto /* ignored */;
75extern return EXTERN; 75extern return EXTERN;
76static return STATIC; 76static return STATIC;
77typedef return TYPEDEF; 77typedef return TYPEDEF;
78inline {yylval.str = "inline"; return QUALIFIER; }
79struct {yylval.str = "struct"; return STRUCT;} 78struct {yylval.str = "struct"; return STRUCT;}
80union {yylval.str = "union"; return STRUCT;} 79union {yylval.str = "union"; return STRUCT;}
81enum {yylval.str = "enum"; return STRUCT;} 80enum {yylval.str = "enum"; return STRUCT;}
@@ -85,30 +84,39 @@ enum {yylval.str = "enum"; return STRUCT;}
85 /* Operators 84 /* Operators
86 * 85 *
87 */ 86 */
88"->" | 87"->" {yylval.str = "->"; return MEMBER_OF;}
89"." return MEMBER_OF; 88"." {yylval.str = "."; return MEMBER_OF;}
90"*=" | 89"*=" {yylval.str = "*="; return OP;}
91"/=" | 90"/=" {yylval.str = "/="; return OP;}
92"%=" | 91"/" {yylval.str = "/"; return OP;}
93"+=" | 92"%=" {yylval.str = "%="; return OP;}
94"-=" | 93"%" {yylval.str = "%"; return OP;}
95"<<=" | 94"+=" {yylval.str = "+="; return OP;}
96">>=" | 95"+" {yylval.str = "+"; return OP;}
97"&=" | 96"-=" {yylval.str = "-="; return OP;}
98"|=" | 97"-" {yylval.str = "-"; return OP;}
99"^=" | 98"<<=" {yylval.str = "<<="; return OP;}
100"||" | 99">>=" {yylval.str = ">>="; return OP;}
101"&&" | 100"&=" {yylval.str = "&="; return OP;}
102"==" | 101"|=" {yylval.str = "|="; return OP;}
103"!=" | 102"^=" {yylval.str = "^="; return OP;}
104">=" | 103"^" {yylval.str = "^"; return OP;}
105">" | 104"||" {yylval.str = "||"; return OP;}
106"<=" | 105"|" {yylval.str = "|"; return OP;}
107"<" | 106"&&" {yylval.str = "&&"; return OP;}
108"<<" | 107"&" {yylval.str = "&"; return OP;}
109">>" | 108"==" {yylval.str = "=="; return OP;}
110"++" | 109"=" {yylval.str = "="; return '=';}
111"--" return OP; 110"!=" {yylval.str = "!="; return OP;}
111"!" {yylval.str = "!"; return OP;}
112">=" {yylval.str = ">="; return OP;}
113">" {yylval.str = ">"; return OP;}
114"<=" {yylval.str = "<="; return OP;}
115"<" {yylval.str = "<"; return OP;}
116"<<" {yylval.str = "<<"; return OP;}
117">>" {yylval.str = ">>"; return OP;}
118"++" {yylval.str = "++"; return OP;}
119"--" {yylval.str = "--"; return OP;}
112'.' | 120'.' |
113'\\.' | 121'\\.' |
114'\\[0-7]{2,3}' | 122'\\[0-7]{2,3}' |
@@ -181,50 +189,67 @@ static char *keywords[] = {
181 189
182static char *types[] = { 190static char *types[] = {
183 "char", 191 "char",
184 "const",
185 "double", 192 "double",
186 "float", 193 "float",
187 "int", 194 "int",
195 "void",
196};
197
198static char *qualifiers[] = {
188 "long", 199 "long",
200 "const",
189 "register", 201 "register",
190 "restrict", 202 "restrict",
191 "short", 203 "short",
192 "signed", 204 "signed",
193 "unsigned", 205 "unsigned",
194 "void",
195 "volatile", 206 "volatile",
207 "inline"
196}; 208};
197 209
198void 210void
199init_lex(int debug_level) 211init_tokens()
200{ 212{
201 int i; 213 int i;
202 Symbol *sp; 214 Symbol *sp;
203 215
204 yy_flex_debug = debug_level;
205
206 obstack_init(&string_stk);
207
208 for (i = 0; i < NUMITEMS(keywords); i++) { 216 for (i = 0; i < NUMITEMS(keywords); i++) {
209 sp = install(keywords[i], 0); 217 sp = install(keywords[i], INSTALL_OVERWRITE);
210 sp->type = SymToken; 218 sp->type = SymToken;
211 sp->token_type = WORD; 219 sp->token_type = WORD;
212 } 220 }
213 221
214 for (i = 0; i < NUMITEMS(types); i++) { 222 for (i = 0; i < NUMITEMS(types); i++) {
215 sp = install(types[i], 0); 223 sp = install(types[i], INSTALL_OVERWRITE);
216 sp->type = SymToken; 224 sp->type = SymToken;
217 sp->token_type = TYPE; 225 sp->token_type = TYPE;
218 sp->source = NULL; 226 sp->source = NULL;
219 sp->def_line = -1; 227 sp->def_line = -1;
220 sp->ref_line = NULL; 228 sp->ref_line = NULL;
221 } 229 }
222 sp = install("...", 0); 230
231 for (i = 0; i < NUMITEMS(qualifiers); i++) {
232 sp = install(qualifiers[i], INSTALL_OVERWRITE);
233 sp->type = SymToken;
234 sp->token_type = QUALIFIER;
235 sp->source = NULL;
236 sp->def_line = -1;
237 sp->ref_line = NULL;
238 }
239 sp = install("...", INSTALL_OVERWRITE);
223 sp->type = SymToken; 240 sp->type = SymToken;
224 sp->token_type = IDENTIFIER; 241 sp->token_type = IDENTIFIER;
225 sp->source = NULL; 242 sp->source = NULL;
226 sp->def_line = -1; 243 sp->def_line = -1;
227 sp->ref_line = NULL; 244 sp->ref_line = NULL;
245}
246
247void
248init_lex(int debug_level)
249{
250 yy_flex_debug = debug_level;
251 obstack_init(&string_stk);
252 init_tokens();
228} 253}
229 254
230int 255int
diff --git a/src/cflow.h b/src/cflow.h
index 1749ada..07cc8cf 100644
--- a/src/cflow.h
+++ b/src/cflow.h
@@ -83,7 +83,8 @@ enum symbol_flag {
83 symbol_none, 83 symbol_none,
84 symbol_temp, /* Temporary symbol. Must be deleted after 84 symbol_temp, /* Temporary symbol. Must be deleted after
85 processing of the current module */ 85 processing of the current module */
86 symbol_parm /* Parameter */ 86 symbol_parm, /* Parameter */
87 symbol_alias /* Alias to another symbol */
87}; 88};
88 89
89typedef struct symbol Symbol; 90typedef struct symbol Symbol;
@@ -96,7 +97,11 @@ struct symbol {
96 enum symtype type; /* Type of the symbol */ 97 enum symtype type; /* Type of the symbol */
97 char *name; /* Identifier */ 98 char *name; /* Identifier */
98 enum symbol_flag flag; /* Specific flag */ 99 enum symbol_flag flag; /* Specific flag */
99 100 struct symbol *alias; /* Points to the aliased symbol if
101 type==SymToken and flag==symbol_alias.
102 In this case, the rest of the structure
103 is ignored */
104
100 int active; /* Set to 1 when the symbol's subtree is 105 int active; /* Set to 1 when the symbol's subtree is
101 being processed, prevent recursion */ 106 being processed, prevent recursion */
102 int expand_line; /* Output line when this symbol was first 107 int expand_line; /* Output line when this symbol was first
@@ -165,7 +170,12 @@ extern int token_stack_increase;
165extern int symbol_count; 170extern int symbol_count;
166extern unsigned input_file_count; 171extern unsigned input_file_count;
167 172
168Symbol *lookup(char*); 173#define INSTALL_DEFAULT 0x00
174#define INSTALL_OVERWRITE 0x01
175#define INSTALL_CHECK_LOCAL 0x02
176#define INSTALL_UNIT_LOCAL 0x04
177
178Symbol *lookup(const char*);
169Symbol *install(char*, int); 179Symbol *install(char*, int);
170Symbol *install_ident(char *name, enum storage storage); 180Symbol *install_ide