4 // This software is copyright (c) 2006 Scott Wood <scott@buserror.net>.
6 // Permission is hereby granted, free of charge, to any person obtaining a copy of
7 // this software and associated documentation files (the "Software"), to deal with
8 // the Software without restriction, including without limitation the rights to
9 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10 // of the Software, and to permit persons to whom the Software is furnished to do
11 // so, subject to the following condition:
13 // The above copyright notice and this permission notice shall be
14 // included in all copies or substantial portions of the Software.
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
18 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
33 #define do_yyerror() do { \
34 fprintf(stderr, "YYERROR at %d\n", __LINE__); \
38 static StrListRef nspace_name;
39 static StrListRef cur_strlist;
40 static IDListRef cur_idlist;
41 static ClassRef cur_class;
42 static MethodRef cur_method;
46 // The lifetime of any of these pointers is one instance
47 // of the one_input rule.
58 struct { // Used for namespace-qualified type declarations
59 NameSpace *ns; // Namespace portion -- all but last field
60 const String *ident; // New identifier portion -- last field
64 // The token list must be exactly the same as in idlparse.y, so that
65 // the same lexer can be used.
67 %token <string> TOK_IDENT
75 %token <con> TOK_INVALID
95 %token <string> TOK_STR
114 // These are not real tokens, but are used as special values in places that
115 // normally accept tokens.
122 %type <strl> qualified_ident
123 %type <idl> qualified_idlist
124 %type <boolean> maybe_dbldot
125 %type <decl> qualified_decl
145 NameSpace *ret = add_nspace(nspace_name, false);
152 NameSpace *ret = add_nspace(nspace_name, true);
161 NameSpace *ret = add_nspace(nspace_name, true);
172 TOK_NAMESPACE qualified_ident {
179 cur_strlist->push_back($1);
181 | ids_body ',' ident {
182 cur_strlist->push_back($3);
188 cur_strlist = new StrList;
198 $$ = new String("async", cur_input_file, curline, TOK_ASYNC);
201 $$ = new String("inout", cur_input_file, curline, TOK_INOUT);
204 $$ = new String("out", cur_input_file, curline, TOK_OUT);
207 $$ = new String("shared", cur_input_file, curline, TOK_SHARED);
210 $$ = new String("push", cur_input_file, curline, TOK_PUSH);
213 $$ = new String("short", cur_input_file, curline, TOK_SHORT);
216 $$ = new String("int", cur_input_file, curline, TOK_INT);
219 $$ = new String("long", cur_input_file, curline, TOK_LONG);
222 $$ = new String("ushort", cur_input_file, curline, TOK_USHORT);
225 $$ = new String("uint", cur_input_file, curline, TOK_UINT);
228 $$ = new String("ulong", cur_input_file, curline, TOK_ULONG);
231 $$ = new String("char", cur_input_file, curline, TOK_CHAR);
234 $$ = new String("octet", cur_input_file, curline, TOK_OCTET);
237 $$ = new String("fshort", cur_input_file, curline, TOK_FSHORT);
240 $$ = new String("flong", cur_input_file, curline, TOK_FLONG);
243 $$ = new String("bool", cur_input_file, curline, TOK_BOOL);
246 $$ = new String("method", cur_input_file, curline, TOK_METHOD);
249 $$ = new String("name", cur_input_file, curline, TOK_NAME);
252 $$ = new String("copy", cur_input_file, curline, TOK_COPY);
255 $$ = new String("class", cur_input_file, curline, TOK_CLASS);
258 $$ = new String("guid", cur_input_file, curline, TOK_GUID);
261 $$ = new String("static", cur_input_file, curline, TOK_STATIC);
264 $$ = new String("interface", cur_input_file, curline, TOK_IFACE);
267 $$ = new String("struct", cur_input_file, curline, TOK_STRUCT);
270 $$ = new String("const", cur_input_file, curline, TOK_CONST);
273 $$ = new String("bitfield", cur_input_file, curline, TOK_BITFIELD);
276 $$ = new String("enum", cur_input_file, curline, TOK_ENUM);
279 $$ = new String("using", cur_input_file, curline, TOK_USING);
282 $$ = new String("typedef", cur_input_file, curline, TOK_TYPEDEF);
285 $$ = new String("alias", cur_input_file, curline, TOK_ALIAS);
288 $$ = new String("virtual", cur_input_file, curline, TOK_VIRTUAL);
291 $$ = new String("inline", cur_input_file, curline, TOK_INLINE);
297 cur_strlist->push_back($1);
299 | qualified_ident_raw '.' ident {
300 cur_strlist->push_back($3);
313 /* The mid-rule action is to keep curline correct, as well
314 as creating cur_strlist. */
317 cur_strlist = new StrList;
320 cur_strlist->push_front(new String("", cur_input_file,
321 curline, TOK_IDENT));
322 } qualified_ident_raw {
330 cur_idlist->push_back($1);
332 | qualified_ids ',' qualified_ident {
333 cur_idlist->push_back($3);
339 cur_idlist = new IDList;
349 yyerrorf("Namespaces cannot be declared "
350 "with an absolute path.");
352 cur_strlist = new StrList;
353 } qualified_ident_raw {
354 $$.ident = cur_strlist->back();
357 cur_strlist->pop_back();
359 if (!cur_strlist->empty())
360 $$.ns = add_nspace(cur_strlist, true);
363 nspace_stack.push_front(cur_nspace);
374 TOK_CLASS qualified_decl {
375 cur_class = new Class($2.ident);
376 $2.ns->add_user(cur_class);
377 } ':' qualified_idlist {
379 yyerrorf("A class must implement at least one interface.");
383 for (IDList::const_iterator i = $5->begin(); i != $5->end(); ++i) {
385 Symbol *sym = lookup_sym(toplevel, strl, toplevel);
386 Interface *iface = dynamic_cast<Interface *>(sym);
389 yyerrorfl(cur_input_file, strl->back()->line,
390 "\"%s\" is not an interface.",
391 strl->flatten()->c_str());
396 cur_class->add_iface(iface);
400 cur_class->finalize();
407 | '{' multi_class_body '}'
412 | multi_class_body one_class_body
416 TOK_METHOD qualified_ident {
417 // FIXME: use the set of supported interfaces as a search path
418 Symbol *sym = lookup_sym(toplevel, $2, toplevel);
419 cur_method = dynamic_cast<Method *>(sym);
422 yyerrorfl(cur_input_file, $2->back()->line,
423 "\"%s\" is not a method.",
424 $2->flatten()->c_str());
434 | '{' multi_method_body '}'
439 | multi_method_body one_method_body
443 TOK_NAME qualified_ident ';' {
444 Class::MethodInfo *mi = cur_class->add_method(cur_method);
448 Class::MethodInfo *mi = cur_class->add_method(cur_method);
450 for (StrList::const_iterator i = $2->begin(); i != $2->end(); ++i) {
451 const String *str = *i;
455 sym = cur_method->lookup(str);
457 catch (SymbolNotFound) {
458 yyerrorfl(cur_input_file, str->line,
459 "\"%s\" is not a parameter of \"%s\".",
461 cur_method->get_fq_name()->flatten()->c_str());
466 Param *p = dynamic_cast<Param *>(sym);
469 Class::ParamInfo *pi = mi->add_param(p);
471 mi->copy_params = true;
478 static Con dummy_con;
480 void setup_cdlparse()
482 yylval_con = &dummy_con;
483 yylval_string = &cdl_lval.string;
486 list<ClassRef> classes;