You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
arts/mcopidl/yacc.yy

452 lines
10 KiB

/*
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;
}