Man page for igen.
[dyninst.git] / igen / src / parser.y
1 %{
2 #include <string.h>
3 extern int generatePVM;
4 extern int generateXDR;
5 #include "parse.h"
6
7 #define YYSTYPE union parseStack
8
9 int firstTag;
10 extern int yylex();
11 extern int emitHeader;
12 extern int generateTHREAD;
13 extern char *serverTypeName;
14 extern void *yyerror(char*);
15 extern List <typeDefn *> types;
16 extern typeDefn *foundType;
17 extern interfaceSpec *currentInterface;
18 %}
19
20 %token tIDENT tCOMMA tARRAY tSTAR tNAME tBASE tINT tUPCALL tASYNC
21 %token tLPAREN tRPAREN tSEMI tLBLOCK tRBLOCK tCMEMBER tSMEMBER
22 %token tTYPEDEF tSTRUCT tVERSION tVIRTUAL
23 %%
24
25 completeDefinition: parsableUnitList ;
26
27 parsableUnitList: 
28                 | parsableUnit { extern int parsing; parsing = 0; }parsableUnitList;
29
30 parsableUnit: interfaceSpec 
31             | typeSpec;
32
33 interfacePreamble: interfaceName tLBLOCK interfaceBase interfaceVersion {
34     interfaceSpec *is;
35
36     is = new interfaceSpec($1.cp, $4.i, $3.i);
37     currentInterface = $$.spec = is;
38
39
40 interfaceSpec: interfacePreamble definitionList tRBLOCK tSEMI {
41     $1.spec->genClass();
42 }
43
44 interfaceName: tIDENT { $$.cp = $1.cp; };
45
46 interfaceBase: tBASE tINT tSEMI { $$.i = $2.i; };
47
48 interfaceVersion: tVERSION tINT tSEMI { $$.i = $2.i; };
49
50 definitionList:
51               | definitionList definition
52               ;
53
54 optUpcall:               { $$.fd.uc = notUpcall; $$.fd.virtual_f = 0; }
55          | tVIRTUAL { $$.fd.uc = notUpcallAsync; $$.fd.virtual_f = 1;}
56          | tASYNC        { $$.fd.uc = notUpcallAsync; $$.fd.virtual_f = 0;}
57          | tVIRTUAL tASYNC { $$.fd.uc = notUpcallAsync; $$.fd.virtual_f = 1;}
58          | tUPCALL       { $$.fd.uc = syncUpcall; $$.fd.virtual_f = 0;}
59          | tVIRTUAL tUPCALL {$$.fd.uc = syncUpcall; $$.fd.virtual_f = 1; }
60          | tUPCALL tASYNC { $$.fd.uc = asyncUpcall; $$.fd.virtual_f = 0;}
61          | tVIRTUAL tUPCALL tASYNC { $$.fd.uc = asyncUpcall; $$.fd.virtual_f = 1;}
62
63 definition: optUpcall typeName pointers tIDENT tLPAREN arglist tRPAREN tSEMI {
64         char *retType;
65         remoteFunc *tf;
66         List <char *> cl;
67         List <argument *> lp, args;
68
69         /* reverse arg list */
70         for (lp = *$6.args; *lp; lp++) {
71             args.add(*lp);
72         }
73
74         retType = (char *) 
75           malloc(strlen($2.td.cp) + 1 + ($3.cl ? $3.cl->count() : 0));
76         strcpy(retType, $2.cp);
77
78         for (cl = *$3.cl; *cl; cl++) strcat(retType, "*");
79
80         tf = new remoteFunc(currentInterface, $3.cl, $4.cp, retType, 
81             args, $1.fd.uc, $1.fd.virtual_f, $2.td.structs);
82         currentInterface->newMethod(tf);
83
84         if (emitHeader) {
85             tf->genHeader();
86         }
87       }
88          | tCMEMBER tIDENT pointers tIDENT tSEMI {
89            addCMember ($2.cp, $4.cp, $3.cl); }
90          |  tSMEMBER typeName pointers tIDENT tSEMI {
91            addSMember ($2.cp, $4.cp, $3.cl);}
92
93 typeSpec: tTYPEDEF tSTRUCT tLBLOCK fieldDeclList tRBLOCK tIDENT tSEMI {
94            typeDefn *s;
95            List<field *> lp, fields;
96
97            /* reverse field list */
98            for (lp = *$4.fields; *lp; lp++) {
99                 fields.add(*lp);
100            }
101            s = new typeDefn($6.cp, fields);
102            s->genHeader();
103        }
104    ;
105
106 fieldDeclList:  { $$.fields = new List<field*>; }
107         | fieldDeclList fieldDecl { $1.fields->add($2.fld); }
108         ;
109
110 // note - $$.td.mallocs will not have any effect for thread code
111 // td.mallocs -> type will malloc memory
112 // td.struct -> type is a struct
113 typeName: tIDENT {
114                 if (!(foundType = types.find($1.cp)) && !generateTHREAD) {
115                     char str[80];
116                     sprintf(str, "unknown type %s", $1.cp);
117                     yyerror(str);
118                 }
119                 $$.td.cp = $1.cp;
120                 $$.td.structs = 0;
121                 $$.td.mallocs = 0;
122                 if (generateTHREAD || (!strcmp("String", $1.cp)))
123                   $$.td.mallocs = 1;
124                 else if (foundType->userDefined == TRUE)
125                   {
126                     $$.td.mallocs = 1;
127                     $$.td.structs = 1;
128                   }
129         }
130         | tARRAY tIDENT {
131                 extern char *findAndAddArrayType(char*);
132
133                 if (!types.find($2.cp) && !generateTHREAD) {
134                     char str[80];
135                     sprintf(str, "unknown type %s", $2.cp);
136                     yyerror(str);
137                 }
138                 $$.td.cp = findAndAddArrayType($2.cp);
139                 $$.td.mallocs = 1;
140                 $$.td.structs = 1;
141         }
142         ;
143
144 fieldDecl: typeName tIDENT tSEMI { 
145                 $$.fld = new field($1.td.cp, $2.cp);
146          }
147          ;
148
149 pointers:                { $$.cl = new List<char*>; }
150         | pointers tSTAR { $1.cl->add("*"); $$.cl = $1.cl; }
151         ;
152
153 argument: typeName pointers tIDENT {
154             $$.arg = new argument($1.td.cp, $3.cp, $2.cl, $1.td.mallocs);
155         }
156         | typeName pointers {
157             $$.arg = new argument($1.td.cp,currentInterface->genVariable(), $2.cl, $1.td.mallocs);
158         }
159         ;
160
161 nonEmptyArg: argument   {    
162                 $$.args = new(List<argument*>);
163                 $$.args->add($1.arg);
164             }
165            | nonEmptyArg tCOMMA argument {
166                $1.args->add($3.arg);
167            }
168            ;
169
170 arglist:                { $$.args = new(List<argument*>); }
171        | nonEmptyArg    { $$.args = $1.args; }
172        ;