KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > fri > patterns > interpreter > parsergenerator > syntax > builder > SyntaxBuilderSemantic


1 package fri.patterns.interpreter.parsergenerator.syntax.builder;
2
3 import java.util.*;
4 import fri.patterns.interpreter.parsergenerator.Semantic;
5 import fri.patterns.interpreter.parsergenerator.Token;
6 import fri.patterns.interpreter.parsergenerator.syntax.*;
7
8 /**
9     A syntax specification similar to EBNF.
10     This semantic is used to build a Parser with Lexer from a textual EBNF syntax specification.
11     <p>
12     The semantics of ".." is the description of the set between leading and trailing character.
13     The leading must be the one with the lower UNICODE value.
14     <p>
15     The semantics of "-" is intersection. When specifiying <i>chars - comment - stringdef</i> this means
16     all <i>chars</i> but not <i>comments</i> or <i>stringdef</i>, i.e. <i>stringdef</i> is not subtracted
17     from <i>comment</i> but from <i>chars</i>!
18     <p>
19     TODO: think over repeat number symbol: parser AND lexer would need this.
20             Better define this by written symbols like "a ::= b b b b;"? But what to do on hundred "b"?
21     
22     @author (c) 2002 Fritz Ritzberger
23 */

24
25 public class SyntaxBuilderSemantic implements Semantic
26 {
27     public static String JavaDoc [][] syntax = {
28         // START rule
29
{ "syntax", "syntax", "rule" }, // the grammar consists of rules
30
{ "syntax", "rule" },
31
32         { "set", "`bnf_chardef`", "\""+Token.UPTO+"\"", "`bnf_chardef`" }, // set of characters
33

34         { "intersectionstartunit", "set" }, // intersection of character sets
35
{ "intersectionstartunit", "`identifier`" },
36         { "intersectionstartunit", "`ruleref`" },
37
38         { "intersectionunit", "`bnf_chardef`" },
39         { "intersectionunit", "`stringdef`" },
40         { "intersectionunit", "intersectionstartunit" },
41
42         { "intersectionsubtracts", "intersectionsubtracts", "intersectionsubtract" },
43         { "intersectionsubtracts", "intersectionsubtract" },
44         { "intersectionsubtract", "'"+Token.BUTNOT+"'", "intersectionunit" },
45
46         { "intersection", "intersectionstartunit", "intersectionsubtracts" },
47
48         { "sequnit", "intersection" }, // unit of a sequence
49
{ "sequnit", "intersectionunit" },
50         { "sequnit", "'('", "unionseq", "')'" },
51
52         { "quantifiedsequnit", "sequnit", "`quantifier`" }, // unit can be quantified
53
{ "quantifiedsequnit", "sequnit" },
54
55         { "sequence", "sequence", "quantifiedsequnit" }, // sequence of units with significant order
56
{ "sequence", "quantifiedsequnit" },
57
58         { "sequence_opt", "sequence" }, // sequence is nullable
59
{ "sequence_opt", /*nothing*/ },
60
61         { "unionseq", "unionseq", "'|'", "sequence_opt" }, // rule alternatives
62
{ "unionseq", "sequence_opt" },
63
64         { "rule", "`identifier`", "\"::=\"", "unionseq", "';'" }, // one rule of a grammar
65

66         // specify what will be ignored. Using StandardLexerRules.lexerSyntax will include this automatically
67
//{ "ignored", "`comment`" },
68
//{ "ignored", "`spaces`" },
69
//{ "ignored", "`newlines`" },
70
};
71     
72     private List initialNonterminals;
73     
74
75     /**
76         Creates a syntax builder semantic that resolves parenthesis and quantifiers.
77     */

78     public SyntaxBuilderSemantic() {
79         this(null);
80     }
81     
82     /**
83         Creates a syntax builder semantic that resolves parenthesis and quantifiers.
84         All nonterminals read from the processed syntax will be collected into the passed List.
85     */

86     public SyntaxBuilderSemantic(List initialNonterminals) {
87         this.initialNonterminals = initialNonterminals;
88     }
89     
90
91     public Object JavaDoc doSemantic(Rule rule, List inputTokens, List ranges) {
92         String JavaDoc nt = rule.getNonterminal();
93
94         if (nt.equals("set"))
95             return inputTokens;
96
97         if (nt.equals("intersectionstartunit") || nt.equals("intersectionunit"))
98             return inputTokens.get(0);
99
100         if (nt.equals("intersectionsubtract"))
101             return inputTokens;
102
103         if (nt.equals("intersectionsubtracts"))
104             if (inputTokens.size() == 2)
105                 return appendAll((List) inputTokens.get(0), (List)inputTokens.get(1));
106             else
107                 return inputTokens.get(0);
108
109         if (nt.equals("intersection"))
110             return insertAtStart(inputTokens.get(0), (List) inputTokens.get(1));
111
112         if (nt.equals("sequnit"))
113             if (inputTokens.size() == 3)
114                 return sequnitInParenthesis(inputTokens.get(1));
115             else
116                 return inputTokens.get(0);
117
118         if (nt.equals("quantifiedsequnit"))
119             if (inputTokens.size() == 2)
120                 return quantifiedsequnit(inputTokens.get(0), inputTokens.get(1));
121             else
122                 return inputTokens.get(0);
123
124         if (nt.equals("sequence"))
125             if (inputTokens.size() == 2)
126                 return append((List) inputTokens.get(0), inputTokens.get(1));
127             else
128                 return inputTokens;
129
130         if (nt.equals("sequence_opt"))
131                 return inputTokens;
132
133         if (nt.equals("unionseq"))
134             if (inputTokens.size() == 3)
135                 return append((List) inputTokens.get(0), (List) inputTokens.get(2));
136             else
137                 return inputTokens;
138
139         if (nt.equals("rule"))
140             return rule((String JavaDoc) inputTokens.get(0), (List) inputTokens.get(2));
141
142         if (nt.equals("syntax"))
143             if (inputTokens.size() == 2)
144                 return syntax((List) inputTokens.get(0), (List) inputTokens.get(1));
145             else
146                 return inputTokens.get(0);
147                 
148         throw new IllegalArgumentException JavaDoc("Unknown rule: "+rule);
149     }
150     
151
152     private ArtificialRule sequnitInParenthesis(Object JavaDoc unionseq) {
153         return new ArtificialRule((List)unionseq, "OR");
154     }
155
156     private ArtificialRule quantifiedsequnit(Object JavaDoc sequnit, Object JavaDoc quantifier) {
157         return new ArtificialRule(sequnit, (String JavaDoc)quantifier);
158     }
159
160     private List append(List list, Object JavaDoc element) {
161         list.add(element);
162         return list;
163     }
164
165     private List appendAll(List list, List elements) {
166         for (int i = 0; i < elements.size(); i++)
167             list.add(elements.get(i));
168         return list;
169     }
170
171     private List insertAtStart(Object JavaDoc intersectionStart, List intersectionList) {
172         intersectionList.add(0, intersectionStart);
173         return intersectionList;
174     }
175     
176     private List rule(String JavaDoc identifier, List unionseq) {
177         if (initialNonterminals != null && initialNonterminals.indexOf(identifier) < 0)
178             initialNonterminals.add(identifier);
179
180         for (int i = 0; i < unionseq.size(); i++) {
181             List deep = (List) unionseq.get(i);
182             List flat = ArtificialRule.flattenLists(deep, new ArrayList());
183             flat.add(0, identifier);
184             unionseq.set(i, flat);
185         }
186         return unionseq;
187     }
188
189     private List syntax(List syntax, List rule) {
190         for (int i = 0; i < rule.size(); i++)
191             syntax.add((List) rule.get(i));
192         return syntax;
193     }
194
195 }
196
Popular Tags