2 /* cdlparse.y -- parser for the CDL compiler
4 * Written by Scott Wood <scott@buserror.net>
16 #define do_yyerror() do { \
17 fprintf(stderr, "YYERROR at %d\n", __LINE__); \
21 static StrListRef nspace_name;
22 static StrListRef cur_strlist;
23 static IDListRef cur_idlist;
24 static ClassRef cur_class;
25 static MethodRef cur_method;
29 // The lifetime of any of these pointers is one instance
30 // of the one_input rule.
41 struct { // Used for namespace-qualified type declarations
42 NameSpace *ns; // Namespace portion -- all but last field
43 const String *ident; // New identifier portion -- last field
47 // The token list must be exactly the same as in idlparse.y, so that
48 // the same lexer can be used.
50 %token <string> TOK_IDENT
58 %token <con> TOK_INVALID
78 %token <string> TOK_STR
97 // These are not real tokens, but are used as special values in places that
98 // normally accept tokens.
105 %type <strl> qualified_ident
106 %type <idl> qualified_idlist
107 %type <boolean> maybe_dbldot
108 %type <decl> qualified_decl
128 NameSpace *ret = add_nspace(nspace_name, false);
135 NameSpace *ret = add_nspace(nspace_name, true);
144 NameSpace *ret = add_nspace(nspace_name, true);
155 TOK_NAMESPACE qualified_ident {
162 cur_strlist->push_back($1);
164 | ids_body ',' ident {
165 cur_strlist->push_back($3);
171 cur_strlist = new StrList;
181 $$ = new String("async", cur_input_file, curline, TOK_ASYNC);
184 $$ = new String("inout", cur_input_file, curline, TOK_INOUT);
187 $$ = new String("out", cur_input_file, curline, TOK_OUT);
190 $$ = new String("shared", cur_input_file, curline, TOK_SHARED);
193 $$ = new String("push", cur_input_file, curline, TOK_PUSH);
196 $$ = new String("short", cur_input_file, curline, TOK_SHORT);
199 $$ = new String("int", cur_input_file, curline, TOK_INT);
202 $$ = new String("long", cur_input_file, curline, TOK_LONG);
205 $$ = new String("ushort", cur_input_file, curline, TOK_USHORT);
208 $$ = new String("uint", cur_input_file, curline, TOK_UINT);
211 $$ = new String("ulong", cur_input_file, curline, TOK_ULONG);
214 $$ = new String("char", cur_input_file, curline, TOK_CHAR);
217 $$ = new String("octet", cur_input_file, curline, TOK_OCTET);
220 $$ = new String("fshort", cur_input_file, curline, TOK_FSHORT);
223 $$ = new String("flong", cur_input_file, curline, TOK_FLONG);
226 $$ = new String("bool", cur_input_file, curline, TOK_BOOL);
229 $$ = new String("method", cur_input_file, curline, TOK_METHOD);
232 $$ = new String("name", cur_input_file, curline, TOK_NAME);
235 $$ = new String("copy", cur_input_file, curline, TOK_COPY);
238 $$ = new String("class", cur_input_file, curline, TOK_CLASS);
241 $$ = new String("guid", cur_input_file, curline, TOK_GUID);
244 $$ = new String("static", cur_input_file, curline, TOK_STATIC);
247 $$ = new String("interface", cur_input_file, curline, TOK_IFACE);
250 $$ = new String("struct", cur_input_file, curline, TOK_STRUCT);
253 $$ = new String("const", cur_input_file, curline, TOK_CONST);
256 $$ = new String("bitfield", cur_input_file, curline, TOK_BITFIELD);
259 $$ = new String("enum", cur_input_file, curline, TOK_ENUM);
262 $$ = new String("using", cur_input_file, curline, TOK_USING);
265 $$ = new String("typedef", cur_input_file, curline, TOK_TYPEDEF);
268 $$ = new String("alias", cur_input_file, curline, TOK_ALIAS);
271 $$ = new String("virtual", cur_input_file, curline, TOK_VIRTUAL);
274 $$ = new String("inline", cur_input_file, curline, TOK_INLINE);
280 cur_strlist->push_back($1);
282 | qualified_ident_raw '.' ident {
283 cur_strlist->push_back($3);
296 /* The mid-rule action is to keep curline correct, as well
297 as creating cur_strlist. */
300 cur_strlist = new StrList;
303 cur_strlist->push_front(new String("", cur_input_file,
304 curline, TOK_IDENT));
305 } qualified_ident_raw {
313 cur_idlist->push_back($1);
315 | qualified_ids ',' qualified_ident {
316 cur_idlist->push_back($3);
322 cur_idlist = new IDList;
332 yyerrorf("Namespaces cannot be declared "
333 "with an absolute path.");
335 cur_strlist = new StrList;
336 } qualified_ident_raw {
337 $$.ident = cur_strlist->back();
340 cur_strlist->pop_back();
342 if (!cur_strlist->empty())
343 $$.ns = add_nspace(cur_strlist, true);
346 nspace_stack.push_front(cur_nspace);
357 TOK_CLASS qualified_decl {
358 cur_class = new Class($2.ident);
359 $2.ns->add_user(cur_class);
360 } ':' qualified_idlist {
362 yyerrorf("A class must implement at least one interface.");
366 for (IDList::const_iterator i = $5->begin(); i != $5->end(); ++i) {
368 Symbol *sym = lookup_sym(toplevel, strl, toplevel);
369 Interface *iface = dynamic_cast<Interface *>(sym);
372 yyerrorfl(cur_input_file, strl->back()->line,
373 "\"%s\" is not an interface.",
374 strl->flatten()->c_str());
379 cur_class->add_iface(iface);
383 cur_class->finalize();
390 | '{' multi_class_body '}'
395 | multi_class_body one_class_body
399 TOK_METHOD qualified_ident {
400 // FIXME: use the set of supported interfaces as a search path
401 Symbol *sym = lookup_sym(toplevel, $2, toplevel);
402 cur_method = dynamic_cast<Method *>(sym);
405 yyerrorfl(cur_input_file, $2->back()->line,
406 "\"%s\" is not a method.",
407 $2->flatten()->c_str());
417 | '{' multi_method_body '}'
422 | multi_method_body one_method_body
426 TOK_NAME qualified_ident ';' {
427 Class::MethodInfo *mi = cur_class->add_method(cur_method);
431 Class::MethodInfo *mi = cur_class->add_method(cur_method);
433 for (StrList::const_iterator i = $2->begin(); i != $2->end(); ++i) {
434 const String *str = *i;
438 sym = cur_method->lookup(str);
440 catch (SymbolNotFound) {
441 yyerrorfl(cur_input_file, str->line,
442 "\"%s\" is not a parameter of \"%s\".",
444 cur_method->get_fq_name()->flatten()->c_str());
449 Param *p = dynamic_cast<Param *>(sym);
452 Class::ParamInfo *pi = mi->add_param(p);
454 mi->copy_params = true;
461 static Con dummy_con;
463 void setup_cdlparse()
465 yylval_con = &dummy_con;
466 yylval_string = &cdl_lval.string;
469 list<ClassRef> classes;