diff options
Diffstat (limited to 'mcopidl/yacc.yy')
-rw-r--r-- | mcopidl/yacc.yy | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/mcopidl/yacc.yy b/mcopidl/yacc.yy new file mode 100644 index 0000000..9e90fbe --- /dev/null +++ b/mcopidl/yacc.yy @@ -0,0 +1,451 @@ + /* + + Copyright (C) 1999 Stefan Westerfeld, stefan@space.twc.de + Nicolas Brodu, nicolas.brodu@free.fr + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. + + */ + +%{ +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <string> +#include "common.h" +#include "namespace.h" + +using namespace std; +using namespace Arts; + +extern int idl_line_no; +extern string idl_filename; + +extern int yylex(); +extern void mcopidlInitFlex( const char *_code ); +extern void addEnumTodo( const EnumDef& edef ); +extern void addStructTodo( const TypeDef& type ); +extern void addInterfaceTodo( const InterfaceDef& iface ); + +void yyerror( const char *s ) +{ + printf( "%s:%i: %s\n", idl_filename.c_str(), idl_line_no, s ); + exit(1); + // theParser->parse_error( idl_lexFile, s, idl_line_no ); +} + +static struct ParserGlobals { + vector<string> noHints; +} *g; + +%} + +%union +{ + // generic data types + long _int; + char* _str; + unsigned short _char; + double _float; + + vector<char*> *_strs; + + // types + vector<TypeComponent> *_typeComponentSeq; + TypeComponent* _typeComponent; + + // enums + vector<EnumComponent> *_enumComponentSeq; + + // interfaces + InterfaceDef *_interfaceDef; + + ParamDef* _paramDef; + vector<ParamDef> *_paramDefSeq; + + MethodDef* _methodDef; + vector<MethodDef> *_methodDefSeq; + + AttributeDef* _attributeDef; + vector<AttributeDef> *_attributeDefSeq; +} + +%token T_STRUCT T_ENUM T_INTERFACE T_MODULE T_VOID +%token T_LEFT_CURLY_BRACKET T_RIGHT_CURLY_BRACKET +%token T_LEFT_PARANTHESIS T_RIGHT_PARANTHESIS +%token T_LESS T_GREATER T_EQUAL +%token T_SEMICOLON T_COLON T_COMMA +%token<_str> T_IDENTIFIER T_QUALIFIED_IDENTIFIER +%type<_str> type +%type<_str> simpletype +%type<_str> enumname +%type<_str> interfacelistelem +/*%type<_typeComponent> typecomponentdef*/ +%type<_typeComponentSeq> structbody +%type<_paramDef> paramdef +%type<_paramDefSeq> paramdefs +%type<_paramDefSeq> paramdefs1 +%type<_methodDef> methoddef +%type<_attributeDefSeq> attributedef +%type<_attributeDefSeq> streamdef +%type<_interfaceDef> classbody +%type<_enumComponentSeq> enumbody +%type<_strs> interfacelist +%type<_strs> identifierlist +%type<_strs> defaultdef +%type<_strs> inheritedinterfaces + +%type<_int> maybereadonly +%type<_int> direction +%type<_int> maybeoneway +%type<_int> maybedefault + +%token T_INTEGER_LITERAL T_UNKNOWN +%type<_int> T_INTEGER_LITERAL + +%token T_BOOLEAN T_STRING T_LONG T_BYTE T_OBJECT T_SEQUENCE T_AUDIO T_FLOAT +%token T_IN T_OUT T_STREAM T_MULTI T_ATTRIBUTE T_READONLY T_ASYNC T_ONEWAY +%token T_DEFAULT + +%% + +aidlfile: definitions; + +definitions: epsilon | definition definitions ; + +definition: structdef | interfacedef | moduledef | enumdef ; + +structdef: + T_STRUCT T_IDENTIFIER { ModuleHelper::define($2); } T_SEMICOLON + | T_STRUCT T_IDENTIFIER { ModuleHelper::define($2); } + T_LEFT_CURLY_BRACKET + structbody + T_RIGHT_CURLY_BRACKET + T_SEMICOLON + { + char *qualified = ModuleHelper::qualify($2); + addStructTodo(TypeDef(qualified,*$5,g->noHints)); + free(qualified); + free($2); + } + ; + +enumdef: + T_ENUM enumname { ModuleHelper::define($2); } + T_LEFT_CURLY_BRACKET + enumbody + T_RIGHT_CURLY_BRACKET + T_SEMICOLON + { + char *qualified = ModuleHelper::qualify($2); + addEnumTodo(EnumDef(qualified,*$5,g->noHints)); + free(qualified); + free($2); + delete $5; + } + ; + +enumname: T_IDENTIFIER { $$ = $1; } | epsilon { $$ = strdup("_anonymous_"); }; + +enumbody: + T_IDENTIFIER + { + $$ = new vector<EnumComponent>; + $$->push_back(EnumComponent($1,0,g->noHints)); + free($1); + } + | T_IDENTIFIER T_EQUAL T_INTEGER_LITERAL + { + $$ = new vector<EnumComponent>; + $$->push_back(EnumComponent($1,$3,g->noHints)); + free($1); + } + | enumbody T_COMMA T_IDENTIFIER + { + EnumComponent& last = (*$1)[$1->size()-1]; + + $$ = $1; + $$->push_back(EnumComponent($3,last.value+1,g->noHints)); + free($3); + } + | enumbody T_COMMA T_IDENTIFIER T_EQUAL T_INTEGER_LITERAL + { + $$ = $1; + $$->push_back(EnumComponent($3,$5,g->noHints)); + free($3); + }; + +interfacedef: + T_INTERFACE T_IDENTIFIER { ModuleHelper::define($2); } T_SEMICOLON + | T_INTERFACE T_IDENTIFIER { ModuleHelper::define($2); } inheritedinterfaces + T_LEFT_CURLY_BRACKET + classbody + T_RIGHT_CURLY_BRACKET + T_SEMICOLON + { + vector<char *>::iterator ii; + for(ii=$4->begin(); ii != $4->end(); ii++) + { + $6->inheritedInterfaces.push_back(*ii); + free(*ii); + } + delete $4; + char *qualified = ModuleHelper::qualify($2); + $6->name = qualified; + free(qualified); + free($2); + addInterfaceTodo(*$6); + delete $6; + } + ; + +inheritedinterfaces: + epsilon { $$ = new vector<char *>; } + | T_COLON interfacelist { $$ = $2; }; + +moduledef: + T_MODULE T_IDENTIFIER { ModuleHelper::enter($2); free($2); } + T_LEFT_CURLY_BRACKET + definitions + T_RIGHT_CURLY_BRACKET { ModuleHelper::leave(); } + T_SEMICOLON + ; + +classbody: + epsilon { + $$ = new InterfaceDef(); + } + | methoddef classbody + { + $$ = $2; + $$->methods.insert($$->methods.begin(),*$1); + delete $1; + } + | attributedef classbody + { + $$ = $2; + $$->attributes.insert($$->attributes.begin(),$1->begin(),$1->end()); + if ((*$1)[0].flags & streamDefault) { + vector<std::string> sv; + for (vector<AttributeDef>::iterator i=$1->begin(); i!=$1->end(); i++) + sv.push_back(i->name); + $$->defaultPorts.insert($$->defaultPorts.begin(),sv.begin(),sv.end()); + } + } + | defaultdef classbody + { + $$ = $2; + for (vector<char *>::iterator i=$1->begin(); i!=$1->end(); i++) + $$->defaultPorts.insert($$->defaultPorts.begin(), *i); + }; + +attributedef: + streamdef + | maybereadonly T_ATTRIBUTE type identifierlist T_SEMICOLON + { + // 16 == attribute + vector<char *>::iterator i; + $$ = new vector<AttributeDef>; + for(i=$4->begin();i != $4->end();i++) + { + $$->push_back(AttributeDef((*i),$3,(AttributeType)($1 + 16),g->noHints)); + free(*i); + } + delete $4; + } + ; + +maybereadonly: + epsilon { $$ = 1+2; /* in&out (read & write) */ } + | T_READONLY { $$ = 2; /* out (readonly) */ } + ; + +maybeoneway: + epsilon { $$ = methodTwoway; } + | T_ONEWAY { $$ = methodOneway; } + ; + +maybedefault: + epsilon { $$ = 0; } + | T_DEFAULT { $$ = streamDefault; } + ; + +streamdef: maybedefault direction type T_STREAM identifierlist T_SEMICOLON + { + // 8 == stream + vector<char *>::iterator i; + $$ = new vector<AttributeDef>; + for(i=$5->begin();i != $5->end();i++) + { + $$->push_back(AttributeDef((*i),$3,(AttributeType)(($2|$1) + 8),g->noHints)); + free(*i); + } + delete $5; + }; + +defaultdef: T_DEFAULT identifierlist T_SEMICOLON + { + $$ = $2; + }; + +direction: + T_IN { $$ = streamIn; } + | T_IN T_MULTI { $$ = streamIn|streamMulti; } + | T_OUT { $$ = streamOut; } + | T_OUT T_MULTI { $$ = streamOut|streamMulti; } + | T_ASYNC T_IN { $$ = streamAsync|streamIn; } + | T_ASYNC T_IN T_MULTI { $$ =streamAsync|streamIn|streamMulti } + | T_ASYNC T_OUT { $$ = streamAsync|streamOut; } + | T_ASYNC T_OUT T_MULTI { $$ = streamAsync|streamOut|streamMulti; } + ; + +// CacheElement getFromCache(string name, bool hit) +methoddef: + maybeoneway type T_IDENTIFIER + T_LEFT_PARANTHESIS paramdefs T_RIGHT_PARANTHESIS T_SEMICOLON + { + $$ = new MethodDef($3,$2,(MethodType)$1,*$5,g->noHints); + free($3); + free($2); + } + ; + +paramdefs: + epsilon + { + $$ = new vector<ParamDef>; + } + | paramdef paramdefs1 + { + $$ = $2; + $$->insert($$->begin(),*$1); + delete $1; + }; + +// at least one parameter (ex: "long a" or "long a, long b, string c") +paramdefs1: + epsilon + { + $$ = new vector<ParamDef>; + } + | paramdefs1 T_COMMA paramdef + { + $$ = $1; + $$->push_back(*$3); + delete $3; + //$$->insert($$->begin(),$3); + } + ; + +// one parameter (ex: "long a") +paramdef: type T_IDENTIFIER + { + $$ = new ParamDef(string($1),string($2),g->noHints); + free($1); + free($2); + }; + +/* +typecomponentdef: type T_IDENTIFIER T_SEMICOLON + { + $$ = new TypeComponent($1,string($2)); + free($2); + }; +*/ + +identifierlist: + T_IDENTIFIER { $$ = new vector<char *>; $$->push_back($1); } + | identifierlist T_COMMA T_IDENTIFIER { $$ = $1; $$->push_back($3); } + +interfacelist: + interfacelistelem { $$ = new vector<char *>; $$->push_back($1); } + | interfacelist T_COMMA interfacelistelem { $$ = $1; $$->push_back($3); } + +interfacelistelem: T_IDENTIFIER { + $$ = ModuleHelper::qualify($1); + free($1); + } + | T_QUALIFIED_IDENTIFIER { + $$ = ModuleHelper::qualify($1); + free($1); + } + ; + +structbody: epsilon { + // is empty by default + $$ = new vector<TypeComponent>; + } + | type identifierlist T_SEMICOLON structbody { + $$ = $4; + vector<char *>::reverse_iterator i; + for(i = $2->rbegin();i != $2->rend();i++) + { + char *identifier = *i; + + $$->insert($$->begin(),TypeComponent($1,identifier,g->noHints)); + free(identifier); + } + delete $2; + }; + /* + | typecomponentdef structbody { + $$ = $2; + $$->insert($$->begin(),$1); + }; + */ + +type: simpletype + | T_SEQUENCE T_LESS simpletype T_GREATER + { + // a sequence<long> is for instance coded as *long + + // alloc new size: add one for the null byte and one for the '*' char + char *result = (char *)malloc(strlen($3)+2); + result[0] = '*'; + strcpy(&result[1],$3); + free($3); /* fails */ + + $$ = result; + }; + +simpletype: + T_BOOLEAN { $$ = strdup("boolean"); } + | T_STRING { $$ = strdup("string"); } + | T_LONG { $$ = strdup("long"); } + | T_BYTE { $$ = strdup("byte"); } + | T_OBJECT { $$ = strdup("object"); } + | T_AUDIO { $$ = strdup("float"); } + | T_FLOAT { $$ = strdup("float"); } + | T_VOID { $$ = strdup("void"); } + | T_IDENTIFIER { + $$ = ModuleHelper::qualify($1); + free($1); + } + | T_QUALIFIED_IDENTIFIER { + $$ = ModuleHelper::qualify($1); + free($1); + }; + + +epsilon: /* empty */ ; +%% + +void mcopidlParse( const char *_code ) +{ + g = new ParserGlobals; + mcopidlInitFlex( _code ); + yyparse(); + delete g; +} |