%{ /* * The Unix Channel * * by Michel Beaudouin-Lafon * * Copyright 1993 * Centre d'Etudes de la Navigation Aerienne (CENA) * * Request management, by Stephane Chatty * * $Id$ * $CurLog$ */ #include "ccu/HashTable.h" extern "C" { int yyerror (const char*); int yyparse(); int yywrap (); int yylex(); } /* This comes from the lexical analyzer */ extern CcuDictionnary* ResWords; static void error (const char*, ...); #include #include #include #include #include "ReqMgr.h" static UchMsgMgr* CurMgr; static MsgType* CurMsg; static CcuListOf * CurFieldList; static CcuDictionnaryOf Fields (16); static void AddFieldToMsg (const char*, const char*, const char*, const char*, const char*); static void AddFieldToList (const char*); %} %union { int integer; const char *string; } %token Y_SERVICE Y_REQUEST Y_ANSWER Y_EVENT Y_YIELDS Y_GETTERS Y_SETTERS Y_CONST %token Y_ID %type opt_star %% file: /* empty */ | file decl ; decl: service | request | answer | event ; service: Y_SERVICE Y_ID ';' { CurMgr->SetName ($2); } ; request: Y_REQUEST Y_ID { CurMsg = new MsgType ($2, MsgType::isRequest); CurMgr->AddRequest (CurMsg); Fields.Clear (); } msg_body ; answer: Y_ANSWER Y_ID { CurMsg = new MsgType ($2, MsgType::isAnswer); CurMgr->AddAnswer (CurMsg); Fields.Clear (); } msg_body ; event: Y_EVENT Y_ID { CurMsg = new MsgType ($2, MsgType::isEvent); CurMgr->AddEvent (CurMsg); Fields.Clear (); } msg_body ; msg_body: '{' msg_entries '}' ';' ; msg_entries: /* empty */ | msg_entries msg_entry ; msg_entry: field | getters | setters | constructor ; field: Y_CONST Y_ID opt_star Y_ID Y_YIELDS Y_ID ';' { AddFieldToMsg ("const", $2, $3, $4, $6); } | Y_ID opt_star Y_ID Y_YIELDS Y_ID ';' { AddFieldToMsg (0, $1, $2, $3, $5); } ; opt_star: /* empty */ { $$ = 0; } | '*' { $$ = "*"; } ; getters: Y_GETTERS { CurFieldList = &CurMsg->Getters; } '(' id_list ')' ';' ; setters: Y_SETTERS { CurFieldList = &CurMsg->Setters; } '(' id_list ')' ';' ; constructor: Y_ID { if (strcmp ($1, CurMsg->GetName ()) != 0) fprintf (stderr, "unknown name %s in request type %s. Considering as constructor.\n", $1, CurMsg->GetName ()); MsgConstructor* c = new MsgConstructor; CurMsg->AddConstructor (c); CurFieldList = &c->Params; } '(' id_list ')' ';' { if (CurFieldList->IsEmpty ()) CurMsg->UseDefaultConstructor (); } ; id_list: /* empty */ | Y_ID { AddFieldToList ($1); } | id_list ',' Y_ID { AddFieldToList ($3); } ; %% #include static void AddFieldToMsg (const char* c, const char* t, const char* s, const char* id, const char* impl) { int found; CcuHashCellOf * hc = Fields.Add (id, &found); if (found) { fprintf (stderr, "warning: duplicate field %s in request %s. Ignoring. \n", id, CurMsg->GetName ()); } else { char buf [128]; if (c || s) { sprintf (buf, "%s %s %s", (c ? c : ""), t, (s ? s : "")); t = buf; } MsgField* f = new MsgField (id, t, impl); hc->SetInfo (f); CurMsg->AddField (f); } } static void AddFieldToList (const char* name) { MsgField* f = Fields [name]; if (!f) { fprintf (stderr, "warning: unknown field %s in request %s\n", name, CurMsg->GetName ()); } else { CurFieldList->Append (f); } } int _DoTee = 0; int tee (int x) { if (_DoTee) { char *s; switch (x) { case '(': s = "("; break; case ')': s = ")"; break; case '*': s = "*"; break; case ';': s = ";"; break; case ',': s = ","; break; case '{': s = "}"; break; case '\n': s = "\n"; break; case Y_ID: s = "ID"; break; case Y_SERVICE: s = "SERVICE"; break; case Y_REQUEST: s = "REQUEST"; break; case Y_ANSWER: s = "ANSWER"; break; case Y_EVENT: s = "EVENT"; break; case Y_YIELDS: s = "->"; break; case Y_GETTERS: s = "GETTERS"; break; case Y_SETTERS: s = "SETTERS"; break; /* case Y_: s = ""; break; */ default : s = "???"; break; } printf ("%s ", s); } return x; } int yyerror (const char *s) { error ("%s\n",s); return (0); } int yywrap () { return 1; } void UchMsgMgr :: Read (const char* file) { extern void LexInit (); extern FILE *yyin; LexInit (); if (!(yyin = fopen (file,"r"))) { char err [1024]; sprintf (err, "Cannot open %s", file); yyerror (err); return; } CurMgr = this; if (yyparse ()) fprintf (stderr, "\nParsing failed on %s\n", file); fclose (yyin); } extern int LineNo; static void error (const char* s, ...) { va_list ap; va_start(ap, s); fprintf (stderr, "Error at line %d: ", LineNo); vfprintf (stderr, s, ap); exit (0); }