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