1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD license"] 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2010 Terence Parr 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved. 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met: 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer. 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * notice, this list of conditions and the following disclaimer in the 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * documentation and/or other materials provided with the distribution. 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * derived from this software without specific prior written permission. 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpackage org.antlr.analysis; 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.codegen.CodeGenerator; 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.grammar.v3.ANTLRParser; 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.tool.Grammar; 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.antlr.tool.GrammarAST; 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.stringtemplate.v4.ST; 35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport org.stringtemplate.v4.STGroup; 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverimport java.util.*; 38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/** A binary tree structure used to record the semantic context in which 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * an NFA configuration is valid. It's either a single predicate or 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a tree representing an operation tree such as: p1&&p2 or p1||p2. 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * For NFA o-p1->o-p2->o, create tree AND(p1,p2). 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * For NFA (1)-p1->(2) 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * | ^ 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * | | 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (3)-p2---- 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * we will have to combine p1 and p2 into DFA state as we will be 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * adding NFA configurations for state 2 with two predicates p1,p2. 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * So, set context for combined NFA config for state 2: OR(p1,p2). 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * I have scoped the AND, NOT, OR, and Predicate subclasses of 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * SemanticContext within the scope of this outer class. 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * July 7, 2006: TJP altered OR to be set of operands. the Binary tree 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * made it really hard to reduce complicated || sequences to their minimum. 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Got huge repeated || conditions. 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverpublic abstract class SemanticContext { 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Create a default value for the semantic context shared among all 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NFAConfigurations that do not have an actual semantic context. 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * This prevents lots of if!=null type checks all over; it represents 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * just an empty set of predicates. 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static final SemanticContext EMPTY_SEMANTIC_CONTEXT = new Predicate(Predicate.INVALID_PRED_VALUE); 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Given a semantic context expression tree, return a tree with all 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * nongated predicates set to true and then reduced. So p&&(q||r) would 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * return p&&r if q is nongated but p and r are gated. 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract SemanticContext getGatedPredicateContext(); 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Generate an expression that will evaluate the semantic context, 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * given a set of output templates. 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract ST genExpr(CodeGenerator generator, 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa); 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract boolean hasUserSemanticPredicate(); // user-specified sempred {}? or {}?=> 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract boolean isSyntacticPredicate(); 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Notify the indicated grammar of any syn preds used within this context */ 84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void trackUseOfSyntacticPredicates(Grammar g) { 85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static class Predicate extends SemanticContext { 88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** The AST node in tree created from the grammar holding the predicate */ 89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public GrammarAST predicateAST; 90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Is this a {...}?=> gating predicate or a normal disambiguating {..}? 92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * If any predicate in expression is gated, then expression is considered 93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * gated. 94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * The simple Predicate object's predicate AST's type is used to set 96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * gated to true if type==GATED_SEMPRED. 97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected boolean gated = false; 99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** syntactic predicates are converted to semantic predicates 101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * but synpreds are generated slightly differently. 102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected boolean synpred = false; 104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static final int INVALID_PRED_VALUE = -2; 106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static final int FALSE_PRED = 0; 107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static final int TRUE_PRED = ~0; 108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** sometimes predicates are known to be true or false; we need 110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * a way to represent this without resorting to a target language 111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * value like true or TRUE. 112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int constantValue = INVALID_PRED_VALUE; 114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Predicate(int constantValue) { 116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicateAST = new GrammarAST(); 117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.constantValue=constantValue; 118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Predicate(GrammarAST predicate) { 121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.predicateAST = predicate; 122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.gated = 123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicate.getType()==ANTLRParser.GATED_SEMPRED || 124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicate.getType()==ANTLRParser.SYN_SEMPRED ; 125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.synpred = 126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicate.getType()==ANTLRParser.SYN_SEMPRED || 127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicate.getType()==ANTLRParser.BACKTRACK_SEMPRED; 128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public Predicate(Predicate p) { 131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.predicateAST = p.predicateAST; 132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.gated = p.gated; 133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.synpred = p.synpred; 134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.constantValue = p.constantValue; 135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /** Two predicates are the same if they are literally the same 138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * text rather than same node in the grammar's AST. 139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Or, if they have the same constant value, return equal. 140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * As of July 2006 I'm not sure these are needed. 141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean equals(Object o) { 143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !(o instanceof Predicate) ) { 144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Predicate other = (Predicate)o; 148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (this.constantValue != other.constantValue){ 149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (this.constantValue != INVALID_PRED_VALUE){ 153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return predicateAST.getText().equals(other.predicateAST.getText()); 157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int hashCode() { 160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (constantValue != INVALID_PRED_VALUE){ 161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return constantValue; 162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( predicateAST ==null ) { 165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return predicateAST.getText().hashCode(); 169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST genExpr(CodeGenerator generator, 172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa) 174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ST eST = null; 176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( templates!=null ) { 177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( synpred ) { 178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = templates.getInstanceOf("evalSynPredicate"); 179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else { 181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = templates.getInstanceOf("evalPredicate"); 182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver generator.grammar.decisionsWhoseDFAsUsesSemPreds.add(dfa); 183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String predEnclosingRuleName = predicateAST.enclosingRuleName; 185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver /* 186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String decisionEnclosingRuleName = 187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver dfa.getNFADecisionStartState().getEnclosingRule(); 188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // if these rulenames are diff, then pred was hoisted out of rule 189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Currently I don't warn you about this as it could be annoying. 190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // I do the translation anyway. 191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //eST.add("pred", this.toString()); 193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( generator!=null ) { 194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("pred", 195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver generator.translateAction(predEnclosingRuleName,predicateAST)); 196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else { 199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = new ST("<pred>"); 200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("pred", this.toString()); 201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return eST; 202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( generator!=null ) { 204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver String description = 205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver generator.target.getTargetStringLiteralFromString(this.toString()); 206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("description", description); 207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return eST; 209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public SemanticContext getGatedPredicateContext() { 213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( gated ) { 214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this; 215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean hasUserSemanticPredicate() { // user-specified sempred 221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return predicateAST !=null && 222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ( predicateAST.getType()==ANTLRParser.GATED_SEMPRED || 223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicateAST.getType()==ANTLRParser.SEMPRED ); 224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isSyntacticPredicate() { 228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return predicateAST !=null && 229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ( predicateAST.getType()==ANTLRParser.SYN_SEMPRED || 230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver predicateAST.getType()==ANTLRParser.BACKTRACK_SEMPRED ); 231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void trackUseOfSyntacticPredicates(Grammar g) { 235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( synpred ) { 236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver g.synPredNamesUsedInDFA.add(predicateAST.getText()); 237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String toString() { 242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( predicateAST ==null ) { 243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "<nopred>"; 244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return predicateAST.getText(); 246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static class TruePredicate extends Predicate { 250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public TruePredicate() { 251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super(TRUE_PRED); 252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST genExpr(CodeGenerator generator, 256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa) 258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( templates!=null ) { 260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return templates.getInstanceOf("true_value"); 261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new ST("true"); 263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean hasUserSemanticPredicate() { 267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; // not user specified. 268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String toString() { 272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "true"; // not used for code gen, just DOT and print outs 273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static class FalsePredicate extends Predicate { 277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public FalsePredicate() { 278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super(FALSE_PRED); 279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST genExpr(CodeGenerator generator, 283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa) 285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( templates!=null ) { 287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return templates.getInstanceOf("false"); 288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new ST("false"); 290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean hasUserSemanticPredicate() { 294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; // not user specified. 295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String toString() { 299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "false"; // not used for code gen, just DOT and print outs 300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static abstract class CommutativePredicate extends SemanticContext { 304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected final Set<SemanticContext> operands = new HashSet<SemanticContext>(); 305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected int hashcode; 306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public CommutativePredicate(SemanticContext a, SemanticContext b) { 308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a.getClass() == this.getClass()){ 309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommutativePredicate predicate = (CommutativePredicate)a; 310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver operands.addAll(predicate.operands); 311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver operands.add(a); 313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (b.getClass() == this.getClass()){ 316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommutativePredicate predicate = (CommutativePredicate)b; 317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver operands.addAll(predicate.operands); 318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver operands.add(b); 320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hashcode = calculateHashCode(); 323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public CommutativePredicate(HashSet<SemanticContext> contexts){ 326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext context : contexts){ 327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (context.getClass() == this.getClass()){ 328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommutativePredicate predicate = (CommutativePredicate)context; 329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver operands.addAll(predicate.operands); 330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } else { 331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver operands.add(context); 332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hashcode = calculateHashCode(); 336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public SemanticContext getGatedPredicateContext() { 340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext result = null; 341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext semctx : operands) { 342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext gatedPred = semctx.getGatedPredicateContext(); 343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( gatedPred!=null ) { 344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result = combinePredicates(result, gatedPred); 345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean hasUserSemanticPredicate() { 352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext semctx : operands) { 353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( semctx.hasUserSemanticPredicate() ) { 354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isSyntacticPredicate() { 362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext semctx : operands) { 363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( semctx.isSyntacticPredicate() ) { 364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void trackUseOfSyntacticPredicates(Grammar g) { 372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext semctx : operands) { 373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver semctx.trackUseOfSyntacticPredicates(g); 374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean equals(Object obj) { 379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (this == obj) 380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (obj.getClass() == this.getClass()) { 383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver CommutativePredicate commutative = (CommutativePredicate)obj; 384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Set<SemanticContext> otherOperands = commutative.operands; 385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (operands.size() != otherOperands.size()) 386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return operands.containsAll(otherOperands); 389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (obj instanceof NOT) 392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver NOT not = (NOT)obj; 394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (not.ctx instanceof CommutativePredicate && not.ctx.getClass() != this.getClass()) { 395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Set<SemanticContext> otherOperands = ((CommutativePredicate)not.ctx).operands; 396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (operands.size() != otherOperands.size()) 397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ArrayList<SemanticContext> temp = new ArrayList<SemanticContext>(operands.size()); 400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext context : otherOperands) { 401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver temp.add(not(context)); 402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return operands.containsAll(temp); 405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int hashCode(){ 413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return hashcode; 414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String toString() { 418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver StringBuffer buf = new StringBuffer(); 419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.append("("); 420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int i = 0; 421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext semctx : operands) { 422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( i>0 ) { 423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.append(getOperandString()); 424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.append(semctx.toString()); 426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver i++; 427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver buf.append(")"); 429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return buf.toString(); 430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract String getOperandString(); 433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract SemanticContext combinePredicates(SemanticContext left, SemanticContext right); 435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public abstract int calculateHashCode(); 437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static class AND extends CommutativePredicate { 440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public AND(SemanticContext a, SemanticContext b) { 441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super(a,b); 442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public AND(HashSet<SemanticContext> contexts) { 445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super(contexts); 446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST genExpr(CodeGenerator generator, 450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa) 452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ST result = null; 454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext operand : operands) { 455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (result == null) 456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result = operand.genExpr(generator, templates, dfa); 457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ST eST = null; 459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( templates!=null ) { 460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = templates.getInstanceOf("andPredicates"); 461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else { 463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = new ST("(<left>&&<right>)"); 464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("left", result); 466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("right", operand.genExpr(generator,templates,dfa)); 467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result = eST; 468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String getOperandString() { 475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "&&"; 476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public SemanticContext combinePredicates(SemanticContext left, SemanticContext right) { 480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return SemanticContext.and(left, right); 481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int calculateHashCode() { 485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int hashcode = 0; 486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext context : operands) { 487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hashcode = hashcode ^ context.hashCode(); 488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return hashcode; 491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static class OR extends CommutativePredicate { 495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public OR(SemanticContext a, SemanticContext b) { 496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super(a,b); 497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public OR(HashSet<SemanticContext> contexts) { 500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver super(contexts); 501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST genExpr(CodeGenerator generator, 505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa) 507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ST eST = null; 509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( templates!=null ) { 510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = templates.getInstanceOf("orPredicates"); 511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else { 513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = new ST("(<first(operands)><rest(operands):{o | ||<o>}>)"); 514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext semctx : operands) { 516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("operands", semctx.genExpr(generator,templates,dfa)); 517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return eST; 519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String getOperandString() { 523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "||"; 524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public SemanticContext combinePredicates(SemanticContext left, SemanticContext right) { 528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return SemanticContext.or(left, right); 529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int calculateHashCode() { 533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver int hashcode = 0; 534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext context : operands) { 535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver hashcode = ~hashcode ^ context.hashCode(); 536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return hashcode; 539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static class NOT extends SemanticContext { 543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver protected SemanticContext ctx; 544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public NOT(SemanticContext ctx) { 545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver this.ctx = ctx; 546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public ST genExpr(CodeGenerator generator, 550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver STGroup templates, 551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver DFA dfa) 552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ST eST = null; 554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( templates!=null ) { 555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = templates.getInstanceOf("notPredicate"); 556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else { 558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST = new ST("!(<pred>)"); 559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver eST.add("pred", ctx.genExpr(generator,templates,dfa)); 561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return eST; 562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public SemanticContext getGatedPredicateContext() { 566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext p = ctx.getGatedPredicateContext(); 567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( p==null ) { 568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return null; 569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new NOT(p); 571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean hasUserSemanticPredicate() { 575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ctx.hasUserSemanticPredicate(); 576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean isSyntacticPredicate() { 580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ctx.isSyntacticPredicate(); 581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public void trackUseOfSyntacticPredicates(Grammar g) { 585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ctx.trackUseOfSyntacticPredicates(g); 586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public boolean equals(Object object) { 590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( !(object instanceof NOT) ) { 591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return this.ctx.equals(((NOT)object).ctx); 594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public int hashCode() { 598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ~ctx.hashCode(); 599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver @Override 602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public String toString() { 603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return "!("+ctx+")"; 604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static SemanticContext and(SemanticContext a, SemanticContext b) { 608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("AND: "+a+"&&"+b); 609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext[] terms = factorOr(a, b); 610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext commonTerms = terms[0]; 611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = terms[1]; 612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = terms[2]; 613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver boolean factored = commonTerms != null && commonTerms != EMPTY_SEMANTIC_CONTEXT && !(commonTerms instanceof TruePredicate); 615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (factored) { 616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return or(commonTerms, and(a, b)); 617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.Console.Out.WriteLine( "AND: " + a + "&&" + b ); 620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a instanceof FalsePredicate || b instanceof FalsePredicate) 621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new FalsePredicate(); 622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( a==EMPTY_SEMANTIC_CONTEXT || a==null ) { 624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return b; 625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( b==EMPTY_SEMANTIC_CONTEXT || b==null ) { 627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return a; 628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a instanceof TruePredicate) 631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return b; 632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (b instanceof TruePredicate) 634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return a; 635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //// Factoring takes care of this case 637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //if (a.Equals(b)) 638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // return a; 639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("## have to AND"); 641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new AND(a,b); 642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static SemanticContext or(SemanticContext a, SemanticContext b) { 645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("OR: "+a+"||"+b); 646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext[] terms = factorAnd(a, b); 647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver SemanticContext commonTerms = terms[0]; 648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = terms[1]; 649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = terms[2]; 650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver boolean factored = commonTerms != null && commonTerms != EMPTY_SEMANTIC_CONTEXT && !(commonTerms instanceof FalsePredicate); 651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (factored) { 652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return and(commonTerms, or(a, b)); 653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( a==EMPTY_SEMANTIC_CONTEXT || a==null || a instanceof FalsePredicate ) { 656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return b; 657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( b==EMPTY_SEMANTIC_CONTEXT || b==null || b instanceof FalsePredicate ) { 660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return a; 661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( a instanceof TruePredicate || b instanceof TruePredicate || commonTerms instanceof TruePredicate ) { 664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new TruePredicate(); 665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //// Factoring takes care of this case 668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //if (a.equals(b)) 669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // return a; 670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( a instanceof NOT ) { 672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver NOT n = (NOT)a; 673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check for !p||p 674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( n.ctx.equals(b) ) { 675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new TruePredicate(); 676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if ( b instanceof NOT ) { 679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver NOT n = (NOT)b; 680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // check for p||!p 681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if ( n.ctx.equals(a) ) { 682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new TruePredicate(); 683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver //System.out.println("## have to OR"); 687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver OR result = new OR(a,b); 688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (result.operands.size() == 1) 689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result.operands.iterator().next(); 690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static SemanticContext not(SemanticContext a) { 695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a instanceof NOT) { 696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ((NOT)a).ctx; 697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a instanceof TruePredicate) 700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new FalsePredicate(); 701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if (a instanceof FalsePredicate) 702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new TruePredicate(); 703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new NOT(a); 705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Factor so (a && b) == (result && a && b) 708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static SemanticContext[] factorAnd(SemanticContext a, SemanticContext b) 709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a == EMPTY_SEMANTIC_CONTEXT || a == null || a instanceof FalsePredicate) 711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { EMPTY_SEMANTIC_CONTEXT, a, b }; 712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (b == EMPTY_SEMANTIC_CONTEXT || b == null || b instanceof FalsePredicate) 713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { EMPTY_SEMANTIC_CONTEXT, a, b }; 714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (a instanceof TruePredicate || b instanceof TruePredicate) 716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { new TruePredicate(), EMPTY_SEMANTIC_CONTEXT, EMPTY_SEMANTIC_CONTEXT }; 718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver HashSet<SemanticContext> opsA = new HashSet<SemanticContext>(getAndOperands(a)); 721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver HashSet<SemanticContext> opsB = new HashSet<SemanticContext>(getAndOperands(b)); 722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver HashSet<SemanticContext> result = new HashSet<SemanticContext>(opsA); 724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.retainAll(opsB); 725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (result.size() == 0) 726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { EMPTY_SEMANTIC_CONTEXT, a, b }; 727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opsA.removeAll(result); 729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (opsA.size() == 0) 730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = new TruePredicate(); 731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if (opsA.size() == 1) 732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = opsA.iterator().next(); 733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 734324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = new AND(opsA); 735324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 736324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opsB.removeAll(result); 737324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (opsB.size() == 0) 738324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = new TruePredicate(); 739324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if (opsB.size() == 1) 740324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = opsB.iterator().next(); 741324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 742324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = new AND(opsB); 743324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 744324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (result.size() == 1) 745324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { result.iterator().next(), a, b }; 746324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 747324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { new AND(result), a, b }; 748324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 749324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 750324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Factor so (a || b) == (result || a || b) 751324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static SemanticContext[] factorOr(SemanticContext a, SemanticContext b) 752324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 753324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver HashSet<SemanticContext> opsA = new HashSet<SemanticContext>(getOrOperands(a)); 754324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver HashSet<SemanticContext> opsB = new HashSet<SemanticContext>(getOrOperands(b)); 755324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 756324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver HashSet<SemanticContext> result = new HashSet<SemanticContext>(opsA); 757324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.retainAll(opsB); 758324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (result.size() == 0) 759324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { EMPTY_SEMANTIC_CONTEXT, a, b }; 760324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 761324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opsA.removeAll(result); 762324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (opsA.size() == 0) 763324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = new FalsePredicate(); 764324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if (opsA.size() == 1) 765324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = opsA.iterator().next(); 766324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 767324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver a = new OR(opsA); 768324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 769324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver opsB.removeAll(result); 770324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (opsB.size() == 0) 771324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = new FalsePredicate(); 772324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else if (opsB.size() == 1) 773324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = opsB.iterator().next(); 774324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver else 775324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver b = new OR(opsB); 776324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 777324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (result.size() == 1) 778324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { result.iterator().next(), a, b }; 779324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 780324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return new SemanticContext[] { new OR(result), a, b }; 781324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 782324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 783324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static Collection<SemanticContext> getAndOperands(SemanticContext context) 784324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 785324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (context instanceof AND) 786324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ((AND)context).operands; 787324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 788324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (context instanceof NOT) { 789324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Collection<SemanticContext> operands = getOrOperands(((NOT)context).ctx); 790324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<SemanticContext> result = new ArrayList<SemanticContext>(operands.size()); 791324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext operand : operands) { 792324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(not(operand)); 793324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 794324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 795324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 796324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 797324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ArrayList<SemanticContext> result = new ArrayList<SemanticContext>(); 798324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(context); 799324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 800324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 801324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 802324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver public static Collection<SemanticContext> getOrOperands(SemanticContext context) 803324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver { 804324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (context instanceof OR) 805324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return ((OR)context).operands; 806324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 807324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (context instanceof NOT) { 808324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver Collection<SemanticContext> operands = getAndOperands(((NOT)context).ctx); 809324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver List<SemanticContext> result = new ArrayList<SemanticContext>(operands.size()); 810324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver for (SemanticContext operand : operands) { 811324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(not(operand)); 812324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 813324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 814324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 815324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 816324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver ArrayList<SemanticContext> result = new ArrayList<SemanticContext>(); 817324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver result.add(context); 818324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return result; 819324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 820324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 821