3838<dependency >
3939 <groupId >com.github.petitparser</groupId >
4040 <artifactId >petitparser-core</artifactId >
41- <version >2.3.1 </version >
41+ <version >2.4.0 </version >
4242</dependency >
4343```
4444
@@ -48,7 +48,7 @@ To also include the example grammars, use the following dependency:
4848<dependency >
4949 <groupId >com.github.petitparser</groupId >
5050 <artifactId >petitparser</artifactId >
51- <version >2.3.1 </version >
51+ <version >2.4.0 </version >
5252</dependency >
5353```
5454
@@ -73,7 +73,7 @@ To depend on the core library, add the following dependency:
7373<dependency >
7474 <groupId >com.github.petitparser.java-petitparser</groupId >
7575 <artifactId >petitparser-core</artifactId >
76- <version >2.3.1 </version >
76+ <version >2.4.0 </version >
7777</dependency >
7878```
7979
@@ -83,7 +83,7 @@ To also include the example grammars, use the following dependency:
8383<dependency >
8484 <groupId >com.github.petitparser</groupId >
8585 <artifactId >java-petitparser</artifactId >
86- <version >2.3.1 </version >
86+ <version >2.4.0 </version >
8787</dependency >
8888```
8989
@@ -153,7 +153,9 @@ parse result using `Success#get()`:
153153
154154``` java
155155System . out. println(id1. get()); // ['y', ['e', 'a', 'h']]
156- System . out. println(id2. get()); // ['f', ['1', '2']]
156+ System . out.
157+
158+ println(id2. get()); // ['f', ['1', '2']]
157159```
158160
159161While it seems odd to get these nested arrays with characters as a return value,
@@ -166,8 +168,12 @@ using `Failure#getMessage()`:
166168
167169``` java
168170Result id3 = id. parse(' 123' );
169- System . out. println(id3. getMessage()); // "letter expected"
170- System . out. println(id3. getPosition()); // 0
171+ System . out.
172+
173+ println(id3. getMessage()); // "letter expected"
174+ System . out.
175+
176+ println(id3. getPosition()); // 0
171177```
172178
173179Trying to retrieve the parse result by calling ` Failure#get() ` would throw the
@@ -179,7 +185,9 @@ helper method `Parser#accept(String)`:
179185
180186``` java
181187System . out. println(id. accept(" foo" )); // true
182- System . out. println(id. accept(" 123" )); // false
188+ System . out.
189+
190+ println(id. accept(" 123" )); // false
183191```
184192
185193### Different Kinds of Parsers
@@ -234,8 +242,10 @@ To conveniently find all matches in a given input string you can
234242use ` Parser#matchesSkipping(String) ` :
235243
236244``` java
237- List<Object > matches= id. matchesSkipping(" foo 123 bar4" );
238- System . out. println(matches); // ["foo", "bar4"]
245+ List<Object > matches = id. matchesSkipping(" foo 123 bar4" );
246+ System . out.
247+
248+ println(matches); // ["foo", "bar4"]
239249```
240250
241251These are the basic elements to build parsers. There are a few more well
@@ -262,15 +272,59 @@ SettableParser term = SettableParser.undefined();
262272SettableParser prod = SettableParser . undefined();
263273SettableParser prim = SettableParser . undefined();
264274
265- term. set(prod. seq(of(' +' ). trim()). seq(term). map((List<Integer > values) - > {
266- return values. get(0 ) + values. get(2 );
267- }). or(prod));
268- prod. set(prim. seq(of(' *' ). trim()). seq(prod). map((List<Integer > values) - > {
269- return values. get(0 ) * values. get(2 );
270- }). or(prim));
271- prim. set((of(' (' ). trim(). seq(term). seq(of(' )' ). trim())). map((List<Integer > values) - > {
272- return values. get(1 );
273- }). or(number));
275+ term.
276+
277+ set(prod. seq(of(' +' ).
278+
279+ trim()).
280+
281+ seq(term).
282+
283+ map((List<Integer > values) - > {
284+ return values.
285+
286+ get(0 ) + values.
287+
288+ get(2 );
289+ }).
290+
291+ or(prod));
292+ prod.
293+
294+ set(prim. seq(of(' *' ).
295+
296+ trim()).
297+
298+ seq(prod).
299+
300+ map((List<Integer > values) - > {
301+ return values.
302+
303+ get(0 ) * values.
304+
305+ get(2 );
306+ }).
307+
308+ or(prim));
309+ prim.
310+
311+ set((of(' (' ).
312+
313+ trim().
314+
315+ seq(term).
316+
317+ seq(of(' )' ).
318+
319+ trim())).
320+
321+ map((List<Integer > values) - > {
322+ return values.
323+
324+ get(1 );
325+ }).
326+
327+ or(number));
274328```
275329
276330To make sure that our parser consumes all input we wrap it with the ` end() `
@@ -283,8 +337,14 @@ Parser start = term.end();
283337That's it, now we can test our parser and evaluator:
284338
285339``` java
286- System . out. println(start. parse(" 1 + 2 * 3" ). get()); // 7
287- System . out. println(start. parse(" (1 + 2) * 3" ). get()); // 9
340+ System . out. println(start. parse(" 1 + 2 * 3" ).
341+
342+ get()); // 7
343+ System . out.
344+
345+ println(start. parse(" (1 + 2) * 3" ).
346+
347+ get()); // 9
288348```
289349
290350As an exercise we could extend the parser to also accept negative numbers and
@@ -312,11 +372,38 @@ parenthesis:
312372
313373``` java
314374builder. group()
315- .primitive(digit(). plus(). seq(of(' .' )
316- .seq(digit(). plus()). optional())
317- .flatten(). trim(). map(Double :: parseDouble))
318- .wrapper(of(' (' ). trim(), of(' )' ). trim(),
319- (List<Double > values) - > values. get(1 ));
375+ .
376+
377+ primitive(digit().
378+
379+ plus().
380+
381+ seq(of(' .' )
382+ .
383+
384+ seq(digit().
385+
386+ plus()).
387+
388+ optional())
389+ .
390+
391+ flatten().
392+
393+ trim().
394+
395+ map(Double :: parseDouble))
396+ .
397+
398+ wrapper(of(' (' ).
399+
400+ trim(),of(' )' ).
401+
402+ trim(),
403+ (
404+ List<Double > values)- > values.
405+
406+ get(1 ));
320407```
321408
322409Then come the normal arithmetic operators. Note, that the action blocks receive
@@ -326,19 +413,77 @@ input:
326413``` java
327414// negation is a prefix operator
328415builder. group()
329- .prefix(of(' -' ). trim(), (List<Double > values) - > - values. get(1 ));
416+ .
417+
418+ prefix(of(' -' ).
419+
420+ trim(), (
421+ List<Double > values)- > - values.
422+
423+ get(1 ));
330424
331425// power is right-associative
332- builder. group()
333- .right(of(' ^' ). trim(), (List<Double > values) - > Math . pow(values. get(0 ), values. get(2 )));
426+ builder.
427+
428+ group()
429+ .
430+
431+ right(of(' ^' ).
432+
433+ trim(), (
434+ List<Double > values)- > Math .
435+
436+ pow(values. get(0 ),values.
437+
438+ get(2 )));
334439
335440// multiplication and addition are left-associative
336- builder. group()
337- .left(of(' *' ). trim(), (List<Double > values) - > values. get(0 ) * values. get(2 ))
338- .left(of(' /' ). trim(), (List<Double > values) - > values. get(0 ) / values. get(2 ));
339- builder. group()
340- .left(of(' +' ). trim(), (List<Double > values) - > values. get(0 ) + values. get(2 ))
341- .left(of(' -' ). trim(), (List<Double > values) - > values. get(0 ) - values. get(2 ));
441+ builder.
442+
443+ group()
444+ .
445+
446+ left(of(' *' ).
447+
448+ trim(), (
449+ List<Double > values)- > values.
450+
451+ get(0 ) * values.
452+
453+ get(2 ))
454+ .
455+
456+ left(of(' /' ).
457+
458+ trim(), (
459+ List<Double > values)- > values.
460+
461+ get(0 ) / values.
462+
463+ get(2 ));
464+ builder.
465+
466+ group()
467+ .
468+
469+ left(of(' +' ).
470+
471+ trim(), (
472+ List<Double > values)- > values.
473+
474+ get(0 ) + values.
475+
476+ get(2 ))
477+ .
478+
479+ left(of(' -' ).
480+
481+ trim(), (
482+ List<Double > values)- > values.
483+
484+ get(0 ) - values.
485+
486+ get(2 ));
342487```
343488
344489Finally we can build the parser:
@@ -352,10 +497,18 @@ evaluates expressions like:
352497
353498``` java
354499parser. parse(" -8" ); // -8
355- parser. parse(" 1+2*3" ); // 7
356- parser. parse(" 1*2+3" ); // 5
357- parser. parse(" 8/4/2" ); // 1
358- parser. parse(" 2^2^3" ); // 256
500+ parser.
501+
502+ parse(" 1+2*3" ); // 7
503+ parser.
504+
505+ parse(" 1*2+3" ); // 5
506+ parser.
507+
508+ parse(" 8/4/2" ); // 1
509+ parser.
510+
511+ parse(" 2^2^3" ); // 256
359512```
360513
361514You can find this example as test case
0 commit comments