4 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
6 // This software is provided 'as-is', without any express or implied warranty.
7 // In no event will the authors or contributors be held liable for any damages
8 // arising from the use of this software.
10 // Permission is hereby granted to everyone, free of charge, to use, copy,
11 // modify, prepare derivative works of, publish, distribute, perform,
12 // sublicense, and/or sell copies of the Software, provided that the above
13 // copyright notice and disclaimer of warranty be included in all copies or
14 // substantial portions of this software.
25 #define do_yyerror() do { \
26 fprintf(stderr, "YYERROR at %d\n", __LINE__); \
30 static StrListRef nspace_name;
31 static StrListRef cur_strlist;
32 static IDListRef cur_idlist;
33 static ClassRef cur_class;
34 static MethodRef cur_method;
38 // The lifetime of any of these pointers is one instance
39 // of the one_input rule.
50 struct { // Used for namespace-qualified type declarations
51 NameSpace *ns; // Namespace portion -- all but last field
52 const String *ident; // New identifier portion -- last field
56 // The token list must be exactly the same as in idlparse.y, so that
57 // the same lexer can be used.
59 %token <string> TOK_IDENT
67 %token <con> TOK_INVALID
87 %token <string> TOK_STR
106 // These are not real tokens, but are used as special values in places that
107 // normally accept tokens.
114 %type <strl> qualified_ident
115 %type <idl> qualified_idlist
116 %type <boolean> maybe_dbldot
117 %type <decl> qualified_decl
137 NameSpace *ret = add_nspace(nspace_name, false);
144 NameSpace *ret = add_nspace(nspace_name, true);
153 NameSpace *ret = add_nspace(nspace_name, true);
164 TOK_NAMESPACE qualified_ident {
171 cur_strlist->push_back($1);
173 | ids_body ',' ident {
174 cur_strlist->push_back($3);
180 cur_strlist = new StrList;
190 $$ = new String("async", cur_input_file, curline, TOK_ASYNC);
193 $$ = new String("inout", cur_input_file, curline, TOK_INOUT);
196 $$ = new String("out", cur_input_file, curline, TOK_OUT);
199 $$ = new String("shared", cur_input_file, curline, TOK_SHARED);
202 $$ = new String("push", cur_input_file, curline, TOK_PUSH);
205 $$ = new String("short", cur_input_file, curline, TOK_SHORT);
208 $$ = new String("int", cur_input_file, curline, TOK_INT);
211 $$ = new String("long", cur_input_file, curline, TOK_LONG);
214 $$ = new String("ushort", cur_input_file, curline, TOK_USHORT);
217 $$ = new String("uint", cur_input_file, curline, TOK_UINT);
220 $$ = new String("ulong", cur_input_file, curline, TOK_ULONG);
223 $$ = new String("char", cur_input_file, curline, TOK_CHAR);
226 $$ = new String("octet", cur_input_file, curline, TOK_OCTET);
229 $$ = new String("fshort", cur_input_file, curline, TOK_FSHORT);
232 $$ = new String("flong", cur_input_file, curline, TOK_FLONG);
235 $$ = new String("bool", cur_input_file, curline, TOK_BOOL);
238 $$ = new String("method", cur_input_file, curline, TOK_METHOD);
241 $$ = new String("name", cur_input_file, curline, TOK_NAME);
244 $$ = new String("copy", cur_input_file, curline, TOK_COPY);
247 $$ = new String("class", cur_input_file, curline, TOK_CLASS);
250 $$ = new String("guid", cur_input_file, curline, TOK_GUID);
253 $$ = new String("static", cur_input_file, curline, TOK_STATIC);
256 $$ = new String("interface", cur_input_file, curline, TOK_IFACE);
259 $$ = new String("struct", cur_input_file, curline, TOK_STRUCT);
262 $$ = new String("const", cur_input_file, curline, TOK_CONST);
265 $$ = new String("bitfield", cur_input_file, curline, TOK_BITFIELD);
268 $$ = new String("enum", cur_input_file, curline, TOK_ENUM);
271 $$ = new String("using", cur_input_file, curline, TOK_USING);
274 $$ = new String("typedef", cur_input_file, curline, TOK_TYPEDEF);
277 $$ = new String("alias", cur_input_file, curline, TOK_ALIAS);
280 $$ = new String("virtual", cur_input_file, curline, TOK_VIRTUAL);
283 $$ = new String("inline", cur_input_file, curline, TOK_INLINE);
289 cur_strlist->push_back($1);
291 | qualified_ident_raw '.' ident {
292 cur_strlist->push_back($3);
305 /* The mid-rule action is to keep curline correct, as well
306 as creating cur_strlist. */
309 cur_strlist = new StrList;
312 cur_strlist->push_front(new String("", cur_input_file,
313 curline, TOK_IDENT));
314 } qualified_ident_raw {
322 cur_idlist->push_back($1);
324 | qualified_ids ',' qualified_ident {
325 cur_idlist->push_back($3);
331 cur_idlist = new IDList;
341 yyerrorf("Namespaces cannot be declared "
342 "with an absolute path.");
344 cur_strlist = new StrList;
345 } qualified_ident_raw {
346 $$.ident = cur_strlist->back();
349 cur_strlist->pop_back();
351 if (!cur_strlist->empty())
352 $$.ns = add_nspace(cur_strlist, true);
355 nspace_stack.push_front(cur_nspace);
366 TOK_CLASS qualified_decl {
367 cur_class = new Class($2.ident);
368 $2.ns->add_user(cur_class);
369 } ':' qualified_idlist {
371 yyerrorf("A class must implement at least one interface.");
375 for (IDList::const_iterator i = $5->begin(); i != $5->end(); ++i) {
377 Symbol *sym = lookup_sym(toplevel, strl, toplevel);
378 Interface *iface = dynamic_cast<Interface *>(sym);
381 yyerrorfl(cur_input_file, strl->back()->line,
382 "\"%s\" is not an interface.",
383 strl->flatten()->c_str());
388 cur_class->add_iface(iface);
392 cur_class->finalize();
399 | '{' multi_class_body '}'
404 | multi_class_body one_class_body
408 TOK_METHOD qualified_ident {
409 // FIXME: use the set of supported interfaces as a search path
410 Symbol *sym = lookup_sym(toplevel, $2, toplevel);
411 cur_method = dynamic_cast<Method *>(sym);
414 yyerrorfl(cur_input_file, $2->back()->line,
415 "\"%s\" is not a method.",
416 $2->flatten()->c_str());
426 | '{' multi_method_body '}'
431 | multi_method_body one_method_body
435 TOK_NAME qualified_ident ';' {
436 Class::MethodInfo *mi = cur_class->add_method(cur_method);
440 Class::MethodInfo *mi = cur_class->add_method(cur_method);
442 for (StrList::const_iterator i = $2->begin(); i != $2->end(); ++i) {
443 const String *str = *i;
447 sym = cur_method->lookup(str);
449 catch (SymbolNotFound) {
450 yyerrorfl(cur_input_file, str->line,
451 "\"%s\" is not a parameter of \"%s\".",
453 cur_method->get_fq_name()->flatten()->c_str());
458 Param *p = dynamic_cast<Param *>(sym);
461 Class::ParamInfo *pi = mi->add_param(p);
463 mi->copy_params = true;
470 static Con dummy_con;
472 void setup_cdlparse()
474 yylval_con = &dummy_con;
475 yylval_string = &cdl_lval.string;
478 list<ClassRef> classes;