~burner/xsb/debianized-xsb

« back to all changes in this revision

Viewing changes to packages/xmc/xl.y

  • Committer: Michael R. Head
  • Date: 2006-09-06 22:11:55 UTC
  • Revision ID: burner@n23-20060906221155-7e398d23438a7ee4
Add the files from the 3.0.1 release package

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
%{
 
2
#include <stdio.h>
 
3
#include <string.h>
 
4
#include <stdlib.h>
 
5
#include "attr.h"
 
6
 
 
7
  /* #define YYERROR_VERBOSE*/
 
8
 
 
9
extern FILE* yyout;
 
10
 
 
11
extern int yyerror(char *);     /* defined in driver.c */
 
12
 extern int yylex();             /* defined in lex.yy.c */
 
13
static char buffer[4096];
 
14
static int arity;               /* to count the predicate's arity */
 
15
 
 
16
void warning(char*, char*);
 
17
 
 
18
void set(AttrType*, char*, AttrType*, AttrType*);
 
19
void infix(char* op, AttrType* a0, AttrType* a1, AttrType* a2);
 
20
void comp1(AttrType*, AttrType*, AttrType*, char*, AttrType*);
 
21
void comp2(AttrType*, AttrType*, AttrType*, char*, AttrType*, AttrType*);
 
22
void compproc(AttrType*, AttrType*, AttrType*, char*, AttrType*, AttrType*);
 
23
void compproc3(AttrType*, AttrType*, AttrType*, char*, AttrType*, AttrType*, AttrType*);
 
24
 
 
25
/* variable management */
 
26
#define TYPE_UNDEFINED  ((char*)0)
 
27
#define TYPE_TYPE       ((char*)1)
 
28
 
 
29
void add_variable(char*, char*);
 
30
void dump_variables();
 
31
 
 
32
%}
 
33
 
 
34
/* Declare ALL tokens here... */
 
35
%type <attr> ','
 
36
%type <attr> ';'
 
37
%type <attr> ':'
 
38
%type <attr> DEFINE
 
39
%type <attr> '.'
 
40
%type <attr> '['
 
41
%type <attr> ']'
 
42
%type <attr> '('
 
43
%type <attr> ')'
 
44
%type <attr> '{'
 
45
%type <attr> '}'
 
46
%type <attr> '+'
 
47
%type <attr> '-'
 
48
%type <attr> '*'
 
49
%type <attr> MOD
 
50
%type <attr> EQ_EQ
 
51
%type <attr> NOT_EQ
 
52
%type <attr> '/'
 
53
%type <attr> PREF
 
54
%type <attr> '|'
 
55
%type <attr> '#'
 
56
%type <attr> IF
 
57
%type <attr> THEN
 
58
%type <attr> ELSE
 
59
%type <attr> '?'
 
60
%type <attr> '!'
 
61
%type <attr> ID
 
62
%type <attr> VAR
 
63
%type <attr> SYNTAX_ERROR
 
64
%type <attr> '='
 
65
%type <attr> ASSIGN
 
66
%type <attr> NOT_EQ_EQ
 
67
%type <attr> PLUS_EQ
 
68
%type <attr> MINUS_EQ
 
69
%type <attr> IS
 
70
%type <attr> INT_CONST
 
71
%type <attr> COL_HY
 
72
%type <attr> PREDICATE
 
73
%type <attr> FROM
 
74
%type <attr> '>'
 
75
%type <attr> '<'
 
76
%type <attr> GREATER_EQ
 
77
%type <attr> LESSER_EQ
 
78
%type <attr> '~'
 
79
%type <attr> AND
 
80
%type <attr> OR
 
81
%type <attr> TRUE
 
82
%type <attr> FALSE
 
83
%type <attr> CHANNEL
 
84
%type <attr> DIAM_ALL   /* <-> */
 
85
%type <attr> DIAM_MINUS /* <- */
 
86
 
 
87
%token ',' ':' DEFINE
 
88
       '.' '['      /* CHECK USCORE*/
 
89
       ']' '(' ')'
 
90
       '{' '}' '+' '-'
 
91
       OP
 
92
       '*' MOD EQ_EQ NOT_EQ '/' DIV
 
93
       PREF ';'
 
94
        '|' '#'
 
95
        IF THEN
 
96
       ELSE '?' '!' ID VAR SYNTAX_ERROR
 
97
       '=' ASSIGN NOT_EQ_EQ PLUS_EQ MINUS_EQ
 
98
       IS INT_CONST COL_HY
 
99
       PREDICATE FROM
 
100
       '>' '<' GREATER_EQ LESSER_EQ
 
101
       AND OR TRUE FALSE CHANNEL
 
102
       DIAM_ALL DIAM_MINUS
 
103
 
 
104
 
 
105
%union{
 
106
    AttrType attr;
 
107
}
 
108
 
 
109
%type <attr> prog
 
110
%type <attr> speclist
 
111
%type <attr> spec
 
112
%type <attr> preddecl
 
113
%type <attr> predlist
 
114
%type <attr> predtype
 
115
%type <attr> predtypelist
 
116
%type <attr> cdecl
 
117
%type <attr> vardecllist
 
118
%type <attr> vardecl
 
119
%type <attr> type
 
120
%type <attr> typelist
 
121
%type <attr> pdefn
 
122
%type <attr> pname
 
123
%type <attr> pexp
 
124
%type <attr> cname
 
125
%type <attr> term
 
126
%type <attr> termlist
 
127
%type <attr> exp
 
128
%type <attr> explist
 
129
%type <attr> fdefn
 
130
%type <attr> fterm
 
131
%type <attr> fexp
 
132
%type <attr> fterm_ng
 
133
%type <attr> fexp_ng
 
134
%type <attr> modality
 
135
%type <attr> posmodal
 
136
%type <attr> unit
 
137
%type <attr> unitlist
 
138
 
 
139
/* Define operator precedences here... */
 
140
%nonassoc  ASSIGN IS
 
141
 
 
142
%left      OR
 
143
%left      AND
 
144
%nonassoc  '~'
 
145
/* 
 
146
%left      '{' '}' 
 
147
*/
 
148
%nonassoc      '[' ']' DIAM_ALL DIAM_MIMUS /* for box/diam formula */
 
149
/* 
 
150
%left      '(' ')' 
 
151
*/
 
152
%right     '#'
 
153
%right     '|'
 
154
%right     PREF ';'
 
155
%nonassoc  THEN
 
156
%nonassoc  ELSE
 
157
%nonassoc  EQ_EQ NOT_EQ_EQ '=' NOT_EQ '<' '>' LESSER_EQ GREATER_EQ
 
158
%left      '+' '-'
 
159
%left      '*' '/' MOD DIV
 
160
%nonassoc  '?' '!'
 
161
%left      ',' ':'
 
162
 
 
163
%%
 
164
 
 
165
prog:     speclist
 
166
;
 
167
 
 
168
speclist: spec
 
169
        | speclist spec
 
170
;
 
171
 
 
172
spec:     pdefn
 
173
        | preddecl
 
174
        | cdecl
 
175
        | fdefn
 
176
        | error '.'  /* catch parse errors and continue */ {}
 
177
;
 
178
 
 
179
/* -------------------- Prolog predicate directive -------------------- */
 
180
preddecl: PREDICATE predlist FROM ID '.'
 
181
                {
 
182
                    /* output import directive */
 
183
                    fprintf(yyout, ":- import %s from %s.\n",
 
184
                           $2.val.str, $4.val.str);
 
185
                }
 
186
        | PREDICATE predlist '.' 
 
187
                {
 
188
                    /* no import print out */
 
189
                }
 
190
;
 
191
 
 
192
predlist: predtype      { $$ = $1; }
 
193
        | predlist ',' predtype
 
194
                        { comp2(&($$), &($1),&($3), "%s, %s", &($1),&($3)); }
 
195
;
 
196
 
 
197
predtype: ID            { fprintf(yyout, "predicate(%s).\n", $1.val.lexeme);
 
198
                          comp1(&($$), &($1),&($1), "%s/0", &($1)); }
 
199
        | ID '(' predtypelist ')'
 
200
                        { /* output datatype directive */
 
201
                            fprintf(yyout, "predicate(%s(%s)).\n",
 
202
                                   $1.val.lexeme, $3.val.str);
 
203
                            sprintf(buffer, "%s/%d",
 
204
                                    $1.val.lexeme, arity);
 
205
                            set(&($$), buffer, &($1), &($4)); }
 
206
;
 
207
 
 
208
predtypelist: type      { arity = 1; $$ = $1; }
 
209
        | predtypelist ',' type 
 
210
                        { arity++;
 
211
                          comp2(&($$), &($1),&($3), "%s,%s", &($1),&($3)); }
 
212
;
 
213
 
 
214
/* -------------------- channel definition -------------------- */
 
215
cdecl:    CHANNEL ID '.'
 
216
                {
 
217
                    fprintf(yyout, "cdef(%s,[%d,%d],[]).\n\n",
 
218
                           $2.val.lexeme, $2.l1_no, $2.c1_no);
 
219
                }                   
 
220
        | CHANNEL ID '(' vardecllist  ')' '.'
 
221
                {
 
222
                    fprintf(yyout, "cdef(%s(%s),[%d,%d],",
 
223
                           $2.val.lexeme, $4.val.str, $2.l1_no, $2.c1_no);
 
224
                    dump_variables();
 
225
                }
 
226
;
 
227
 
 
228
vardecllist: vardecl    { set(&($$), $1.val.str, &($1), &($1)); }
 
229
        | vardecllist ',' vardecl
 
230
                        { comp2(&($$), &($1),&($3), "%s,%s", &($1),&($3)); }
 
231
;
 
232
 
 
233
vardecl:  VAR           { set(&($$), $1.val.lexeme, &($1), &($1));
 
234
                          add_variable($1.val.lexeme, TYPE_UNDEFINED); }
 
235
        | VAR ':' type  { comp2(&($$), &($1),&($3), "%s:%s", &($1),&($3));
 
236
                          add_variable($1.val.lexeme, $3.val.str); }
 
237
;
 
238
 
 
239
type:     ID            { set(&($$), $1.val.str, &($1), &($1)); }
 
240
        | VAR           { set(&($$), $1.val.lexeme, &($1), &($1));
 
241
                          add_variable($1.val.lexeme, TYPE_TYPE);
 
242
                        }
 
243
        | ID '(' typelist ')'
 
244
                        { comp2(&($$), &($1),&($4), "%s(%s)", &($1),&($3)); }
 
245
;
 
246
 
 
247
typelist: type          { set(&($$), $1.val.str, &($1), &($1)); }
 
248
        | typelist ',' type 
 
249
                        { comp2(&($$), &($1),&($3), "%s,%s", &($1),&($3)); }
 
250
;
 
251
 
 
252
/* -------------------- process definition -------------------- */
 
253
 
 
254
pdefn:  pname DEFINE pexp '.'
 
255
                {
 
256
                  fprintf(yyout, "pdef([%s,[%d,%d,%d,%d]],\n\t[%s,[%d,%d,%d,%d]],\n\t",
 
257
                         $1.val.str, $1.l1_no, $1.c1_no, $1.l2_no, $1.c2_no,
 
258
                         $3.val.str, $3.l1_no, $3.c1_no, $3.l2_no, $3.c2_no);
 
259
                  dump_variables();
 
260
                }
 
261
;
 
262
 
 
263
pname:  ID '(' vardecllist ')' 
 
264
                        { comp2(&($$), &($1),&($4), "%s(%s)", &($1),&($3));}
 
265
        | ID            { set(&($$), $1.val.lexeme, &($1), &($1)); }
 
266
;
 
267
 
 
268
pexp:     exp           { set(&($$), $1.val.str, &($1), &($1)); }
 
269
 
 
270
        | cname '?' term {comp2(&($$), &($1),&($3), "in(%s,%s)", &($1),&($3));}
 
271
        | cname '?' '*'  {comp1(&($$), &($1),&($3), "in(%s,*)", &($1)); }
 
272
        | cname '!' term {comp2(&($$), &($1),&($3), "out(%s,%s)",&($1),&($3));}
 
273
        | cname '!' '*'  { comp1(&($$), &($1),&($3), "out(%s,*)", &($1)); }
 
274
 
 
275
        | IF exp 
 
276
          THEN pexp 
 
277
          ELSE pexp     { compproc3(&($$),&($1),&($6),"if",&($2),&($4),&($6));}
 
278
 
 
279
        | IF exp 
 
280
          THEN pexp     { compproc(&($$), &($1),&($4),"if",&($2),&($4)); }
 
281
 
 
282
        | pexp PREF pexp
 
283
                        { compproc(&($$), &($1),&($3), "pref", &($1), &($3)); }
 
284
        | pexp ';' pexp { compproc(&($$), &($1),&($3), "pref", &($1), &($3)); }
 
285
        | pexp '#' pexp { compproc(&($$), &($1),&($3), "choice",&($1),&($3)); }
 
286
        | pexp '|' pexp { compproc(&($$), &($1),&($3), "par", &($1), &($3)); }
 
287
        | '{' pexp '}'  { set(&($$), $2.val.str, &($1), &($3)); }
 
288
;
 
289
 
 
290
cname:  vardecl         { set(&($$), $1.val.str, &($1), &($1)); }
 
291
        | ID            { set(&($$), $1.val.str, &($1), &($1)); }
 
292
;
 
293
 
 
294
term:   ID '(' explist ')' { comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3)); }
 
295
/*      ID '(' termlist ')' { comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3)); } */
 
296
        | ID                    { set(&($$), $1.val.str, &($1), &($1)); }
 
297
        | vardecl               { set(&($$), $1.val.str, &($1), &($1)); }
 
298
        | INT_CONST             { set(&($$), $1.val.lexeme, &($1), &($1)); }
 
299
        | '[' ']'               { set(&($$), "[]", &($1), &($2)); }
 
300
        | '[' termlist ']'      { comp1(&($$), &($1),&($3), "[%s]", &($2)); }
 
301
        | '[' termlist '|' term ']' {
 
302
                                  comp2(&($$), &($1),&($5), 
 
303
                                        "[%s | %s]", &($2), &($4)); }
 
304
        | '(' term ',' termlist ')' {
 
305
                                  comp2(&($$), &($1), &($5),
 
306
                                        "(%s,%s)", &($2), &($4)); }
 
307
;
 
308
 
 
309
termlist: term                  { set(&($$), $1.val.str, &($1), &($1)); }
 
310
        | termlist ',' term     { comp2(&($$),&($1),&($3),"%s,%s",&($1),&($3));}
 
311
;
 
312
 
 
313
explist: exp                    { set(&($$), $1.val.str, &($1), &($1)); }
 
314
        | explist ',' exp       { comp2(&($$),&($1),&($3),"%s,%s",&($1),&($3));}
 
315
;
 
316
 
 
317
exp:    term                    { $$ = $1; }
 
318
        | '+' exp               { set(&($$), $1.val.str, &($1), &($1)); }
 
319
        | '-' exp               { comp1(&($$), &($1),&($2), "(- %s)", &($2)); }
 
320
        | '~' exp               { comp1(&($$), &($1),&($2), "not(%s)", &($2)); }
 
321
        | exp '+' exp           { infix("+",   &($$), &($1), &($3)); }
 
322
        | exp '-' exp           { infix("-",   &($$), &($1), &($3)); }
 
323
        | exp '*' exp           { infix("*",   &($$), &($1), &($3)); }
 
324
        | exp MOD exp           { infix("mod", &($$), &($1), &($3)); }
 
325
        | exp DIV exp           { infix("//", &($$), &($1), &($3)); }
 
326
        | exp '/' exp           { infix("/",   &($$), &($1), &($3)); }
 
327
        | exp '<' exp           { infix("<",    &($$), &($1), &($3)); }
 
328
        | exp '>' exp           { infix(">",    &($$), &($1), &($3)); }
 
329
        | exp GREATER_EQ exp    { infix(">=",&($$), &($1), &($3)); }
 
330
        | exp LESSER_EQ exp     { infix("=<", &($$), &($1), &($3)); }
 
331
        | exp '=' exp           { infix("=",    &($$), &($1), &($3)); }
 
332
        | exp EQ_EQ  exp        { infix("==",   &($$), &($1), &($3)); }
 
333
        | exp NOT_EQ exp        { infix("\\=",  &($$), &($1), &($3)); }
 
334
        | exp NOT_EQ_EQ exp 
 
335
                                { infix("\\==", &($$), &($1), &($3)); }
 
336
        | exp AND exp           { infix(",",    &($$), &($1), &($3)); }
 
337
                                  /* note^ changed to Prolog format */
 
338
        | exp OR exp            { infix(";",    &($$), &($1), &($3)); }
 
339
        | exp ASSIGN exp        { infix(":=",  &($$), &($1), &($3)); }
 
340
        | exp IS exp            { infix("is",  &($$), &($1), &($3)); }
 
341
        | '(' exp ')'           { set(&($$),$2.val.str, &($1), &($1)); }
 
342
;
 
343
 
 
344
/*-------------------- Formula definition --------------------*/
 
345
fdefn:  fterm PLUS_EQ fexp '.'
 
346
                {
 
347
                    $$.l1_no=$1.l1_no;
 
348
                    $$.c1_no=$1.c1_no;
 
349
                    $$.l2_no=$4.l1_no;
 
350
                    $$.c2_no=$4.c1_no;
 
351
                    fprintf(yyout, "fdef(%s, %s).\n",
 
352
                           $1.val.str,$3.val.str);
 
353
                    fprintf(yyout, "fneg(%s, neg_form(%s)).\n",
 
354
                           $1.val.str,$1.val.str);
 
355
                }
 
356
 
 
357
        | fterm MINUS_EQ fexp_ng '.'
 
358
                {
 
359
                    $$.l1_no=$1.l1_no;
 
360
                    $$.c1_no=$1.c1_no;
 
361
                    $$.l2_no=$4.l1_no;
 
362
                    $$.c2_no=$4.c1_no;
 
363
                    /* neg_xxx = neg_form(neg_xxx) */
 
364
                    fprintf(yyout, "fdef(%s, neg_form(neg_%s)).\n",
 
365
                            $1.val.str,$1.val.str);
 
366
                    /* neg_xxx = form(neg. of expr) */
 
367
                    fprintf(yyout, "fdef(neg_%s, %s).\n",
 
368
                            $1.val.str, $3.val.str);
 
369
                    fprintf(yyout, "fneg(%s, form(neg_%s)).\n",
 
370
                           $1.val.str,$1.val.str);
 
371
                }
 
372
;
 
373
 
 
374
fterm:  ID '(' vardecllist ')'  
 
375
                        { comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3)); }
 
376
        | ID            { set(&($$), $1.val.str, &($1), &($1)); }
 
377
;
 
378
 
 
379
fexp:     fexp AND fexp { comp2(&($$),&($1),&($3), "and(%s,%s)",&($1),&($3)); }
 
380
        | fexp OR fexp  { comp2(&($$),&($1),&($3), "or(%s,%s)", &($1),&($3)); }
 
381
        | '<' modality '>' fexp
 
382
                        { comp2(&($$),&($1),&($4),"diam%s,%s)",&($2),&($4)); }
 
383
        | DIAM_ALL fexp { comp1(&($$),&($1),&($2),"diamAll(%s)",&($2)); }
 
384
        | DIAM_MINUS modality '>' fexp
 
385
                        { comp2(&($$),&($1),&($2),"diamMinus%s,%s)",&($2),&($4));}
 
386
        | '[' modality ']' fexp
 
387
                        { comp2(&($$),&($1),&($4),"box%s,%s)",&($2),&($4)); }
 
388
 
 
389
        | TRUE          { set(&($$), "tt", &($1), &($1)); }
 
390
        | FALSE         { set(&($$), "ff", &($1), &($1)); }
 
391
        | fterm         { comp1(&($$),&($1),&($1),"form(%s)",&($1)); }
 
392
        | '(' fexp ')'  { set(&($$), $2.val.str, &($1), &($3)); }
 
393
;
 
394
 
 
395
fterm_ng: ID '(' vardecllist ')'        
 
396
                        { comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3)); }
 
397
        | ID            { $$ = $1; }
 
398
;
 
399
 
 
400
fexp_ng:  fexp_ng AND fexp_ng
 
401
                        { comp2(&($$),&($1),&($3), "or(%s,%s)",&($1),&($3)); }
 
402
        | fexp_ng OR fexp_ng
 
403
                        { comp2(&($$),&($1),&($3), "and(%s,%s)",&($1),&($3)); }
 
404
        | '<' modality '>' fexp_ng
 
405
                        { comp2(&($$),&($1),&($4),"box%s,%s)",&($2),&($4)); }
 
406
        | DIAM_ALL fexp_ng
 
407
                        { comp1(&($$),&($1),&($2),"boxAll(%s)",&($2)); }
 
408
        | DIAM_MINUS modality '>' fexp_ng
 
409
                        { comp2(&($$),&($1),&($2),"boxMinus%s,%s)",&($2),&($4));}
 
410
        | '[' modality ']' fexp_ng
 
411
                        { comp2(&($$),&($1),&($4),"diam%s,%s)",&($2),&($4)); }
 
412
        | TRUE          { set(&($$), "ff", &($1), &($1)); }
 
413
        | FALSE         { set(&($$), "tt", &($1), &($1)); }
 
414
        | fterm_ng      { comp1(&($$), &($1),&($1), "neg(%s)", &($1)); }
 
415
        | '(' fexp_ng ')' { set(&($$), $2.val.str, &($1), &($3));       }
 
416
;
 
417
 
 
418
modality: '-' posmodal  { comp1(&($$),&($1),&($2),"Minus%s",&($2)); }
 
419
        | '-'           { set(&($$), "MinusSet([]", &($1), &($1)); }
 
420
        | posmodal      { set(&($$), $1.val.str, &($1), &($1)); }
 
421
;
 
422
 
 
423
posmodal: unit          { comp1(&($$),&($1),&($1),"(%s",&($1)); }
 
424
        | '{' unitlist '}'
 
425
                        { comp1(&($$),&($1),&($3),"Set([%s]",&($2)); }
 
426
 
 
427
unit:   ID '(' unitlist ')'
 
428
                        {
 
429
                            if (strcmp($1.val.str, "in") != 0 &&
 
430
                                strcmp($1.val.str, "out") != 0) {
 
431
                                comp2(&($$),&($1),&($4),"action(%s(%s))",
 
432
                                      &($1),&($3));
 
433
                            } else
 
434
                                comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3));
 
435
                        }
 
436
        | ID            {
 
437
                            if (strcmp($1.val.str, "nop") != 0 &&
 
438
                                strcmp($1.val.str, "tau") != 0) {
 
439
                                comp1(&($$), &($1),&($1),"action(%s)",&($1));
 
440
                            } else
 
441
                                $$ = $1;
 
442
                        }
 
443
        | VAR           { $$ = $1; }
 
444
        | INT_CONST     { set(&($$),$1.val.lexeme, &($1), &($1)); }
 
445
;
 
446
 
 
447
unitlist:  unit         { $$ = $1; }
 
448
        | unitlist ',' unit
 
449
                        { comp2(&($$),&($1),&($3),"%s,%s",&($1),&($3)); }
 
450
;
 
451
 
 
452
%%
 
453
 
 
454
void set(AttrType *nt, char* bd, AttrType* a1, AttrType* a2)
 
455
{
 
456
    if (bd == buffer)
 
457
        /* copy from temporary string */
 
458
        nt->val.str = strdup(bd);
 
459
    else
 
460
        nt->val.str = bd;
 
461
    nt->l1_no = a1->l1_no;
 
462
    nt->c1_no = a1->c1_no;
 
463
    nt->l2_no = a2->l2_no;
 
464
    nt->c2_no = a2->c2_no;
 
465
}
 
466
 
 
467
void infix(char* op, AttrType* a0, AttrType* a1, AttrType* a2)
 
468
{
 
469
    sprintf(buffer, "(%s %s %s)",
 
470
            a1->val.str, op, a2->val.str);
 
471
    set(a0, buffer, a1, a2);
 
472
}
 
473
 
 
474
 
 
475
void comp1(AttrType* a0, AttrType* first, AttrType* last,
 
476
                char* format, AttrType* op1)
 
477
{
 
478
    sprintf(buffer, format, op1->val.str);
 
479
    set(a0, buffer, first, last);
 
480
}
 
481
 
 
482
void comp2(AttrType* a0, AttrType* first, AttrType* last,
 
483
                char* format, AttrType* op1, AttrType* op2)
 
484
{
 
485
    sprintf(buffer, format, op1->val.str, op2->val.str);
 
486
    set(a0, buffer, first, last);
 
487
}
 
488
 
 
489
void compproc(AttrType* a0, AttrType* first, AttrType* last,
 
490
                char* op, AttrType* op1, AttrType* op2)
 
491
{
 
492
    sprintf(buffer, "%s([%s,[%d,%d,%d,%d]],[%s,[%d,%d,%d,%d]])",
 
493
            op,
 
494
            op1->val.str, op1->l1_no, op1->c1_no, op1->l2_no, op1->c2_no,
 
495
            op2->val.str, op2->l1_no, op2->c1_no, op2->l2_no, op2->c2_no);
 
496
    set(a0, buffer, first, last);
 
497
}
 
498
 
 
499
void compproc3(AttrType* a0, AttrType* first, AttrType* last,
 
500
                char* op, AttrType* op1, AttrType* op2, AttrType* op3)
 
501
{
 
502
    sprintf(buffer, "%s([%s,[%d,%d,%d,%d]],[%s,[%d,%d,%d,%d]],[%s,[%d,%d,%d,%d]])",
 
503
            op,
 
504
            op1->val.str, op1->l1_no, op1->c1_no, op1->l2_no, op1->c2_no,
 
505
            op2->val.str, op2->l1_no, op2->c1_no, op2->l2_no, op2->c2_no,
 
506
            op3->val.str, op3->l1_no, op3->c1_no, op3->l2_no, op3->c2_no);
 
507
    set(a0, buffer, first, last);
 
508
}
 
509
 
 
510
/* -------------------- variable management -------------------- */
 
511
 
 
512
typedef struct node
 
513
{
 
514
    char* varname;
 
515
    char* type;
 
516
    struct node* next;
 
517
} node;
 
518
 
 
519
static node* head = NULL;
 
520
 
 
521
void add_variable(char* newname, char* newtype)
 
522
{
 
523
    node* t;
 
524
 
 
525
    /* skip unnamed variable */
 
526
    if (newname[0] == '_' && newname[1] == '\0')
 
527
        return;
 
528
 
 
529
    /* check whether the variable is recorded */
 
530
    for (t = head; t != NULL; t = t->next)
 
531
        if (strcmp(newname, t->varname) == 0) {
 
532
            if (t->type == TYPE_UNDEFINED) {
 
533
                if (newtype == TYPE_TYPE) 
 
534
                    warning("Data variable used as type", newname);
 
535
                else 
 
536
                    t->type = newtype;
 
537
            } else if (t->type == TYPE_TYPE) {
 
538
                if (newtype != TYPE_TYPE)
 
539
                    warning("Type variable %s used as data", newname);
 
540
            } else {
 
541
                if (newtype == TYPE_TYPE)
 
542
                    warning("Data variable %s used as type", newname);
 
543
                else if (newtype != TYPE_UNDEFINED 
 
544
                         && strcmp(t->type, newtype) != 0)
 
545
                    warning("Data variable %s's type defined twice", newname);
 
546
            }
 
547
            return;
 
548
        }
 
549
 
 
550
    /* add the variable at head */
 
551
    t = (node*)malloc(sizeof(node));
 
552
    t->varname = strdup(newname);
 
553
    t->type = newtype;
 
554
    t->next = head;
 
555
    head = t;
 
556
}
 
557
 
 
558
void dump_variables()
 
559
{
 
560
    node* t;
 
561
 
 
562
    fprintf(yyout, "[");
 
563
    /* print the first data variable */
 
564
    for (t = head; t != NULL; ) {
 
565
        head = t->next;
 
566
        if (t->type != TYPE_TYPE) {
 
567
            fprintf(yyout, "(%s,'%s')", t->varname, t->varname);
 
568
            free(t);
 
569
            break;
 
570
        }
 
571
        free(t);
 
572
    }
 
573
 
 
574
    /* print the remaining data variables */
 
575
    for (t = head; t != NULL; ) {
 
576
        if (t->type != TYPE_TYPE)
 
577
            fprintf(yyout, ", (%s,'%s')", t->varname, t->varname);
 
578
        head = t->next;
 
579
        free(t);
 
580
        t = head;
 
581
    }
 
582
    fprintf(yyout, "]).\n\n");
 
583
}