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
61public class ExpressionParser {
62
63 Tokenizer scanner_ = null;
64 boolean verbose_ = false;
65
71 public ExpressionTree parse(String input) {
72 scanner_ = new Tokenizer(input);
73 scanner_.next(); // use as "lookahead"
75 expect(Tokenizer.END_OF_INPUT,"<end of input>");
76 return tree;
77 }
78
80 public void setVerbose(boolean b) {
81 verbose_=b;
82 }
83
85 protected String errorNear() {
86 return "near '"+scanner_.matchedText()+
87 "'\nbefore '"+scanner_.remainder()+"'";
88 }
89
91 protected int lookahead() {
92 return scanner_.matchedTokenId();
93 }
94
96 protected void nextToken() {
97 if (scanner_.next()==Tokenizer.NO_MATCH)
98 throw new SyntaxError("unknown token: lexcial analysis failed at '"+
99 scanner_.remainder()+"'");
100 }
101
105 protected String matchedText() {
106 return scanner_.matchedText();
107 }
108
112 protected void expect(int tokenid,String text) {
113 if (lookahead()!=tokenid)
114 throw new SyntaxError("expected '"+text+"' got '"+
115 scanner_.matchedText()+"'\nbefore '"+
116 scanner_.remainder());
117 }
118
120 protected void verbose(int level,String message) {
121 if (verbose_) {
122 System.err.println(Sys.indent(level)+message+
123 " ['"+scanner_.matchedText()+"','"+
124 scanner_.remainder()+"']");
125 }
126 }
127
128 //
129 // Here is the implementation of BNF rules as methods:
130 //
131
134 protected ExpressionTree expression(int level) {
135 verbose(level,"<expression>");
136 return sum(level+1);
137 }
138
145 protected ExpressionTree sum(int level) {
146 verbose(level,"<sum>");
147
148 ExpressionTree left=product(level+1);
149
150 if (lookahead()==Tokenizer.PLUS) {
151 nextToken();
152 ExpressionTree right=sum(level+1);
153 return new ExpressionTree(new Plus(),left,right);
154 }
155 else if (lookahead()==Tokenizer.MINUS) {
156 nextToken();
157 ExpressionTree right=sum(level+1);
158 return new ExpressionTree(new Minus(),left,right);
159 }
160
161 return left;
162 }
163
170 protected ExpressionTree product(int level) {
171 verbose(level,"<product>");
172
173 ExpressionTree left=factor(level+1);
174
175 if (lookahead()==Tokenizer.TIMES) {
176 nextToken();
177 ExpressionTree right=product(level+1);
178 return new ExpressionTree(new Times(),left,right);
179 }
180 else if (lookahead()==Tokenizer.DIVIDE) {
181 nextToken();
182 ExpressionTree right=product(level+1);
183 return new ExpressionTree(new Divide(),left,right);
184 }
185
186 return left;
187 }
188
199 protected ExpressionTree factor(int level) {
200 verbose(level,"<factor>");
201
202 ExpressionTree tree=null;
203
204 if (lookahead()==Tokenizer.NUMBER) {
205 tree=new ExpressionTree
206 (new Number(Double.parseDouble(matchedText())));
207 }
208 else if (lookahead()==Tokenizer.IDENTIFIER) {
209 tree=new ExpressionTree(new Symbol(matchedText()));
210 }
211 else if (lookahead()==Tokenizer.LEFT_PAREN) {
212 nextToken();
213 tree=expression(level+1);
214 expect(Tokenizer.RIGHT_PAREN,"closing parenthesis )");
215 }
216 else if (lookahead()==Tokenizer.PLUS) { // unary plus
217 nextToken();
218 return factor(level+1); // ignore: +x == x
219 }
220 else if (lookahead()==Tokenizer.MINUS) { // unary minus
221 nextToken();
222 return new ExpressionTree(new UnaryMinus(),factor(level+1),null);
223 }
224 else
225 throw new SyntaxError(errorNear());
226
227 nextToken();
228 assert(tree!=null);
229
230 return tree;
231 }
232
233
234
235
237 public static void main(String[] args) {
238
239 String input=(args.length>0) ? args[0] : "1+2*(3+4)";
240
241 System.out.println("input = '"+input+"'");
242
244 p.setVerbose(true);
245 ExpressionTree tree=p.parse(input);
246
247 System.out.println("output = '"+tree+"'");
248
249 System.out.println(tree.postorder().toString());
250
251 System.out.println(tree.toTikZ());
252 }
253}
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 varibale.
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").
Definition: Tokenizer.java:9
static final int RIGHT_PAREN
Definition: Tokenizer.java:25
static final int LEFT_PAREN
Definition: Tokenizer.java:24
static final int MINUS
Definition: Tokenizer.java:20
static final int IDENTIFIER
Definition: Tokenizer.java:27
static final int DIVIDE
Definition: Tokenizer.java:22
static final int PLUS
Definition: Tokenizer.java:19
static final int NUMBER
Definition: Tokenizer.java:28
static final int TIMES
Definition: Tokenizer.java:21
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.