00001
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00043
00044 #include "parseInt.h"
00045
00046
00047 #define PARSE_SYM_OPEN '(' // opening paranthesis
00048 #define PARSE_SYM_CLOSE ')' // closing paranthesis
00049 #define PARSE_SYM_LOWER '[' // shifts one rank down
00050 #define PARSE_SYM_RAISE ']' // shifts one rank up
00051 #define PARSE_SYM_CONST0 '0' // constant 0
00052 #define PARSE_SYM_CONST1 '1' // constant 1
00053 #define PARSE_SYM_NEGBEF1 '!' // negation before the variable
00054 #define PARSE_SYM_NEGBEF2 '~' // negation before the variable
00055 #define PARSE_SYM_NEGAFT '\'' // negation after the variable
00056 #define PARSE_SYM_AND1 '&' // logic AND
00057 #define PARSE_SYM_AND2 '*' // logic AND
00058 #define PARSE_SYM_XOR1 '<' // logic EXOR (the 1st symbol)
00059 #define PARSE_SYM_XOR2 '+' // logic EXOR (the 2nd symbol)
00060 #define PARSE_SYM_XOR3 '>' // logic EXOR (the 3rd symbol)
00061 #define PARSE_SYM_OR '+' // logic OR
00062 #define PARSE_SYM_EQU1 '<' // equvalence (the 1st symbol)
00063 #define PARSE_SYM_EQU2 '=' // equvalence (the 2nd symbol)
00064 #define PARSE_SYM_EQU3 '>' // equvalence (the 3rd symbol)
00065 #define PARSE_SYM_FLR1 '=' // implication (the 1st symbol)
00066 #define PARSE_SYM_FLR2 '>' // implication (the 2nd symbol)
00067 #define PARSE_SYM_FLL1 '<' // backward imp (the 1st symbol)
00068 #define PARSE_SYM_FLL2 '=' // backward imp (the 2nd symbol)
00069
00070
00071
00072 #define PARSE_OPER_NEG 10 // negation
00073 #define PARSE_OPER_AND 9 // logic AND
00074 #define PARSE_OPER_XOR 8 // logic EXOR (a'b | ab')
00075 #define PARSE_OPER_OR 7 // logic OR
00076 #define PARSE_OPER_EQU 6 // equvalence (a'b'| ab )
00077 #define PARSE_OPER_FLR 5 // implication ( a' | b )
00078 #define PARSE_OPER_FLL 4 // backward imp ( 'b | a )
00079 #define PARSE_OPER_MARK 1 // OpStack token standing for an opening paranthesis
00080
00081
00082 #define PARSE_FLAG_START 1 // after the opening parenthesis
00083 #define PARSE_FLAG_VAR 2 // after operation is received
00084 #define PARSE_FLAG_OPER 3 // after operation symbol is received
00085 #define PARSE_FLAG_ERROR 4 // when error is detected
00086
00087 #define STACKSIZE 1000
00088
00089 static DdNode * Parse_ParserPerformTopOp( DdManager * dd, Parse_StackFn_t * pStackFn, int Oper );
00090
00094
00111 DdNode * Parse_FormulaParser( FILE * pOutput, char * pFormulaInit, int nVars, int nRanks,
00112 char * ppVarNames[], DdManager * dd, DdNode * pbVars[] )
00113 {
00114 char * pFormula;
00115 Parse_StackFn_t * pStackFn;
00116 Parse_StackOp_t * pStackOp;
00117 DdNode * bFunc, * bTemp;
00118 char * pTemp;
00119 int nParans, fFound, Flag;
00120 int Oper, Oper1, Oper2;
00121 int i, v, fLower;
00122
00123
00124 if ( nVars * (nRanks + 1) > dd->size )
00125 {
00126 printf( "Parse_FormulaParser(): The BDD manager does not have enough variables.\n" );
00127 return NULL;
00128 }
00129
00130
00131 nParans = 0;
00132 for ( pTemp = pFormulaInit; *pTemp; pTemp++ )
00133 if ( *pTemp == '(' )
00134 nParans++;
00135 else if ( *pTemp == ')' )
00136 nParans--;
00137 if ( nParans != 0 )
00138 {
00139 fprintf( pOutput, "Parse_FormulaParser(): Different number of opening and closing parantheses ().\n" );
00140 return NULL;
00141 }
00142
00143 nParans = 0;
00144 for ( pTemp = pFormulaInit; *pTemp; pTemp++ )
00145 if ( *pTemp == '[' )
00146 nParans++;
00147 else if ( *pTemp == ']' )
00148 nParans--;
00149 if ( nParans != 0 )
00150 {
00151 fprintf( pOutput, "Parse_FormulaParser(): Different number of opening and closing brackets [].\n" );
00152 return NULL;
00153 }
00154
00155
00156 pFormula = ALLOC( char, strlen(pFormulaInit) + 3 );
00157 sprintf( pFormula, "(%s)", pFormulaInit );
00158
00159
00160 pStackFn = Parse_StackFnStart( STACKSIZE );
00161 pStackOp = Parse_StackOpStart( STACKSIZE );
00162
00163 Flag = PARSE_FLAG_START;
00164 fLower = 0;
00165 for ( pTemp = pFormula; *pTemp; pTemp++ )
00166 {
00167 switch ( *pTemp )
00168 {
00169
00170 case ' ':
00171 case '\t':
00172 case '\r':
00173 case '\n':
00174 continue;
00175
00176
00177 case PARSE_SYM_CONST0:
00178 Parse_StackFnPush( pStackFn, b0 ); Cudd_Ref( b0 );
00179 if ( Flag == PARSE_FLAG_VAR )
00180 {
00181 fprintf( pOutput, "Parse_FormulaParser(): No operation symbol before constant 0.\n" );
00182 Flag = PARSE_FLAG_ERROR;
00183 break;
00184 }
00185 Flag = PARSE_FLAG_VAR;
00186 break;
00187
00188
00189 case PARSE_SYM_CONST1:
00190 Parse_StackFnPush( pStackFn, b1 ); Cudd_Ref( b1 );
00191 if ( Flag == PARSE_FLAG_VAR )
00192 {
00193 fprintf( pOutput, "Parse_FormulaParser(): No operation symbol before constant 1.\n" );
00194 Flag = PARSE_FLAG_ERROR;
00195 break;
00196 }
00197 Flag = PARSE_FLAG_VAR;
00198 break;
00199
00200 case PARSE_SYM_NEGBEF1:
00201 case PARSE_SYM_NEGBEF2:
00202 if ( Flag == PARSE_FLAG_VAR )
00203 {
00204 Parse_StackOpPush( pStackOp, PARSE_OPER_AND );
00205 Flag = PARSE_FLAG_OPER;
00206 }
00207 Parse_StackOpPush( pStackOp, PARSE_OPER_NEG );
00208 break;
00209
00210 case PARSE_SYM_NEGAFT:
00211 if ( Flag != PARSE_FLAG_VAR )
00212 {
00213 fprintf( pOutput, "Parse_FormulaParser(): No variable is specified before the negation suffix.\n" );
00214 Flag = PARSE_FLAG_ERROR;
00215 break;
00216 }
00217 else
00218 Parse_StackFnPush( pStackFn, Cudd_Not( Parse_StackFnPop(pStackFn) ) );
00219 break;
00220
00221 case PARSE_SYM_AND1:
00222 case PARSE_SYM_AND2:
00223 case PARSE_SYM_OR:
00224 if ( Flag != PARSE_FLAG_VAR )
00225 {
00226 fprintf( pOutput, "Parse_FormulaParser(): There is no variable before AND, EXOR, or OR.\n" );
00227 Flag = PARSE_FLAG_ERROR;
00228 break;
00229 }
00230 if ( *pTemp == PARSE_SYM_AND1 || *pTemp == PARSE_SYM_AND2 )
00231 Parse_StackOpPush( pStackOp, PARSE_OPER_AND );
00232 else
00233 Parse_StackOpPush( pStackOp, PARSE_OPER_OR );
00234 Flag = PARSE_FLAG_OPER;
00235 break;
00236
00237 case PARSE_SYM_EQU1:
00238 if ( Flag != PARSE_FLAG_VAR )
00239 {
00240 fprintf( pOutput, "Parse_FormulaParser(): There is no variable before Equivalence or Implication\n" );
00241 Flag = PARSE_FLAG_ERROR; break;
00242 }
00243 if ( pTemp[1] == PARSE_SYM_EQU2 )
00244 {
00245 pTemp++;
00246 if ( pTemp[1] == PARSE_SYM_EQU3 )
00247 {
00248 pTemp++;
00249 Parse_StackOpPush( pStackOp, PARSE_OPER_EQU );
00250 }
00251 else
00252 {
00253 Parse_StackOpPush( pStackOp, PARSE_OPER_FLL );
00254 }
00255 }
00256 else if ( pTemp[1] == PARSE_SYM_XOR2 )
00257 {
00258 pTemp++;
00259 if ( pTemp[1] == PARSE_SYM_XOR3 )
00260 {
00261 pTemp++;
00262 Parse_StackOpPush( pStackOp, PARSE_OPER_XOR );
00263 }
00264 else
00265 {
00266 fprintf( pOutput, "Parse_FormulaParser(): Wrong symbol after \"%c%c\"\n", PARSE_SYM_EQU1, PARSE_SYM_XOR2 );
00267 Flag = PARSE_FLAG_ERROR;
00268 break;
00269 }
00270 }
00271 else
00272 {
00273 fprintf( pOutput, "Parse_FormulaParser(): Wrong symbol after \"%c\"\n", PARSE_SYM_EQU1 );
00274 Flag = PARSE_FLAG_ERROR;
00275 break;
00276 }
00277 Flag = PARSE_FLAG_OPER;
00278 break;
00279
00280 case PARSE_SYM_EQU2:
00281 if ( Flag != PARSE_FLAG_VAR )
00282 {
00283 fprintf( pOutput, "Parse_FormulaParser(): There is no variable before Reverse Implication\n" );
00284 Flag = PARSE_FLAG_ERROR;
00285 break;
00286 }
00287 if ( pTemp[1] == PARSE_SYM_EQU3 )
00288 {
00289 pTemp++;
00290 Parse_StackOpPush( pStackOp, PARSE_OPER_FLR );
00291 }
00292 else
00293 {
00294 fprintf( pOutput, "Parse_FormulaParser(): Wrong symbol after \"%c\"\n", PARSE_SYM_EQU2 );
00295 Flag = PARSE_FLAG_ERROR;
00296 break;
00297 }
00298 Flag = PARSE_FLAG_OPER;
00299 break;
00300
00301 case PARSE_SYM_LOWER:
00302 case PARSE_SYM_OPEN:
00303 if ( Flag == PARSE_FLAG_VAR )
00304 Parse_StackOpPush( pStackOp, PARSE_OPER_AND );
00305 Parse_StackOpPush( pStackOp, PARSE_OPER_MARK );
00306
00307 Flag = PARSE_FLAG_START;
00308 break;
00309
00310 case PARSE_SYM_RAISE:
00311 fLower = 1;
00312 case PARSE_SYM_CLOSE:
00313 if ( !Parse_StackOpIsEmpty( pStackOp ) )
00314 {
00315 while ( 1 )
00316 {
00317 if ( Parse_StackOpIsEmpty( pStackOp ) )
00318 {
00319 fprintf( pOutput, "Parse_FormulaParser(): There is no opening paranthesis\n" );
00320 Flag = PARSE_FLAG_ERROR;
00321 break;
00322 }
00323 Oper = Parse_StackOpPop( pStackOp );
00324 if ( Oper == PARSE_OPER_MARK )
00325 break;
00326
00327
00328 if ( Parse_ParserPerformTopOp( dd, pStackFn, Oper ) == NULL )
00329 {
00330 fprintf( pOutput, "Parse_FormulaParser(): Unknown operation\n" );
00331 free( pFormula );
00332 return NULL;
00333 }
00334 }
00335
00336 if ( fLower )
00337 {
00338 bFunc = Parse_StackFnPop( pStackFn );
00339 bFunc = Extra_bddMove( dd, bTemp = bFunc, -nVars ); Cudd_Ref( bFunc );
00340 Cudd_RecursiveDeref( dd, bTemp );
00341 Parse_StackFnPush( pStackFn, bFunc );
00342 }
00343 }
00344 else
00345 {
00346 fprintf( pOutput, "Parse_FormulaParser(): There is no opening paranthesis\n" );
00347 Flag = PARSE_FLAG_ERROR;
00348 break;
00349 }
00350 if ( Flag != PARSE_FLAG_ERROR )
00351 Flag = PARSE_FLAG_VAR;
00352 fLower = 0;
00353 break;
00354
00355
00356 default:
00357
00358 fFound = 0;
00359 for ( i = 0; pTemp[i] && pTemp[i] != ' ' && pTemp[i] != '\t' && pTemp[i] != '\r' && pTemp[i] != '\n'; i++ )
00360 {
00361 for ( v = 0; v < nVars; v++ )
00362 if ( strncmp( pTemp, ppVarNames[v], i+1 ) == 0 && strlen(ppVarNames[v]) == (unsigned)(i+1) )
00363 {
00364 pTemp += i;
00365 fFound = 1;
00366 break;
00367 }
00368 if ( fFound )
00369 break;
00370 }
00371 if ( !fFound )
00372 {
00373 fprintf( pOutput, "Parse_FormulaParser(): The parser cannot find var \"%s\" in the input var list.\n", pTemp );
00374 Flag = PARSE_FLAG_ERROR;
00375 break;
00376 }
00377
00378
00379 if ( Flag == PARSE_FLAG_VAR )
00380 Parse_StackOpPush( pStackOp, PARSE_OPER_AND );
00381 Parse_StackFnPush( pStackFn, pbVars[v] ); Cudd_Ref( pbVars[v] );
00382 Flag = PARSE_FLAG_VAR;
00383 break;
00384 }
00385
00386 if ( Flag == PARSE_FLAG_ERROR )
00387 break;
00388 else if ( Flag == PARSE_FLAG_START )
00389 continue;
00390 else if ( Flag == PARSE_FLAG_VAR )
00391 while ( 1 )
00392 {
00393 if ( Parse_StackOpIsEmpty(pStackOp) )
00394 break;
00395 Oper = Parse_StackOpPop( pStackOp );
00396 if ( Oper != PARSE_OPER_NEG )
00397 {
00398 Parse_StackOpPush( pStackOp, Oper );
00399 break;
00400 }
00401 else
00402 {
00403 Parse_StackFnPush( pStackFn, Cudd_Not(Parse_StackFnPop(pStackFn)) );
00404 }
00405 }
00406 else
00407 while ( 1 )
00408 {
00409
00410 Oper1 = Parse_StackOpPop( pStackOp );
00411 if ( Parse_StackOpIsEmpty(pStackOp) )
00412 {
00413 Parse_StackOpPush( pStackOp, Oper1 );
00414 break;
00415 }
00416 Oper2 = Parse_StackOpPop( pStackOp );
00417 if ( Oper2 >= Oper1 )
00418 {
00419
00420 if ( Parse_ParserPerformTopOp( dd, pStackFn, Oper2 ) == NULL )
00421 {
00422 fprintf( pOutput, "Parse_FormulaParser(): Unknown operation\n" );
00423 free( pFormula );
00424 return NULL;
00425 }
00426 Parse_StackOpPush( pStackOp, Oper1 );
00427 }
00428 else
00429 {
00430 Parse_StackOpPush( pStackOp, Oper2 );
00431 Parse_StackOpPush( pStackOp, Oper1 );
00432 break;
00433 }
00434 }
00435 }
00436
00437 if ( Flag != PARSE_FLAG_ERROR )
00438 {
00439 if ( !Parse_StackFnIsEmpty(pStackFn) )
00440 {
00441 bFunc = Parse_StackFnPop(pStackFn);
00442 if ( Parse_StackFnIsEmpty(pStackFn) )
00443 if ( Parse_StackOpIsEmpty(pStackOp) )
00444 {
00445 Parse_StackFnFree(pStackFn);
00446 Parse_StackOpFree(pStackOp);
00447 Cudd_Deref( bFunc );
00448 free( pFormula );
00449 return bFunc;
00450 }
00451 else
00452 fprintf( pOutput, "Parse_FormulaParser(): Something is left in the operation stack\n" );
00453 else
00454 fprintf( pOutput, "Parse_FormulaParser(): Something is left in the function stack\n" );
00455 }
00456 else
00457 fprintf( pOutput, "Parse_FormulaParser(): The input string is empty\n" );
00458 }
00459 free( pFormula );
00460 return NULL;
00461 }
00462
00474 DdNode * Parse_ParserPerformTopOp( DdManager * dd, Parse_StackFn_t * pStackFn, int Oper )
00475 {
00476 DdNode * bArg1, * bArg2, * bFunc;
00477
00478 bArg2 = Parse_StackFnPop( pStackFn );
00479 bArg1 = Parse_StackFnPop( pStackFn );
00480 if ( Oper == PARSE_OPER_AND )
00481 bFunc = Cudd_bddAnd( dd, bArg1, bArg2 );
00482 else if ( Oper == PARSE_OPER_XOR )
00483 bFunc = Cudd_bddXor( dd, bArg1, bArg2 );
00484 else if ( Oper == PARSE_OPER_OR )
00485 bFunc = Cudd_bddOr( dd, bArg1, bArg2 );
00486 else if ( Oper == PARSE_OPER_EQU )
00487 bFunc = Cudd_bddXnor( dd, bArg1, bArg2 );
00488 else if ( Oper == PARSE_OPER_FLR )
00489 bFunc = Cudd_bddOr( dd, Cudd_Not(bArg1), bArg2 );
00490 else if ( Oper == PARSE_OPER_FLL )
00491 bFunc = Cudd_bddOr( dd, Cudd_Not(bArg2), bArg1 );
00492 else
00493 return NULL;
00494 Cudd_Ref( bFunc );
00495 Cudd_RecursiveDeref( dd, bArg1 );
00496 Cudd_RecursiveDeref( dd, bArg2 );
00497 Parse_StackFnPush( pStackFn, bFunc );
00498 return bFunc;
00499 }
00500
00501