AuD
Lecture 'Algorithmen und Datenstrukturen' (code examples)
ExpressionParser.java
Go to the documentation of this file.
1
2package aud.example.expr;
3
4import aud.util.Sys;
5
69public class ExpressionParser {
70
71 Tokenizer scanner_ = null;
72 boolean verbose_ = false;
73
79 public ExpressionTree parse(String input) {
80 scanner_ = new Tokenizer(input);
81 scanner_.next(); // use as "lookahead"
83 expect(Tokenizer.END_OF_INPUT,"<end of input>");
84 return tree;
85 }
86
88 public void setVerbose(boolean b) {
89 verbose_=b;
90 }
91
93 protected String errorNear() {
94 return "near '"+scanner_.matchedText()+
95 "'\nbefore '"+scanner_.remainder()+"'";
96 }
97
99 protected int lookahead() {
100 return scanner_.matchedTokenId();
101 }
102
104 protected void nextToken() {
105 if (scanner_.next()==Tokenizer.NO_MATCH)
106 throw new SyntaxError("unknown token: lexcial analysis failed at '"+
107 scanner_.remainder()+"'");
108 }
109
113 protected String matchedText() {
114 return scanner_.matchedText();
115 }
116
120 protected void expect(int tokenid,String text) {
121 if (lookahead()!=tokenid)
122 throw new SyntaxError("expected '"+text+"' got '"+
123 scanner_.matchedText()+"'\nbefore '"+
124 scanner_.remainder());
125 }
126
128 protected void verbose(int level,String message) {
129 if (verbose_) {
130 System.err.println(Sys.indent(level)+message+
131 " ['"+scanner_.matchedText()+"','"+
132 scanner_.remainder()+"']");
133 }
134 }
135
136 //
137 // Here is the implementation of BNF rules as methods:
138 //
139
142 protected ExpressionTree expression(int level) {
143 verbose(level,"<expression>");
144 return sum(level+1);
145 }
146
153 protected ExpressionTree sum(int level) {
154 verbose(level,"<sum>");
155
156 ExpressionTree left=product(level+1);
157
158 if (lookahead()==Tokenizer.PLUS) {
159 nextToken();
160 ExpressionTree right=sum(level+1);
161 return new ExpressionTree(new Plus(),left,right);
162 }
163 else if (lookahead()==Tokenizer.MINUS) {
164 nextToken();
165 ExpressionTree right=sum(level+1);
166 return new ExpressionTree(new Minus(),left,right);
167 }
168
169 return left;
170 }
171
178 protected ExpressionTree product(int level) {
179 verbose(level,"<product>");
180
181 ExpressionTree left=factor(level+1);
182
183 if (lookahead()==Tokenizer.TIMES) {
184 nextToken();
185 ExpressionTree right=product(level+1);
186 return new ExpressionTree(new Times(),left,right);
187 }
188 else if (lookahead()==Tokenizer.DIVIDE) {
189 nextToken();
190 ExpressionTree right=product(level+1);
191 return new ExpressionTree(new Divide(),left,right);
192 }
193
194 return left;
195 }
196
207 protected ExpressionTree factor(int level) {
208 verbose(level,"<factor>");
209
210 ExpressionTree tree=null;
211
212 if (lookahead()==Tokenizer.NUMBER) {
213 tree=new ExpressionTree
214 (new Number(Double.parseDouble(matchedText())));
215 }
216 else if (lookahead()==Tokenizer.IDENTIFIER) {
217 tree=new ExpressionTree(new Symbol(matchedText()));
218 }
219 else if (lookahead()==Tokenizer.LEFT_PAREN) {
220 nextToken();
221 tree=expression(level+1);
222 expect(Tokenizer.RIGHT_PAREN,"closing parenthesis )");
223 }
224 else if (lookahead()==Tokenizer.PLUS) { // unary plus
225 nextToken();
226 return factor(level+1); // ignore: +x == x
227 }
228 else if (lookahead()==Tokenizer.MINUS) { // unary minus
229 nextToken();
230 return new ExpressionTree(new UnaryMinus(),factor(level+1),null);
231 }
232 else
233 throw new SyntaxError(errorNear());
234
235 nextToken();
236 assert(tree!=null);
237
238 return tree;
239 }
240
241
242
243
245 public static void main(String[] args) {
246
247 String input=(args.length>0) ? args[0] : "1+2*(3+4)";
248
249 System.out.println("input = '"+input+"'");
250
252 p.setVerbose(true);
253 ExpressionTree tree=p.parse(input);
254
255 System.out.println("output = '"+tree+"'");
256
257 System.out.println(tree.postorder().toString());
258
259 System.out.println(tree.toTikZ());
260 }
261}
BinaryTreeTraversal< T >.Postorder postorder()
Get postorder iterator over nodes in tree .
String toTikZ()
get TikZ code for LaTeX export
binary / operator: A/B
Definition: Divide.java:4
ExpressionTree product(int level)
parse product
String errorNear()
helper: generate a simple error message
ExpressionTree parse(String input)
parse input
ExpressionTree factor(int level)
parse factor
void setVerbose(boolean b)
set verbose mode (report state to System.err)
int lookahead()
helper: "lookahead" is the usual phrasing
void expect(int tokenid, String text)
helper: check token (without calling nextToken!)
static void main(String[] args)
test and example for usage
ExpressionTree expression(int level)
parse expression
ExpressionTree sum(int level)
parse sum
void verbose(int level, String message)
helper: print out information
String matchedText()
helper: get match corresponding to lookahead
void nextToken()
helper: consume current token and advance to next token
Tree representation of arithmetic expression.
binary - operator: A-B
Definition: Minus.java:4
Node representing constant number.
Definition: Number.java:6
binary + operator: A+B
Definition: Plus.java:4
Node representing a symbolic parameter, e.g., a variable.
Definition: Symbol.java:6
signals syntax error during parsing a term
Definition: SyntaxError.java:7
binary * operator: A*B
Definition: Times.java:4
Breaks input string into pieces ("tokens").
static final int RIGHT_PAREN
unary - operator: -A ("sign")
Definition: UnaryMinus.java:4
static final int END_OF_INPUT
no more input
int next(Rule[] rules)
match remainder to table of rules @endiliteral
int matchedTokenId()
get result of last call to next()
String matchedText()
get text of last match or call to next
String remainder()
get remaining text
static final int NO_MATCH
no match (usually implies a syntax error)
System related utilities.
Definition: Sys.java:58
static String indent(int level)
get indentation string filled with spaces
Definition: Sys.java:183
utilities (not related to AuD lecture)
Definition: Colormap.java:1
AuD lecture: Data structures, algorithms, examples.
Definition: A234Tree.java:1