def _antecedent_and(self): ''' condition_and ::= clause {('COMMA' | 'AND') clause} Assuming 'COMMA' is just another way of saying 'AND' ''' left = self.clause(parent_rule=self.antecedent) while self.lex.peek_some(['COMMA', 'AND']): self.lex.recognise_some(['COMMA', 'AND']) right = self.clause(parent_rule=self.antecedent) left = fuzzterm.TermAggregate(left, right, 'and') return left
def antecedent(self, input_string=None): ''' condition ::= clause {('AND' | 'OR') clause} I need to do enforce precedence, so this is actually: condition ::= _condition_and {'OR' _condition_and} ''' self.lex.maybe_set_input(input_string) left = self._antecedent_and() while self.lex.recognise_if_there('OR'): right = self._antecedent_and() left = fuzzterm.TermAggregate(left, right, 'or') return left
def clause(self, input_string=None, parent_rule=None): ''' clause ::= | 'NOT' condition() | '(' condition() ')' # Allow extra parentheses | atomic_clause The syntax has been loosened to permit more flexible expressions; These are the same: 'NOT v IS t', 'v IS NOT t', 'NOT(v IS t') ''' # Note that the parent (caller) might be antecedent or consequent # We pass it as a parameter so we can call it for sub-clauses. self.lex.maybe_set_input(input_string) if self.lex.recognise_if_there('NOT'): subclause = self.clause(parent_rule=parent_rule) return fuzzterm.TermAggregate(subclause, None, 'not') elif self.lex.recognise_if_there('LPAREN'): subclause = parent_rule() if parent_rule else self.clause() self.lex.recognise('RPAREN') return subclause else: in_consequent = (parent_rule == self.consequent) return self.atomic_clause(in_consequent=in_consequent)
def atomic_clause(self, input_string=None, in_consequent=False): ''' atomic_clause ::= | variable_name # Not doing this! | variable_name 'IS' {hedge} term_name The optional hedges are: any identifier or 'NOT'. ''' varname = self.lex.recognise('IDENTIFIER') hedges = [] self.lex.recognise('IS') while self.lex.peek_some(['IDENTIFIER', 'NOT']): hedges.append(self.lex.recognise_some(['IDENTIFIER', 'NOT'])) # Actually, the last one was the member function name: membfun = hedges.pop() fvar = self.get_var_defn(varname) this_clause = fvar[membfun] # Special case when the only hedge is 'not': if len(hedges) == 1 and hedges[0] == 'NOT': this_clause = fuzzterm.TermAggregate(this_clause, None, 'not') # Otherwise apply the hedge functions, if there are any: elif len(hedges) > 0: this_clause = self._add_hedges(fvar, hedges, membfun) return this_clause