7
/* #define YYERROR_VERBOSE*/
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 */
16
void warning(char*, char*);
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*);
25
/* variable management */
26
#define TYPE_UNDEFINED ((char*)0)
27
#define TYPE_TYPE ((char*)1)
29
void add_variable(char*, char*);
30
void dump_variables();
34
/* Declare ALL tokens here... */
63
%type <attr> SYNTAX_ERROR
66
%type <attr> NOT_EQ_EQ
70
%type <attr> INT_CONST
72
%type <attr> PREDICATE
76
%type <attr> GREATER_EQ
77
%type <attr> LESSER_EQ
84
%type <attr> DIAM_ALL /* <-> */
85
%type <attr> DIAM_MINUS /* <- */
88
'.' '[' /* CHECK USCORE*/
92
'*' MOD EQ_EQ NOT_EQ '/' DIV
96
ELSE '?' '!' ID VAR SYNTAX_ERROR
97
'=' ASSIGN NOT_EQ_EQ PLUS_EQ MINUS_EQ
100
'>' '<' GREATER_EQ LESSER_EQ
101
AND OR TRUE FALSE CHANNEL
110
%type <attr> speclist
112
%type <attr> preddecl
113
%type <attr> predlist
114
%type <attr> predtype
115
%type <attr> predtypelist
117
%type <attr> vardecllist
120
%type <attr> typelist
126
%type <attr> termlist
132
%type <attr> fterm_ng
134
%type <attr> modality
135
%type <attr> posmodal
137
%type <attr> unitlist
139
/* Define operator precedences here... */
148
%nonassoc '[' ']' DIAM_ALL DIAM_MIMUS /* for box/diam formula */
157
%nonassoc EQ_EQ NOT_EQ_EQ '=' NOT_EQ '<' '>' LESSER_EQ GREATER_EQ
159
%left '*' '/' MOD DIV
176
| error '.' /* catch parse errors and continue */ {}
179
/* -------------------- Prolog predicate directive -------------------- */
180
preddecl: PREDICATE predlist FROM ID '.'
182
/* output import directive */
183
fprintf(yyout, ":- import %s from %s.\n",
184
$2.val.str, $4.val.str);
186
| PREDICATE predlist '.'
188
/* no import print out */
192
predlist: predtype { $$ = $1; }
193
| predlist ',' predtype
194
{ comp2(&($$), &($1),&($3), "%s, %s", &($1),&($3)); }
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)); }
208
predtypelist: type { arity = 1; $$ = $1; }
209
| predtypelist ',' type
211
comp2(&($$), &($1),&($3), "%s,%s", &($1),&($3)); }
214
/* -------------------- channel definition -------------------- */
215
cdecl: CHANNEL ID '.'
217
fprintf(yyout, "cdef(%s,[%d,%d],[]).\n\n",
218
$2.val.lexeme, $2.l1_no, $2.c1_no);
220
| CHANNEL ID '(' vardecllist ')' '.'
222
fprintf(yyout, "cdef(%s(%s),[%d,%d],",
223
$2.val.lexeme, $4.val.str, $2.l1_no, $2.c1_no);
228
vardecllist: vardecl { set(&($$), $1.val.str, &($1), &($1)); }
229
| vardecllist ',' vardecl
230
{ comp2(&($$), &($1),&($3), "%s,%s", &($1),&($3)); }
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); }
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);
243
| ID '(' typelist ')'
244
{ comp2(&($$), &($1),&($4), "%s(%s)", &($1),&($3)); }
247
typelist: type { set(&($$), $1.val.str, &($1), &($1)); }
249
{ comp2(&($$), &($1),&($3), "%s,%s", &($1),&($3)); }
252
/* -------------------- process definition -------------------- */
254
pdefn: pname DEFINE pexp '.'
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);
263
pname: ID '(' vardecllist ')'
264
{ comp2(&($$), &($1),&($4), "%s(%s)", &($1),&($3));}
265
| ID { set(&($$), $1.val.lexeme, &($1), &($1)); }
268
pexp: exp { set(&($$), $1.val.str, &($1), &($1)); }
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)); }
277
ELSE pexp { compproc3(&($$),&($1),&($6),"if",&($2),&($4),&($6));}
280
THEN pexp { compproc(&($$), &($1),&($4),"if",&($2),&($4)); }
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)); }
290
cname: vardecl { set(&($$), $1.val.str, &($1), &($1)); }
291
| ID { set(&($$), $1.val.str, &($1), &($1)); }
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)); }
309
termlist: term { set(&($$), $1.val.str, &($1), &($1)); }
310
| termlist ',' term { comp2(&($$),&($1),&($3),"%s,%s",&($1),&($3));}
313
explist: exp { set(&($$), $1.val.str, &($1), &($1)); }
314
| explist ',' exp { comp2(&($$),&($1),&($3),"%s,%s",&($1),&($3));}
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)); }
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)); }
344
/*-------------------- Formula definition --------------------*/
345
fdefn: fterm PLUS_EQ fexp '.'
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);
357
| fterm MINUS_EQ fexp_ng '.'
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);
374
fterm: ID '(' vardecllist ')'
375
{ comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3)); }
376
| ID { set(&($$), $1.val.str, &($1), &($1)); }
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)); }
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)); }
395
fterm_ng: ID '(' vardecllist ')'
396
{ comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3)); }
400
fexp_ng: fexp_ng AND fexp_ng
401
{ comp2(&($$),&($1),&($3), "or(%s,%s)",&($1),&($3)); }
403
{ comp2(&($$),&($1),&($3), "and(%s,%s)",&($1),&($3)); }
404
| '<' modality '>' fexp_ng
405
{ comp2(&($$),&($1),&($4),"box%s,%s)",&($2),&($4)); }
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)); }
418
modality: '-' posmodal { comp1(&($$),&($1),&($2),"Minus%s",&($2)); }
419
| '-' { set(&($$), "MinusSet([]", &($1), &($1)); }
420
| posmodal { set(&($$), $1.val.str, &($1), &($1)); }
423
posmodal: unit { comp1(&($$),&($1),&($1),"(%s",&($1)); }
425
{ comp1(&($$),&($1),&($3),"Set([%s]",&($2)); }
427
unit: ID '(' unitlist ')'
429
if (strcmp($1.val.str, "in") != 0 &&
430
strcmp($1.val.str, "out") != 0) {
431
comp2(&($$),&($1),&($4),"action(%s(%s))",
434
comp2(&($$),&($1),&($4),"%s(%s)",&($1),&($3));
437
if (strcmp($1.val.str, "nop") != 0 &&
438
strcmp($1.val.str, "tau") != 0) {
439
comp1(&($$), &($1),&($1),"action(%s)",&($1));
444
| INT_CONST { set(&($$),$1.val.lexeme, &($1), &($1)); }
447
unitlist: unit { $$ = $1; }
449
{ comp2(&($$),&($1),&($3),"%s,%s",&($1),&($3)); }
454
void set(AttrType *nt, char* bd, AttrType* a1, AttrType* a2)
457
/* copy from temporary string */
458
nt->val.str = strdup(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;
467
void infix(char* op, AttrType* a0, AttrType* a1, AttrType* a2)
469
sprintf(buffer, "(%s %s %s)",
470
a1->val.str, op, a2->val.str);
471
set(a0, buffer, a1, a2);
475
void comp1(AttrType* a0, AttrType* first, AttrType* last,
476
char* format, AttrType* op1)
478
sprintf(buffer, format, op1->val.str);
479
set(a0, buffer, first, last);
482
void comp2(AttrType* a0, AttrType* first, AttrType* last,
483
char* format, AttrType* op1, AttrType* op2)
485
sprintf(buffer, format, op1->val.str, op2->val.str);
486
set(a0, buffer, first, last);
489
void compproc(AttrType* a0, AttrType* first, AttrType* last,
490
char* op, AttrType* op1, AttrType* op2)
492
sprintf(buffer, "%s([%s,[%d,%d,%d,%d]],[%s,[%d,%d,%d,%d]])",
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);
499
void compproc3(AttrType* a0, AttrType* first, AttrType* last,
500
char* op, AttrType* op1, AttrType* op2, AttrType* op3)
502
sprintf(buffer, "%s([%s,[%d,%d,%d,%d]],[%s,[%d,%d,%d,%d]],[%s,[%d,%d,%d,%d]])",
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);
510
/* -------------------- variable management -------------------- */
519
static node* head = NULL;
521
void add_variable(char* newname, char* newtype)
525
/* skip unnamed variable */
526
if (newname[0] == '_' && newname[1] == '\0')
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);
537
} else if (t->type == TYPE_TYPE) {
538
if (newtype != TYPE_TYPE)
539
warning("Type variable %s used as data", newname);
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);
550
/* add the variable at head */
551
t = (node*)malloc(sizeof(node));
552
t->varname = strdup(newname);
558
void dump_variables()
563
/* print the first data variable */
564
for (t = head; t != NULL; ) {
566
if (t->type != TYPE_TYPE) {
567
fprintf(yyout, "(%s,'%s')", t->varname, t->varname);
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);
582
fprintf(yyout, "]).\n\n");