summaryrefslogtreecommitdiff
path: root/src/tests/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests/parser.cpp')
-rw-r--r--src/tests/parser.cpp576
1 files changed, 288 insertions, 288 deletions
diff --git a/src/tests/parser.cpp b/src/tests/parser.cpp
index af53bc8..6ad722f 100644
--- a/src/tests/parser.cpp
+++ b/src/tests/parser.cpp
@@ -16,185 +16,185 @@ using namespace Bu;
16 16
17enum Tok 17enum Tok
18{ 18{
19 tokNumber, 19 tokNumber,
20 tokPlus, 20 tokPlus,
21 tokMinus, 21 tokMinus,
22 tokDivide, 22 tokDivide,
23 tokMultiply, 23 tokMultiply,
24 tokOpenParen, 24 tokOpenParen,
25 tokCloseParen, 25 tokCloseParen,
26 tokCompute, 26 tokCompute,
27 tokEndOfInput=-1 27 tokEndOfInput=-1
28}; 28};
29 29
30Bu::Formatter &operator<<( Bu::Formatter &f, Tok e ) 30Bu::Formatter &operator<<( Bu::Formatter &f, Tok e )
31{ 31{
32 switch( e ) 32 switch( e )
33 { 33 {
34 case tokNumber: return f << "tokNumber"; 34 case tokNumber: return f << "tokNumber";
35 case tokPlus: return f << "tokPlus"; 35 case tokPlus: return f << "tokPlus";
36 case tokMinus: return f << "tokMinus"; 36 case tokMinus: return f << "tokMinus";
37 case tokDivide: return f << "tokDivide"; 37 case tokDivide: return f << "tokDivide";
38 case tokMultiply: return f << "tokMultiply"; 38 case tokMultiply: return f << "tokMultiply";
39 case tokOpenParen: return f << "tokOpenParen"; 39 case tokOpenParen: return f << "tokOpenParen";
40 case tokCloseParen: return f << "tokCloseParen"; 40 case tokCloseParen: return f << "tokCloseParen";
41 case tokCompute: return f << "tokCompute"; 41 case tokCompute: return f << "tokCompute";
42 case tokEndOfInput: return f << "tokEndOfInput"; 42 case tokEndOfInput: return f << "tokEndOfInput";
43 } 43 }
44 44
45 return f << "***error***"; 45 return f << "***error***";
46} 46}
47 47
48class MathLexer : public Lexer 48class MathLexer : public Lexer
49{ 49{
50public: 50public:
51 MathLexer( Bu::Stream &rSrc ) : 51 MathLexer( Bu::Stream &rSrc ) :
52 rSrc( rSrc ) 52 rSrc( rSrc )
53 { 53 {
54 } 54 }
55 55
56 virtual ~MathLexer() 56 virtual ~MathLexer()
57 { 57 {
58 } 58 }
59 59
60 enum TokenTypes 60 enum TokenTypes
61 { 61 {
62 tokStuff 62 tokStuff
63 }; 63 };
64 64
65 virtual Token *nextToken() 65 virtual Token *nextToken()
66 { 66 {
67 for(;;) 67 for(;;)
68 { 68 {
69 if( qbIn.getSize() == 0 ) 69 if( qbIn.getSize() == 0 )
70 { 70 {
71 char buf[4096]; 71 char buf[4096];
72 qbIn.write( buf, rSrc.read( buf, 4096 ) ); 72 qbIn.write( buf, rSrc.read( buf, 4096 ) );
73 73
74 if( rSrc.isEos() && qbIn.getSize() == 0 ) 74 if( rSrc.isEos() && qbIn.getSize() == 0 )
75 return new Token( tokEndOfInput ); 75 return new Token( tokEndOfInput );
76 } 76 }
77 77
78 char b; 78 char b;
79 qbIn.peek( &b, 1 ); 79 qbIn.peek( &b, 1 );
80 switch( b ) 80 switch( b )
81 { 81 {
82 case '+': 82 case '+':
83 qbIn.seek( 1 ); 83 qbIn.seek( 1 );
84 return new Token( tokPlus ); 84 return new Token( tokPlus );
85 85
86 case '-': 86 case '-':
87 qbIn.seek( 1 ); 87 qbIn.seek( 1 );
88 return new Token( tokMinus ); 88 return new Token( tokMinus );
89 89
90 case '/': 90 case '/':
91 qbIn.seek( 1 ); 91 qbIn.seek( 1 );
92 return new Token( tokDivide ); 92 return new Token( tokDivide );
93 93
94 case '*': 94 case '*':
95 qbIn.seek( 1 ); 95 qbIn.seek( 1 );
96 return new Token( tokMultiply ); 96 return new Token( tokMultiply );
97 97
98 case ' ': 98 case ' ':
99 case '\t': 99 case '\t':
100 case '\n': 100 case '\n':
101 qbIn.seek( 1 ); 101 qbIn.seek( 1 );
102 break; 102 break;
103 103
104 case '=': 104 case '=':
105 qbIn.seek( 1 ); 105 qbIn.seek( 1 );
106 return new Token( tokCompute ); 106 return new Token( tokCompute );
107 107
108 case '(': 108 case '(':
109 qbIn.seek( 1 ); 109 qbIn.seek( 1 );
110 return new Token( tokOpenParen ); 110 return new Token( tokOpenParen );
111 111
112 case ')': 112 case ')':
113 qbIn.seek( 1 ); 113 qbIn.seek( 1 );
114 return new Token( tokCloseParen ); 114 return new Token( tokCloseParen );
115 115
116 case '.': 116 case '.':
117 case '0': 117 case '0':
118 case '1': 118 case '1':
119 case '2': 119 case '2':
120 case '3': 120 case '3':
121 case '4': 121 case '4':
122 case '5': 122 case '5':
123 case '6': 123 case '6':
124 case '7': 124 case '7':
125 case '8': 125 case '8':
126 case '9': 126 case '9':
127 { 127 {
128 Bu::String sTmp; 128 Bu::String sTmp;
129 sTmp += b; 129 sTmp += b;
130 qbIn.seek( 1 ); 130 qbIn.seek( 1 );
131 for(;;) 131 for(;;)
132 { 132 {
133 qbIn.peek( &b, 1 ); 133 qbIn.peek( &b, 1 );
134 if( b != '.' && (b < '0' || b > '9') ) 134 if( b != '.' && (b < '0' || b > '9') )
135 { 135 {
136 sio << "!! Convert '" << sTmp << "' to " 136 sio << "!! Convert '" << sTmp << "' to "
137 << strtod( sTmp.getStr(), NULL ) << sio.nl; 137 << strtod( sTmp.getStr(), NULL ) << sio.nl;
138 return new Token( 138 return new Token(
139 tokNumber, strtod( sTmp.getStr(), NULL ) 139 tokNumber, strtod( sTmp.getStr(), NULL )
140 ); 140 );
141 } 141 }
142 qbIn.seek( 1 ); 142 qbIn.seek( 1 );
143 sTmp += b; 143 sTmp += b;
144 } 144 }
145 } 145 }
146 break; 146 break;
147 147
148 default: 148 default:
149 throw Bu::ExceptionBase("Unexpected character '%c'.", b ); 149 throw Bu::ExceptionBase("Unexpected character '%c'.", b );
150 } 150 }
151 } 151 }
152 } 152 }
153 153
154private: 154private:
155 Bu::Stream &rSrc; 155 Bu::Stream &rSrc;
156 QueueBuf qbIn; 156 QueueBuf qbIn;
157}; 157};
158 158
159void redAdd( Bu::Parser &p ) 159void redAdd( Bu::Parser &p )
160{ 160{
161 Lexer::Token *a = p.popToken(); 161 Lexer::Token *a = p.popToken();
162 Lexer::Token *b = p.popToken(); 162 Lexer::Token *b = p.popToken();
163 163
164 sio << "Add! " << b->vExtra.get<double>() << " + " 164 sio << "Add! " << b->vExtra.get<double>() << " + "
165 << a->vExtra.get<double>() << sio.nl; 165 << a->vExtra.get<double>() << sio.nl;
166 166
167 Lexer::Token *c = new Lexer::Token( tokNumber, 167 Lexer::Token *c = new Lexer::Token( tokNumber,
168 b->vExtra.get<double>() + a->vExtra.get<double>() 168 b->vExtra.get<double>() + a->vExtra.get<double>()
169 ); 169 );
170 p.pushToken( c ); 170 p.pushToken( c );
171 171
172 delete a; 172 delete a;
173 delete b; 173 delete b;
174} 174}
175 175
176void redSubtract( Bu::Parser &p ) 176void redSubtract( Bu::Parser &p )
177{ 177{
178 Lexer::Token *a = p.popToken(); 178 Lexer::Token *a = p.popToken();
179 Lexer::Token *b = p.popToken(); 179 Lexer::Token *b = p.popToken();
180 180
181 sio << "Subtract! " << b->vExtra.get<double>() << " - " 181 sio << "Subtract! " << b->vExtra.get<double>() << " - "
182 << a->vExtra.get<double>() << sio.nl; 182 << a->vExtra.get<double>() << sio.nl;
183 183
184 Lexer::Token *c = new Lexer::Token( tokNumber, 184 Lexer::Token *c = new Lexer::Token( tokNumber,
185 b->vExtra.get<double>() - a->vExtra.get<double>() 185 b->vExtra.get<double>() - a->vExtra.get<double>()
186 ); 186 );
187 p.pushToken( c ); 187 p.pushToken( c );
188 188
189 delete a; 189 delete a;
190 delete b; 190 delete b;
191} 191}
192 192
193void redPrint( Bu::Parser &p ) 193void redPrint( Bu::Parser &p )
194{ 194{
195 Lexer::Token *a = p.popToken(); 195 Lexer::Token *a = p.popToken();
196 sio << "Print! = " << a->vExtra.get<double>() << sio.nl; 196 sio << "Print! = " << a->vExtra.get<double>() << sio.nl;
197 delete a; 197 delete a;
198} 198}
199 199
200/* Basic grammer example: 200/* Basic grammer example:
@@ -227,143 +227,143 @@ void redPrint( Bu::Parser &p )
227 227
228int main( int argc, char *argv[] ) 228int main( int argc, char *argv[] )
229{ 229{
230 if( argc < 2 ) 230 if( argc < 2 )
231 { 231 {
232 println("Provide an input filename as the first parameter."); 232 println("Provide an input filename as the first parameter.");
233 return 0; 233 return 0;
234 } 234 }
235 File fIn( argv[1], File::Read ); 235 File fIn( argv[1], File::Read );
236 236
237 Parser p; 237 Parser p;
238 238
239 p.addNonTerminal("expr"); 239 p.addNonTerminal("expr");
240 p.addNonTerminal("expr-sub1"); 240 p.addNonTerminal("expr-sub1");
241 p.addNonTerminal("expr-sub2"); 241 p.addNonTerminal("expr-sub2");
242 { 242 {
243 Parser::NonTerminal nt; 243 Parser::NonTerminal nt;
244 nt.addProduction( 244 nt.addProduction(
245 Parser::Production( 245 Parser::Production(
246 Parser::State( 246 Parser::State(
247 Parser::State::typeTerminal, 247 Parser::State::typeTerminal,
248 tokPlus 248 tokPlus
249 ) 249 )
250 ).append( 250 ).append(
251 Parser::State( 251 Parser::State(
252 Parser::State::typeNonTerminal, 252 Parser::State::typeNonTerminal,
253 p.getNonTerminalId("expr") 253 p.getNonTerminalId("expr")
254 ) 254 )
255 ).append( 255 ).append(
256 Parser::State( 256 Parser::State(
257 Parser::State::typeReduction, 257 Parser::State::typeReduction,
258 p.addReduction("add") 258 p.addReduction("add")
259 ) 259 )
260 ) 260 )
261 ); 261 );
262 nt.addProduction( 262 nt.addProduction(
263 Parser::Production( 263 Parser::Production(
264 Parser::State( 264 Parser::State(
265 Parser::State::typeTerminal, 265 Parser::State::typeTerminal,
266 tokMinus 266 tokMinus
267 ) 267 )
268 ).append( 268 ).append(
269 Parser::State( 269 Parser::State(
270 Parser::State::typeNonTerminal, 270 Parser::State::typeNonTerminal,
271 p.getNonTerminalId("expr") 271 p.getNonTerminalId("expr")
272 ) 272 )
273 ).append( 273 ).append(
274 Parser::State( 274 Parser::State(
275 Parser::State::typeReduction, 275 Parser::State::typeReduction,
276 p.addReduction("subtract") 276 p.addReduction("subtract")
277 ) 277 )
278 ) 278 )
279 ); 279 );
280 nt.addProduction( 280 nt.addProduction(
281 Parser::Production( 281 Parser::Production(
282 ) 282 )
283 ); 283 );
284 nt.setCanSkip(); 284 nt.setCanSkip();
285 p.setNonTerminal("expr-sub2", nt ); 285 p.setNonTerminal("expr-sub2", nt );
286 } 286 }
287 { 287 {
288 Parser::NonTerminal nt; 288 Parser::NonTerminal nt;
289 nt.addProduction( 289 nt.addProduction(
290 Parser::Production( 290 Parser::Production(
291 Parser::State( 291 Parser::State(
292 Parser::State::typeTerminalPush, 292 Parser::State::typeTerminalPush,
293 tokNumber 293 tokNumber
294 ) 294 )
295 ) 295 )
296 ); 296 );
297 nt.addProduction( 297 nt.addProduction(
298 Parser::Production( 298 Parser::Production(
299 Parser::State( 299 Parser::State(
300 Parser::State::typeTerminal, 300 Parser::State::typeTerminal,
301 tokOpenParen 301 tokOpenParen
302 ) 302 )
303 ).append( 303 ).append(
304 Parser::State( 304 Parser::State(
305 Parser::State::typeNonTerminal, 305 Parser::State::typeNonTerminal,
306 p.getNonTerminalId("expr") 306 p.getNonTerminalId("expr")
307 ) 307 )
308 ).append( 308 ).append(
309 Parser::State( 309 Parser::State(
310 Parser::State::typeTerminal, 310 Parser::State::typeTerminal,
311 tokCloseParen 311 tokCloseParen
312 ) 312 )
313 ) 313 )
314 ); 314 );
315 p.setNonTerminal("expr-sub1", nt ); 315 p.setNonTerminal("expr-sub1", nt );
316 } 316 }
317 { 317 {
318 Parser::NonTerminal nt; 318 Parser::NonTerminal nt;
319 nt.addProduction( 319 nt.addProduction(
320 Parser::Production( 320 Parser::Production(
321 Parser::State( 321 Parser::State(
322 Parser::State::typeNonTerminal, 322 Parser::State::typeNonTerminal,
323 p.getNonTerminalId("expr-sub1") 323 p.getNonTerminalId("expr-sub1")
324 ) 324 )
325 ).append( 325 ).append(
326 Parser::State( 326 Parser::State(
327 Parser::State::typeNonTerminal, 327 Parser::State::typeNonTerminal,
328 p.getNonTerminalId("expr-sub2") 328 p.getNonTerminalId("expr-sub2")
329 ) 329 )
330 ) 330 )
331 ); 331 );
332 p.setNonTerminal("expr", nt ); 332 p.setNonTerminal("expr", nt );
333 } 333 }
334 { 334 {
335 Parser::NonTerminal nt; 335 Parser::NonTerminal nt;
336 nt.addProduction( 336 nt.addProduction(
337 Parser::Production( 337 Parser::Production(
338 Parser::State( 338 Parser::State(
339 Parser::State::typeNonTerminal, 339 Parser::State::typeNonTerminal,
340 p.getNonTerminalId("expr") 340 p.getNonTerminalId("expr")
341 ) 341 )
342 ).append( 342 ).append(
343 Parser::State( 343 Parser::State(
344 Parser::State::typeTerminal, 344 Parser::State::typeTerminal,
345 tokCompute 345 tokCompute
346 ) 346 )
347 ).append( 347 ).append(
348 Parser::State( 348 Parser::State(
349 Parser::State::typeReduction, 349 Parser::State::typeReduction,
350 p.addReduction("print") 350 p.addReduction("print")
351 ) 351 )
352 ) 352 )
353 ); 353 );
354 p.addNonTerminal("input", nt ); 354 p.addNonTerminal("input", nt );
355 } 355 }
356 356
357 p.setRootNonTerminal("input"); 357 p.setRootNonTerminal("input");
358 358
359 p.setReduction("add", Bu::slot( &redAdd ) ); 359 p.setReduction("add", Bu::slot( &redAdd ) );
360 p.setReduction("subtract", Bu::slot( &redSubtract ) ); 360 p.setReduction("subtract", Bu::slot( &redSubtract ) );
361 p.setReduction("print", Bu::slot( &redPrint ) ); 361 p.setReduction("print", Bu::slot( &redPrint ) );
362 362
363 p.pushLexer( new MathLexer( fIn ) ); 363 p.pushLexer( new MathLexer( fIn ) );
364 364
365 p.parse(); 365 p.parse();
366 366
367 return 0; 367 return 0;
368} 368}
369 369