diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-10-10 23:41:40 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-10-10 23:41:40 +0300 |
commit | 27e0842899c6d2a674d95d888e10d0b036e27753 (patch) | |
tree | 6f9519b8b40747aca8c505b8a7af0c3fcae6a0f5 | |
parent | 250d9aab8f79ebd7a2f2535de9db60172df51598 (diff) | |
download | cflow-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.am | 9 | ||||
-rw-r--r-- | src/c.l | 95 | ||||
-rw-r--r-- | src/cflow.h | 16 | ||||
-rw-r--r-- | src/cflow.rc | 20 | ||||
-rw-r--r-- | src/main.c | 45 | ||||
-rw-r--r-- | src/parser.c | 175 | ||||
-rw-r--r-- | src/symbol.c | 30 | ||||
-rw-r--r-- | tests/nfparg.at | 2 |
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)\" | |||
44 | AM_LFLAGS=-dvp | 44 | AM_LFLAGS=-dvp |
45 | EXTRA_DIST=cflow.rc | 45 | EXTRA_DIST=cflow.rc |
46 | 46 | ||
47 | CFLOW=$(abs_builddir)/cflow | ||
47 | CFLOW_FLAGS=-i^s --brief | 48 | CFLOW_FLAGS=-i^s --brief |
48 | cflow_CFLOW_INPUT=$(cflow_OBJECTS:.@OBJEXT@=.c) | 49 | cflow_CFLOW_INPUT=$(cflow_OBJECTS:.@OBJEXT@=.c) |
49 | cflow.cflow: $(cflow_CFLOW_INPUT) cflow.rc Makefile | 50 | cflow.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) |
@@ -75,7 +75,6 @@ auto /* ignored */; | |||
75 | extern return EXTERN; | 75 | extern return EXTERN; |
76 | static return STATIC; | 76 | static return STATIC; |
77 | typedef return TYPEDEF; | 77 | typedef return TYPEDEF; |
78 | inline {yylval.str = "inline"; return QUALIFIER; } | ||
79 | struct {yylval.str = "struct"; return STRUCT;} | 78 | struct {yylval.str = "struct"; return STRUCT;} |
80 | union {yylval.str = "union"; return STRUCT;} | 79 | union {yylval.str = "union"; return STRUCT;} |
81 | enum {yylval.str = "enum"; return STRUCT;} | 80 | enum {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 | ||
182 | static char *types[] = { | 190 | static char *types[] = { |
183 | "char", | 191 | "char", |
184 | "const", | ||
185 | "double", | 192 | "double", |
186 | "float", | 193 | "float", |
187 | "int", | 194 | "int", |
195 | "void", | ||
196 | }; | ||
197 | |||
198 | static 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 | ||
198 | void | 210 | void |
199 | init_lex(int debug_level) | 211 | init_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 | |||
247 | void | ||
248 | init_lex(int debug_level) | ||
249 | { | ||
250 | yy_flex_debug = debug_level; | ||
251 | obstack_init(&string_stk); | ||
252 | init_tokens(); | ||
228 | } | 253 | } |
229 | 254 | ||
230 | int | 255 | int |
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 | ||
89 | typedef struct symbol Symbol; | 90 | typedef 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; | |||
165 | extern int symbol_count; | 170 | extern int symbol_count; |
166 | extern unsigned input_file_count; | 171 | extern unsigned input_file_count; |
167 | 172 | ||
168 | Symbol *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 | |||
178 | Symbol *lookup(const char*); | ||
169 | Symbol *install(char*, int); | 179 | Symbol *install(char*, int); |
170 | Symbol *install_ident(char *name, enum storage storage); | 180 | Symbol *install_ide |