|
|
|
/*
|
|
|
|
|
|
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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;
|
|
|
|
}
|