001: package org.ofbiz.rules.parse;
002:
003: import java.util.*;
004:
005: /**
006: * <p><b>Title:</b> Alternation
007: * <p><b>Description:</b> None
008: * <p>Copyright (c) 1999 Steven J. Metsker.
009: * <p>Copyright (c) 2001 The Open For Business Project - www.ofbiz.org
010: *
011: * <p>Permission is hereby granted, free of charge, to any person obtaining a
012: * copy of this software and associated documentation files (the "Software"),
013: * to deal in the Software without restriction, including without limitation
014: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
015: * and/or sell copies of the Software, and to permit persons to whom the
016: * Software is furnished to do so, subject to the following conditions:
017: *
018: * <p>The above copyright notice and this permission notice shall be included
019: * in all copies or substantial portions of the Software.
020: *
021: * <p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
022: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
023: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
024: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
025: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
026: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
027: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
028: *
029: * <br>
030: * <p>An <code>Alternation</code> object is a collection of
031: * parsers, any one of which can successfully match against
032: * an assembly.
033: *
034: * @author Steven J. Metsker
035: * @version 1.0
036: */
037: public class Alternation extends CollectionParser {
038:
039: /**
040: * Constructs a nameless alternation.
041: */
042: public Alternation() {
043: }
044:
045: /**
046: * Constructs an alternation with the given name.
047: *
048: * @param name a name to be known by
049: */
050: public Alternation(String name) {
051: super (name);
052: }
053:
054: /**
055: * Accept a "visitor" and a collection of previously visited
056: * parsers.
057: *
058: * @param pv the visitor to accept
059: *
060: * @param visited a collection of previously visited parsers
061: */
062: public void accept(ParserVisitor pv, List visited) {
063: pv.visitAlternation(this , visited);
064: }
065:
066: /**
067: * Given a set of assemblies, this method matches this
068: * alternation against all of them, and returns a new set
069: * of the assemblies that result from the matches.
070: *
071: * @return a List of assemblies that result from
072: * matching against a beginning set of assemblies
073: *
074: * @param in a vector of assemblies to match against
075: *
076: */
077: public List match(List in) {
078: List out = new ArrayList();
079: Enumeration e = Collections.enumeration(subparsers);
080:
081: while (e.hasMoreElements()) {
082: Parser p = (Parser) e.nextElement();
083:
084: add(out, p.matchAndAssemble(in));
085: }
086: return out;
087: }
088:
089: /**
090: * Create a random collection of elements that correspond to
091: * this alternation.
092: */
093: protected List randomExpansion(int maxDepth, int depth) {
094: if (depth >= maxDepth) {
095: return randomSettle(maxDepth, depth);
096: }
097: double n = (double) subparsers.size();
098: int i = (int) (n * Math.random());
099: Parser j = (Parser) subparsers.get(i);
100:
101: return j.randomExpansion(maxDepth, depth++);
102: }
103:
104: /**
105: * This method is similar to randomExpansion, but it will
106: * pick a terminal if one is available.
107: */
108: protected List randomSettle(int maxDepth, int depth) {
109:
110: // which alternatives are terminals?
111:
112: List terms = new ArrayList();
113: Enumeration e = Collections.enumeration(subparsers);
114:
115: while (e.hasMoreElements()) {
116: Parser j = (Parser) e.nextElement();
117:
118: if (j instanceof Terminal) {
119: terms.add(j);
120: }
121: }
122:
123: // pick one of the terminals or, if there are no
124: // terminals, pick any subparser
125:
126: List which = terms;
127:
128: if (terms.isEmpty()) {
129: which = subparsers;
130: }
131:
132: double n = (double) which.size();
133: int i = (int) (n * Math.random());
134: Parser p = (Parser) which.get(i);
135:
136: return p.randomExpansion(maxDepth, depth++);
137: }
138:
139: /**
140: * Returns the string to show between the parsers this
141: * parser is an alternation of.
142: */
143: protected String toStringSeparator() {
144: return "|";
145: }
146: }
|