KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fri > patterns > interpreter > parsergenerator > lexer > ConsumerAlternatives


1 package fri.patterns.interpreter.parsergenerator.lexer;
2
3 import java.util.*;
4 import java.io.*;
5 import fri.util.Equals;
6 import fri.patterns.interpreter.parsergenerator.syntax.Rule;
7
8 /**
9     Container for alternative rules/Consumers.
10     If one of the contained consumers succeeds, the
11     alternative succeeds, else it fails.
12     
13     @author (c) 2002, Fritz Ritzberger
14 */

15
16 class ConsumerAlternatives extends Consumer
17 {
18     private List alternates = new ArrayList(3);
19     private StrategyFactoryMethod strategyFactoryMethod;
20     private Strategy strategy;
21     
22     
23     /** Create a list of alternative consumers, inserting passed consumer. */
24     ConsumerAlternatives(Consumer alternateConsumer) {
25         addAlternate(alternateConsumer);
26     }
27
28
29     /** Add another alternative consumer for same nonterminal. */
30     public void addAlternate(Consumer alternateConsumer) {
31         alternates.add(alternateConsumer);
32     }
33
34     /**
35         Returns the stored alternative consumers that have the same nonterminal.
36         This is for the Lexer to retrieve alternative consumers and call them
37         explicitely to read input. This must be done to match the longest input.
38     */

39     public List getAlternatives() {
40         return alternates;
41     }
42     
43     /** Tries to match to all alternates. Returns true when at least one succeeds. */
44     boolean matchesRepeatableRule(Rule rule) {
45         for (int i = 0; i < alternates.size(); i++) {
46             Consumer ac = (Consumer)alternates.get(i);
47             if (ac.matchesRepeatableRule(rule))
48                 return true;
49         }
50         return false;
51     }
52
53     /** Returns the common start character if all alternatives have the same, else null. */
54     public Character JavaDoc getStartCharacter() {
55         Character JavaDoc c = null;
56         
57         for (int i = 0; i < alternates.size(); i++) {
58             Consumer cc = (Consumer)alternates.get(i);
59             Character JavaDoc c1 = cc.getStartCharacter();
60             
61             if (i == 0)
62                 c = c1;
63             else
64             if (Equals.equals(c, c1) == false)
65                 return null;
66         }
67
68         return c;
69     }
70
71     /**
72         Returns 1 if start character exists, else the sum of possible start variances of all consumers
73         (silently assuming that they have different character sets).
74     */

75     public int getStartVariance() {
76         if (getStartCharacter() != null)
77             return 1;
78             
79         int v = 0;
80         for (int i = 0; i < alternates.size(); i++)
81             v += ((Consumer) alternates.get(i)).getStartVariance();
82
83         return v;
84     }
85     
86     /**
87         Returns the maximum fixed length of all alternating consumers.
88         A fixed start sequence ends at the first found character set (like "0..9").
89         <p>
90         Returns the maximum start length of all alternating consumers.
91         A consumer start length ends at the first found repeatable or nullable consumer (like "chars*").
92     */

93     protected int getSomeLength(boolean exploreStartLength, List breakIndicator) {
94         int max = 0;
95         for (int i = 0; i < alternates.size(); i++) {
96             Consumer cc = (Consumer)alternates.get(i);
97             int len = cc.getSomeLength(exploreStartLength, breakIndicator);
98             if (len > max)
99                 max = len;
100         }
101         return max;
102     }
103     
104
105     /**
106         Reads from input by delegating to a Strategy object.
107         @param input Input object where to read from.
108         @return null if no match, else scanned input as a StringBuffer.
109     */

110     protected ResultTree consumeInternal(InputText input)
111         throws IOException
112     {
113         if (strategy == null) { // sort alternatives by their start/fixed length
114
strategy = strategyFactoryMethod != null ? strategyFactoryMethod.newStrategy() : new Strategy();
115
116             for (int i = 0; i < alternates.size(); i++) {
117                 Consumer cc = (Consumer) alternates.get(i);
118                 strategy.addTokenConsumer(cc.rule.getNonterminal(), cc);
119             }
120         }
121
122         Strategy.Item item = strategy.consume(input, input.peek(), null);
123         if (item != null)
124             return item.getResultTree();
125             
126         return null;
127     }
128
129
130     /** Returns true if the passed consumer could be concurrent with one of the contained alternatives. */
131     public boolean overlaps(Consumer cc) {
132         for (int i = 0; i < alternates.size(); i++) {
133             Consumer ac = (Consumer) alternates.get(i);
134             if (ac.overlaps(cc))
135                 return true;
136         }
137         return false;
138     }
139
140
141     /** Returns the base string for toString() method. */
142     protected String JavaDoc toStringBase() {
143         StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
144         listToString(alternates, sb, " | ", false);
145         return sb.toString();
146     }
147
148
149     /** Sets the factory for Strategy objects. */
150     public void setStrategyFactoryMethod(StrategyFactoryMethod strategyFactoryMethod) {
151         this.strategyFactoryMethod = strategyFactoryMethod;
152         
153         for (int i = 0; i < alternates.size(); i++) {
154             Consumer c = (Consumer) alternates.get(i);
155             c.setStrategyFactoryMethod(strategyFactoryMethod);
156         }
157     }
158
159 }
Popular Tags