spot/buddy/examples/bddcalc/parser.y
Alexandre Duret-Lutz b98c47246c [buddy] Adjust parser construction to support Automake 1.11 and 1.12.
* examples/bddcalc/parser.yxx: Rename as ...
* examples/bddcalc/parser.y: ... this.
* examples/bddcalc/parser_.cxx: New file that includes parser.c.
* examples/bddcalc/Makefile.am: Adjust.
* examples/bddcalc/parser.hxx: Delete this unused file.
2012-06-19 17:03:34 +02:00

459 lines
9.6 KiB
Text

/*************************************************************************
FILE: parser.y
DESCR: BISON rules and main program for BDD calculator
AUTH: Jorn Lind
DATE: (C) may 1999
*************************************************************************/
%{
#include <string.h>
#include <stdarg.h>
#include <fstream>
#include <getopt.h>
#define IMPLEMENTSLIST /* Special for list template handling */
#include "slist.h"
#include "hashtbl.h"
#include "parser_.h"
using namespace std;
/* Definitions for storing and caching of identifiers */
#define inputTag 0
#define exprTag 1
struct nodeData
{
nodeData(const nodeData &d) { tag=d.tag; name=sdup(d.name); val=d.val; }
nodeData(int t, char *n, bdd v) { tag=t; name=n; val=v; }
~nodeData(void) { delete[] name; }
int tag;
char *name;
bdd val;
};
typedef SList<nodeData> nodeLst;
nodeLst inputs;
hashTable names;
/* Other */
int linenum;
bddgbchandler gbcHandler = bdd_default_gbchandler;
/* Prototypes */
void actInit(token *nodes, token *cache);
void actInputs(void);
void actAddInput(token *id);
void actAssign(token *id, token *expr);
void actOpr2(token *res, token *left, token *right, int opr);
void actNot(token *res, token *right);
void actId(token *res, token *id);
void actConst(token *res, int);
void actSize(token *id);
void actDot(token *fname, token *id);
void actAutoreorder(token *times, token *method);
void actCache(void);
void actTautology(token *id);
void actExist(token *res, token *var, token *expr);
void actForall(token *res, token *var, token *expr);
void actQuantVar2(token *res, token *id, token *list);
void actQuantVar1(token *res, token *id);
void actPrint(token *id);
%}
/*************************************************************************
Token definitions
*************************************************************************/
%token T_id T_str T_intval T_true T_false
%token T_initial T_inputs T_actions
%token T_size T_dumpdot
%token T_autoreorder T_reorder T_win2 T_win2ite T_sift T_siftite T_none
%token T_cache T_tautology T_print
%token T_lpar T_rpar
%token T_equal
%token T_semi T_dot
%right T_exist T_forall T_dot
%left T_biimp
%left T_imp
%left T_or T_nor
%left T_xor
%left T_nand T_and
%right T_not
/*************************************************************************
BISON rules
*************************************************************************/
%%
/*=[ Top ]==============================================================*/
calc:
initial inputs actions
;
/*=[ Initializers ]=====================================================*/
initial:
T_initial T_intval T_intval T_semi { actInit(&$2,&$3); }
;
inputs:
T_inputs inputSeq T_semi { actInputs(); }
;
inputSeq:
inputSeq T_id { actAddInput(&$2); }
| T_id { actAddInput(&$1); }
;
/*=[ Actions ]==========================================================*/
actions:
T_actions actionSeq
;
actionSeq:
actionSeq action T_semi
| action T_semi
;
action:
assign
| size
| dot
| reorder
| cache
| tautology
| print
;
assign:
T_id T_equal expr { actAssign(&$1,&$3); }
;
expr:
expr T_and expr { actOpr2(&$$,&$1,&$3,bddop_and); }
| expr T_nand expr { actOpr2(&$$,&$1,&$3,bddop_nand); }
| expr T_xor expr { actOpr2(&$$,&$1,&$3,bddop_xor); }
| expr T_or expr { actOpr2(&$$,&$1,&$3,bddop_or); }
| expr T_nor expr { actOpr2(&$$,&$1,&$3,bddop_nor); }
| expr T_imp expr { actOpr2(&$$,&$1,&$3,bddop_imp); }
| expr T_biimp expr { actOpr2(&$$,&$1,&$3,bddop_biimp); }
| T_not expr { actNot(&$$,&$2); }
| T_lpar expr T_rpar { $$.bval = $2.bval; }
| T_id { actId(&$$,&$1); }
| T_true { $$.bval = new bdd(bddtrue); }
| T_false { $$.bval = new bdd(bddfalse); }
| quantifier { $$.bval = $1.bval; }
;
quantifier:
T_exist varlist T_dot expr { actExist(&$$,&$2,&$4); }
| T_forall varlist T_dot expr { actForall(&$$,&$2,&$4); }
;
varlist:
varlist T_id { actQuantVar2(&$$,&$2,&$1); }
| T_id { actQuantVar1(&$$,&$1); }
;
size:
T_size T_id { actSize(&$2); }
;
dot:
T_dumpdot T_str T_id { actDot(&$2,&$3); }
;
reorder:
T_reorder method { bdd_reorder($2.ival); }
| T_autoreorder T_intval method { actAutoreorder(&$2,&$3); }
;
method:
T_win2 { $$.ival = BDD_REORDER_WIN2; }
| T_win2ite { $$.ival = BDD_REORDER_WIN2ITE; }
| T_sift { $$.ival = BDD_REORDER_SIFT; }
| T_siftite { $$.ival = BDD_REORDER_SIFTITE; }
| T_none { $$.ival = BDD_REORDER_NONE; }
;
cache:
T_cache { actCache(); }
;
tautology:
T_tautology T_id { actTautology(&$2); }
;
print:
T_print T_id { actPrint(&$2); }
%%
/*************************************************************************
Main and more
*************************************************************************/
void usage(void)
{
cerr << "USAGE: bddcalc [-hg] file\n";
cerr << " -h : print this message\n";
cerr << " -g : disable garbage collection info\n";
}
int main(int ac, char **av)
{
int c;
while ((c=getopt(ac, av, "hg")) != EOF)
{
switch (c)
{
case 'h':
usage();
break;
case 'g':
gbcHandler = bdd_default_gbchandler;
break;
}
}
if (optind >= ac)
usage();
yyin = fopen(av[optind],"r");
if (!yyin)
{
cerr << "Could not open file: " << av[optind] << endl;
exit(2);
}
linenum = 1;
bdd_setcacheratio(2);
yyparse();
bdd_printstat();
bdd_done();
return 0;
}
void yyerror(const char *fmt, ...)
{
va_list argp;
va_start(argp,fmt);
fprintf(stderr, "Parse error in (or before) line %d: ", linenum);
vfprintf(stderr, fmt, argp);
va_end(argp);
exit(3);
}
/*************************************************************************
Semantic actions
*************************************************************************/
void actInit(token *nodes, token *cache)
{
bdd_init(nodes->ival, cache->ival);
bdd_gbc_hook(gbcHandler);
bdd_reorder_verbose(0);
}
void actInputs(void)
{
bdd_setvarnum(inputs.size());
int vnum=0;
for (nodeLst::ite i=inputs.first() ; i.more() ; i++, vnum++)
{
if (names.exists((*i).name))
yyerror("Redefinition of input %s", (*i).name);
(*i).val = bdd_ithvar(vnum);
hashData hd((*i).name, 0, &(*i));
names.add(hd);
}
bdd_varblockall();
}
void actAddInput(token *id)
{
inputs.append( nodeData(inputTag,sdup(id->id),bddtrue) );
}
void actAssign(token *id, token *expr)
{
if (names.exists(id->id))
yyerror("Redefinition of %s", id->id);
nodeData *d = new nodeData(exprTag, sdup(id->id), *expr->bval);
hashData hd(d->name, 0, d);
names.add(hd);
delete expr->bval;
}
void actOpr2(token *res, token *left, token *right, int opr)
{
res->bval = new bdd( bdd_apply(*left->bval, *right->bval, opr) );
delete left->bval;
delete right->bval;
}
void actNot(token *res, token *right)
{
res->bval = new bdd( bdd_not(*right->bval) );
delete right->bval;
//printf("%5d -> %f\n", fixme, bdd_satcount(*res->bval));
}
void actId(token *res, token *id)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
{
res->bval = new bdd( ((nodeData*)hd.def)->val );
}
else
yyerror("Unknown variable %s", id->id);
}
void actExist(token *res, token *var, token *expr)
{
res->bval = new bdd( bdd_exist(*expr->bval, *var->bval) );
delete var->bval;
delete expr->bval;
}
void actForall(token *res, token *var, token *expr)
{
res->bval = new bdd( bdd_forall(*expr->bval, *var->bval) );
delete var->bval;
delete expr->bval;
}
void actQuantVar2(token *res, token *id, token *list)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
{
if (hd.type == inputTag)
{
res->bval = list->bval;
*res->bval &= ((nodeData*)hd.def)->val;
}
else
yyerror("%s is not a variable", id->id);
}
else
yyerror("Unknown variable %s", id->id);
}
void actQuantVar1(token *res, token *id)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
{
if (hd.type == inputTag)
res->bval = new bdd( ((nodeData*)hd.def)->val );
else
yyerror("%s is not a variable", id->id);
}
else
yyerror("Unknown variable %s", id->id);
}
void actSize(token *id)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
{
cout << "Number of nodes used for " << id->id << " = "
<< bdd_nodecount(((nodeData*)hd.def)->val) << endl;
}
else
yyerror("Unknown variable %s", id->id);
}
void actDot(token *fname, token *id)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
{
if (bdd_fnprintdot(fname->str, ((nodeData*)hd.def)->val) < 0)
cout << "Could not open file: " << fname->str << endl;
}
else
yyerror("Unknown variable %s", id->id);
}
void actAutoreorder(token *times, token *method)
{
if (times->ival == 0)
bdd_autoreorder(method->ival);
else
bdd_autoreorder_times(method->ival, times->ival);
}
void actCache(void)
{
bdd_printstat();
}
void actTautology(token *id)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
{
if (((nodeData*)hd.def)->val == bddtrue)
cout << "Formula " << id->id << " is a tautology!\n";
else
cout << "Formula " << id->id << " is NOT a tautology!\n";
}
else
yyerror("Unknown variable %s", id->id);
}
void actPrint(token *id)
{
hashData hd;
if (names.lookup(id->id,hd) == 0)
cout << id->id << " = " << bddset << ((nodeData*)hd.def)->val << endl;
else
yyerror("Unknown variable %s", id->id);
}
/* EOF */