#define _P_DOWN "!" #define _P_OK (c && c!=')') char *_P_ERR[2]; WFF *_P_stak, *_P_dummy = 0; /**********************************************************/ WFF *parse( fla, Pstak, cn) char fla[]; /** Text of formula to be parsed **/ WFF Pstak[]; /** Target array of subformulas **/ char *cn[]; /** Available connectives **/ { int i=0,j=0; _P_stak = Pstak; while ( fla[i] && fla[i] != '\n' ) if ( fla[i++] != ' ' ) fla[j++] = fla[i-1]; fla[j] = '\0'; i = s_parse( fla, cn ); if (i) return(Pstak+i); printf("\n ERROR: "); puts(*_P_ERR); for ( i = 0; i < _P_ERR[1]-fla; i++ ) printf(" "); puts(_P_DOWN); puts(fla); return(0); } /**********************************************************/ #define ERROR(s,ws) { *_P_ERR=s; _P_ERR[1]=ws; return(0); } /**********************************************************/ int s_parse( fla, cn ) char fla[], *cn[]; { int sbf[20], pptr=0, oldptr, ns=0, i,j; char dcn[19], c; c = *fla; while (_P_OK) { oldptr = pptr; while (strchr(cn[1],(c=fla[pptr++]))) ; i = pptr-1; if (islower(c) || strchr(*cn,c)) sbf[ns] = Loc(c, _P_dummy, _P_dummy); else if (c == '(' || c == '.') { if (!(sbf[ns] = s_parse( fla+pptr, cn,_P_stak))) return(0); j = Match(fla+pptr-1); if (!j) return(0); pptr += j-1; } else ERROR("This can't begin a subformula", fla+pptr-1) if (strchr(cn[1], fla[oldptr])) while (i > oldptr) sbf[ns] = Loc(fla[--i], _P_dummy, _P_stak+sbf[ns]); c = fla[pptr]; if (_P_OK) { if (c == '-' && fla[pptr+1] == '>') c = fla[++pptr]; if (strchr(cn[2],c)) dcn[ns++] = c; else { printf("Bad character %c\n", c); ERROR("Dyadic connective expected here", fla+pptr) } c = fla[++pptr]; if (!_P_OK) ERROR("Subformula expected", fla+pptr) } } return(Finish(sbf, dcn, ns, cn[2])); } /**********************************************************/ int Match( start ) char *start; { int i; for (i = 1; start[i] && start[i] != ')'; i++) if (start[i] == '(') i += Match(start+i)-1; if (*start == '.') return(i); if (!start[i]) ERROR("Unmatched left parenthesis", start) return(i+1); } /***********************************************************/ int Finish( subf, conn, tot, dyads ) int subf[]; /** Offsets of main subformulas **/ char conn[]; /** Corresponding connectives **/ int tot; /** Number of subformulas **/ char dyads[]; /** Available dyadic connectives **/ { int i, m=0; char *sk; if (!tot) return(*subf); sk = dyads; for (i = 0; i < tot; i++) if (strchr(dyads,conn[i]) >= sk) { m = i; sk = strchr(dyads,conn[i]); } i = m+1; return(Loc(conn[m], _P_stak+Finish(subf, conn, m, dyads), _P_stak+Finish(subf+i, conn+i, tot-i, dyads))); } /***********************************************************/ int Loc( mn, lft, rgt ) char mn; /** Main connective of sbfml **/ WFF *lft, *rgt; /** Pointers left and right **/ { int i; for (i = 0; (_P_stak+i)->sym; i++) if ( (_P_stak+i)->sym == mn && (_P_stak+i)->lsub == lft && (_P_stak+i)->rsub == rgt ) return(i); (_P_stak+i)->sym = mn; (_P_stak+i)->lsub = lft; (_P_stak+i)->rsub = rgt; return(i); }