#include #include #include #include "Wff.h" #include "Parser.h" Wff forked(int, Wff, Wff); /* prototype */ Wff wff(); /* prototype */ char word[11]; int len; int ch; int sy; /*parser "state" variables*/ void Error(char *msg) /* print error message and stop */ { printf("Error: %s (word=%s)(ch=%c)\n", msg, word, ch); exit(-1); }/*Error*/ void insymbol() /* Simple Lexical Analyser Routine */ { strncpy(word, "?", 10); while( ch==' ' ) ch=getchar(); len = 0; if( ch == '\n' ) sy=eoExp; else { if( ch >= 'a' && ch <= 'z' ) /* alphanumeric */ { while( ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9' ) { if(len <= 10) { word[len] = ch; len++; word[len] = 0/*eos*/; } ch=getchar(); } if( strcmp("true", word) == 0 ) sy = trueSy; else if( strcmp("false", word) == 0 ) sy = falseSy; else if( strcmp("not", word) == 0 ) sy = notSy; else if( strcmp("and", word) == 0 ) sy = andSy; else if( strcmp("or", word) == 0 ) sy = orSy; else sy=ident; } else/*not alphanumeric*/ { word[0]=ch; word[1]=0; len=1; switch(ch) { case '&': sy=andSy; break; case '|': sy=orSy; break; case '(': sy=openSy; break; case ')': sy=closeSy; break; case '-': /* drop through */ case '=': ch = getchar(); if( ch == '>' ) { sy=implies; break; } default: Error("bad symbol"); }/*switch*/ ch=getchar(); } } }/*insymbol*/ void check( int symbol, char *errMsg ) /* check and skip specified symbol */ { if( sy == symbol ) insymbol(); else Error(errMsg); } Wff sequence(Wff NonTerminal(void), int symbols) /*L*/ /* Parse [ symbols ]* .*/ { int operator; Wff T; /*A*/ T = NonTerminal(); /*l*/ while( sy & symbols ) /* i.e. sy in symbols */ /*l*/ { operator = sy; /*i*/ insymbol(); /*s*/ T = forked(operator, T, NonTerminal()); /* left associative. o*/ } /*n*/ return T; }/*sequence*/ Wff operand() /* the parser proper starts here */ { Wff oprnd; if( sy & (ident | trueSy | falseSy) ) /* ident | true | false */ { oprnd = forked(sy, (Wff)NULL, (Wff)NULL); if( sy == ident ) strncpy(oprnd->id, word, 10); insymbol(); return oprnd; } else if( sy == notSy ) /* not operand */ { insymbol(); return forked(notSy, (Wff)NULL, operand()); /* NB unary operator */ } else if( sy == openSy ) /* ( wff ) */ { insymbol(); oprnd = wff(); check(closeSy, "missing )"); return oprnd; } else Error("bad Operand"); }/*operand*/ /* Released under the GNU General Public License Version 2, June 1991, L.Allison 19 February 2001, 18 January 2002, Computer Science & Software Engineering, Monash University, Australia 3168. */ /* conjunction ::= operand [and operand]* */ Wff conjunction() { return sequence(operand, andSy); } /* disjunction ::= conjunction [or conjunction]* */ Wff disjunction() { return sequence(conjunction, orSy); } /* wff ::= disjunction [=> disjunction]* */ Wff wff() { return sequence(disjunction, implies); } /* i.e. a wff is a sequence of one or more */ /* disjunctions separated by implies symbols */ Wff parse() { Wff w; strncpy(word, "?", 10); len=0; ch=' '; /* initialise state... */ insymbol(); /* begin! */ w = wff(); /* parse */ check(eoExp, "incomplete"); /* done? */ return w; }/*parse*/ /* Simple Wff Parser */