/*- *----------------------------------------------------------------------- * CondF -- * Parse a conjunctive factor (nice name, wot?) * F -> T && F | T * * Results: * True, False or Err * * Side Effects: * Tokens are consumed. *----------------------------------------------------------------------- */ static Token CondF(bool doEval) { Token l, o; l = CondT(doEval); if (l != Err) { o = CondToken(doEval); if (o == And) { /* F -> T && F * * If T is False, the whole thing will be False, but we * have to parse the r.h.s. anyway (to throw it away). If * T is True, the result is the r.h.s., be it an Err or no. * */ if (l == True) l = CondF(doEval); else (void)CondF(false); } else /* F -> T. */ condPushBack = o; } return l; }
/*- *----------------------------------------------------------------------- * CondT -- * Parse a single term in the expression. This consists of a terminal * symbol or TOK_NOT and a terminal symbol (not including the binary * operators): * T -> defined(variable) | make(target) | exists(file) | symbol * T -> ! T | ( E ) * * Results: * TOK_TRUE, TOK_FALSE or TOK_ERROR. * * Side Effects: * Tokens are consumed. * *----------------------------------------------------------------------- */ static Token CondT(Boolean doEval) { Token t; t = CondToken(doEval); if (t == TOK_EOF) { /* * If we reached the end of the expression, the expression * is malformed... */ t = TOK_ERROR; } else if (t == TOK_LPAREN) { /* * T -> ( E ) */ t = CondE(doEval); if (t != TOK_ERROR) { if (CondToken(doEval) != TOK_RPAREN) { t = TOK_ERROR; } } } else if (t == TOK_NOT) { t = CondT(doEval); if (t == TOK_TRUE) { t = TOK_FALSE; } else if (t == TOK_FALSE) { t = TOK_TRUE; } } return (t); }
/*- *----------------------------------------------------------------------- * CondT -- * Parse a single term in the expression. This consists of a terminal * symbol or Not and a terminal symbol (not including the binary * operators): * T -> defined(variable) | make(target) | exists(file) | symbol * T -> ! T | ( E ) * * Results: * True, False or Err. * * Side Effects: * Tokens are consumed. *----------------------------------------------------------------------- */ static Token CondT(bool doEval) { Token t; t = CondToken(doEval); if (t == EndOfFile) /* If we reached the end of the expression, the expression * is malformed... */ t = Err; else if (t == LParen) { /* T -> ( E ). */ t = CondE(doEval); if (t != Err) if (CondToken(doEval) != RParen) t = Err; } else if (t == Not) { t = CondT(doEval); if (t == True) t = False; else if (t == False) t = True; } return t; }
/*- *----------------------------------------------------------------------- * CondF -- * Parse a conjunctive factor (nice name, wot?) * F -> T && F | T * * Results: * TOK_TRUE, TOK_FALSE or TOK_ERROR * * Side Effects: * Tokens are consumed. * *----------------------------------------------------------------------- */ static Token CondF(Boolean doEval) { Token l, o; l = CondT(doEval); if (l != TOK_ERROR) { o = CondToken(doEval); if (o == TOK_AND) { /* * F -> T && F * * If T is TOK_FALSE, the whole thing will be TOK_FALSE, but we have to * parse the r.h.s. anyway (to throw it away). * If T is TOK_TRUE, the result is the r.h.s., be it an TOK_ERROR or no. */ if (l == TOK_TRUE) { l = CondF(doEval); } else { (void)CondF(FALSE); } } else { /* * F -> T */ CondPushBack(o); } } return (l); }