All tests moved from stx:goodies/petitparser to stx:goodies/petitparser/tests
authorJan Vrany <jan.vrany@fit.cvut.cz>
Fri, 03 Oct 2014 01:36:33 +0100
changeset 375 e2b2f08d054e
parent 374 1ba87229ee7e
child 376 a2656b27cace
All tests moved from stx:goodies/petitparser to stx:goodies/petitparser/tests ..,to conform package layout standards.
Make.spec
PPAbstractParseTest.st
PPArithmeticParser.st
PPArithmeticParserTest.st
PPComposedTest.st
PPExpressionParserTest.st
PPExtensionTest.st
PPLambdaParser.st
PPLambdaParserTest.st
PPMappingTest.st
PPObjectTest.st
PPParserResource.st
PPParserTest.st
PPPredicateTest.st
PPScriptingTest.st
PPTokenTest.st
abbrev.stc
libInit.cc
stx_goodies_petitparser.st
tests/PPAbstractParseTest.st
tests/PPArithmeticParser.st
tests/PPArithmeticParserTest.st
tests/PPComposedTest.st
tests/PPExpressionParserTest.st
tests/PPExtensionTest.st
tests/PPLambdaParser.st
tests/PPLambdaParserTest.st
tests/PPMappingTest.st
tests/PPObjectTest.st
tests/PPParserResource.st
tests/PPParserTest.st
tests/PPPredicateTest.st
tests/PPScriptingTest.st
tests/PPTokenTest.st
tests/stx_goodies_petitparser_tests.st
--- a/Make.spec	Fri Oct 03 00:52:34 2014 +0100
+++ b/Make.spec	Fri Oct 03 01:36:33 2014 +0100
@@ -82,8 +82,6 @@
 	PPRepeatingParser \
 	PPSequenceParser \
 	PPTrimmingParser \
-	PPArithmeticParser \
-	PPLambdaParser \
 	PPLimitedRepeatingParser \
 	PPPossessiveRepeatingParser \
 	PPTokenParser \
@@ -127,8 +125,6 @@
     $(OUTDIR_SLASH)PPRepeatingParser.$(O) \
     $(OUTDIR_SLASH)PPSequenceParser.$(O) \
     $(OUTDIR_SLASH)PPTrimmingParser.$(O) \
-    $(OUTDIR_SLASH)PPArithmeticParser.$(O) \
-    $(OUTDIR_SLASH)PPLambdaParser.$(O) \
     $(OUTDIR_SLASH)PPLimitedRepeatingParser.$(O) \
     $(OUTDIR_SLASH)PPPossessiveRepeatingParser.$(O) \
     $(OUTDIR_SLASH)PPTokenParser.$(O) \
--- a/PPAbstractParseTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-TestCase subclass:#PPAbstractParseTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Core'
-!
-
-
-!PPAbstractParseTest class methodsFor:'accessing'!
-
-packageNamesUnderTest
-	^ #('PetitParser' 'PetitTests')
-! !
-
-!PPAbstractParseTest class methodsFor:'testing'!
-
-isAbstract
-	^ self name = #PPAbstractParseTest
-! !
-
-!PPAbstractParseTest methodsFor:'utilities'!
-
-assert: aParser fail: aCollection
-	self assert: aParser fail: aCollection end: 0
-!
-
-assert: aParser fail: aCollection end: anInteger
-	| stream result |
-	self 
-		assert: aParser isPetitParser
-		description: 'Parser invalid'.
-	stream := aCollection asPetitStream.
-	result := aParser parse: stream.
-	self 
-		assert: result isPetitFailure
-		description: 'Parser did not fail'.
-	self
-		assert: stream position = anInteger
-		description: 'Parser failed at wrong position'
-!
-
-assert: aParser parse: aCollection
-	self assert: aParser parse: aCollection to: nil end: aCollection size 
-!
-
-assert: aParser parse: aCollection end: anInteger
-	self assert: aParser parse: aCollection to: nil end: anInteger
-!
-
-assert: aParser parse: aCollection to: anObject
-	self assert: aParser parse: aCollection to: anObject end: aCollection size 
-!
-
-assert: aParser parse: aParseObject to: aTargetObject end: anInteger
-        | stream result |
-        self 
-                assert: aParser isPetitParser
-                description: 'Parser invalid'.
-        stream := aParseObject asPetitStream.
-        result := aParser parse: stream.
-        aTargetObject isNil
-                ifTrue: [ self deny: result isPetitFailure ]
-                ifFalse: [ self assert: result = aTargetObject ].
-        self 
-                assert: stream position = anInteger
-                description: 'Parser accepted at wrong position'
-
-    "Modified: / 18-12-2010 / 18:01:30 / Jan Kurs <kurs.jan@post.cz>"
-!
-
-assert: aParser parse: aParserObject toToken: from stop: to
-	| token |
-	token := PPToken on: aParserObject start: from stop: to.
-	^ self assert: aParser parse: aParserObject to: token
-!
-
-assert: aParser parse: aParserObject toToken: from stop: to end: end
-	| token |
-	token := PPToken on: aParserObject start: from stop: to.
-	^ self assert: aParser parse: aParserObject to: token end: end
-! !
-
-!PPAbstractParseTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPAbstractParseTest.st,v 1.3 2012-05-04 22:09:07 vrany Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPAbstractParseTest.st,v 1.3 2012-05-04 22:09:07 vrany Exp $'
-!
-
-version_SVN
-    ^ '§Id: PPAbstractParseTest.st 4 2010-12-18 17:02:23Z kursjan §'
-! !
--- a/PPArithmeticParser.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPCompositeParser subclass:#PPArithmeticParser
-	instanceVariableNames:'terms addition factors multiplication power primary parentheses
-		number'
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Examples'
-!
-
-
-!PPArithmeticParser methodsFor:'accessing'!
-
-start
-	^ terms end
-! !
-
-!PPArithmeticParser methodsFor:'grammar'!
-
-addition
-	^ (factors separatedBy: ($+ asParser / $- asParser) trim) 
-		foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]
-!
-
-factors
-	^ multiplication / power
-!
-
-multiplication
-	^ (power separatedBy: ($* asParser / $/ asParser) trim)
-		foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]
-!
-
-number
-	^ ($- asParser optional , #digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten trim 
-		==> [ :value | value asNumber ]
-!
-
-parentheses
-	^ $( asParser trim , terms , $) asParser trim
-		==> [ :nodes | nodes second ]
-!
-
-power
-	^ (primary separatedBy: $^ asParser trim)
-		foldRight: [ :a :op :b | a raisedTo: b ]
-!
-
-primary
-	^ number / parentheses
-!
-
-terms
-	^ addition / factors
-! !
-
-!PPArithmeticParser class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParser.st,v 1.4 2014-03-04 14:33:59 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParser.st,v 1.4 2014-03-04 14:33:59 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPArithmeticParser.st,v 1.4 2014-03-04 14:33:59 cg Exp $'
-! !
-
--- a/PPArithmeticParserTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPCompositeParserTest subclass:#PPArithmeticParserTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPArithmeticParserTest methodsFor:'accessing'!
-
-parserClass
-	^ PPArithmeticParser
-! !
-
-!PPArithmeticParserTest methodsFor:'testing'!
-
-testNum
-	self assert: '0' is: 0.
-	self assert: '0.0' is: 0.0.
-	self assert: '1' is: 1.
-	self assert: '1.2' is: 1.2.
-	self assert: '34' is: 34.
-	self assert: '56.78' is: 56.78.
-	self assert: '-9' is: -9.
-	self assert: '-9.9' is: -9.9
-! !
-
-!PPArithmeticParserTest methodsFor:'testing-expression'!
-
-testBrackets
-	self assert: '(1)' is: 1.
-	self assert: '(1 + 2)' is: 3.
-	
-	self assert: '((1))' is: 1.
-	self assert: '((1 + 2))' is: 3.
-
-	self assert: '2 * (3 + 4)' is: 14.
-	self assert: '(2 + 3) * 4' is: 20.
-	self assert: '6 / (2 + 4)' is: 1.
-	self assert: '(2 + 6) / 2' is: 4
-!
-
-testPriority
-	self assert: '2 * 3 + 4' is: 10.
-	self assert: '2 + 3 * 4' is: 14.
-	self assert: '6 / 3 + 4' is: 6.
-	self assert: '2 + 6 / 2' is: 5
-! !
-
-!PPArithmeticParserTest methodsFor:'testing-operations'!
-
-testAdd
-	self assert: '1 + 2' is: 3.
-	self assert: '2 + 1' is: 3.
-	self assert: '1 + 2.3' is: 3.3.
-	self assert: '2.3 + 1' is: 3.3.
-	self assert: '1 + -2' is: -1.
-	self assert: '-2 + 1' is: -1
-!
-
-testAddMany
-	self assert: '1' is: 1.
-	self assert: '1 + 2' is: 3.
-	self assert: '1 + 2 + 3' is: 6.
-	self assert: '1 + 2 + 3 + 4' is: 10.
-	self assert: '1 + 2 + 3 + 4 + 5' is: 15
-!
-
-testDiv
-	self assert: '12 / 3' is: 4.
-	self assert: '-16 / -4' is: 4
-!
-
-testDivMany
-	self assert: '100 / 2' is: 50.
-	self assert: '100 / 2 / 2' is: 25.
-	self assert: '100 / 2 / 2 / 5' is: 5.
-	self assert: '100 / 2 / 2 / 5 / 5' is: 1
-	
-!
-
-testMul
-	self assert: '2 * 3' is: 6.
-	self assert: '2 * -4' is: -8
-!
-
-testMulMany
-	self assert: '1 * 2' is: 2.
-	self assert: '1 * 2 * 3' is: 6.
-	self assert: '1 * 2 * 3 * 4' is: 24.
-	self assert: '1 * 2 * 3 * 4 * 5' is: 120
-!
-
-testPow
-	self assert: '2 ^ 3' is: 8.
-	self assert: '-2 ^ 3' is: -8.
-	self assert: '-2 ^ -3' is: -0.125
-!
-
-testPowMany
-	self assert: '4 ^ 3' is: 64.
-	self assert: '4 ^ 3 ^ 2' is: 262144.
-	self assert: '4 ^ 3 ^ 2 ^ 1' is: 262144.
-	self assert: '4 ^ 3 ^ 2 ^ 1 ^ 0' is: 262144
-!
-
-testSub
-	self assert: '1 - 2' is: -1.
-	self assert: '1.2 - 1.2' is: 0.
-	self assert: '1 - -2' is: 3.
-	self assert: '-1 - -2' is: 1
-!
-
-testSubMany
-	self assert: '1' is: 1.
-	self assert: '1 - 2' is: -1.
-	self assert: '1 - 2 - 3' is: -4.
-	self assert: '1 - 2 - 3 - 4' is: -8.
-	self assert: '1 - 2 - 3 - 4 - 5' is: -13
-! !
-
-!PPArithmeticParserTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParserTest.st,v 1.4 2014-03-04 14:34:09 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParserTest.st,v 1.4 2014-03-04 14:34:09 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPArithmeticParserTest.st,v 1.4 2014-03-04 14:34:09 cg Exp $'
-! !
-
--- a/PPComposedTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,416 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPComposedTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPComposedTest methodsFor:'accessing'!
-
-comment
-	^ ($" asParser , $" asParser negate star , $" asParser) flatten
-!
-
-identifier
-	^ (#letter asParser , #word asParser star) flatten
-!
-
-number
-	^ ($- asParser optional , #digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten
-! !
-
-!PPComposedTest methodsFor:'testing'!
-
-testDoubledString
-	| parser |
-	parser := ($' asParser , (($' asParser , $' asParser) / $' asParser negate) star flatten , $' asParser) 
-		==> [ :nodes | nodes second copyReplaceAll: '''''' with: '''' ].
-
-	self assert: parser parse: '''''' to: ''.
-	self assert: parser parse: '''a''' to: 'a'.
-	self assert: parser parse: '''ab''' to: 'ab'.
-	self assert: parser parse: '''a''''b''' to: 'a''b'.
-	self assert: parser parse: '''a''''''''b''' to: 'a''''b'
-!
-
-testEvenNumber
-	"Create a grammar that parses an even number of a's and b's."
-	
-	| a as b bs s |
-	a := $a asParser ==> [ :char | as := as + 1 ].
-	b := $b asParser ==> [ :char | bs := bs + 1 ].
-	s := (a / b) star >=> [ :stream :cc |
-		as := bs := 0.
-		cc value.
-		(as even and: [ bs even ])
-			ifFalse: [ PPFailure message: 'Even number of a and b expected' at: 0 ] ].
-
-	self assert: s fail: 'a' end: 1.
-	self assert: s fail: 'b' end: 1.
-	self assert: s fail: 'ab' end: 2.
-	self assert: s fail: 'ba' end: 2.
-	self assert: s fail: 'aaa' end: 3.
-	self assert: s fail: 'bbb' end: 3.
-	self assert: s fail: 'aab' end: 3.
-	self assert: s fail: 'abb' end: 3.
-	
-	self assert: s parse: ''.
-	self assert: s parse: 'aa'.
-	self assert: s parse: 'bb'.
-	self assert: s parse: 'aaaa'.
-	self assert: s parse: 'aabb'.
-	self assert: s parse: 'abab'.
-	self assert: s parse: 'baba'.
-	self assert: s parse: 'bbaa'.
-	self assert: s parse: 'bbbb'
-!
-
-testIfThenElse
-	"S ::= if C then S else S | if C then S | X"
-
-	| start if then else cond expr parser |
-	start := PPDelegateParser new.
-	if := 'if' asParser token trim.
-	then := 'then' asParser token trim.
-	else := 'else' asParser token trim.
-	cond := 'C' asParser token trim.
-	expr := 'X' asParser token trim.
-	start setParser: (if , cond , then , start , else , start) / (if , cond , then , start) / expr.
-	parser := start end.
-	self assert: parser parse: 'X'.
-	self assert: parser parse: 'if C then X'.
-	self assert: parser parse: 'if C then X else X'.
-	self assert: parser parse: 'if C then if C then X'.
-	self assert: parser parse: 'if C then if C then X else if C then X'.
-	self assert: parser parse: 'if C then if C then X else X else if C then X'.
-	self assert: parser parse: 'if C then if C then X else X else if C then X else X'.
-	self assert: parser fail: 'if C'.
-	self assert: parser fail: 'if C else X'.
-	self assert: parser fail: 'if C then if C'
-!
-
-testLeftRecursion
-	"S ::= S 'x' S / '1'"
-	
-	| parser |
-	parser := PPDelegateParser new.
-	parser setParser: ((parser , $x asParser , parser) / $1 asParser) memoized flatten.
-
-	self assert: parser parse: '1' to: '1'.
-	self assert: parser parse: '1x1' to: '1x1'.
-	self assert: parser parse: '1x1x1' to: '1x1x1'.
-	self assert: parser parse: '1x1x1x1' to: '1x1x1x1'.
-	self assert: parser parse: '1x1x1x1x1' to: '1x1x1x1x1'.
-	self assert: parser parse: '1x1x1x1x1x1' to: '1x1x1x1x1x1'
-!
-
-testListOfIntegers
-	"S ::= S , number | number"
-	
-	| number list parser |
-	number := #digit asParser plus flatten trim
-		==> [ :node | node asInteger ].
-	list := (number separatedBy: $, asParser token trim)
-		==> [ :node | node select: [ :each | each isInteger ] ].
-	parser := list end.
-
-	self assert: parser parse: '1' to: (1 to: 1) asArray.
-	self assert: parser parse: '1,2' to: (1 to: 2) asArray.
-	self assert: parser parse: '1,2,3' to: (1 to: 3) asArray.
-	self assert: parser parse: '1,2,3,4' to: (1 to: 4) asArray.
-	self assert: parser parse: '1,2,3,4,5' to: (1 to: 5) asArray.
-
-	self assert: parser parse: '1' to: (1 to: 1) asArray.
-	self assert: parser parse: '1, 2' to: (1 to: 2) asArray.
-	self assert: parser parse: '1, 2, 3' to: (1 to: 3) asArray.
-	self assert: parser parse: '1, 2, 3, 4' to: (1 to: 4) asArray.
-	self assert: parser parse: '1, 2, 3, 4, 5' to: (1 to: 5) asArray.
-
-	self assert: parser parse: '1' to: (1 to: 1) asArray.
-	self assert: parser parse: '1 ,2' to: (1 to: 2) asArray.
-	self assert: parser parse: '1 ,2 ,3' to: (1 to: 3) asArray.
-	self assert: parser parse: '1 ,2 ,3 ,4' to: (1 to: 4) asArray.
-	self assert: parser parse: '1 ,2 ,3 ,4 ,5' to: (1 to: 5) asArray.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: ','.
-	self assert: parser fail: '1,'.
-	self assert: parser fail: '1,,2'
-!
-
-testNestedComments
-	"C ::= B I* E"
-	"I ::= !!E (C | T)"
-	"B ::= /*"
-	"E ::= */"
-	"T ::= ."
-	
-	| begin end any inside parser |
-	begin := '/*' asParser.
-	end := '*/' asParser.
-	any := #any asParser.
-	
-	parser := PPDelegateParser new.
-	inside := end not , (parser / any).
-	parser setParser: begin , inside star , end.
-	
-	self assert: parser parse: '/*ab*/cd' end: 6.
-	self assert: parser parse: '/*a/*b*/c*/'.
-	self assert: parser fail: '/*a/*b*/c'
-!
-
-testPalindrome
-	"S0 ::= a S1 a | b S1 b | ...
-	 S1 ::= S0 | epsilon"
-	
-	| s0 s1 parser |
-	s0 := PPDelegateParser new.
-	s1 := PPDelegateParser new.
-	s0 setParser: ($a asParser , s1 , $a asParser)
-		/ ($b asParser , s1 , $b asParser)
-		/ ($c asParser , s1 , $c asParser).	
-	s1 setParser: s0 / nil asParser.
-	parser := s0 flatten end.
-
-	self assert: parser parse: 'aa' to: 'aa'.
-	self assert: parser parse: 'bb' to: 'bb'.
-	self assert: parser parse: 'cc' to: 'cc'.
-	
-	self assert: parser parse: 'abba' to: 'abba'.
-	self assert: parser parse: 'baab' to: 'baab'.
-
-	self assert: parser parse: 'abccba' to: 'abccba'.
-	self assert: parser parse: 'abaaba' to: 'abaaba'.
-	self assert: parser parse: 'cbaabc' to: 'cbaabc'.
-
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'ab'.
-	self assert: parser fail: 'aab'.
-	self assert: parser fail: 'abccbb'
-!
-
-testParseAaaBbb
-	"S0 ::= a S1 b
-	 S1 ::= S0 | epsilon"
-	
-	| s0 s1 parser |
-	s0 := PPDelegateParser new.
-	s1 := PPDelegateParser new.
-	s0 setParser: $a asParser , s1 , $b asParser.
-	s1 setParser: s0 / nil asParser.
-	parser := s0 flatten.
-
-	self assert: parser parse: 'ab' to: 'ab'.
-	self assert: parser parse: 'aabb' to: 'aabb'.
-	self assert: parser parse: 'aaabbb' to: 'aaabbb'.
-	self assert: parser parse: 'aaaabbbb' to: 'aaaabbbb'.
-
-	self assert: parser parse: 'abb' to: 'ab' end: 2.
-	self assert: parser parse: 'aabbb' to: 'aabb' end: 4.
-	self assert: parser parse: 'aaabbbb' to: 'aaabbb' end: 6.
-	self assert: parser parse: 'aaaabbbbb' to: 'aaaabbbb' end: 8.
-
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'aab'.
-	self assert: parser fail: 'aaabb'
-!
-
-testParseAaaaaa
-	"S ::= a a S | epsilon"
-	
-	| s0 s1 parser |
-	s0 := PPDelegateParser new.
-	s1 := $a asParser , $a asParser , s0.
-	s0 setParser: s1 / nil asParser.
-	parser := s0 flatten.
-
-	self assert: parser parse: '' to: ''.
-	self assert: parser parse: 'aa' to: 'aa'.
-	self assert: parser parse: 'aaaa' to: 'aaaa'.
-	self assert: parser parse: 'aaaaaa' to: 'aaaaaa'.
-
-	self assert: parser parse: 'a' to: '' end: 0.
-	self assert: parser parse: 'aaa' to: 'aa' end: 2.
-	self assert: parser parse: 'aaaaa' to: 'aaaa' end: 4.
-	self assert: parser parse: 'aaaaaaa' to: 'aaaaaa' end: 6
-!
-
-testParseAbAbAb
-	"S ::= (A B)+"
-	
-	| parser |
-	parser := ($a asParser , $b asParser) plus flatten.
-
-	self assert: parser parse: 'ab' to: 'ab'.
-	self assert: parser parse: 'abab' to: 'abab'.
-	self assert: parser parse: 'ababab' to: 'ababab'.
-	self assert: parser parse: 'abababab' to: 'abababab'.
-
-	self assert: parser parse: 'abb' to: 'ab' end: 2.
-	self assert: parser parse: 'ababa' to: 'abab' end: 4.
-	self assert: parser parse: 'abababb' to: 'ababab' end: 6.
-	self assert: parser parse: 'ababababa' to: 'abababab' end: 8.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'bab'
-!
-
-testParseAbabbb
-	"S ::= (A | B)+"
-
-	| parser |
-	parser := ($a asParser / $b asParser) plus flatten.
-
-	self assert: parser parse: 'a' to: 'a'.
-	self assert: parser parse: 'b' to: 'b'.
-	self assert: parser parse: 'ab' to: 'ab'.
-	self assert: parser parse: 'ba' to: 'ba'.
-	self assert: parser parse: 'aaa' to: 'aaa'.
-	self assert: parser parse: 'aab' to: 'aab'.
-	self assert: parser parse: 'aba' to: 'aba'.
-	self assert: parser parse: 'baa' to: 'baa'.
-	self assert: parser parse: 'abb' to: 'abb'.
-	self assert: parser parse: 'bab' to: 'bab'.
-	self assert: parser parse: 'bba' to: 'bba'.
-	self assert: parser parse: 'bbb' to: 'bbb'.
-
-	self assert: parser parse: 'ac' to: 'a' end: 1.
-	self assert: parser parse: 'bc' to: 'b' end: 1.
-	self assert: parser parse: 'abc' to: 'ab' end: 2.
-	self assert: parser parse: 'bac' to: 'ba' end: 2.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'c'
-!
-
-testParseAnBnCn
-	"PEGs for a non context- free language: 
-		
-		a^n , b^n , c^n
-		
-	S <- &P1 P2 
-	P1 <- AB 'c' 
-	AB <- 'a' AB 'b' / epsilon
-	P2 <- 'a'* BC end
-	BC <- 'b' BC 'c' / epsilon"
-	
-	| s p1 ab p2 bc |
-	s := PPDelegateParser new.
-	p1 := PPDelegateParser new.
-	ab := PPDelegateParser new.
-	p2 := PPDelegateParser new.
-	bc := PPDelegateParser new.
-	
-	s setParser: (p1 and , p2 end) flatten.
-	p1 setParser: ab , $c asParser.
-	ab setParser: ($a asParser , ab , $b asParser) optional.
-	p2 setParser: $a asParser star , bc.
-	bc setParser: ($b asParser , bc , $c asParser) optional.
-	
-	self assert: s parse: 'abc' to: 'abc'.
-	self assert: s parse: 'aabbcc' to: 'aabbcc'.
-	self assert: s parse: 'aaabbbccc' to: 'aaabbbccc'.
-
-	self assert: s fail: 'bc'.
-	self assert: s fail: 'ac'.
-	self assert: s fail: 'ab'.
-	self assert: s fail: 'abbcc'.
-	self assert: s fail: 'aabcc'.
-	self assert: s fail: 'aabbc'
-! !
-
-!PPComposedTest methodsFor:'testing-examples'!
-
-testComment
-	self assert: self comment parse: '""' to: '""'.
-	self assert: self comment parse: '"a"' to: '"a"'.
-	self assert: self comment parse: '"ab"' to: '"ab"'.
-	self assert: self comment parse: '"abc"' to: '"abc"'.
-
-	self assert: self comment parse: '""a' to: '""' end: 2.
-	self assert: self comment parse: '"a"a' to: '"a"' end: 3.
-	self assert: self comment parse: '"ab"a' to: '"ab"' end: 4.
-	self assert: self comment parse: '"abc"a' to: '"abc"' end: 5.
-
-	self assert: self comment fail: '"'.
-	self assert: self comment fail: '"a'.
-	self assert: self comment fail: '"aa'.
-	self assert: self comment fail: 'a"'.
-	self assert: self comment fail: 'aa"'
-!
-
-testIdentifier
-	self assert: self identifier parse: 'a' to: 'a'.
-	self assert: self identifier parse: 'a1' to: 'a1'.
-	self assert: self identifier parse: 'a12' to: 'a12'.
-	self assert: self identifier parse: 'ab' to: 'ab'.
-	self assert: self identifier parse: 'a1b' to: 'a1b'.
-
-	self assert: self identifier parse: 'a_' to: 'a' end: 1.
-	self assert: self identifier parse: 'a1-' to: 'a1' end: 2.
-	self assert: self identifier parse: 'a12+' to: 'a12' end: 3.
-	self assert: self identifier parse: 'ab^' to: 'ab' end: 2.
-	self assert: self identifier parse: 'a1b*' to: 'a1b' end: 3.
-
-	self assert: self identifier fail: ''.
-	self assert: self identifier fail: '1'.
-	self assert: self identifier fail: '1a'
-!
-
-testNumber
-	self assert: self number parse: '1' to: '1'.
-	self assert: self number parse: '12' to: '12'.
-	self assert: self number parse: '12.3' to: '12.3'.
-	self assert: self number parse: '12.34' to: '12.34'.
-
-	self assert: self number parse: '1..' to: '1' end: 1.
-	self assert: self number parse: '12-' to: '12' end: 2.
-	self assert: self number parse: '12.3.' to: '12.3' end: 4.
-	self assert: self number parse: '12.34.' to: '12.34' end: 5.
-	
-	self assert: self number parse: '-1' to: '-1'.
-	self assert: self number parse: '-12' to: '-12'.
-	self assert: self number parse: '-12.3' to: '-12.3'.
-	self assert: self number parse: '-12.34' to: '-12.34'.
-	
-	self assert: self number fail: ''.
-	self assert: self number fail: '-'.
-	self assert: self number fail: '.'.
-	self assert: self number fail: '.1'
-!
-
-testReturn
-	| number spaces return |
-	number := #digit asParser plus flatten.
-	spaces := #space asParser star.
-	return := (spaces , $^ asParser token , spaces , number)
-		==> [ :nodes | Array with: #return with: (nodes at: 4) ].
-
-	self assert: return parse: '^1' to: #(return '1').
-	self assert: return parse: '^12' to: #(return '12').
-	self assert: return parse: '^ 123' to: #(return '123').
-	self assert: return parse: '^  1234' to: #(return '1234').
-	
-	self assert: return fail: '1'.
-	self assert: return fail: '^'
-! !
-
-!PPComposedTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPComposedTest.st,v 1.5 2014-03-04 14:34:10 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPComposedTest.st,v 1.5 2014-03-04 14:34:10 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPComposedTest.st,v 1.5 2014-03-04 14:34:10 cg Exp $'
-! !
-
--- a/PPExpressionParserTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPArithmeticParserTest subclass:#PPExpressionParserTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPExpressionParserTest class methodsFor:'testing'!
-
-shouldInheritSelectors
-	^ true
-! !
-
-!PPExpressionParserTest methodsFor:'accessing'!
-
-parserInstance
-	| expression parens number |
-	expression := PPExpressionParser new.
-	parens := $( asParser trim , expression , $) asParser trim
-		==> [ :value | value second ].
-	number := (#digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten trim
-		==> [ :value | value asNumber ].
-	expression term: parens / number.
-	expression
-		group: [ :g |
-			g prefix: $- asParser trim do: [ :op :a | a negated ] ];
-		group: [ :g |
-			g postfix: '++' asParser trim do: [ :a :op | a + 1 ].
-			g postfix: '--' asParser trim do: [ :a :op | a - 1 ] ];
-		group: [ :g |
-			g right: $^ asParser trim do: [ :a :op :b | a raisedTo: b ] ];
-		group: [ :g |
-			g left: $* asParser trim do: [ :a :op :b | a * b ].
-			g left: $/ asParser trim do: [ :a :op :b | a / b ] ];
-		group: [ :g |
-			g left: $+ asParser trim do: [ :a :op :b | a + b ].
-			g left: $- asParser trim do: [ :a :op :b | a - b ] ].
-	^ expression end
-! !
-
-!PPExpressionParserTest methodsFor:'testing'!
-
-testPostfixAdd
-	self assert: '0++' is: 1.
-	self assert: '0++++' is: 2.
-	self assert: '0++++++' is: 3.
-
-	self assert: '0+++1' is: 2.
-	self assert: '0+++++1' is: 3.
-	self assert: '0+++++++1' is: 4
-!
-
-testPostfixSub
-	self assert: '1--' is: 0.
-	self assert: '2----' is: 0.
-	self assert: '3------' is: 0.
-
-	self assert: '2---1' is: 0.
-	self assert: '3-----1' is: 0.
-	self assert: '4-------1' is: 0.
-!
-
-testPrefixNegate
-	self assert: '1' is: 1.
-	self assert: '-1' is: -1.
-	self assert: '--1' is: 1.
-	self assert: '---1' is: -1
-! !
-
-!PPExpressionParserTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExpressionParserTest.st,v 1.4 2014-03-04 14:34:13 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExpressionParserTest.st,v 1.4 2014-03-04 14:34:13 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPExpressionParserTest.st,v 1.4 2014-03-04 14:34:13 cg Exp $'
-! !
-
--- a/PPExtensionTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPExtensionTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPExtensionTest methodsFor:'testing-parser'!
-
-testCharacter
-	| parser |
-	parser := $a asParser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser fail: 'b'
-!
-
-testChoice
-	| parser |
-	parser := #(1 2) asChoiceParser.
-	self assert: parser parse: #(1) to: 1.
-	self assert: parser parse: #(2) to: 2.
-	self assert: parser parse: #(1 2) to: 1 end: 1.
-	self assert: parser parse: #(2 1) to: 2 end: 1.
-	self assert: parser fail: #().
-	self assert: parser fail: #(3)
-!
-
-testClosure
-	| parser |
-	parser := [ :stream | stream upTo: $s ] asParser.
-	self assert: parser parse: '' to: ''.
-	self assert: parser parse: 'a' to: 'a'.
-	self assert: parser parse: 'aa' to: 'aa'.
-	self assert: parser parse: 's' to: ''.
-	self assert: parser parse: 'as' to: 'a'.
-	self assert: parser parse: 'aas' to: 'aa'.
-	self assert: parser parse: 'sa' to: '' end: 1.
-	self assert: parser parse: 'saa' to: '' end: 1.
-	
-	parser := [ :stream | stream upTo: $s. PPFailure message: 'stream' at: stream position ] asParser.
-	self assert: parser fail: ''.
-	self assert: parser fail: 's'.
-	self assert: parser fail: 'as'
-	
-!
-
-testEpsilon
-	| parser |
-	parser := nil asParser.
-	self assert: parser asParser = parser
-!
-
-testOrdered
-	| parser |
-	parser := #(1 2) asParser.
-	self assert: parser parse: #(1 2) to: #(1 2).
-	self assert: parser parse: #(1 2 3) to: #(1 2) end: 2.
-	self assert: parser fail: #().
-	self assert: parser fail: #(1).
-	self assert: parser fail: #(1 1).
-	self assert: parser fail: #(1 1 2)
-!
-
-testParser
-	| parser |
-	parser := $a asParser.
-	self assert: parser asParser = parser
-!
-
-testRange
-        | parser |
-        parser := ($a to: $c) asParser.
-        self assert: parser parse: 'a' to: $a.
-        self assert: parser parse: 'b' to: $b.
-        self assert: parser parse: 'c' to: $c.
-        self assert: parser fail: 'd'
-!
-
-testSequence
-	| parser |
-	parser := #(1 2) asSequenceParser.
-	self assert: parser parse: #(1 2) to: #(1 2).
-	self assert: parser parse: #(1 2 3) to: #(1 2) end: 2.
-	self assert: parser fail: #().
-	self assert: parser fail: #(1).
-	self assert: parser fail: #(1 1).
-	self assert: parser fail: #(1 1 2)
-!
-
-testString
-	| parser |
-	parser := 'ab' asParser.
-	self assert: parser parse: 'ab' to: 'ab'.
-	self assert: parser parse: 'aba' to: 'ab' end: 2.
-	self assert: parser parse: 'abb' to: 'ab' end: 2.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'ac'
-!
-
-testSymbol
-	| parser |
-	parser := #any asParser.
-	self assert: parser parse: 'a'.
-	self assert: parser fail: ''
-!
-
-testUnordered
-	| parser |
-	parser := #(1 2) asSet asParser.
-	self assert: parser parse: #(1) to: 1.
-	self assert: parser parse: #(2) to: 2.
-	self assert: parser parse: #(1 2) to: 1 end: 1.
-	self assert: parser parse: #(2 1) to: 2 end: 1.
-	self assert: parser fail: #().
-	self assert: parser fail: #(3)
-! !
-
-!PPExtensionTest methodsFor:'testing-stream'!
-
-testStream
-	| stream |
-	stream := 'abc' readStream asPetitStream.
-	self assert: (stream class = PPStream).
-	self assert: (stream printString = '·abc').
-	self assert: (stream peek) = $a.
-	self assert: (stream uncheckedPeek = $a).
-	self assert: (stream next) = $a.
-	self assert: (stream printString = 'a·bc').
-	self assert: (stream asPetitStream = stream)
-!
-
-testText
-	| stream |
-	stream := 'abc' asText asPetitStream.
-	self assert: stream class = PPStream
-! !
-
-!PPExtensionTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExtensionTest.st,v 1.4 2014-03-04 14:34:17 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExtensionTest.st,v 1.4 2014-03-04 14:34:17 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPExtensionTest.st,v 1.4 2014-03-04 14:34:17 cg Exp $'
-! !
-
--- a/PPLambdaParser.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPCompositeParser subclass:#PPLambdaParser
-	instanceVariableNames:'expression abstraction application variable'
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Examples'
-!
-
-
-!PPLambdaParser class methodsFor:'curch-booleans'!
-
-and
-	^ self parse: '\p.\q.((p q) p)'
-!
-
-false
-	^ self parse: '\x.\y.y'
-!
-
-ifthenelse
-	^ self parse: '\p.p'
-!
-
-not
-	^ self parse: '\p.\a.\b.((p b) a)'
-!
-
-or
-	^ self parse: '\p.\q.((p p) q)'
-!
-
-true
-	^ self parse: '\x.\y.x'
-! !
-
-!PPLambdaParser methodsFor:'accessing'!
-
-start
-	^ expression end
-! !
-
-!PPLambdaParser methodsFor:'productions'!
-
-abstraction
-	^ $\ asParser trim , variable , $. asParser trim , expression ==> [ :node | Array with: node second with: node fourth ]
-!
-
-application
-	^ $( asParser trim , expression , expression , $) asParser trim ==> [ :node | Array with: node second with: node third ]
-!
-
-expression
-	^ variable / abstraction / application
-!
-
-variable
-	^ (#letter asParser , #word asParser star) flatten trim
-! !
-
-!PPLambdaParser class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParser.st,v 1.4 2014-03-04 14:34:00 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParser.st,v 1.4 2014-03-04 14:34:00 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPLambdaParser.st,v 1.4 2014-03-04 14:34:00 cg Exp $'
-! !
-
--- a/PPLambdaParserTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPCompositeParserTest subclass:#PPLambdaParserTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPLambdaParserTest methodsFor:'accessing'!
-
-parserClass
-	^ PPLambdaParser
-! !
-
-!PPLambdaParserTest methodsFor:'testing'!
-
-testAbstraction
-	self assert: '\x.y' is: #('x' 'y').
-	self assert: '\x.\y.z' is: #('x' ('y' 'z'))
-!
-
-testApplication
-	self assert: '(x x)' is: #('x' 'x').
-	self assert: '(x y)' is: #('x' 'y').
-	self assert: '((x y) z)' is: #(('x' 'y') 'z').
-	self assert: '(x (y z))' is: #('x' ('y' 'z'))
-!
-
-testVariable
-	self assert: 'x' is: 'x'.
-	self assert: 'xy' is: 'xy'.
-	self assert: 'x12' is: 'x12'
-! !
-
-!PPLambdaParserTest methodsFor:'testing-curch'!
-
-testAnd
-	self assert: self parserClass and = #('p' ('q' (('p' 'q') 'p')))
-!
-
-testFalse
-	self assert: self parserClass false = #('x' ('y' 'y'))
-!
-
-testIfThenElse
-	self assert: self parserClass ifthenelse = #('p' 'p')
-!
-
-testNot
-	self assert: self parserClass not = #('p' ('a' ('b' (('p' 'b') 'a'))))
-!
-
-testOr
-	self assert: self parserClass or = #('p' ('q' (('p' 'p') 'q')))
-!
-
-testTrue
-	self assert: self parserClass true = #('x' ('y' 'x'))
-! !
-
-!PPLambdaParserTest methodsFor:'testing-utilities'!
-
-testParseOnError
-	| beenHere |
-	result := self parserClass
-		parse: '\x.y'
-		onError: [ self fail ].
-	self assert: result = #('x' 'y').
-
-	beenHere := false.
-	result := self parserClass
-		parse: '\x.'
-		onError: [ beenHere := true ].
-	self assert: beenHere.
-
-	beenHere := false.
-	result := self parserClass
-		parse: '\x.'
-		onError: [ :fail | beenHere := true. fail ].
-	self assert: beenHere.
-	self assert: (result message findString: '$(') > 0.
-	self assert: (result message findString: 'expected') > 0.
-	self assert: (result position = 0).
-
-	beenHere := false.
-	result := self parserClass
-		parse: '\x.'
-		onError: [ :msg :pos | 
-			self assert: (msg findString: '$(') > 0.
-			self assert: (msg findString: 'expected') > 0.
-			self assert: (pos = 0).
-			beenHere := true ].
-	self assert: result.
-	self assert: beenHere
-!
-
-testParseStartingAtOnError
-	| beenHere |
-	result := self parserClass
-		parse: 'x'
-		startingAt: #variable
-		onError: [ self fail ].
-	self assert: result = 'x'.
-	
-	beenHere := false.
-	result := self parserClass
-		parse: '\'
-		startingAt: #variable
-		onError: [ beenHere := true ].
-	self assert: beenHere.
-	
-	beenHere := false.
-	result := self parserClass
-		parse: '\'
-		startingAt: #variable
-		onError: [ :fail | beenHere := true. fail ].
-	self assert: beenHere.
-	self assert: result message = 'letter expected'.
-	self assert: result position = 0.
-
-	beenHere := false.
-	result := self parserClass
-		parse: '\'
-		startingAt: #variable
-		onError: [ :msg :pos | 
-			self assert: msg = 'letter expected'.
-			self assert: pos = 0.
-			beenHere := true ].
-	self assert: beenHere
-!
-
-testProductionAt
-	self assert: (parser productionAt: #foo) isNil.
-	self assert: (parser productionAt: #foo ifAbsent: [ true ]).
-	
-	self assert: (parser productionAt: #start) notNil.
-	self assert: (parser productionAt: #start ifAbsent: [ true ]) notNil.
-	
-	self assert: (parser productionAt: #variable) notNil.
-	self assert: (parser productionAt: #variable ifAbsent: [ true ]) notNil
-! !
-
-!PPLambdaParserTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParserTest.st,v 1.4 2014-03-04 14:34:18 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParserTest.st,v 1.4 2014-03-04 14:34:18 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPLambdaParserTest.st,v 1.4 2014-03-04 14:34:18 cg Exp $'
-! !
-
--- a/PPMappingTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParseTest subclass:#PPMappingTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPMappingTest methodsFor:'testing'!
-
-testFoldLeft2
-	| parser |
-	parser := #any asParser star 
-		foldLeft: [ :a :b | Array with: a with: b ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b) to: #(a b).
-	self assert: parser parse: #(a b c) to: #((a b) c).
-	self assert: parser parse: #(a b c d) to: #(((a b) c) d).
-	self assert: parser parse: #(a b c d e) to: #((((a b) c) d) e)
-!
-
-testFoldLeft3
-	| parser |
-	parser := #any asParser star 
-		foldLeft: [ :a :b :c | Array with: a with: b with: c ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b c) to: #(a b c).
-	self assert: parser parse: #(a b c d e) to: #((a b c) d e)
-!
-
-testFoldRight2
-	| parser |
-	parser := #any asParser star 
-		foldRight: [ :a :b | Array with: a with: b ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b) to: #(a b).
-	self assert: parser parse: #(a b c) to: #(a (b c)).
-	self assert: parser parse: #(a b c d) to: #(a (b (c d))).
-	self assert: parser parse: #(a b c d e) to: #(a (b (c (d e))))
-!
-
-testFoldRight3
-	| parser |
-	parser := #any asParser star 
-		foldRight: [ :a :b :c | Array with: a with: b with: c ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b c) to: #(a b c).
-	self assert: parser parse: #(a b c d e) to: #(a b (c d e))
-!
-
-testMap1
-	| parser |
-	parser := #any asParser 
-		map: [ :a | Array with: a ].
-
-	self assert: parser parse: #(a) to: #(a)
-!
-
-testMap2
-	| parser |
-	parser := (#any asParser , #any asParser) 
-		map: [ :a :b | Array with: b with: a ].
-
-	self assert: parser parse: #(a b) to: #(b a)
-!
-
-testMap3
-	| parser |
-	parser := (#any asParser , #any asParser , #any asParser)
-		map: [ :a :b :c | Array with: c with: b with: a ].
-
-	self assert: parser parse: #(a b c) to: #(c b a)
-! !
-
-!PPMappingTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPMappingTest.st,v 1.3 2012-05-04 22:03:40 vrany Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPMappingTest.st,v 1.3 2012-05-04 22:03:40 vrany Exp $'
-!
-
-version_SVN
-    ^ '§Id: PPMappingTest.st 4 2010-12-18 17:02:23Z kursjan §'
-! !
--- a/PPObjectTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPObjectTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPObjectTest methodsFor:'parsers'!
-
-integer
-	^ PPPredicateObjectParser
-		on: [ :each | each isInteger ]
-		message: 'integer expected'
-!
-
-string
-	^ PPPredicateObjectParser
-		on: [ :each | each isString ]
-		message: 'string expected'
-! !
-
-!PPObjectTest methodsFor:'testing'!
-
-testInteger
-	self assert: self integer parse: #(123) to: 123.
-	self assert: self integer fail: #('abc')
-!
-
-testString
-	self assert: self string parse: #('abc') to: 'abc'.
-	self assert: self string fail: #(123)
-! !
-
-!PPObjectTest methodsFor:'testing-fancy'!
-
-testFibonacci
-	"This parser accepts fibonacci sequences with arbitrary start pairs."
-	
-	| parser |
-	parser := ((self integer , self integer) end ==> [ :pair | pair first + pair last ])
-		/ (self integer , (self integer , self integer) and >=> [ :stream :continuation |
-			| result |
-			result := continuation value.
-			(result isPetitFailure or: [ result first + result last first ~= result last last ])
-				ifFalse: [ parser parseOn: stream ]
-				ifTrue: [ PPFailure message: 'invalid fibonacci sequence' at: stream position ] ]).
-	self assert: parser parse: #(1 1) to: 2.
-	self assert: parser parse: #(1 1 2) to: 3.
-	self assert: parser parse: #(1 1 2 3) to: 5.
-	self assert: parser parse: #(1 1 2 3 5) to: 8.
-	self assert: parser parse: #(1 1 2 3 5 8) to: 13.
-	self assert: parser parse: #(1 1 2 3 5 8 13) to: 21.
-	self assert: parser fail: #().
-	self assert: parser fail: #(1).
-	self assert: parser fail: #(1 2 3 4) end: 2
-	
-! !
-
-!PPObjectTest methodsFor:'testing-operators'!
-
-testChoice
-	| parser |
-	parser := self integer / self string.
-	self assert: parser parse: #(123) to: 123.
-	self assert: parser parse: #('abc') to: 'abc'
-!
-
-testSequence
-	| parser |
-	parser := self integer , self string.
-	self assert: parser parse: #(123 'abc') to: #(123 'abc').
-	self assert: parser fail: #(123 456).
-	self assert: parser fail: #('abc' 'def').
-	self assert: parser fail: #('abc' 123)
-	
-! !
-
-!PPObjectTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
-! !
-
--- a/PPParserResource.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-TestResource subclass:#PPParserResource
-	instanceVariableNames:'parsers'
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Core'
-!
-
-
-!PPParserResource methodsFor:'accessing'!
-
-parserAt: aParserClass
-	"Answer a cached instance of aParserClass."
-	
-	^ parsers at: aParserClass name ifAbsentPut: [ aParserClass new ]
-! !
-
-!PPParserResource methodsFor:'running'!
-
-setUp
-	super setUp.
-	parsers := Dictionary new
-! !
-
-!PPParserResource class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserResource.st,v 1.3 2012-05-04 22:09:18 vrany Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserResource.st,v 1.3 2012-05-04 22:09:18 vrany Exp $'
-!
-
-version_SVN
-    ^ '§Id: PPParserResource.st 4 2010-12-18 17:02:23Z kursjan §'
-! !
--- a/PPParserTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1372 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPParserTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPParserTest methodsFor:'testing'!
-
-testAnd
-	| parser |
-	parser := 'foo' asParser flatten , 'bar' asParser flatten and.
-	
-	self assert: parser parse: 'foobar' to: #('foo' 'bar') end: 3.
-	self assert: parser fail: 'foobaz'.
-	
-	parser := 'foo' asParser and.
-	self assert: parser and = parser
-!
-
-testBlock
-	| parser |
-	parser := [ :s | s next ] asParser.
-	
-	self assert: parser parse: 'ab' to: $a end: 1.
-	self assert: parser parse: 'b' to: $b.
-	self assert: parser parse: '' to: nil
-!
-
-testChoice
-	| parser |
-	parser := $a asParser / $b asParser.
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'b' to: $b.
-
-	self assert: parser parse: 'ab' to: $a end: 1.
-	self assert: parser parse: 'ba' to: $b end: 1.
-
-	self assert: parser fail: ''.
-	self assert: parser fail: 'c'.
-	self assert: parser fail: 'ca'
-!
-
-testDelimitedBy
-	| parser |
-	parser := $a asParser delimitedBy: $b asParser.
-	
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aba' to: #($a $b $a).
-	self assert: parser parse: 'ababa' to: #($a $b $a $b $a).
-
-	self assert: parser parse: 'ab' to: #($a $b).
-	self assert: parser parse: 'abab' to: #($a $b $a $b).
-	self assert: parser parse: 'ababab' to: #($a $b $a $b $a $b).
-	
-	self assert: parser parse: 'ac' to: #($a) end: 1.
-	self assert: parser parse: 'abc' to: #($a $b) end: 2.
-	self assert: parser parse: 'abac' to: #($a $b $a) end: 3.
-	self assert: parser parse: 'ababc' to: #($a $b $a $b) end: 4.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'c'
-!
-
-testDelimitedByWithoutSeparators
-	| parser |
-	parser := ($a asParser delimitedBy: $b asParser)
-		withoutSeparators.
-	
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aba' to: #($a $a).
-	self assert: parser parse: 'ababa' to: #($a $a $a).
-
-	self assert: parser parse: 'ab' to: #($a).
-	self assert: parser parse: 'abab' to: #($a $a).
-	self assert: parser parse: 'ababab' to: #($a $a $a).
-	
-	self assert: parser parse: 'ac' to: #($a) end: 1.
-	self assert: parser parse: 'abc' to: #($a) end: 2.
-	self assert: parser parse: 'abac' to: #($a $a) end: 3.
-	self assert: parser parse: 'ababc' to: #($a $a) end: 4.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'c'
-!
-
-testEndOfInput
-	| parser |
-	parser := PPEndOfInputParser on: $a asParser.
-	self assert: parser end = parser.
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'aa'
-!
-
-testEndOfInputAfterMatch
-	| parser |
-	parser := 'stuff' asParser end.
-	self assert: parser parse: 'stuff' to: 'stuff'.
-	self assert: parser fail: 'stufff'.
-	self assert: parser fail: 'fluff'
-!
-
-testEpsilon
-	| parser |
-	parser := nil asParser.
-	
-	self assert: parser parse: '' to: nil.
-	
-	self assert: parser parse: 'a' to: nil end: 0.
-	self assert: parser parse: 'ab' to: nil end: 0
-!
-
-testFailing
-	| parser result |
-	parser := PPFailingParser message: 'Plonk'.
-	self assert: parser message = 'Plonk'.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'aa'.
-	
-	result := parser parse: 'a'.
-	self assert: result message = 'Plonk'.
-	self assert: result printString = 'Plonk at 0'
-!
-
-testLiteralObject
-	| parser |
-	parser := PPLiteralObjectParser 
-		on: $a
-		message: 'letter "a" expected'.
-	self assert: parser literal = $a.
-	self assert: parser message = 'letter "a" expected'.
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser fail: 'b'
-	
-!
-
-testLiteralObjectCaseInsensitive
-	| parser |
-	parser := $a asParser caseInsensitive.
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'A' to: $A.
-
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'B'
-	
-!
-
-testLiteralSequence
-	| parser |
-	parser := PPLiteralSequenceParser 
-		on: 'abc'
-		message: 'sequence "abc" expected'.
-	self assert: parser size = 3.
-	self assert: parser literal = 'abc'.
-	self assert: parser message = 'sequence "abc" expected'.
-	
-	self assert: parser parse: 'abc' to: 'abc'.
-	self assert: parser fail: 'ab'.
-	self assert: parser fail: 'abd'
-!
-
-testLiteralSequenceCaseInsensitive
-	| parser |
-	parser := 'abc' asParser caseInsensitive.
-	
-	self assert: parser parse: 'abc' to: 'abc'.
-	self assert: parser parse: 'ABC' to: 'ABC'.
-	self assert: parser parse: 'abC' to: 'abC'.
-	self assert: parser parse: 'AbC' to: 'AbC'.
-	
-	self assert: parser fail: 'ab'.
-	self assert: parser fail: 'abd'
-!
-
-testMax
-	| parser |
-	parser := $a asParser max: 2.
-	self assert: parser min = 0.
-	self assert: parser max = 2.
-
-	self assert: parser parse: '' to: #().
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aa' to: #($a $a).
-	self assert: parser parse: 'aaa' to: #($a $a) end: 2.
-	self assert: parser parse: 'aaaa' to: #($a $a) end: 2.
-	
-	self assert: (parser printString endsWith: '[0, 2]')
-!
-
-testMaxGreedy
-	| parser |
-	parser := #word asParser max: 2 greedy: #digit asParser.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'abc'.
-	
-	self assert: parser parse: '1' to: #() end: 0.
-	self assert: parser parse: 'a1' to: #($a) end: 1.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser fail: 'abc1'.
-	
-	self assert: parser parse: '12' to: #($1) end: 1.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
-	self assert: parser fail: 'abc12'.
-	
-	self assert: parser parse: '123' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a123' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
-	self assert: parser fail: 'abc123'
-!
-
-testMaxLazy
-	| parser |
-	parser := #word asParser max: 2 lazy: #digit asParser.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'abc'.
-	
-	self assert: parser parse: '1' to: #() end: 0.
-	self assert: parser parse: 'a1' to: #($a) end: 1.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser fail: 'abc1'.
-	
-	self assert: parser parse: '12' to: #() end: 0.
-	self assert: parser parse: 'a12' to: #($a) end: 1.
-	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
-	self assert: parser fail: 'abc12'.
-	
-	self assert: parser parse: '123' to: #() end: 0.
-	self assert: parser parse: 'a123' to: #($a) end: 1.
-	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
-	self assert: parser fail: 'abc123'
-!
-
-testMemoized
-	| count parser twice |
-	count := 0.
-	parser := [ :s | count := count + 1. s next ] asParser memoized.
-	twice := parser and , parser.
-	
-	count := 0.
-	self assert: parser parse: 'a' to: $a.
-	self assert: count = 1.
-
-	count := 0.
-	self assert: twice parse: 'a' to: #($a $a).
-	self assert: count = 1.
-	
-	self assert: parser memoized = parser
-!
-
-testMin
-	| parser |
-	parser := $a asParser min: 2.
-	self assert: parser min = 2.
-	self assert: parser max > parser min.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser parse: 'aa' to: #($a $a).
-	self assert: parser parse: 'aaa' to: #($a $a $a).
-	self assert: parser parse: 'aaaa' to: #($a $a $a $a).
-	
-	self assert: (parser printString endsWith: '[2, *]')
-!
-
-testMinGreedy
-	| parser |
-	parser := #word asParser min: 2 greedy: #digit asParser.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'abcde'.
-	
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a1'.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
-	self assert: parser parse: 'abcde1' to: #($a $b $c $d $e) end: 5.
-	
-	self assert: parser fail: '12'.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
-	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
-	self assert: parser parse: 'abcd12' to: #($a $b $c $d $1) end: 5.
-	self assert: parser parse: 'abcde12' to: #($a $b $c $d $e $1) end: 6.
-	
-	self assert: parser parse: '123' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
-	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
-	self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5.
-	self assert: parser parse: 'abcd123' to: #($a $b $c $d $1 $2) end: 6.
-	self assert: parser parse: 'abcde123' to: #($a $b $c $d $e $1 $2) end: 7.
-	
-	self assert: parser parse: '1234' to: #($1 $2 $3) end: 3.
-	self assert: parser parse: 'a1234' to: #($a $1 $2 $3) end: 4.
-	self assert: parser parse: 'ab1234' to: #($a $b $1 $2 $3) end: 5.
-	self assert: parser parse: 'abc1234' to: #($a $b $c $1 $2 $3) end: 6.
-	self assert: parser parse: 'abcd1234' to: #($a $b $c $d $1 $2 $3) end: 7.
-	self assert: parser parse: 'abcde1234' to: #($a $b $c $d $e $1 $2 $3) end: 8
-!
-
-testMinLazy
-	| parser |
-	parser := #word asParser min: 2 lazy: #digit asParser.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'abcde'.
-	
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a1'.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
-	self assert: parser parse: 'abcde1' to: #($a $b $c $d $e) end: 5.
-	
-	self assert: parser fail: '12'.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4.
-	self assert: parser parse: 'abcde12' to: #($a $b $c $d $e) end: 5.
-	
-	self assert: parser parse: '123' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a123' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4.
-	self assert: parser parse: 'abcde123' to: #($a $b $c $d $e) end: 5.
-	
-	self assert: parser parse: '1234' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a1234' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab1234' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1234' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4.
-	self assert: parser parse: 'abcde1234' to: #($a $b $c $d $e) end: 5
-!
-
-testMinMax
-	| parser |
-	parser := $a asParser min: 2 max: 4.
-	self assert: parser min = 2.
-	self assert: parser max = 4.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser parse: 'aa' to: #($a $a).
-	self assert: parser parse: 'aaa' to: #($a $a $a).
-	self assert: parser parse: 'aaaa' to: #($a $a $a $a).
-	self assert: parser parse: 'aaaaa' to: #($a $a $a $a) end: 4.
-	self assert: parser parse: 'aaaaaa' to: #($a $a $a $a) end: 4.
-	
-	self assert: (parser printString endsWith: '[2, 4]')
-!
-
-testMinMaxGreedy
-	| parser |
-	parser := #word asParser min: 2 max: 4 greedy: #digit asParser.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'abcde'.
-	
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a1'.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde1'.
-	
-	self assert: parser fail: '12'.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
-	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
-	self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde12'.
-	
-	self assert: parser parse: '123' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
-	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
-	self assert: parser parse: 'abc123' to: #($a $b $c $1) end: 4.
-	self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde123'.
-	
-	self assert: parser parse: '1234' to: #($1 $2 $3) end: 3.
-	self assert: parser parse: 'a1234' to: #($a $1 $2 $3) end: 4.
-	self assert: parser parse: 'ab1234' to: #($a $b $1 $2) end: 4.
-	self assert: parser parse: 'abc1234' to: #($a $b $c $1) end: 4.
-	self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde1234'
-!
-
-testMinMaxLazy
-	| parser |
-	parser := #word asParser min: 2 max: 4 lazy: #digit asParser.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'abcde'.
-	
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a1'.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde1'.
-	
-	self assert: parser fail: '12'.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde12'.
-	
-	self assert: parser parse: '123' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a123' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde123'.
-	
-	self assert: parser parse: '1234' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a1234' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab1234' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1234' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4.
-	self assert: parser fail: 'abcde1234'
-!
-
-testNegate
-	| parser |
-	parser := 'foo' asParser negate.
-	
-	self assert: parser parse: 'f' to: $f end: 1.
-	self assert: parser parse: 'fo' to: $f end: 1.
-	self assert: parser parse: 'fob' to: $f end: 1.
-	self assert: parser parse: 'ffoo' to: $f end: 1.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'foo'
-!
-
-testNot
-	| parser |
-	parser := 'foo' asParser flatten , 'bar' asParser flatten not.
-	
-	self assert: parser parse: 'foobaz' to: #('foo' nil) end: 3.
-	self assert: parser fail: 'foobar'
-!
-
-testOptional
-	| parser |
-	parser := $a asParser optional.
-	
-	self assert: parser parse: '' to: nil.
-	self assert: parser parse: 'a' to: $a.
-	
-	self assert: parser parse: 'aa' to: $a end: 1.
-	self assert: parser parse: 'ab' to: $a end: 1.
-	self assert: parser parse: 'b' to: nil end: 0.
-	self assert: parser parse: 'bb' to: nil end: 0.
-	self assert: parser parse: 'ba' to: nil end: 0
-!
-
-testPluggable
-	| block parser |
-	block := [ :stream | stream position ].
-	parser := block asParser.
-	self assert: parser block = block
-!
-
-testPlus
-	| parser |
-	parser := $a asParser plus.
-	
-	self assert: parser min = 1.
-	self assert: parser max > parser min.
-	
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aa' to: #($a $a).
-	self assert: parser parse: 'aaa' to: #($a $a $a).
-	
-	self assert: parser parse: 'ab' to: #($a) end: 1.
-	self assert: parser parse: 'aab' to: #($a $a) end: 2.
-	self assert: parser parse: 'aaab' to: #($a $a $a) end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'ba'
-!
-
-testPlusGreedy
-	| limit parser |
-	limit := #digit asParser.
-	parser := #word asParser plusGreedy: limit.
-	
-	self assert: parser min = 1.
-	self assert: parser max > parser min.	
-	self assert: parser limit = limit.
-	self assert: parser children size = 2.
-	self assert: parser children last = limit.
-
-	self assert: parser fail: ''.
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'ab'.
-
-	self assert: parser parse: 'a1' to: #($a) end: 1.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
-	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
-	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
-	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
-	self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5.
-!
-
-testPlusLazy
-	| limit parser |
-	limit := #digit asParser.
-	parser := #word asParser plusLazy: limit.
-	
-	self assert: parser min = 1.
-	self assert: parser max > parser min.	
-	self assert: parser limit = limit.
-	self assert: parser children size = 2.
-	self assert: parser children last = limit.
-
-	self assert: parser fail: ''.
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'ab'.
-
-	self assert: parser parse: 'a1' to: #($a) end: 1.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'a12' to: #($a) end: 1.
-	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
-	self assert: parser parse: 'a123' to: #($a) end: 1.
-	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3
-!
-
-testSeparatedBy
-	| parser |
-	parser := $a asParser separatedBy: $b asParser.
-	
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aba' to: #($a $b $a).
-	self assert: parser parse: 'ababa' to: #($a $b $a $b $a).
-	
-	self assert: parser parse: 'ab' to: #($a) end: 1.
-	self assert: parser parse: 'abab' to: #($a $b $a) end: 3.
-	self assert: parser parse: 'ac' to: #($a) end: 1.
-	self assert: parser parse: 'abac' to: #($a $b $a) end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'c'
-!
-
-testSeparatedByWithoutSeparators
-	| parser |
-	parser := ($a asParser separatedBy: $b asParser)
-		withoutSeparators.
-	
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aba' to: #($a $a).
-	self assert: parser parse: 'ababa' to: #($a $a $a).
-	
-	self assert: parser parse: 'ab' to: #($a) end: 1.
-	self assert: parser parse: 'abab' to: #($a $a) end: 3.
-	self assert: parser parse: 'ac' to: #($a) end: 1.
-	self assert: parser parse: 'abac' to: #($a $a) end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'c'
-!
-
-testSequence
-	| parser |
-	parser := $a asParser , $b asParser.
-	
-	self assert: parser parse: 'ab' to: #($a $b).
-	
-	self assert: parser parse: 'aba' to: #($a $b) end: 2.
-	self assert: parser parse: 'abb' to: #($a $b) end: 2.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'aa'.
-	self assert: parser fail: 'ba'.
-	self assert: parser fail: 'bab'
-!
-
-testStar
-	| parser |
-	parser := $a asParser star.
-	
-	self assert: parser min = 0.
-	self assert: parser max > parser min.
-	
-	self assert: parser parse: '' to: #().
-	self assert: parser parse: 'a' to: #($a).
-	self assert: parser parse: 'aa' to: #($a $a).
-	self assert: parser parse: 'aaa' to: #($a $a $a).
-	
-	self assert: parser parse: 'b' to: #() end: 0.
-	self assert: parser parse: 'ab' to: #($a) end: 1.
-	self assert: parser parse: 'aab' to: #($a $a) end: 2.
-	self assert: parser parse: 'aaab' to: #($a $a $a) end: 3
-!
-
-testStarGreedy
-	| limit parser |
-	limit := #digit asParser.
-	parser := #word asParser starGreedy: limit.
-	
-	self assert: parser min = 0.
-	self assert: parser max > parser min.
-	self assert: parser limit = limit.
-	self assert: parser children size = 2.
-	self assert: parser children last = limit.
-
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'ab'.
-
-	self assert: parser parse: '1' to: #() end: 0.
-	self assert: parser parse: 'a1' to: #($a) end: 1.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: '12' to: #($1) end: 1.
-	self assert: parser parse: 'a12' to: #($a $1) end: 2.
-	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
-	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
-	self assert: parser parse: '123' to: #($1 $2) end: 2.
-	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
-	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
-	self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5
-!
-
-testStarLazy
-	| limit parser |
-	limit := #digit asParser.
-	parser := #word asParser starLazy: limit.
-	
-	self assert: parser min = 0.
-	self assert: parser max > parser min.
-	self assert: parser limit = limit.
-	self assert: parser children size = 2.
-	self assert: parser children last = limit.
-
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: 'ab'.
-
-	self assert: parser parse: '1' to: #() end: 0.
-	self assert: parser parse: 'a1' to: #($a) end: 1.
-	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
-	self assert: parser parse: '12' to: #() end: 0.
-	self assert: parser parse: 'a12' to: #($a) end: 1.
-	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
-	self assert: parser parse: '123' to: #() end: 0.
-	self assert: parser parse: 'a123' to: #($a) end: 1.
-	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
-	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3
-!
-
-testTimes
-	| parser |
-	parser := $a asParser times: 2.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser parse: 'aa' to: #($a $a).
-	self assert: parser parse: 'aaa' to: #($a $a) end: 2
-!
-
-testUnresolved
-	| parser |
-	parser := PPUnresolvedParser new.
-	
-	self assert: parser isUnresolved.
-	self should: [ parser parse: '' ] raise: Error.
-	self should: [ parser parse: 'a' ] raise: Error.
-	self should: [ parser parse: 'ab' ] raise: Error.
-	
-	parser := nil asParser.
-	self deny: parser isUnresolved
-!
-
-testWrapped
-	| parser |
-	parser := $a asParser wrapped.
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser fail: 'b'.
-	
-	parser := (($a asParser , $b asParser ) wrapped , $c asParser).
-	self assert: parser parse: 'abc' to: #(#($a $b) $c)
-!
-
-testXor
-	| parser |
-	parser := ($a asParser / $b asParser)
-			|  ($b asParser / $c asParser).
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'c' to: $c.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'd'.
-	
-	" truly symmetric "
-	parser := ($b asParser / $c asParser)
-			|  ($a asParser / $b asParser).
-	
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'c' to: $c.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: 'd'
-! !
-
-!PPParserTest methodsFor:'testing-accessing'!
-
-testNamed
-	| parser |
-	parser := PPSequenceParser new.
-	self assert: parser name isNil.
-	
-	parser := PPChoiceParser named: 'choice'.
-	self assert: parser name = 'choice'.
-	
-	parser := $* asParser name: 'star'.
-	self assert: parser name = 'star'
-!
-
-testPrint
-	| parser |
-	parser := PPParser new.
-	self assert: (parser printString findString: 'PPParser') > 0.
-	
-	parser := PPParser named: 'choice'.
-	self assert: (parser printString findString: 'PPParser(choice') > 0.
-	
-	parser := PPLiteralObjectParser on: $a.
-	self assert: (parser printString findString: '$a') > 0.
-	
-	parser := PPFailingParser message: 'error'.
-	self assert: (parser printString findString: 'error') > 0.
-	
-	parser := PPPredicateObjectParser on: [ :c | true ] message: 'error'.
-	self assert: (parser printString findString: 'error') > 0
-! !
-
-!PPParserTest methodsFor:'testing-fixtures'!
-
-testSideEffectChoice
-	"Adding another element to a choice should create a copy, otherwise we get unwanted side-effects."
-
-	| p1 p2 p3 |
-	p1 := $a asParser.
-	p2 := p1 / $b asParser.
-	p3 := p1 / $c asParser.
-	
-	self assert: p1 parse: 'a'.
-	self assert: p1 fail: 'b'.
-	self assert: p1 fail: 'c'.
-	
-	self assert: p2 parse: 'a'.
-	self assert: p2 parse: 'b'.
-	self assert: p2 fail: 'c'.
-	
-	self assert: p3 parse: 'a'.
-	self assert: p3 fail: 'b'.
-	self assert: p3 parse: 'c'
-!
-
-testSideEffectListCopy
-	| old new |
-	old := $a asParser , $b asParser.
-	new := old copy.
-	
-	self deny: old == new.
-	self deny: old children == new children.
-	self assert: old children first == new children first.
-	self assert: old children last == new children last
-!
-
-testSideEffectSequence
-	"Adding another element to a sequence should create a copy, otherwise we get unwanted side-effects."
-
-	| p1 p2 p3 |
-	p1 := $a asParser.
-	p2 := p1 , $b asParser.
-	p3 := p1 , $c asParser.
-	
-	self assert: p1 parse: 'a'.	
-	self assert: p1 parse: 'ab' end: 1.
-	self assert: p1 parse: 'ac' end: 1.
-	
-	self assert: p2 fail: 'a'.	
-	self assert: p2 parse: 'ab'.
-	self assert: p2 fail: 'ac'.
-
-	self assert: p3 fail: 'a'.	
-	self assert: p3 fail: 'ab'.
-	self assert: p3 parse: 'ac'
-! !
-
-!PPParserTest methodsFor:'testing-mapping'!
-
-testAction
-	| block parser |
-	block := [ :char | char asUppercase ].
-	parser := #any asParser ==> block.
-	self assert: parser block = block.
-
-	self assert: parser parse: 'a' to: $A.
-	self assert: parser parse: 'b' to: $B
-!
-
-testAnswer
-	| parser |
-	parser := $a asParser answer: $b.
-	
-	self assert: parser parse: 'a' to: $b.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'
-!
-
-testFlatten
-	| parser |
-	parser := $a asParser flatten.
-	
-	self assert: parser parse: 'a' to: 'a'.
-	self assert: parser parse: #($a) to: #($a).
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'
-!
-
-testFoldLeft2
-	| parser |
-	parser := #any asParser star 
-		foldLeft: [ :a :b | Array with: a with: b ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b) to: #(a b).
-	self assert: parser parse: #(a b c) to: #((a b) c).
-	self assert: parser parse: #(a b c d) to: #(((a b) c) d).
-	self assert: parser parse: #(a b c d e) to: #((((a b) c) d) e)
-!
-
-testFoldLeft3
-	| parser |
-	parser := #any asParser star 
-		foldLeft: [ :a :b :c | Array with: a with: b with: c ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b c) to: #(a b c).
-	self assert: parser parse: #(a b c d e) to: #((a b c) d e)
-!
-
-testFoldRight2
-	| parser |
-	parser := #any asParser star 
-		foldRight: [ :a :b | Array with: a with: b ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b) to: #(a b).
-	self assert: parser parse: #(a b c) to: #(a (b c)).
-	self assert: parser parse: #(a b c d) to: #(a (b (c d))).
-	self assert: parser parse: #(a b c d e) to: #(a (b (c (d e))))
-!
-
-testFoldRight3
-	| parser |
-	parser := #any asParser star 
-		foldRight: [ :a :b :c | Array with: a with: b with: c ].
-
-	self assert: parser parse: #(a) to: #a.
-	self assert: parser parse: #(a b c) to: #(a b c).
-	self assert: parser parse: #(a b c d e) to: #(a b (c d e))
-!
-
-testMap1
-	| parser |
-	parser := #any asParser 
-		map: [ :a | Array with: a ].
-
-	self assert: parser parse: #(a) to: #(a)
-!
-
-testMap2
-	| parser |
-	parser := (#any asParser , #any asParser) 
-		map: [ :a :b | Array with: b with: a ].
-
-	self assert: parser parse: #(a b) to: #(b a)
-!
-
-testMap3
-	| parser |
-	parser := (#any asParser , #any asParser , #any asParser)
-		map: [ :a :b :c | Array with: c with: b with: a ].
-
-	self assert: parser parse: #(a b c) to: #(c b a)
-!
-
-testMapFail1
-	self
-		should: [ #any asParser map: [  ] ]
-		raise: Error.
-	self
-		should: [ #any asParser map: [ :a :b | ] ]
-		raise: Error
-!
-
-testMapFail2
-	self
-		should: [ (#any asParser , #any asParser) map: [ :a | ] ]
-		raise: Error.
-	self
-		should: [ (#any asParser , #any asParser) map: [ :a :b :c | ] ]
-		raise: Error
-!
-
-testPermutation
-	| parser |
-	parser := #any asParser , #any asParser , #any asParser.
-
-	self assert: (parser permutation: #()) parse: '123' to: #().
-	self assert: (parser permutation: #(1)) parse: '123' to: #($1).
-	self assert: (parser permutation: #(1 3)) parse: '123' to: #($1 $3).
-	self assert: (parser permutation: #(3 1)) parse: '123' to: #($3 $1).
-	self assert: (parser permutation: #(2 2)) parse: '123' to: #($2 $2).
-	self assert: (parser permutation: #(3 2 1)) parse: '123' to: #($3 $2 $1).
-	
-	self should: [ parser permutation: #(0) ] raise: Error.
-	self should: [ parser permutation: #(4) ] raise: Error.
-	self should: [ parser permutation: #($2) ] raise: Error
-!
-
-testToken
-	| parser |
-	parser := $a asParser token.
-	self assert: parser tokenClass = PPToken.
-	self assert: parser parse: 'a' toToken: 1 stop: 1.	
-	self assert: parser fail: 'b'.
-	self assert: parser fail: ''.
-	
-	parser := $a asParser token: PPToken.
-	self assert: parser tokenClass = PPToken.
-	self assert: parser parse: 'a' toToken: 1 stop: 1.	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'
-!
-
-testTrim
-	| parser |
-	parser := $a asParser token trim.
-	
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: 'a ' toToken: 1 stop: 1.
-	self assert: parser parse: 'a	' toToken: 1 stop: 1.
-	self assert: parser parse: 'a  ' toToken: 1 stop: 1.
-	self assert: parser parse: 'a 
-	 ' toToken: 1 stop: 1.
-		
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: ' a' toToken: 2 stop: 2.
-	self assert: parser parse: '	a' toToken: 2 stop: 2.
-	self assert: parser parse: '    a' toToken: 5 stop: 5.
-	self assert: parser parse: '   
-a' toToken: 5 stop: 5.
-	
-	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
-	self assert: parser parse: 'a	a' toToken: 1 stop: 1 end: 2.
-	self assert: parser parse: 'a  a' toToken: 1 stop: 1 end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'
-!
-
-testTrimBlanks
-	| parser |
-	parser := $a asParser token trimBlanks.
-	
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: 'a ' toToken: 1 stop: 1.
-	self assert: parser parse: 'a	' toToken: 1 stop: 1.
-	self assert: parser parse: 'a  ' toToken: 1 stop: 1.
-	
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: ' a' toToken: 2 stop: 2.
-	self assert: parser parse: '	a' toToken: 2 stop: 2.
-	self assert: parser parse: '    a' toToken: 5 stop: 5.
-	
-	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
-	self assert: parser parse: 'a	a' toToken: 1 stop: 1 end: 2.
-	self assert: parser parse: 'a  a' toToken: 1 stop: 1 end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: '
-'.
-	self assert: parser fail: '
-a'.
-	self assert: parser fail: 'b'.
-!
-
-testTrimCustom
-	| parser |
-	parser := $a asParser token trim: $b asParser.
-	
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: 'ab' toToken: 1 stop: 1.
-	self assert: parser parse: 'abb' toToken: 1 stop: 1.
-		
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: 'ba' toToken: 2 stop: 2.
-	self assert: parser parse: 'bba' toToken: 3 stop: 3.
-	
-	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
-	self assert: parser parse: 'ab' toToken: 1 stop: 1 end: 2.
-	self assert: parser parse: 'abba' toToken: 1 stop: 1 end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'
-!
-
-testTrimSpaces
-	| parser |
-	parser := $a asParser token trimSpaces.
-	
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: 'a ' toToken: 1 stop: 1.
-	self assert: parser parse: 'a	' toToken: 1 stop: 1.
-	self assert: parser parse: 'a  ' toToken: 1 stop: 1.
-	self assert: parser parse: 'a 
-	 ' toToken: 1 stop: 1.
-		
-	self assert: parser parse: 'a' toToken: 1 stop: 1.
-	self assert: parser parse: ' a' toToken: 2 stop: 2.
-	self assert: parser parse: '	a' toToken: 2 stop: 2.
-	self assert: parser parse: '    a' toToken: 5 stop: 5.
-	self assert: parser parse: '   
-a' toToken: 5 stop: 5.
-	
-	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
-	self assert: parser parse: 'a	a' toToken: 1 stop: 1 end: 2.
-	self assert: parser parse: 'a  a' toToken: 1 stop: 1 end: 3.
-	
-	self assert: parser fail: ''.
-	self assert: parser fail: 'b'
-!
-
-testWrapping
-	| parser result |
-	parser := #digit asParser plus >=> [ :stream :cc | 
-		Array 
-			with: stream position 
-			with: cc value 
-			with: stream position ].
-
-	self assert: parser parse: '1' to: #(0 ($1) 1).
-	self assert: parser parse: '12' to: #(0 ($1 $2) 2).
-	self assert: parser parse: '123' to: #(0 ($1 $2 $3) 3).
-	
-	result := parser parse: 'a'.
-	self assert: result first = 0.
-	self assert: result second isPetitFailure.
-	self assert: result last = 0
-! !
-
-!PPParserTest methodsFor:'testing-properties'!
-
-testHasProperty
-	| parser |
-	parser := PPParser new.
-	self deny: (parser hasProperty: #foo).
-	parser propertyAt: #foo put: 123.
-	self assert: (parser hasProperty: #foo)
-!
-
-testPostCopy
-	| parser copy |
-	parser := PPParser new.
-	parser propertyAt: #foo put: true.
-	copy := parser copy.
-	copy propertyAt: #foo put: false.
-	self assert: (parser propertyAt: #foo).
-	self deny: (copy propertyAt: #foo)
-!
-
-testPropertyAt
-	| parser |
-	parser := PPParser new.
-	self should: [ parser propertyAt: #foo ] raise: Error.
-	parser propertyAt: #foo put: true.
-	self assert: (parser propertyAt: #foo)
-!
-
-testPropertyAtIfAbsent
-	| parser |
-	parser := PPParser new.
-	self assert: (parser propertyAt: #foo ifAbsent: [ true ]).
-	parser propertyAt: #foo put: true.
-	self assert: (parser propertyAt: #foo ifAbsent: [ false ])
-!
-
-testPropertyAtIfAbsentPut
-	| parser |
-	parser := PPParser new.
-	self assert: (parser propertyAt: #foo ifAbsentPut: [ true ]).
-	self assert: (parser propertyAt: #foo ifAbsentPut: [ false ])
-!
-
-testRemoveProperty
-	| parser |
-	parser := PPParser new.
-	self should: [ parser removeProperty: #foo ] raise: Error.
-	parser propertyAt: #foo put: true.
-	self assert: (parser removeProperty: #foo)
-!
-
-testRemovePropertyIfAbsent
-	| parser |
-	parser := PPParser new.
-	self assert: (parser removeProperty: #foo ifAbsent: [ true ]).
-	parser propertyAt: #foo put: true.
-	self assert: (parser removeProperty: #foo ifAbsent: [ false ])
-! !
-
-!PPParserTest methodsFor:'testing-utilities'!
-
-testChildren
-	| p1 p2 p3 |
-	p1 := #lowercase asParser.
-	p2 := p1 ==> #asUppercase.
-	p3 := PPUnresolvedParser new.
-	p3 def: p2 / p3.
-	self assert: p1 children isEmpty.
-	self assert: p2 children size = 1.
-	self assert: p3 children size = 2
-!
-
-testFailure
-	| failure |
-	failure := PPFailure message: 'Error' at: 3.
-	
-	self assert: failure message = 'Error'.
-	self assert: failure position = 3.
-	self assert: failure isPetitFailure.
-
-	self deny: 4 isPetitFailure.
-	self deny: 'foo' isPetitFailure
-!
-
-testListConstructor
-	| p1 p2 p3 |
-	p1 := PPChoiceParser with: $a asParser.
-	p2 := PPChoiceParser with: $a asParser with: $b asParser.
-	p3 := PPChoiceParser withAll: (Array with: $a asParser with: $b asParser with: $c asParser).
-	
-	self assert: p1 children size = 1.
-	self assert: p2 children size = 2.
-	self assert: p3 children size = 3
-!
-
-testMatches
-	| parser |
-	parser := $a asParser.
-	
-	self assert: (parser matches: 'a').
-	self deny: (parser matches: 'b').
-	
-	self assert: (parser matches: 'a' readStream).
-	self deny: (parser matches: 'b' readStream)
-!
-
-testMatchesIn
-	| parser result |
-	parser := $a asParser.
-	
-	result := parser matchesIn: 'abba'.
-	self assert: result size = 2.
-	self assert: result first = $a.
-	self assert: result last = $a.
-	
-	result := parser matchesIn: 'baaah'.
-	self assert: result size = 3.
-	self assert: result first = $a.
-	self assert: result last = $a
-!
-
-testMatchesInEmpty
-	"Empty matches should properly advance and match at each position and at the end."
-
-	| parser result |
-	parser := [ :stream | stream position ] asParser.
-	
-	result := parser matchesIn: '123'.
-	self assert: result asArray = #(0 1 2 3)
-!
-
-testMatchesInOverlapping
-	"Matches that overlap should be properly reported."
-
-	| parser result |
-	parser := #digit asParser , #digit asParser.
-	
-	result := parser matchesIn: 'a123b'.
-	self assert: result size = 2.
-	self assert: result first = #($1 $2).
-	self assert: result last = #($2 $3)
-!
-
-testMatchesSkipIn
-	| parser result |
-	parser := $a asParser.
-	
-	result := parser matchesSkipIn: 'abba'.
-	self assert: result size = 2.
-	self assert: result first = $a.
-	self assert: result last = $a.
-	
-	result := parser matchesSkipIn: 'baaah'.
-	self assert: result size = 3.
-	self assert: result first = $a.
-	self assert: result last = $a
-!
-
-testMatchesSkipInOverlapping
-	"Matches that overlap should be properly reported."
-
-	| parser result |
-	parser := #digit asParser , #digit asParser.
-	
-	result := parser matchesSkipIn: 'a123b'.
-	self assert: result size = 1.
-	self assert: result first = #($1 $2)
-!
-
-testMatchingRangesIn
-	| input parser result |
-	input := 'a12b3'.
-	parser := #digit asParser plus.
-	result := parser matchingRangesIn: input.
-	result := result collect: [ :each | input copyFrom: each first to: each last ].
-	self assert: result size = 3.
-	self assert: result first = '12'.
-	self assert: result second = '2'.
-	self assert: result last = '3'
-!
-
-testMatchingSkipRangesIn
-	| input parser result |
-	input := 'a12b3'.
-	parser := #digit asParser plus.
-	result := parser matchingSkipRangesIn: input.
-	result := result collect: [ :each | input copyFrom: each first to: each last ].
-	self assert: result size = 2.
-	self assert: result first = '12'.
-	self assert: result last = '3'
-!
-
-testParse
-	| parser result |
-	parser := $a asParser.
-	
-	self assert: (parser parse: 'a') = $a.
-	self assert: (result := parser parse: 'b') isPetitFailure.
-	self assert: (result message findString: '$a') > 0.
-	self assert: (result message findString: 'expected') > 0.
-	self assert: (result position = 0).
-	
-	self assert: (parser parse: 'a' readStream) = $a.
-	self assert: (result := parser parse: 'b' readStream) isPetitFailure.
-	self assert: (result message findString: '$a') > 0.
-	self assert: (result message findString: 'expected') > 0.
-	self assert: (result position = 0)
-!
-
-testParseOnError0
-	| parser result seen |
-	parser := $a asParser.
-
-	result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ].
-	self assert: result = $a.
-
-	result := parser parse: 'b' onError: [ seen := true ].
-	self assert: result.
-	self assert: seen
-!
-
-testParseOnError1
-	| parser result seen |
-	parser := $a asParser.
-
-	result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ].
-	self assert: result = $a.
-	
-	result := parser parse: 'b' onError: [ :failure | 
-		self assert: (failure position = 0).
-		self assert: (failure message findString: '$a') > 0.
-		self assert: (failure message findString: 'expected') > 0.
-		seen := true ].
-	self assert: result.
-	self assert: seen
-!
-
-testParseOnError2
-	| parser result seen |
-	parser := $a asParser.
-	
-	result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ].
-	self assert: result = $a.
-
-	result := parser parse: 'b' onError: [ :msg :pos | 
-		self assert: (msg findString: '$a') > 0.
-		self assert: (msg findString: 'expected') > 0.
-		self assert: pos = 0.
-		seen := true ].
-	self assert: result.
-	self assert: seen
-!
-
-testParser
-	| parser |
-	parser := PPParser new.
-	
-	self assert: parser isPetitParser.
-
-	self deny: 4 isPetitParser.
-	self deny: 'foo' isPetitParser
-! !
-
-!PPParserTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserTest.st,v 1.4 2014-03-04 14:34:21 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserTest.st,v 1.4 2014-03-04 14:34:21 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPParserTest.st,v 1.4 2014-03-04 14:34:21 cg Exp $'
-! !
-
--- a/PPPredicateTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,313 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPPredicateTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPPredicateTest methodsFor:'private'!
-
-charactersDo: aBlock
-    "cg: isn't 256 one too many?"
-
-    Smalltalk isSmalltalkX ifTrue:[
-        0 to: 255 do: [ :index | aBlock value: (Character codePoint: index) ]
-    ] ifFalse:[
-        1 to: 256 do: [ :index | aBlock value: (Character codePoint: index) ]
-    ].
-! !
-
-!PPPredicateTest methodsFor:'testing'!
-
-testOnMessage
-	| block parser |
-	block := [ :char | char = $* ].
-	parser := PPPredicateObjectParser on: block message: 'starlet'.
-	self assert: parser block = block.
-	self assert: parser message = 'starlet'.
-	
-	self assertCharacterSets: parser.
-	self assert: parser parse: '*' to: $*.
-	self assert: parser parse: '**' to: $* end: 1.
-	self assert: parser fail: ''.
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a'
-! !
-
-!PPPredicateTest methodsFor:'testing-chars'!
-
-testBlank
-        | parser cr|
-        parser := #blank asParser.
-        self assertCharacterSets: parser.
-        self assert: parser parse: (String with: Character space) to: Character space.
-        self assert: parser parse: (String with: Character tab) to: Character tab.
-        self assert: parser fail: ''.
-        self assert: parser fail: '1'.
-        cr := Smalltalk isSmalltalkX 
-            ifTrue:[Character return] 
-            ifFalse:[Character cr].
-        self assert: parser fail: (String with: cr)
-!
-
-testChar
-	| parser |
-	parser := $* asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: '*' to: $*.
-	self assert: parser parse: '**' to: $* end: 1.
-	self assert: parser fail: ''.
-	self assert: parser fail: '1'.
-	self assert: parser fail: 'a'
-!
-
-testCr
-        | parser cr |
-
-        cr := Smalltalk isSmalltalkX 
-                ifTrue:[Character return] 
-                ifFalse:[Character cr].
-
-        parser := #cr asParser.
-        self assertCharacterSets: parser.
-        self assert: parser parse: (String with: cr) to: cr
-!
-
-testDigit
-	| parser |
-	parser := #digit asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: '0' to: $0.
-	self assert: parser parse: '9' to: $9.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'
-!
-
-testHex
-	| parser |
-	parser := #hex asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: '0' to: $0.
-	self assert: parser parse: '5' to: $5.
-	self assert: parser parse: '9' to: $9.
-	self assert: parser parse: 'A' to: $A.
-	self assert: parser parse: 'D' to: $D.
-	self assert: parser parse: 'F' to: $F.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'e' to: $e.
-	self assert: parser parse: 'f' to: $f.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'g'
-!
-
-testLetter
-	| parser |
-	parser := #letter asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'Z' to: $Z.
-	self assert: parser fail: ''.
-	self assert: parser fail: '0'
-!
-
-testLf
-	| parser |
-	parser := #lf asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: (String with: Character lf) to: Character lf
-!
-
-testLowercase
-	| parser |
-	parser := #lowercase asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'z' to: $z.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'A'.
-	self assert: parser fail: '0'
-!
-
-testNewline
-        | parser cr|
-        cr := Smalltalk isSmalltalkX 
-                ifTrue:[Character return] 
-                ifFalse:[Character cr].
-        parser := #newline asParser.
-        self assertCharacterSets: parser.
-        self assert: parser parse: (String with: cr) to: cr.
-        self assert: parser parse: (String with: Character lf) to: Character lf.
-        self assert: parser fail: ' '
-!
-
-testPunctuation
-	| parser |
-	parser := #punctuation asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: '.' to: $..
-	self assert: parser parse: ',' to: $,.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: '1'
-!
-
-testSpace
-	| parser |
-	parser := #space asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: (String with: Character tab) to: Character tab.
-	self assert: parser parse: ' ' to: Character space.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'
-!
-
-testTab
-	| parser |
-	parser := #tab asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: (String with: Character tab) to: Character tab
-!
-
-testUppercase
-	| parser |
-	parser := #uppercase asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'A' to: $A.
-	self assert: parser parse: 'Z' to: $Z.
-	self assert: parser fail: ''.
-	self assert: parser fail: 'a'.
-	self assert: parser fail: '0'
-!
-
-testWord
-	| parser |
-	parser := #word asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'A' to: $A.
-	self assert: parser parse: '0' to: $0.
-	self assert: parser fail: ''.
-	self assert: parser fail: '-'
-! !
-
-!PPPredicateTest methodsFor:'testing-objects'!
-
-testAny
-	| parser |
-	parser := #any asParser.
-	self assertCharacterSets: parser.
-	self assert: parser parse: ' ' to: $ .
-	self assert: parser parse: '1' to: $1.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser fail: ''
-!
-
-testAnyExceptAnyOf
-	| parser |
-	parser := PPPredicateObjectParser anyExceptAnyOf: #($: $,).
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'z' to: $z.
-	self assert: parser fail: ':'.
-	self assert: parser fail: ','
-!
-
-testAnyOf
-	| parser |
-	parser := PPPredicateObjectParser anyOf: #($a $z).
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser parse: 'z' to: $z.
-	self assert: parser fail: 'x'
-!
-
-testBetweenAnd
-	| parser |
-	parser := PPPredicateObjectParser between: $b and: $d.
-	self assertCharacterSets: parser.
-	self assert: parser fail: 'a'.
-	self assert: parser parse: 'b' to: $b.
-	self assert: parser parse: 'c' to: $c.
-	self assert: parser parse: 'd' to: $d.
-	self assert: parser fail: 'e'
-!
-
-testExpect
-	| parser |
-	parser := PPPredicateObjectParser expect: $a.
-	self assertCharacterSets: parser.
-	self assert: parser parse: 'a' to: $a.
-	self assert: parser fail: 'b'.
-	self assert: parser fail: ''
-! !
-
-!PPPredicateTest methodsFor:'testing-sequence'!
-
-testSequenceParser
-	| parser |
-	parser := PPPredicateSequenceParser 
-		on: [ :value | value first isUppercase ] 
-		message: 'uppercase 3 letter words'
-		size: 3.
-	self assert: parser size = 3.
-	self assert: parser parse: 'Abc'.
-	self assert: parser parse: 'ABc'.
-	self assert: parser parse: 'ABC'.
-	self assert: parser fail: 'abc'.
-	self assert: parser fail: 'aBC'.
-	self assert: parser fail: 'Ab'.
-	
-	parser := parser negate.
-	self assert: parser size = 3.
-	self assert: parser fail: 'Abc'.
-	self assert: parser fail: 'ABc'.
-	self assert: parser fail: 'ABC'.
-	self assert: parser parse: 'abc'.
-	self assert: parser parse: 'aBC'.
-	self assert: parser fail: 'Ab'
-! !
-
-!PPPredicateTest methodsFor:'utilities'!
-
-assertCharacterSets: aParser
-	"Assert the character set of aParser does not overlap with the character set with the negated parser, and that they both cover the complete character space."
-
-	| positives negatives |
-	positives := self parsedCharacterSet: aParser.
-	negatives := self parsedCharacterSet: aParser negate.
-	self charactersDo: [ :char | 
-		| positive negative |
-		positive := positives includes: char.
-		negative := negatives includes: char.
-		self 
-			assert: ((positive and: [ negative not ])
-				or: [ positive not and: [ negative ] ])
-			description: char printString , ' should be in exactly one set' ]
-!
-
-parsedCharacterSet: aParser
-	| result |
-	result := WriteStream on: String new.
-	self charactersDo: [ :char |
-		(aParser matches: (String with: char))
-			ifTrue: [ result nextPut: char ] ].
-	^ result contents
-! !
-
-!PPPredicateTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPPredicateTest.st,v 1.6 2014-03-04 20:09:46 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPPredicateTest.st,v 1.6 2014-03-04 20:09:46 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPPredicateTest.st,v 1.6 2014-03-04 20:09:46 cg Exp $'
-! !
-
--- a/PPScriptingTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPScriptingTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-PPScriptingTest comment:'These are some simple demo-scripts of parser combinators for the compiler construction course.
http://www.iam.unibe.ch/~scg/Teaching/CC/index.html'
-!
-
-
-!PPScriptingTest methodsFor:'examples'!
-
-expressionInterpreter
-        "Same as #expressionInterpreter but with semantic actions."
-        
-        | mul prim add dec |
-        add := PPUnresolvedParser new.
-        mul := PPUnresolvedParser new.
-        prim := PPUnresolvedParser new.
-        dec := ($0 to: $9) asParser ==> [ :token | token codePoint - $0 codePoint ].
-        add def: ((mul , $+ asParser , add) ==> [ :nodes | (nodes at: 1) + (nodes at: 3) ])
-                / mul.
-        mul def: ((prim , $* asParser , mul) ==> [ :nodes | (nodes at: 1) * (nodes at: 3) ])
-                / prim.
-        prim def: (($( asParser , add , $) asParser) ==> [ :nodes | nodes at: 2 ])
-                / dec.
-        ^ add end
-!
-
-expressionParser
-        "Simple demo of scripting an expression parser."
-        
-        | mul prim add dec |
-        add := PPUnresolvedParser new.
-        mul := PPUnresolvedParser new.
-        prim := PPUnresolvedParser new.
-        dec := ($0 to: $9) asParser.
-        add def: (mul , $+ asParser , add)
-                / mul.
-        mul def: (prim , $* asParser , mul)
-                / prim.
-        prim def: ($( asParser , add , $) asParser)
-                / dec.
-        ^ add end
-!
-
-straightLineParser
-        | goal stm stmList id char dec exp expList mulExp primExp nonzero num lower upper |
-        goal := PPUnresolvedParser new.
-        stmList := PPUnresolvedParser new.
-        stm := PPUnresolvedParser new.
-        exp := PPUnresolvedParser new.
-        expList := PPUnresolvedParser new.
-        mulExp := PPUnresolvedParser new.
-        primExp := PPUnresolvedParser new.
-        
-        lower := ($a to: $z) asParser.
-        upper := ($A to: $Z) asParser.
-        char := lower / upper.
-        nonzero := ($1 to: $9) asParser.
-        dec := ($0 to: $9) asParser.
-        id := char, ( char / dec ) star.
-        num := $0 asParser / ( nonzero, dec star).
-
-        goal def: stmList end.
-        stmList def: stm , ( $; asParser, stm ) star.
-        stm def: ( id, ':=' asParser, exp )
-                / ( 'print' asParser, $( asParser, expList, $) asParser ). 
-        exp def: mulExp, ( ( $+ asParser / $- asParser ), mulExp ) star.
-        expList def: exp, ( $, asParser, exp ) star.
-        mulExp def: primExp, ( ( $* asParser / $/ asParser ), primExp ) star.
-        primExp def: id
-                / num
-                / ( $( asParser, stmList, $, asParser, exp, $) asParser ).
-        ^ goal
-! !
-
-!PPScriptingTest methodsFor:'tests'!
-
-testExpressionInterpreter
-	self 
-		assert: self expressionInterpreter
-		parse: '2*(3+4)'
-		to: 14
-!
-
-testExpressionParser
-	self
-		assert: self expressionParser
-		parse: '2*(3+4)'
-		to: #($2 $* ($( ($3 $+ $4) $)))
-!
-
-testSLassign
-	
-	self assert: self straightLineParser
-		parse: 'abc:=1'
-		to: #(#($a #($b $c) ':=' #(#(#($1 #()) #()) #())) #())
-!
-
-testSLprint
-	self 
-		assert: self straightLineParser
-		parse: 'print(3,4)'
-		to: #(('print' $( ((($3 ()) ()) () (($, ((($4 ()) ()) ())))) $)) ())
-! !
-
-!PPScriptingTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPScriptingTest.st,v 1.4 2014-03-04 14:34:23 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPScriptingTest.st,v 1.4 2014-03-04 14:34:23 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPScriptingTest.st,v 1.4 2014-03-04 14:34:23 cg Exp $'
-! !
-
--- a/PPTokenTest.st	Fri Oct 03 00:52:34 2014 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,168 +0,0 @@
-"{ Package: 'stx:goodies/petitparser' }"
-
-PPAbstractParserTest subclass:#PPTokenTest
-	instanceVariableNames:''
-	classVariableNames:''
-	poolDictionaries:''
-	category:'PetitTests-Tests'
-!
-
-
-!PPTokenTest methodsFor:'accessing'!
-
-identifier
-	^ #word asParser plus token
-! !
-
-!PPTokenTest methodsFor:'testing'!
-
-testCollection
-	| input result |
-	input := 'foo    '.
-	result := self 
-		parse: input
-		using: self identifier.
-	self assert: (result collection = input).
-	self assert: (result collection == input)
-!
-
-testInitialize
-	PPToken initialize
-!
-
-testNew
-	self should: [ PPToken new ] raise: Error.
-	
-!
-
-testPrinting
-	| result |
-	result := PPToken on: 'var'.
-	self assert: (result printString findString: 'PPToken[1,3]') > 0
-!
-
-testSize
-	| result |
-	result := self 
-		parse: 'foo'
-		using: self identifier.
-	self assert: result size = 3
-!
-
-testStart
-	| result |
-	result := self 
-		parse: 'foo'
-		using: self identifier.
-	self assert: result start = 1
-!
-
-testStop
-	| result |
-	result := self 
-		parse: 'foo'
-		using: self identifier.
-	self assert: result stop = 3
-!
-
-testValue
-	| result |
-	result := PPToken on: 'var'.
-	self should: [ result value ] raise: Notification
-! !
-
-!PPTokenTest methodsFor:'testing-comparing'!
-
-testEquality
-	| token1 token2 |
-	token1 := self  parse: 'foo' using: self identifier.
-	token2 := self  parse: 'foo' using: self identifier.
-	self deny: token1 == token2.
-	self assert: token1 = token2.
-	self assert: token1 hash = token2 hash.
-! !
-
-!PPTokenTest methodsFor:'testing-copying'!
-
-testCopyFromTo
-	| result other |
-	result := PPToken on: 'abc'.
-	other := result copyFrom: 2 to: 2.
-	
-	self assert: other size = 1.
-	self assert: other start = 2.
-	self assert: other stop = 2.
-	self assert: other collection = result collection
-! !
-
-!PPTokenTest methodsFor:'testing-querying'!
-
-testColumn
-        | input parser result cr |
-
-        cr := Smalltalk isSmalltalkX 
-                ifTrue:[ Character return]
-                ifFalse:[ Character cr ].
-        input := '1' , (String with:cr) , '12' , (String with: cr with: Character lf) , '123' , (String with: Character lf) , '1234'.
-        parser := #any asParser token star.
-        result := parser parse: input.
-        result 
-                with:  #(1 2 1 2 3 4 1 2 3 4 1 2 3 4)
-                do: [ :token :line | self assert: token column = line ]
-!
-
-testLine
-        | input parser result cr|
-
-        cr := Smalltalk isSmalltalkX 
-            ifTrue:[Character return] 
-            ifFalse:[Character cr].
-        input := '1' , (String with: cr) , '12' , (String with: cr with: Character lf) , '123' , (String with: Character lf) , '1234'.
-        parser := #any asParser token star.
-        result := parser parse: input.
-        result 
-                with: #(1 1 2 2 2 2 3 3 3 3 4 4 4 4) 
-                do: [ :token :line | self assert: token line = line ]
-! !
-
-!PPTokenTest methodsFor:'testing-values'!
-
-testInputValue
-	| input result |
-	input := 'foo'.
-	result := self 
-		parse: input
-		using: self identifier.
-	self assert: result inputValue = input.
-	self deny: result inputValue == input
-!
-
-testParsedValue
-	| input result |
-	input := 'foo'.
-	result := self 
-		parse: input
-		using: self identifier.
-	self assert: result parsedValue = #($f $o $o)
-! !
-
-!PPTokenTest methodsFor:'utilities'!
-
-parse: aString using: aParser
-	^ aParser parse: aString
-! !
-
-!PPTokenTest class methodsFor:'documentation'!
-
-version
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPTokenTest.st,v 1.5 2014-03-04 14:34:24 cg Exp $'
-!
-
-version_CVS
-    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPTokenTest.st,v 1.5 2014-03-04 14:34:24 cg Exp $'
-!
-
-version_SVN
-    ^ '$Id: PPTokenTest.st,v 1.5 2014-03-04 14:34:24 cg Exp $'
-! !
-
--- a/abbrev.stc	Fri Oct 03 00:52:34 2014 +0100
+++ b/abbrev.stc	Fri Oct 03 01:36:33 2014 +0100
@@ -1,31 +1,18 @@
 # automagically generated by the project definition
 # this file is needed for stc to be able to compile modules independently.
 # it provides information about a classes filename, category and especially namespace.
-PPAbstractParseTest PPAbstractParseTest stx:goodies/petitparser 'PetitTests-Core' 1
-PPArithmeticParserTest PPArithmeticParserTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPCharSetPredicate PPCharSetPredicate stx:goodies/petitparser 'PetitParser-Tools' 0
-PPComposedTest PPComposedTest stx:goodies/petitparser 'PetitTests-Tests' 1
-PPExtensionTest PPExtensionTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPFailure PPFailure stx:goodies/petitparser 'PetitParser-Core' 0
-PPLambdaParserTest PPLambdaParserTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPMemento PPMemento stx:goodies/petitparser 'PetitParser-Core' 0
-PPObjectTest PPObjectTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPParser PPParser stx:goodies/petitparser 'PetitParser-Parsers' 0
-PPParserResource PPParserResource stx:goodies/petitparser 'PetitTests-Core' 1
-PPParserTest PPParserTest stx:goodies/petitparser 'PetitTests-Tests' 1
-PPPredicateTest PPPredicateTest stx:goodies/petitparser 'PetitTests-Tests' 1
-PPScriptingTest PPScriptingTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPStream PPStream stx:goodies/petitparser 'PetitParser-Core' 0
 PPToken PPToken stx:goodies/petitparser 'PetitParser-Core' 0
-PPTokenTest PPTokenTest stx:goodies/petitparser 'PetitTests-Tests' 1
 stx_goodies_petitparser stx_goodies_petitparser stx:goodies/petitparser '* Projects & Packages *' 3
 PPDelegateParser PPDelegateParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPEpsilonParser PPEpsilonParser stx:goodies/petitparser 'PetitParser-Parsers' 0
-PPExpressionParserTest PPExpressionParserTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPFailingParser PPFailingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPListParser PPListParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPLiteralParser PPLiteralParser stx:goodies/petitparser 'PetitParser-Parsers' 0
-PPMappingTest PPMappingTest stx:goodies/petitparser 'PetitTests-Tests' 1
 PPPluggableParser PPPluggableParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPPredicateParser PPPredicateParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPUnresolvedParser PPUnresolvedParser stx:goodies/petitparser 'PetitParser-Tools' 0
@@ -46,8 +33,6 @@
 PPRepeatingParser PPRepeatingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPSequenceParser PPSequenceParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPTrimmingParser PPTrimmingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
-PPArithmeticParser PPArithmeticParser stx:goodies/petitparser 'PetitTests-Examples' 0
-PPLambdaParser PPLambdaParser stx:goodies/petitparser 'PetitTests-Examples' 0
 PPLimitedRepeatingParser PPLimitedRepeatingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPPossessiveRepeatingParser PPPossessiveRepeatingParser stx:goodies/petitparser 'PetitParser-Parsers' 0
 PPTokenParser PPTokenParser stx:goodies/petitparser 'PetitParser-Parsers' 0
--- a/libInit.cc	Fri Oct 03 00:52:34 2014 +0100
+++ b/libInit.cc	Fri Oct 03 01:36:33 2014 +0100
@@ -59,8 +59,6 @@
 _PPRepeatingParser_Init(pass,__pRT__,snd);
 _PPSequenceParser_Init(pass,__pRT__,snd);
 _PPTrimmingParser_Init(pass,__pRT__,snd);
-_PPArithmeticParser_Init(pass,__pRT__,snd);
-_PPLambdaParser_Init(pass,__pRT__,snd);
 _PPLimitedRepeatingParser_Init(pass,__pRT__,snd);
 _PPPossessiveRepeatingParser_Init(pass,__pRT__,snd);
 _PPTokenParser_Init(pass,__pRT__,snd);
--- a/stx_goodies_petitparser.st	Fri Oct 03 00:52:34 2014 +0100
+++ b/stx_goodies_petitparser.st	Fri Oct 03 01:36:33 2014 +0100
@@ -18,6 +18,16 @@
     "Created: / 17-12-2010 / 19:44:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!stx_goodies_petitparser class methodsFor:'accessing - tests'!
+
+testSuite
+    "generate and return a testSuite containing all of my test-classes"
+
+    Smalltalk loadPackage: 'stx:goodies/petitparser/tests'.
+    ^ 'stx:goodies/petitparser/tests' asPackageId projectDefinitionClass testSuite
+
+! !
+
 !stx_goodies_petitparser class methodsFor:'description'!
 
 excludedFromPreRequisites
@@ -94,31 +104,18 @@
 
     ^ #(
         "<className> or (<className> attributes...) in load order"
-        (PPAbstractParseTest autoload)
-        (PPArithmeticParserTest autoload)
         PPCharSetPredicate
-        (PPComposedTest autoload)
-        (PPExtensionTest autoload)
         PPFailure
-        (PPLambdaParserTest autoload)
         PPMemento
-        (PPObjectTest autoload)
         PPParser
-        (PPParserResource autoload)
-        (PPParserTest autoload)
-        (PPPredicateTest autoload)
-        (PPScriptingTest autoload)
         PPStream
         PPToken
-        (PPTokenTest autoload)
         #'stx_goodies_petitparser'
         PPDelegateParser
         PPEpsilonParser
-        (PPExpressionParserTest autoload)
         PPFailingParser
         PPListParser
         PPLiteralParser
-        (PPMappingTest autoload)
         PPPluggableParser
         PPPredicateParser
         PPUnresolvedParser
@@ -139,8 +136,6 @@
         PPRepeatingParser
         PPSequenceParser
         PPTrimmingParser
-        PPArithmeticParser
-        PPLambdaParser
         PPLimitedRepeatingParser
         PPPossessiveRepeatingParser
         PPTokenParser
@@ -253,6 +248,8 @@
 
 !stx_goodies_petitparser class methodsFor:'documentation'!
 
+!stx_goodies_petitparser class methodsFor:'documentation'!
+
 version
     ^ '$Header: /cvs/stx/stx/goodies/petitparser/stx_goodies_petitparser.st,v 1.15 2014-03-04 20:30:48 cg Exp $'
 !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPAbstractParseTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,97 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+TestCase subclass:#PPAbstractParseTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Core'
+!
+
+
+!PPAbstractParseTest class methodsFor:'accessing'!
+
+packageNamesUnderTest
+	^ #('PetitParser' 'PetitTests')
+! !
+
+!PPAbstractParseTest class methodsFor:'testing'!
+
+isAbstract
+	^ self name = #PPAbstractParseTest
+! !
+
+!PPAbstractParseTest methodsFor:'utilities'!
+
+assert: aParser fail: aCollection
+	self assert: aParser fail: aCollection end: 0
+!
+
+assert: aParser fail: aCollection end: anInteger
+	| stream result |
+	self 
+		assert: aParser isPetitParser
+		description: 'Parser invalid'.
+	stream := aCollection asPetitStream.
+	result := aParser parse: stream.
+	self 
+		assert: result isPetitFailure
+		description: 'Parser did not fail'.
+	self
+		assert: stream position = anInteger
+		description: 'Parser failed at wrong position'
+!
+
+assert: aParser parse: aCollection
+	self assert: aParser parse: aCollection to: nil end: aCollection size 
+!
+
+assert: aParser parse: aCollection end: anInteger
+	self assert: aParser parse: aCollection to: nil end: anInteger
+!
+
+assert: aParser parse: aCollection to: anObject
+	self assert: aParser parse: aCollection to: anObject end: aCollection size 
+!
+
+assert: aParser parse: aParseObject to: aTargetObject end: anInteger
+        | stream result |
+        self 
+                assert: aParser isPetitParser
+                description: 'Parser invalid'.
+        stream := aParseObject asPetitStream.
+        result := aParser parse: stream.
+        aTargetObject isNil
+                ifTrue: [ self deny: result isPetitFailure ]
+                ifFalse: [ self assert: result = aTargetObject ].
+        self 
+                assert: stream position = anInteger
+                description: 'Parser accepted at wrong position'
+
+    "Modified: / 18-12-2010 / 18:01:30 / Jan Kurs <kurs.jan@post.cz>"
+!
+
+assert: aParser parse: aParserObject toToken: from stop: to
+	| token |
+	token := PPToken on: aParserObject start: from stop: to.
+	^ self assert: aParser parse: aParserObject to: token
+!
+
+assert: aParser parse: aParserObject toToken: from stop: to end: end
+	| token |
+	token := PPToken on: aParserObject start: from stop: to.
+	^ self assert: aParser parse: aParserObject to: token end: end
+! !
+
+!PPAbstractParseTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPAbstractParseTest.st,v 1.3 2012-05-04 22:09:07 vrany Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPAbstractParseTest.st,v 1.3 2012-05-04 22:09:07 vrany Exp $'
+!
+
+version_SVN
+    ^ '§Id: PPAbstractParseTest.st 4 2010-12-18 17:02:23Z kursjan §'
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPArithmeticParser.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,70 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPCompositeParser subclass:#PPArithmeticParser
+	instanceVariableNames:'terms addition factors multiplication power primary parentheses
+		number'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Examples'
+!
+
+
+!PPArithmeticParser methodsFor:'accessing'!
+
+start
+	^ terms end
+! !
+
+!PPArithmeticParser methodsFor:'grammar'!
+
+addition
+	^ (factors separatedBy: ($+ asParser / $- asParser) trim) 
+		foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]
+!
+
+factors
+	^ multiplication / power
+!
+
+multiplication
+	^ (power separatedBy: ($* asParser / $/ asParser) trim)
+		foldLeft: [ :a :op :b | a perform: op asSymbol with: b ]
+!
+
+number
+	^ ($- asParser optional , #digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten trim 
+		==> [ :value | value asNumber ]
+!
+
+parentheses
+	^ $( asParser trim , terms , $) asParser trim
+		==> [ :nodes | nodes second ]
+!
+
+power
+	^ (primary separatedBy: $^ asParser trim)
+		foldRight: [ :a :op :b | a raisedTo: b ]
+!
+
+primary
+	^ number / parentheses
+!
+
+terms
+	^ addition / factors
+! !
+
+!PPArithmeticParser class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParser.st,v 1.4 2014-03-04 14:33:59 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParser.st,v 1.4 2014-03-04 14:33:59 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPArithmeticParser.st,v 1.4 2014-03-04 14:33:59 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPArithmeticParserTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,137 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPCompositeParserTest subclass:#PPArithmeticParserTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPArithmeticParserTest methodsFor:'accessing'!
+
+parserClass
+	^ PPArithmeticParser
+! !
+
+!PPArithmeticParserTest methodsFor:'testing'!
+
+testNum
+	self assert: '0' is: 0.
+	self assert: '0.0' is: 0.0.
+	self assert: '1' is: 1.
+	self assert: '1.2' is: 1.2.
+	self assert: '34' is: 34.
+	self assert: '56.78' is: 56.78.
+	self assert: '-9' is: -9.
+	self assert: '-9.9' is: -9.9
+! !
+
+!PPArithmeticParserTest methodsFor:'testing-expression'!
+
+testBrackets
+	self assert: '(1)' is: 1.
+	self assert: '(1 + 2)' is: 3.
+	
+	self assert: '((1))' is: 1.
+	self assert: '((1 + 2))' is: 3.
+
+	self assert: '2 * (3 + 4)' is: 14.
+	self assert: '(2 + 3) * 4' is: 20.
+	self assert: '6 / (2 + 4)' is: 1.
+	self assert: '(2 + 6) / 2' is: 4
+!
+
+testPriority
+	self assert: '2 * 3 + 4' is: 10.
+	self assert: '2 + 3 * 4' is: 14.
+	self assert: '6 / 3 + 4' is: 6.
+	self assert: '2 + 6 / 2' is: 5
+! !
+
+!PPArithmeticParserTest methodsFor:'testing-operations'!
+
+testAdd
+	self assert: '1 + 2' is: 3.
+	self assert: '2 + 1' is: 3.
+	self assert: '1 + 2.3' is: 3.3.
+	self assert: '2.3 + 1' is: 3.3.
+	self assert: '1 + -2' is: -1.
+	self assert: '-2 + 1' is: -1
+!
+
+testAddMany
+	self assert: '1' is: 1.
+	self assert: '1 + 2' is: 3.
+	self assert: '1 + 2 + 3' is: 6.
+	self assert: '1 + 2 + 3 + 4' is: 10.
+	self assert: '1 + 2 + 3 + 4 + 5' is: 15
+!
+
+testDiv
+	self assert: '12 / 3' is: 4.
+	self assert: '-16 / -4' is: 4
+!
+
+testDivMany
+	self assert: '100 / 2' is: 50.
+	self assert: '100 / 2 / 2' is: 25.
+	self assert: '100 / 2 / 2 / 5' is: 5.
+	self assert: '100 / 2 / 2 / 5 / 5' is: 1
+	
+!
+
+testMul
+	self assert: '2 * 3' is: 6.
+	self assert: '2 * -4' is: -8
+!
+
+testMulMany
+	self assert: '1 * 2' is: 2.
+	self assert: '1 * 2 * 3' is: 6.
+	self assert: '1 * 2 * 3 * 4' is: 24.
+	self assert: '1 * 2 * 3 * 4 * 5' is: 120
+!
+
+testPow
+	self assert: '2 ^ 3' is: 8.
+	self assert: '-2 ^ 3' is: -8.
+	self assert: '-2 ^ -3' is: -0.125
+!
+
+testPowMany
+	self assert: '4 ^ 3' is: 64.
+	self assert: '4 ^ 3 ^ 2' is: 262144.
+	self assert: '4 ^ 3 ^ 2 ^ 1' is: 262144.
+	self assert: '4 ^ 3 ^ 2 ^ 1 ^ 0' is: 262144
+!
+
+testSub
+	self assert: '1 - 2' is: -1.
+	self assert: '1.2 - 1.2' is: 0.
+	self assert: '1 - -2' is: 3.
+	self assert: '-1 - -2' is: 1
+!
+
+testSubMany
+	self assert: '1' is: 1.
+	self assert: '1 - 2' is: -1.
+	self assert: '1 - 2 - 3' is: -4.
+	self assert: '1 - 2 - 3 - 4' is: -8.
+	self assert: '1 - 2 - 3 - 4 - 5' is: -13
+! !
+
+!PPArithmeticParserTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParserTest.st,v 1.4 2014-03-04 14:34:09 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPArithmeticParserTest.st,v 1.4 2014-03-04 14:34:09 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPArithmeticParserTest.st,v 1.4 2014-03-04 14:34:09 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPComposedTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,416 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPComposedTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPComposedTest methodsFor:'accessing'!
+
+comment
+	^ ($" asParser , $" asParser negate star , $" asParser) flatten
+!
+
+identifier
+	^ (#letter asParser , #word asParser star) flatten
+!
+
+number
+	^ ($- asParser optional , #digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten
+! !
+
+!PPComposedTest methodsFor:'testing'!
+
+testDoubledString
+	| parser |
+	parser := ($' asParser , (($' asParser , $' asParser) / $' asParser negate) star flatten , $' asParser) 
+		==> [ :nodes | nodes second copyReplaceAll: '''''' with: '''' ].
+
+	self assert: parser parse: '''''' to: ''.
+	self assert: parser parse: '''a''' to: 'a'.
+	self assert: parser parse: '''ab''' to: 'ab'.
+	self assert: parser parse: '''a''''b''' to: 'a''b'.
+	self assert: parser parse: '''a''''''''b''' to: 'a''''b'
+!
+
+testEvenNumber
+	"Create a grammar that parses an even number of a's and b's."
+	
+	| a as b bs s |
+	a := $a asParser ==> [ :char | as := as + 1 ].
+	b := $b asParser ==> [ :char | bs := bs + 1 ].
+	s := (a / b) star >=> [ :stream :cc |
+		as := bs := 0.
+		cc value.
+		(as even and: [ bs even ])
+			ifFalse: [ PPFailure message: 'Even number of a and b expected' at: 0 ] ].
+
+	self assert: s fail: 'a' end: 1.
+	self assert: s fail: 'b' end: 1.
+	self assert: s fail: 'ab' end: 2.
+	self assert: s fail: 'ba' end: 2.
+	self assert: s fail: 'aaa' end: 3.
+	self assert: s fail: 'bbb' end: 3.
+	self assert: s fail: 'aab' end: 3.
+	self assert: s fail: 'abb' end: 3.
+	
+	self assert: s parse: ''.
+	self assert: s parse: 'aa'.
+	self assert: s parse: 'bb'.
+	self assert: s parse: 'aaaa'.
+	self assert: s parse: 'aabb'.
+	self assert: s parse: 'abab'.
+	self assert: s parse: 'baba'.
+	self assert: s parse: 'bbaa'.
+	self assert: s parse: 'bbbb'
+!
+
+testIfThenElse
+	"S ::= if C then S else S | if C then S | X"
+
+	| start if then else cond expr parser |
+	start := PPDelegateParser new.
+	if := 'if' asParser token trim.
+	then := 'then' asParser token trim.
+	else := 'else' asParser token trim.
+	cond := 'C' asParser token trim.
+	expr := 'X' asParser token trim.
+	start setParser: (if , cond , then , start , else , start) / (if , cond , then , start) / expr.
+	parser := start end.
+	self assert: parser parse: 'X'.
+	self assert: parser parse: 'if C then X'.
+	self assert: parser parse: 'if C then X else X'.
+	self assert: parser parse: 'if C then if C then X'.
+	self assert: parser parse: 'if C then if C then X else if C then X'.
+	self assert: parser parse: 'if C then if C then X else X else if C then X'.
+	self assert: parser parse: 'if C then if C then X else X else if C then X else X'.
+	self assert: parser fail: 'if C'.
+	self assert: parser fail: 'if C else X'.
+	self assert: parser fail: 'if C then if C'
+!
+
+testLeftRecursion
+	"S ::= S 'x' S / '1'"
+	
+	| parser |
+	parser := PPDelegateParser new.
+	parser setParser: ((parser , $x asParser , parser) / $1 asParser) memoized flatten.
+
+	self assert: parser parse: '1' to: '1'.
+	self assert: parser parse: '1x1' to: '1x1'.
+	self assert: parser parse: '1x1x1' to: '1x1x1'.
+	self assert: parser parse: '1x1x1x1' to: '1x1x1x1'.
+	self assert: parser parse: '1x1x1x1x1' to: '1x1x1x1x1'.
+	self assert: parser parse: '1x1x1x1x1x1' to: '1x1x1x1x1x1'
+!
+
+testListOfIntegers
+	"S ::= S , number | number"
+	
+	| number list parser |
+	number := #digit asParser plus flatten trim
+		==> [ :node | node asInteger ].
+	list := (number separatedBy: $, asParser token trim)
+		==> [ :node | node select: [ :each | each isInteger ] ].
+	parser := list end.
+
+	self assert: parser parse: '1' to: (1 to: 1) asArray.
+	self assert: parser parse: '1,2' to: (1 to: 2) asArray.
+	self assert: parser parse: '1,2,3' to: (1 to: 3) asArray.
+	self assert: parser parse: '1,2,3,4' to: (1 to: 4) asArray.
+	self assert: parser parse: '1,2,3,4,5' to: (1 to: 5) asArray.
+
+	self assert: parser parse: '1' to: (1 to: 1) asArray.
+	self assert: parser parse: '1, 2' to: (1 to: 2) asArray.
+	self assert: parser parse: '1, 2, 3' to: (1 to: 3) asArray.
+	self assert: parser parse: '1, 2, 3, 4' to: (1 to: 4) asArray.
+	self assert: parser parse: '1, 2, 3, 4, 5' to: (1 to: 5) asArray.
+
+	self assert: parser parse: '1' to: (1 to: 1) asArray.
+	self assert: parser parse: '1 ,2' to: (1 to: 2) asArray.
+	self assert: parser parse: '1 ,2 ,3' to: (1 to: 3) asArray.
+	self assert: parser parse: '1 ,2 ,3 ,4' to: (1 to: 4) asArray.
+	self assert: parser parse: '1 ,2 ,3 ,4 ,5' to: (1 to: 5) asArray.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: ','.
+	self assert: parser fail: '1,'.
+	self assert: parser fail: '1,,2'
+!
+
+testNestedComments
+	"C ::= B I* E"
+	"I ::= !!E (C | T)"
+	"B ::= /*"
+	"E ::= */"
+	"T ::= ."
+	
+	| begin end any inside parser |
+	begin := '/*' asParser.
+	end := '*/' asParser.
+	any := #any asParser.
+	
+	parser := PPDelegateParser new.
+	inside := end not , (parser / any).
+	parser setParser: begin , inside star , end.
+	
+	self assert: parser parse: '/*ab*/cd' end: 6.
+	self assert: parser parse: '/*a/*b*/c*/'.
+	self assert: parser fail: '/*a/*b*/c'
+!
+
+testPalindrome
+	"S0 ::= a S1 a | b S1 b | ...
+	 S1 ::= S0 | epsilon"
+	
+	| s0 s1 parser |
+	s0 := PPDelegateParser new.
+	s1 := PPDelegateParser new.
+	s0 setParser: ($a asParser , s1 , $a asParser)
+		/ ($b asParser , s1 , $b asParser)
+		/ ($c asParser , s1 , $c asParser).	
+	s1 setParser: s0 / nil asParser.
+	parser := s0 flatten end.
+
+	self assert: parser parse: 'aa' to: 'aa'.
+	self assert: parser parse: 'bb' to: 'bb'.
+	self assert: parser parse: 'cc' to: 'cc'.
+	
+	self assert: parser parse: 'abba' to: 'abba'.
+	self assert: parser parse: 'baab' to: 'baab'.
+
+	self assert: parser parse: 'abccba' to: 'abccba'.
+	self assert: parser parse: 'abaaba' to: 'abaaba'.
+	self assert: parser parse: 'cbaabc' to: 'cbaabc'.
+
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'ab'.
+	self assert: parser fail: 'aab'.
+	self assert: parser fail: 'abccbb'
+!
+
+testParseAaaBbb
+	"S0 ::= a S1 b
+	 S1 ::= S0 | epsilon"
+	
+	| s0 s1 parser |
+	s0 := PPDelegateParser new.
+	s1 := PPDelegateParser new.
+	s0 setParser: $a asParser , s1 , $b asParser.
+	s1 setParser: s0 / nil asParser.
+	parser := s0 flatten.
+
+	self assert: parser parse: 'ab' to: 'ab'.
+	self assert: parser parse: 'aabb' to: 'aabb'.
+	self assert: parser parse: 'aaabbb' to: 'aaabbb'.
+	self assert: parser parse: 'aaaabbbb' to: 'aaaabbbb'.
+
+	self assert: parser parse: 'abb' to: 'ab' end: 2.
+	self assert: parser parse: 'aabbb' to: 'aabb' end: 4.
+	self assert: parser parse: 'aaabbbb' to: 'aaabbb' end: 6.
+	self assert: parser parse: 'aaaabbbbb' to: 'aaaabbbb' end: 8.
+
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'aab'.
+	self assert: parser fail: 'aaabb'
+!
+
+testParseAaaaaa
+	"S ::= a a S | epsilon"
+	
+	| s0 s1 parser |
+	s0 := PPDelegateParser new.
+	s1 := $a asParser , $a asParser , s0.
+	s0 setParser: s1 / nil asParser.
+	parser := s0 flatten.
+
+	self assert: parser parse: '' to: ''.
+	self assert: parser parse: 'aa' to: 'aa'.
+	self assert: parser parse: 'aaaa' to: 'aaaa'.
+	self assert: parser parse: 'aaaaaa' to: 'aaaaaa'.
+
+	self assert: parser parse: 'a' to: '' end: 0.
+	self assert: parser parse: 'aaa' to: 'aa' end: 2.
+	self assert: parser parse: 'aaaaa' to: 'aaaa' end: 4.
+	self assert: parser parse: 'aaaaaaa' to: 'aaaaaa' end: 6
+!
+
+testParseAbAbAb
+	"S ::= (A B)+"
+	
+	| parser |
+	parser := ($a asParser , $b asParser) plus flatten.
+
+	self assert: parser parse: 'ab' to: 'ab'.
+	self assert: parser parse: 'abab' to: 'abab'.
+	self assert: parser parse: 'ababab' to: 'ababab'.
+	self assert: parser parse: 'abababab' to: 'abababab'.
+
+	self assert: parser parse: 'abb' to: 'ab' end: 2.
+	self assert: parser parse: 'ababa' to: 'abab' end: 4.
+	self assert: parser parse: 'abababb' to: 'ababab' end: 6.
+	self assert: parser parse: 'ababababa' to: 'abababab' end: 8.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'bab'
+!
+
+testParseAbabbb
+	"S ::= (A | B)+"
+
+	| parser |
+	parser := ($a asParser / $b asParser) plus flatten.
+
+	self assert: parser parse: 'a' to: 'a'.
+	self assert: parser parse: 'b' to: 'b'.
+	self assert: parser parse: 'ab' to: 'ab'.
+	self assert: parser parse: 'ba' to: 'ba'.
+	self assert: parser parse: 'aaa' to: 'aaa'.
+	self assert: parser parse: 'aab' to: 'aab'.
+	self assert: parser parse: 'aba' to: 'aba'.
+	self assert: parser parse: 'baa' to: 'baa'.
+	self assert: parser parse: 'abb' to: 'abb'.
+	self assert: parser parse: 'bab' to: 'bab'.
+	self assert: parser parse: 'bba' to: 'bba'.
+	self assert: parser parse: 'bbb' to: 'bbb'.
+
+	self assert: parser parse: 'ac' to: 'a' end: 1.
+	self assert: parser parse: 'bc' to: 'b' end: 1.
+	self assert: parser parse: 'abc' to: 'ab' end: 2.
+	self assert: parser parse: 'bac' to: 'ba' end: 2.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'c'
+!
+
+testParseAnBnCn
+	"PEGs for a non context- free language: 
+		
+		a^n , b^n , c^n
+		
+	S <- &P1 P2 
+	P1 <- AB 'c' 
+	AB <- 'a' AB 'b' / epsilon
+	P2 <- 'a'* BC end
+	BC <- 'b' BC 'c' / epsilon"
+	
+	| s p1 ab p2 bc |
+	s := PPDelegateParser new.
+	p1 := PPDelegateParser new.
+	ab := PPDelegateParser new.
+	p2 := PPDelegateParser new.
+	bc := PPDelegateParser new.
+	
+	s setParser: (p1 and , p2 end) flatten.
+	p1 setParser: ab , $c asParser.
+	ab setParser: ($a asParser , ab , $b asParser) optional.
+	p2 setParser: $a asParser star , bc.
+	bc setParser: ($b asParser , bc , $c asParser) optional.
+	
+	self assert: s parse: 'abc' to: 'abc'.
+	self assert: s parse: 'aabbcc' to: 'aabbcc'.
+	self assert: s parse: 'aaabbbccc' to: 'aaabbbccc'.
+
+	self assert: s fail: 'bc'.
+	self assert: s fail: 'ac'.
+	self assert: s fail: 'ab'.
+	self assert: s fail: 'abbcc'.
+	self assert: s fail: 'aabcc'.
+	self assert: s fail: 'aabbc'
+! !
+
+!PPComposedTest methodsFor:'testing-examples'!
+
+testComment
+	self assert: self comment parse: '""' to: '""'.
+	self assert: self comment parse: '"a"' to: '"a"'.
+	self assert: self comment parse: '"ab"' to: '"ab"'.
+	self assert: self comment parse: '"abc"' to: '"abc"'.
+
+	self assert: self comment parse: '""a' to: '""' end: 2.
+	self assert: self comment parse: '"a"a' to: '"a"' end: 3.
+	self assert: self comment parse: '"ab"a' to: '"ab"' end: 4.
+	self assert: self comment parse: '"abc"a' to: '"abc"' end: 5.
+
+	self assert: self comment fail: '"'.
+	self assert: self comment fail: '"a'.
+	self assert: self comment fail: '"aa'.
+	self assert: self comment fail: 'a"'.
+	self assert: self comment fail: 'aa"'
+!
+
+testIdentifier
+	self assert: self identifier parse: 'a' to: 'a'.
+	self assert: self identifier parse: 'a1' to: 'a1'.
+	self assert: self identifier parse: 'a12' to: 'a12'.
+	self assert: self identifier parse: 'ab' to: 'ab'.
+	self assert: self identifier parse: 'a1b' to: 'a1b'.
+
+	self assert: self identifier parse: 'a_' to: 'a' end: 1.
+	self assert: self identifier parse: 'a1-' to: 'a1' end: 2.
+	self assert: self identifier parse: 'a12+' to: 'a12' end: 3.
+	self assert: self identifier parse: 'ab^' to: 'ab' end: 2.
+	self assert: self identifier parse: 'a1b*' to: 'a1b' end: 3.
+
+	self assert: self identifier fail: ''.
+	self assert: self identifier fail: '1'.
+	self assert: self identifier fail: '1a'
+!
+
+testNumber
+	self assert: self number parse: '1' to: '1'.
+	self assert: self number parse: '12' to: '12'.
+	self assert: self number parse: '12.3' to: '12.3'.
+	self assert: self number parse: '12.34' to: '12.34'.
+
+	self assert: self number parse: '1..' to: '1' end: 1.
+	self assert: self number parse: '12-' to: '12' end: 2.
+	self assert: self number parse: '12.3.' to: '12.3' end: 4.
+	self assert: self number parse: '12.34.' to: '12.34' end: 5.
+	
+	self assert: self number parse: '-1' to: '-1'.
+	self assert: self number parse: '-12' to: '-12'.
+	self assert: self number parse: '-12.3' to: '-12.3'.
+	self assert: self number parse: '-12.34' to: '-12.34'.
+	
+	self assert: self number fail: ''.
+	self assert: self number fail: '-'.
+	self assert: self number fail: '.'.
+	self assert: self number fail: '.1'
+!
+
+testReturn
+	| number spaces return |
+	number := #digit asParser plus flatten.
+	spaces := #space asParser star.
+	return := (spaces , $^ asParser token , spaces , number)
+		==> [ :nodes | Array with: #return with: (nodes at: 4) ].
+
+	self assert: return parse: '^1' to: #(return '1').
+	self assert: return parse: '^12' to: #(return '12').
+	self assert: return parse: '^ 123' to: #(return '123').
+	self assert: return parse: '^  1234' to: #(return '1234').
+	
+	self assert: return fail: '1'.
+	self assert: return fail: '^'
+! !
+
+!PPComposedTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPComposedTest.st,v 1.5 2014-03-04 14:34:10 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPComposedTest.st,v 1.5 2014-03-04 14:34:10 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPComposedTest.st,v 1.5 2014-03-04 14:34:10 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPExpressionParserTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,86 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPArithmeticParserTest subclass:#PPExpressionParserTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPExpressionParserTest class methodsFor:'testing'!
+
+shouldInheritSelectors
+	^ true
+! !
+
+!PPExpressionParserTest methodsFor:'accessing'!
+
+parserInstance
+	| expression parens number |
+	expression := PPExpressionParser new.
+	parens := $( asParser trim , expression , $) asParser trim
+		==> [ :value | value second ].
+	number := (#digit asParser plus , ($. asParser , #digit asParser plus) optional) flatten trim
+		==> [ :value | value asNumber ].
+	expression term: parens / number.
+	expression
+		group: [ :g |
+			g prefix: $- asParser trim do: [ :op :a | a negated ] ];
+		group: [ :g |
+			g postfix: '++' asParser trim do: [ :a :op | a + 1 ].
+			g postfix: '--' asParser trim do: [ :a :op | a - 1 ] ];
+		group: [ :g |
+			g right: $^ asParser trim do: [ :a :op :b | a raisedTo: b ] ];
+		group: [ :g |
+			g left: $* asParser trim do: [ :a :op :b | a * b ].
+			g left: $/ asParser trim do: [ :a :op :b | a / b ] ];
+		group: [ :g |
+			g left: $+ asParser trim do: [ :a :op :b | a + b ].
+			g left: $- asParser trim do: [ :a :op :b | a - b ] ].
+	^ expression end
+! !
+
+!PPExpressionParserTest methodsFor:'testing'!
+
+testPostfixAdd
+	self assert: '0++' is: 1.
+	self assert: '0++++' is: 2.
+	self assert: '0++++++' is: 3.
+
+	self assert: '0+++1' is: 2.
+	self assert: '0+++++1' is: 3.
+	self assert: '0+++++++1' is: 4
+!
+
+testPostfixSub
+	self assert: '1--' is: 0.
+	self assert: '2----' is: 0.
+	self assert: '3------' is: 0.
+
+	self assert: '2---1' is: 0.
+	self assert: '3-----1' is: 0.
+	self assert: '4-------1' is: 0.
+!
+
+testPrefixNegate
+	self assert: '1' is: 1.
+	self assert: '-1' is: -1.
+	self assert: '--1' is: 1.
+	self assert: '---1' is: -1
+! !
+
+!PPExpressionParserTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExpressionParserTest.st,v 1.4 2014-03-04 14:34:13 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExpressionParserTest.st,v 1.4 2014-03-04 14:34:13 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPExpressionParserTest.st,v 1.4 2014-03-04 14:34:13 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPExtensionTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,154 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPExtensionTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPExtensionTest methodsFor:'testing-parser'!
+
+testCharacter
+	| parser |
+	parser := $a asParser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser fail: 'b'
+!
+
+testChoice
+	| parser |
+	parser := #(1 2) asChoiceParser.
+	self assert: parser parse: #(1) to: 1.
+	self assert: parser parse: #(2) to: 2.
+	self assert: parser parse: #(1 2) to: 1 end: 1.
+	self assert: parser parse: #(2 1) to: 2 end: 1.
+	self assert: parser fail: #().
+	self assert: parser fail: #(3)
+!
+
+testClosure
+	| parser |
+	parser := [ :stream | stream upTo: $s ] asParser.
+	self assert: parser parse: '' to: ''.
+	self assert: parser parse: 'a' to: 'a'.
+	self assert: parser parse: 'aa' to: 'aa'.
+	self assert: parser parse: 's' to: ''.
+	self assert: parser parse: 'as' to: 'a'.
+	self assert: parser parse: 'aas' to: 'aa'.
+	self assert: parser parse: 'sa' to: '' end: 1.
+	self assert: parser parse: 'saa' to: '' end: 1.
+	
+	parser := [ :stream | stream upTo: $s. PPFailure message: 'stream' at: stream position ] asParser.
+	self assert: parser fail: ''.
+	self assert: parser fail: 's'.
+	self assert: parser fail: 'as'
+	
+!
+
+testEpsilon
+	| parser |
+	parser := nil asParser.
+	self assert: parser asParser = parser
+!
+
+testOrdered
+	| parser |
+	parser := #(1 2) asParser.
+	self assert: parser parse: #(1 2) to: #(1 2).
+	self assert: parser parse: #(1 2 3) to: #(1 2) end: 2.
+	self assert: parser fail: #().
+	self assert: parser fail: #(1).
+	self assert: parser fail: #(1 1).
+	self assert: parser fail: #(1 1 2)
+!
+
+testParser
+	| parser |
+	parser := $a asParser.
+	self assert: parser asParser = parser
+!
+
+testRange
+        | parser |
+        parser := ($a to: $c) asParser.
+        self assert: parser parse: 'a' to: $a.
+        self assert: parser parse: 'b' to: $b.
+        self assert: parser parse: 'c' to: $c.
+        self assert: parser fail: 'd'
+!
+
+testSequence
+	| parser |
+	parser := #(1 2) asSequenceParser.
+	self assert: parser parse: #(1 2) to: #(1 2).
+	self assert: parser parse: #(1 2 3) to: #(1 2) end: 2.
+	self assert: parser fail: #().
+	self assert: parser fail: #(1).
+	self assert: parser fail: #(1 1).
+	self assert: parser fail: #(1 1 2)
+!
+
+testString
+	| parser |
+	parser := 'ab' asParser.
+	self assert: parser parse: 'ab' to: 'ab'.
+	self assert: parser parse: 'aba' to: 'ab' end: 2.
+	self assert: parser parse: 'abb' to: 'ab' end: 2.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'ac'
+!
+
+testSymbol
+	| parser |
+	parser := #any asParser.
+	self assert: parser parse: 'a'.
+	self assert: parser fail: ''
+!
+
+testUnordered
+	| parser |
+	parser := #(1 2) asSet asParser.
+	self assert: parser parse: #(1) to: 1.
+	self assert: parser parse: #(2) to: 2.
+	self assert: parser parse: #(1 2) to: 1 end: 1.
+	self assert: parser parse: #(2 1) to: 2 end: 1.
+	self assert: parser fail: #().
+	self assert: parser fail: #(3)
+! !
+
+!PPExtensionTest methodsFor:'testing-stream'!
+
+testStream
+	| stream |
+	stream := 'abc' readStream asPetitStream.
+	self assert: (stream class = PPStream).
+	self assert: (stream printString = '·abc').
+	self assert: (stream peek) = $a.
+	self assert: (stream uncheckedPeek = $a).
+	self assert: (stream next) = $a.
+	self assert: (stream printString = 'a·bc').
+	self assert: (stream asPetitStream = stream)
+!
+
+testText
+	| stream |
+	stream := 'abc' asText asPetitStream.
+	self assert: stream class = PPStream
+! !
+
+!PPExtensionTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExtensionTest.st,v 1.4 2014-03-04 14:34:17 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExtensionTest.st,v 1.4 2014-03-04 14:34:17 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPExtensionTest.st,v 1.4 2014-03-04 14:34:17 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPLambdaParser.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,74 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPCompositeParser subclass:#PPLambdaParser
+	instanceVariableNames:'expression abstraction application variable'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Examples'
+!
+
+
+!PPLambdaParser class methodsFor:'curch-booleans'!
+
+and
+	^ self parse: '\p.\q.((p q) p)'
+!
+
+false
+	^ self parse: '\x.\y.y'
+!
+
+ifthenelse
+	^ self parse: '\p.p'
+!
+
+not
+	^ self parse: '\p.\a.\b.((p b) a)'
+!
+
+or
+	^ self parse: '\p.\q.((p p) q)'
+!
+
+true
+	^ self parse: '\x.\y.x'
+! !
+
+!PPLambdaParser methodsFor:'accessing'!
+
+start
+	^ expression end
+! !
+
+!PPLambdaParser methodsFor:'productions'!
+
+abstraction
+	^ $\ asParser trim , variable , $. asParser trim , expression ==> [ :node | Array with: node second with: node fourth ]
+!
+
+application
+	^ $( asParser trim , expression , expression , $) asParser trim ==> [ :node | Array with: node second with: node third ]
+!
+
+expression
+	^ variable / abstraction / application
+!
+
+variable
+	^ (#letter asParser , #word asParser star) flatten trim
+! !
+
+!PPLambdaParser class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParser.st,v 1.4 2014-03-04 14:34:00 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParser.st,v 1.4 2014-03-04 14:34:00 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPLambdaParser.st,v 1.4 2014-03-04 14:34:00 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPLambdaParserTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,158 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPCompositeParserTest subclass:#PPLambdaParserTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPLambdaParserTest methodsFor:'accessing'!
+
+parserClass
+	^ PPLambdaParser
+! !
+
+!PPLambdaParserTest methodsFor:'testing'!
+
+testAbstraction
+	self assert: '\x.y' is: #('x' 'y').
+	self assert: '\x.\y.z' is: #('x' ('y' 'z'))
+!
+
+testApplication
+	self assert: '(x x)' is: #('x' 'x').
+	self assert: '(x y)' is: #('x' 'y').
+	self assert: '((x y) z)' is: #(('x' 'y') 'z').
+	self assert: '(x (y z))' is: #('x' ('y' 'z'))
+!
+
+testVariable
+	self assert: 'x' is: 'x'.
+	self assert: 'xy' is: 'xy'.
+	self assert: 'x12' is: 'x12'
+! !
+
+!PPLambdaParserTest methodsFor:'testing-curch'!
+
+testAnd
+	self assert: self parserClass and = #('p' ('q' (('p' 'q') 'p')))
+!
+
+testFalse
+	self assert: self parserClass false = #('x' ('y' 'y'))
+!
+
+testIfThenElse
+	self assert: self parserClass ifthenelse = #('p' 'p')
+!
+
+testNot
+	self assert: self parserClass not = #('p' ('a' ('b' (('p' 'b') 'a'))))
+!
+
+testOr
+	self assert: self parserClass or = #('p' ('q' (('p' 'p') 'q')))
+!
+
+testTrue
+	self assert: self parserClass true = #('x' ('y' 'x'))
+! !
+
+!PPLambdaParserTest methodsFor:'testing-utilities'!
+
+testParseOnError
+	| beenHere |
+	result := self parserClass
+		parse: '\x.y'
+		onError: [ self fail ].
+	self assert: result = #('x' 'y').
+
+	beenHere := false.
+	result := self parserClass
+		parse: '\x.'
+		onError: [ beenHere := true ].
+	self assert: beenHere.
+
+	beenHere := false.
+	result := self parserClass
+		parse: '\x.'
+		onError: [ :fail | beenHere := true. fail ].
+	self assert: beenHere.
+	self assert: (result message findString: '$(') > 0.
+	self assert: (result message findString: 'expected') > 0.
+	self assert: (result position = 0).
+
+	beenHere := false.
+	result := self parserClass
+		parse: '\x.'
+		onError: [ :msg :pos | 
+			self assert: (msg findString: '$(') > 0.
+			self assert: (msg findString: 'expected') > 0.
+			self assert: (pos = 0).
+			beenHere := true ].
+	self assert: result.
+	self assert: beenHere
+!
+
+testParseStartingAtOnError
+	| beenHere |
+	result := self parserClass
+		parse: 'x'
+		startingAt: #variable
+		onError: [ self fail ].
+	self assert: result = 'x'.
+	
+	beenHere := false.
+	result := self parserClass
+		parse: '\'
+		startingAt: #variable
+		onError: [ beenHere := true ].
+	self assert: beenHere.
+	
+	beenHere := false.
+	result := self parserClass
+		parse: '\'
+		startingAt: #variable
+		onError: [ :fail | beenHere := true. fail ].
+	self assert: beenHere.
+	self assert: result message = 'letter expected'.
+	self assert: result position = 0.
+
+	beenHere := false.
+	result := self parserClass
+		parse: '\'
+		startingAt: #variable
+		onError: [ :msg :pos | 
+			self assert: msg = 'letter expected'.
+			self assert: pos = 0.
+			beenHere := true ].
+	self assert: beenHere
+!
+
+testProductionAt
+	self assert: (parser productionAt: #foo) isNil.
+	self assert: (parser productionAt: #foo ifAbsent: [ true ]).
+	
+	self assert: (parser productionAt: #start) notNil.
+	self assert: (parser productionAt: #start ifAbsent: [ true ]) notNil.
+	
+	self assert: (parser productionAt: #variable) notNil.
+	self assert: (parser productionAt: #variable ifAbsent: [ true ]) notNil
+! !
+
+!PPLambdaParserTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParserTest.st,v 1.4 2014-03-04 14:34:18 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPLambdaParserTest.st,v 1.4 2014-03-04 14:34:18 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPLambdaParserTest.st,v 1.4 2014-03-04 14:34:18 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPMappingTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,93 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParseTest subclass:#PPMappingTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPMappingTest methodsFor:'testing'!
+
+testFoldLeft2
+	| parser |
+	parser := #any asParser star 
+		foldLeft: [ :a :b | Array with: a with: b ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b) to: #(a b).
+	self assert: parser parse: #(a b c) to: #((a b) c).
+	self assert: parser parse: #(a b c d) to: #(((a b) c) d).
+	self assert: parser parse: #(a b c d e) to: #((((a b) c) d) e)
+!
+
+testFoldLeft3
+	| parser |
+	parser := #any asParser star 
+		foldLeft: [ :a :b :c | Array with: a with: b with: c ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b c) to: #(a b c).
+	self assert: parser parse: #(a b c d e) to: #((a b c) d e)
+!
+
+testFoldRight2
+	| parser |
+	parser := #any asParser star 
+		foldRight: [ :a :b | Array with: a with: b ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b) to: #(a b).
+	self assert: parser parse: #(a b c) to: #(a (b c)).
+	self assert: parser parse: #(a b c d) to: #(a (b (c d))).
+	self assert: parser parse: #(a b c d e) to: #(a (b (c (d e))))
+!
+
+testFoldRight3
+	| parser |
+	parser := #any asParser star 
+		foldRight: [ :a :b :c | Array with: a with: b with: c ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b c) to: #(a b c).
+	self assert: parser parse: #(a b c d e) to: #(a b (c d e))
+!
+
+testMap1
+	| parser |
+	parser := #any asParser 
+		map: [ :a | Array with: a ].
+
+	self assert: parser parse: #(a) to: #(a)
+!
+
+testMap2
+	| parser |
+	parser := (#any asParser , #any asParser) 
+		map: [ :a :b | Array with: b with: a ].
+
+	self assert: parser parse: #(a b) to: #(b a)
+!
+
+testMap3
+	| parser |
+	parser := (#any asParser , #any asParser , #any asParser)
+		map: [ :a :b :c | Array with: c with: b with: a ].
+
+	self assert: parser parse: #(a b c) to: #(c b a)
+! !
+
+!PPMappingTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPMappingTest.st,v 1.3 2012-05-04 22:03:40 vrany Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPMappingTest.st,v 1.3 2012-05-04 22:03:40 vrany Exp $'
+!
+
+version_SVN
+    ^ '§Id: PPMappingTest.st 4 2010-12-18 17:02:23Z kursjan §'
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPObjectTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,94 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPObjectTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPObjectTest methodsFor:'parsers'!
+
+integer
+	^ PPPredicateObjectParser
+		on: [ :each | each isInteger ]
+		message: 'integer expected'
+!
+
+string
+	^ PPPredicateObjectParser
+		on: [ :each | each isString ]
+		message: 'string expected'
+! !
+
+!PPObjectTest methodsFor:'testing'!
+
+testInteger
+	self assert: self integer parse: #(123) to: 123.
+	self assert: self integer fail: #('abc')
+!
+
+testString
+	self assert: self string parse: #('abc') to: 'abc'.
+	self assert: self string fail: #(123)
+! !
+
+!PPObjectTest methodsFor:'testing-fancy'!
+
+testFibonacci
+	"This parser accepts fibonacci sequences with arbitrary start pairs."
+	
+	| parser |
+	parser := ((self integer , self integer) end ==> [ :pair | pair first + pair last ])
+		/ (self integer , (self integer , self integer) and >=> [ :stream :continuation |
+			| result |
+			result := continuation value.
+			(result isPetitFailure or: [ result first + result last first ~= result last last ])
+				ifFalse: [ parser parseOn: stream ]
+				ifTrue: [ PPFailure message: 'invalid fibonacci sequence' at: stream position ] ]).
+	self assert: parser parse: #(1 1) to: 2.
+	self assert: parser parse: #(1 1 2) to: 3.
+	self assert: parser parse: #(1 1 2 3) to: 5.
+	self assert: parser parse: #(1 1 2 3 5) to: 8.
+	self assert: parser parse: #(1 1 2 3 5 8) to: 13.
+	self assert: parser parse: #(1 1 2 3 5 8 13) to: 21.
+	self assert: parser fail: #().
+	self assert: parser fail: #(1).
+	self assert: parser fail: #(1 2 3 4) end: 2
+	
+! !
+
+!PPObjectTest methodsFor:'testing-operators'!
+
+testChoice
+	| parser |
+	parser := self integer / self string.
+	self assert: parser parse: #(123) to: 123.
+	self assert: parser parse: #('abc') to: 'abc'
+!
+
+testSequence
+	| parser |
+	parser := self integer , self string.
+	self assert: parser parse: #(123 'abc') to: #(123 'abc').
+	self assert: parser fail: #(123 456).
+	self assert: parser fail: #('abc' 'def').
+	self assert: parser fail: #('abc' 123)
+	
+! !
+
+!PPObjectTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPObjectTest.st,v 1.4 2014-03-04 14:34:19 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPParserResource.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,38 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+TestResource subclass:#PPParserResource
+	instanceVariableNames:'parsers'
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Core'
+!
+
+
+!PPParserResource methodsFor:'accessing'!
+
+parserAt: aParserClass
+	"Answer a cached instance of aParserClass."
+	
+	^ parsers at: aParserClass name ifAbsentPut: [ aParserClass new ]
+! !
+
+!PPParserResource methodsFor:'running'!
+
+setUp
+	super setUp.
+	parsers := Dictionary new
+! !
+
+!PPParserResource class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserResource.st,v 1.3 2012-05-04 22:09:18 vrany Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserResource.st,v 1.3 2012-05-04 22:09:18 vrany Exp $'
+!
+
+version_SVN
+    ^ '§Id: PPParserResource.st 4 2010-12-18 17:02:23Z kursjan §'
+! !
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPParserTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,1372 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPParserTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPParserTest methodsFor:'testing'!
+
+testAnd
+	| parser |
+	parser := 'foo' asParser flatten , 'bar' asParser flatten and.
+	
+	self assert: parser parse: 'foobar' to: #('foo' 'bar') end: 3.
+	self assert: parser fail: 'foobaz'.
+	
+	parser := 'foo' asParser and.
+	self assert: parser and = parser
+!
+
+testBlock
+	| parser |
+	parser := [ :s | s next ] asParser.
+	
+	self assert: parser parse: 'ab' to: $a end: 1.
+	self assert: parser parse: 'b' to: $b.
+	self assert: parser parse: '' to: nil
+!
+
+testChoice
+	| parser |
+	parser := $a asParser / $b asParser.
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'b' to: $b.
+
+	self assert: parser parse: 'ab' to: $a end: 1.
+	self assert: parser parse: 'ba' to: $b end: 1.
+
+	self assert: parser fail: ''.
+	self assert: parser fail: 'c'.
+	self assert: parser fail: 'ca'
+!
+
+testDelimitedBy
+	| parser |
+	parser := $a asParser delimitedBy: $b asParser.
+	
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aba' to: #($a $b $a).
+	self assert: parser parse: 'ababa' to: #($a $b $a $b $a).
+
+	self assert: parser parse: 'ab' to: #($a $b).
+	self assert: parser parse: 'abab' to: #($a $b $a $b).
+	self assert: parser parse: 'ababab' to: #($a $b $a $b $a $b).
+	
+	self assert: parser parse: 'ac' to: #($a) end: 1.
+	self assert: parser parse: 'abc' to: #($a $b) end: 2.
+	self assert: parser parse: 'abac' to: #($a $b $a) end: 3.
+	self assert: parser parse: 'ababc' to: #($a $b $a $b) end: 4.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'c'
+!
+
+testDelimitedByWithoutSeparators
+	| parser |
+	parser := ($a asParser delimitedBy: $b asParser)
+		withoutSeparators.
+	
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aba' to: #($a $a).
+	self assert: parser parse: 'ababa' to: #($a $a $a).
+
+	self assert: parser parse: 'ab' to: #($a).
+	self assert: parser parse: 'abab' to: #($a $a).
+	self assert: parser parse: 'ababab' to: #($a $a $a).
+	
+	self assert: parser parse: 'ac' to: #($a) end: 1.
+	self assert: parser parse: 'abc' to: #($a) end: 2.
+	self assert: parser parse: 'abac' to: #($a $a) end: 3.
+	self assert: parser parse: 'ababc' to: #($a $a) end: 4.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'c'
+!
+
+testEndOfInput
+	| parser |
+	parser := PPEndOfInputParser on: $a asParser.
+	self assert: parser end = parser.
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'aa'
+!
+
+testEndOfInputAfterMatch
+	| parser |
+	parser := 'stuff' asParser end.
+	self assert: parser parse: 'stuff' to: 'stuff'.
+	self assert: parser fail: 'stufff'.
+	self assert: parser fail: 'fluff'
+!
+
+testEpsilon
+	| parser |
+	parser := nil asParser.
+	
+	self assert: parser parse: '' to: nil.
+	
+	self assert: parser parse: 'a' to: nil end: 0.
+	self assert: parser parse: 'ab' to: nil end: 0
+!
+
+testFailing
+	| parser result |
+	parser := PPFailingParser message: 'Plonk'.
+	self assert: parser message = 'Plonk'.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'aa'.
+	
+	result := parser parse: 'a'.
+	self assert: result message = 'Plonk'.
+	self assert: result printString = 'Plonk at 0'
+!
+
+testLiteralObject
+	| parser |
+	parser := PPLiteralObjectParser 
+		on: $a
+		message: 'letter "a" expected'.
+	self assert: parser literal = $a.
+	self assert: parser message = 'letter "a" expected'.
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser fail: 'b'
+	
+!
+
+testLiteralObjectCaseInsensitive
+	| parser |
+	parser := $a asParser caseInsensitive.
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'A' to: $A.
+
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'B'
+	
+!
+
+testLiteralSequence
+	| parser |
+	parser := PPLiteralSequenceParser 
+		on: 'abc'
+		message: 'sequence "abc" expected'.
+	self assert: parser size = 3.
+	self assert: parser literal = 'abc'.
+	self assert: parser message = 'sequence "abc" expected'.
+	
+	self assert: parser parse: 'abc' to: 'abc'.
+	self assert: parser fail: 'ab'.
+	self assert: parser fail: 'abd'
+!
+
+testLiteralSequenceCaseInsensitive
+	| parser |
+	parser := 'abc' asParser caseInsensitive.
+	
+	self assert: parser parse: 'abc' to: 'abc'.
+	self assert: parser parse: 'ABC' to: 'ABC'.
+	self assert: parser parse: 'abC' to: 'abC'.
+	self assert: parser parse: 'AbC' to: 'AbC'.
+	
+	self assert: parser fail: 'ab'.
+	self assert: parser fail: 'abd'
+!
+
+testMax
+	| parser |
+	parser := $a asParser max: 2.
+	self assert: parser min = 0.
+	self assert: parser max = 2.
+
+	self assert: parser parse: '' to: #().
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aa' to: #($a $a).
+	self assert: parser parse: 'aaa' to: #($a $a) end: 2.
+	self assert: parser parse: 'aaaa' to: #($a $a) end: 2.
+	
+	self assert: (parser printString endsWith: '[0, 2]')
+!
+
+testMaxGreedy
+	| parser |
+	parser := #word asParser max: 2 greedy: #digit asParser.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'abc'.
+	
+	self assert: parser parse: '1' to: #() end: 0.
+	self assert: parser parse: 'a1' to: #($a) end: 1.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser fail: 'abc1'.
+	
+	self assert: parser parse: '12' to: #($1) end: 1.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
+	self assert: parser fail: 'abc12'.
+	
+	self assert: parser parse: '123' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a123' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
+	self assert: parser fail: 'abc123'
+!
+
+testMaxLazy
+	| parser |
+	parser := #word asParser max: 2 lazy: #digit asParser.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'abc'.
+	
+	self assert: parser parse: '1' to: #() end: 0.
+	self assert: parser parse: 'a1' to: #($a) end: 1.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser fail: 'abc1'.
+	
+	self assert: parser parse: '12' to: #() end: 0.
+	self assert: parser parse: 'a12' to: #($a) end: 1.
+	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
+	self assert: parser fail: 'abc12'.
+	
+	self assert: parser parse: '123' to: #() end: 0.
+	self assert: parser parse: 'a123' to: #($a) end: 1.
+	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
+	self assert: parser fail: 'abc123'
+!
+
+testMemoized
+	| count parser twice |
+	count := 0.
+	parser := [ :s | count := count + 1. s next ] asParser memoized.
+	twice := parser and , parser.
+	
+	count := 0.
+	self assert: parser parse: 'a' to: $a.
+	self assert: count = 1.
+
+	count := 0.
+	self assert: twice parse: 'a' to: #($a $a).
+	self assert: count = 1.
+	
+	self assert: parser memoized = parser
+!
+
+testMin
+	| parser |
+	parser := $a asParser min: 2.
+	self assert: parser min = 2.
+	self assert: parser max > parser min.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser parse: 'aa' to: #($a $a).
+	self assert: parser parse: 'aaa' to: #($a $a $a).
+	self assert: parser parse: 'aaaa' to: #($a $a $a $a).
+	
+	self assert: (parser printString endsWith: '[2, *]')
+!
+
+testMinGreedy
+	| parser |
+	parser := #word asParser min: 2 greedy: #digit asParser.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'abcde'.
+	
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a1'.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
+	self assert: parser parse: 'abcde1' to: #($a $b $c $d $e) end: 5.
+	
+	self assert: parser fail: '12'.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
+	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
+	self assert: parser parse: 'abcd12' to: #($a $b $c $d $1) end: 5.
+	self assert: parser parse: 'abcde12' to: #($a $b $c $d $e $1) end: 6.
+	
+	self assert: parser parse: '123' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
+	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
+	self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5.
+	self assert: parser parse: 'abcd123' to: #($a $b $c $d $1 $2) end: 6.
+	self assert: parser parse: 'abcde123' to: #($a $b $c $d $e $1 $2) end: 7.
+	
+	self assert: parser parse: '1234' to: #($1 $2 $3) end: 3.
+	self assert: parser parse: 'a1234' to: #($a $1 $2 $3) end: 4.
+	self assert: parser parse: 'ab1234' to: #($a $b $1 $2 $3) end: 5.
+	self assert: parser parse: 'abc1234' to: #($a $b $c $1 $2 $3) end: 6.
+	self assert: parser parse: 'abcd1234' to: #($a $b $c $d $1 $2 $3) end: 7.
+	self assert: parser parse: 'abcde1234' to: #($a $b $c $d $e $1 $2 $3) end: 8
+!
+
+testMinLazy
+	| parser |
+	parser := #word asParser min: 2 lazy: #digit asParser.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'abcde'.
+	
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a1'.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
+	self assert: parser parse: 'abcde1' to: #($a $b $c $d $e) end: 5.
+	
+	self assert: parser fail: '12'.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4.
+	self assert: parser parse: 'abcde12' to: #($a $b $c $d $e) end: 5.
+	
+	self assert: parser parse: '123' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a123' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4.
+	self assert: parser parse: 'abcde123' to: #($a $b $c $d $e) end: 5.
+	
+	self assert: parser parse: '1234' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a1234' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab1234' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1234' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4.
+	self assert: parser parse: 'abcde1234' to: #($a $b $c $d $e) end: 5
+!
+
+testMinMax
+	| parser |
+	parser := $a asParser min: 2 max: 4.
+	self assert: parser min = 2.
+	self assert: parser max = 4.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser parse: 'aa' to: #($a $a).
+	self assert: parser parse: 'aaa' to: #($a $a $a).
+	self assert: parser parse: 'aaaa' to: #($a $a $a $a).
+	self assert: parser parse: 'aaaaa' to: #($a $a $a $a) end: 4.
+	self assert: parser parse: 'aaaaaa' to: #($a $a $a $a) end: 4.
+	
+	self assert: (parser printString endsWith: '[2, 4]')
+!
+
+testMinMaxGreedy
+	| parser |
+	parser := #word asParser min: 2 max: 4 greedy: #digit asParser.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'abcde'.
+	
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a1'.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde1'.
+	
+	self assert: parser fail: '12'.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
+	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
+	self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde12'.
+	
+	self assert: parser parse: '123' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
+	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
+	self assert: parser parse: 'abc123' to: #($a $b $c $1) end: 4.
+	self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde123'.
+	
+	self assert: parser parse: '1234' to: #($1 $2 $3) end: 3.
+	self assert: parser parse: 'a1234' to: #($a $1 $2 $3) end: 4.
+	self assert: parser parse: 'ab1234' to: #($a $b $1 $2) end: 4.
+	self assert: parser parse: 'abc1234' to: #($a $b $c $1) end: 4.
+	self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde1234'
+!
+
+testMinMaxLazy
+	| parser |
+	parser := #word asParser min: 2 max: 4 lazy: #digit asParser.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'abcde'.
+	
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a1'.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd1' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde1'.
+	
+	self assert: parser fail: '12'.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd12' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde12'.
+	
+	self assert: parser parse: '123' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a123' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd123' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde123'.
+	
+	self assert: parser parse: '1234' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a1234' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab1234' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1234' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'abcd1234' to: #($a $b $c $d) end: 4.
+	self assert: parser fail: 'abcde1234'
+!
+
+testNegate
+	| parser |
+	parser := 'foo' asParser negate.
+	
+	self assert: parser parse: 'f' to: $f end: 1.
+	self assert: parser parse: 'fo' to: $f end: 1.
+	self assert: parser parse: 'fob' to: $f end: 1.
+	self assert: parser parse: 'ffoo' to: $f end: 1.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'foo'
+!
+
+testNot
+	| parser |
+	parser := 'foo' asParser flatten , 'bar' asParser flatten not.
+	
+	self assert: parser parse: 'foobaz' to: #('foo' nil) end: 3.
+	self assert: parser fail: 'foobar'
+!
+
+testOptional
+	| parser |
+	parser := $a asParser optional.
+	
+	self assert: parser parse: '' to: nil.
+	self assert: parser parse: 'a' to: $a.
+	
+	self assert: parser parse: 'aa' to: $a end: 1.
+	self assert: parser parse: 'ab' to: $a end: 1.
+	self assert: parser parse: 'b' to: nil end: 0.
+	self assert: parser parse: 'bb' to: nil end: 0.
+	self assert: parser parse: 'ba' to: nil end: 0
+!
+
+testPluggable
+	| block parser |
+	block := [ :stream | stream position ].
+	parser := block asParser.
+	self assert: parser block = block
+!
+
+testPlus
+	| parser |
+	parser := $a asParser plus.
+	
+	self assert: parser min = 1.
+	self assert: parser max > parser min.
+	
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aa' to: #($a $a).
+	self assert: parser parse: 'aaa' to: #($a $a $a).
+	
+	self assert: parser parse: 'ab' to: #($a) end: 1.
+	self assert: parser parse: 'aab' to: #($a $a) end: 2.
+	self assert: parser parse: 'aaab' to: #($a $a $a) end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'ba'
+!
+
+testPlusGreedy
+	| limit parser |
+	limit := #digit asParser.
+	parser := #word asParser plusGreedy: limit.
+	
+	self assert: parser min = 1.
+	self assert: parser max > parser min.	
+	self assert: parser limit = limit.
+	self assert: parser children size = 2.
+	self assert: parser children last = limit.
+
+	self assert: parser fail: ''.
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'ab'.
+
+	self assert: parser parse: 'a1' to: #($a) end: 1.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
+	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
+	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
+	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
+	self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5.
+!
+
+testPlusLazy
+	| limit parser |
+	limit := #digit asParser.
+	parser := #word asParser plusLazy: limit.
+	
+	self assert: parser min = 1.
+	self assert: parser max > parser min.	
+	self assert: parser limit = limit.
+	self assert: parser children size = 2.
+	self assert: parser children last = limit.
+
+	self assert: parser fail: ''.
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'ab'.
+
+	self assert: parser parse: 'a1' to: #($a) end: 1.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'a12' to: #($a) end: 1.
+	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
+	self assert: parser parse: 'a123' to: #($a) end: 1.
+	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3
+!
+
+testSeparatedBy
+	| parser |
+	parser := $a asParser separatedBy: $b asParser.
+	
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aba' to: #($a $b $a).
+	self assert: parser parse: 'ababa' to: #($a $b $a $b $a).
+	
+	self assert: parser parse: 'ab' to: #($a) end: 1.
+	self assert: parser parse: 'abab' to: #($a $b $a) end: 3.
+	self assert: parser parse: 'ac' to: #($a) end: 1.
+	self assert: parser parse: 'abac' to: #($a $b $a) end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'c'
+!
+
+testSeparatedByWithoutSeparators
+	| parser |
+	parser := ($a asParser separatedBy: $b asParser)
+		withoutSeparators.
+	
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aba' to: #($a $a).
+	self assert: parser parse: 'ababa' to: #($a $a $a).
+	
+	self assert: parser parse: 'ab' to: #($a) end: 1.
+	self assert: parser parse: 'abab' to: #($a $a) end: 3.
+	self assert: parser parse: 'ac' to: #($a) end: 1.
+	self assert: parser parse: 'abac' to: #($a $a) end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'c'
+!
+
+testSequence
+	| parser |
+	parser := $a asParser , $b asParser.
+	
+	self assert: parser parse: 'ab' to: #($a $b).
+	
+	self assert: parser parse: 'aba' to: #($a $b) end: 2.
+	self assert: parser parse: 'abb' to: #($a $b) end: 2.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'aa'.
+	self assert: parser fail: 'ba'.
+	self assert: parser fail: 'bab'
+!
+
+testStar
+	| parser |
+	parser := $a asParser star.
+	
+	self assert: parser min = 0.
+	self assert: parser max > parser min.
+	
+	self assert: parser parse: '' to: #().
+	self assert: parser parse: 'a' to: #($a).
+	self assert: parser parse: 'aa' to: #($a $a).
+	self assert: parser parse: 'aaa' to: #($a $a $a).
+	
+	self assert: parser parse: 'b' to: #() end: 0.
+	self assert: parser parse: 'ab' to: #($a) end: 1.
+	self assert: parser parse: 'aab' to: #($a $a) end: 2.
+	self assert: parser parse: 'aaab' to: #($a $a $a) end: 3
+!
+
+testStarGreedy
+	| limit parser |
+	limit := #digit asParser.
+	parser := #word asParser starGreedy: limit.
+	
+	self assert: parser min = 0.
+	self assert: parser max > parser min.
+	self assert: parser limit = limit.
+	self assert: parser children size = 2.
+	self assert: parser children last = limit.
+
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'ab'.
+
+	self assert: parser parse: '1' to: #() end: 0.
+	self assert: parser parse: 'a1' to: #($a) end: 1.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: '12' to: #($1) end: 1.
+	self assert: parser parse: 'a12' to: #($a $1) end: 2.
+	self assert: parser parse: 'ab12' to: #($a $b $1) end: 3.
+	self assert: parser parse: 'abc12' to: #($a $b $c $1) end: 4.
+	self assert: parser parse: '123' to: #($1 $2) end: 2.
+	self assert: parser parse: 'a123' to: #($a $1 $2) end: 3.
+	self assert: parser parse: 'ab123' to: #($a $b $1 $2) end: 4.
+	self assert: parser parse: 'abc123' to: #($a $b $c $1 $2) end: 5
+!
+
+testStarLazy
+	| limit parser |
+	limit := #digit asParser.
+	parser := #word asParser starLazy: limit.
+	
+	self assert: parser min = 0.
+	self assert: parser max > parser min.
+	self assert: parser limit = limit.
+	self assert: parser children size = 2.
+	self assert: parser children last = limit.
+
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: 'ab'.
+
+	self assert: parser parse: '1' to: #() end: 0.
+	self assert: parser parse: 'a1' to: #($a) end: 1.
+	self assert: parser parse: 'ab1' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc1' to: #($a $b $c) end: 3.
+	self assert: parser parse: '12' to: #() end: 0.
+	self assert: parser parse: 'a12' to: #($a) end: 1.
+	self assert: parser parse: 'ab12' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc12' to: #($a $b $c) end: 3.
+	self assert: parser parse: '123' to: #() end: 0.
+	self assert: parser parse: 'a123' to: #($a) end: 1.
+	self assert: parser parse: 'ab123' to: #($a $b) end: 2.
+	self assert: parser parse: 'abc123' to: #($a $b $c) end: 3
+!
+
+testTimes
+	| parser |
+	parser := $a asParser times: 2.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser parse: 'aa' to: #($a $a).
+	self assert: parser parse: 'aaa' to: #($a $a) end: 2
+!
+
+testUnresolved
+	| parser |
+	parser := PPUnresolvedParser new.
+	
+	self assert: parser isUnresolved.
+	self should: [ parser parse: '' ] raise: Error.
+	self should: [ parser parse: 'a' ] raise: Error.
+	self should: [ parser parse: 'ab' ] raise: Error.
+	
+	parser := nil asParser.
+	self deny: parser isUnresolved
+!
+
+testWrapped
+	| parser |
+	parser := $a asParser wrapped.
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser fail: 'b'.
+	
+	parser := (($a asParser , $b asParser ) wrapped , $c asParser).
+	self assert: parser parse: 'abc' to: #(#($a $b) $c)
+!
+
+testXor
+	| parser |
+	parser := ($a asParser / $b asParser)
+			|  ($b asParser / $c asParser).
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'c' to: $c.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'd'.
+	
+	" truly symmetric "
+	parser := ($b asParser / $c asParser)
+			|  ($a asParser / $b asParser).
+	
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'c' to: $c.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: 'd'
+! !
+
+!PPParserTest methodsFor:'testing-accessing'!
+
+testNamed
+	| parser |
+	parser := PPSequenceParser new.
+	self assert: parser name isNil.
+	
+	parser := PPChoiceParser named: 'choice'.
+	self assert: parser name = 'choice'.
+	
+	parser := $* asParser name: 'star'.
+	self assert: parser name = 'star'
+!
+
+testPrint
+	| parser |
+	parser := PPParser new.
+	self assert: (parser printString findString: 'PPParser') > 0.
+	
+	parser := PPParser named: 'choice'.
+	self assert: (parser printString findString: 'PPParser(choice') > 0.
+	
+	parser := PPLiteralObjectParser on: $a.
+	self assert: (parser printString findString: '$a') > 0.
+	
+	parser := PPFailingParser message: 'error'.
+	self assert: (parser printString findString: 'error') > 0.
+	
+	parser := PPPredicateObjectParser on: [ :c | true ] message: 'error'.
+	self assert: (parser printString findString: 'error') > 0
+! !
+
+!PPParserTest methodsFor:'testing-fixtures'!
+
+testSideEffectChoice
+	"Adding another element to a choice should create a copy, otherwise we get unwanted side-effects."
+
+	| p1 p2 p3 |
+	p1 := $a asParser.
+	p2 := p1 / $b asParser.
+	p3 := p1 / $c asParser.
+	
+	self assert: p1 parse: 'a'.
+	self assert: p1 fail: 'b'.
+	self assert: p1 fail: 'c'.
+	
+	self assert: p2 parse: 'a'.
+	self assert: p2 parse: 'b'.
+	self assert: p2 fail: 'c'.
+	
+	self assert: p3 parse: 'a'.
+	self assert: p3 fail: 'b'.
+	self assert: p3 parse: 'c'
+!
+
+testSideEffectListCopy
+	| old new |
+	old := $a asParser , $b asParser.
+	new := old copy.
+	
+	self deny: old == new.
+	self deny: old children == new children.
+	self assert: old children first == new children first.
+	self assert: old children last == new children last
+!
+
+testSideEffectSequence
+	"Adding another element to a sequence should create a copy, otherwise we get unwanted side-effects."
+
+	| p1 p2 p3 |
+	p1 := $a asParser.
+	p2 := p1 , $b asParser.
+	p3 := p1 , $c asParser.
+	
+	self assert: p1 parse: 'a'.	
+	self assert: p1 parse: 'ab' end: 1.
+	self assert: p1 parse: 'ac' end: 1.
+	
+	self assert: p2 fail: 'a'.	
+	self assert: p2 parse: 'ab'.
+	self assert: p2 fail: 'ac'.
+
+	self assert: p3 fail: 'a'.	
+	self assert: p3 fail: 'ab'.
+	self assert: p3 parse: 'ac'
+! !
+
+!PPParserTest methodsFor:'testing-mapping'!
+
+testAction
+	| block parser |
+	block := [ :char | char asUppercase ].
+	parser := #any asParser ==> block.
+	self assert: parser block = block.
+
+	self assert: parser parse: 'a' to: $A.
+	self assert: parser parse: 'b' to: $B
+!
+
+testAnswer
+	| parser |
+	parser := $a asParser answer: $b.
+	
+	self assert: parser parse: 'a' to: $b.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'
+!
+
+testFlatten
+	| parser |
+	parser := $a asParser flatten.
+	
+	self assert: parser parse: 'a' to: 'a'.
+	self assert: parser parse: #($a) to: #($a).
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'
+!
+
+testFoldLeft2
+	| parser |
+	parser := #any asParser star 
+		foldLeft: [ :a :b | Array with: a with: b ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b) to: #(a b).
+	self assert: parser parse: #(a b c) to: #((a b) c).
+	self assert: parser parse: #(a b c d) to: #(((a b) c) d).
+	self assert: parser parse: #(a b c d e) to: #((((a b) c) d) e)
+!
+
+testFoldLeft3
+	| parser |
+	parser := #any asParser star 
+		foldLeft: [ :a :b :c | Array with: a with: b with: c ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b c) to: #(a b c).
+	self assert: parser parse: #(a b c d e) to: #((a b c) d e)
+!
+
+testFoldRight2
+	| parser |
+	parser := #any asParser star 
+		foldRight: [ :a :b | Array with: a with: b ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b) to: #(a b).
+	self assert: parser parse: #(a b c) to: #(a (b c)).
+	self assert: parser parse: #(a b c d) to: #(a (b (c d))).
+	self assert: parser parse: #(a b c d e) to: #(a (b (c (d e))))
+!
+
+testFoldRight3
+	| parser |
+	parser := #any asParser star 
+		foldRight: [ :a :b :c | Array with: a with: b with: c ].
+
+	self assert: parser parse: #(a) to: #a.
+	self assert: parser parse: #(a b c) to: #(a b c).
+	self assert: parser parse: #(a b c d e) to: #(a b (c d e))
+!
+
+testMap1
+	| parser |
+	parser := #any asParser 
+		map: [ :a | Array with: a ].
+
+	self assert: parser parse: #(a) to: #(a)
+!
+
+testMap2
+	| parser |
+	parser := (#any asParser , #any asParser) 
+		map: [ :a :b | Array with: b with: a ].
+
+	self assert: parser parse: #(a b) to: #(b a)
+!
+
+testMap3
+	| parser |
+	parser := (#any asParser , #any asParser , #any asParser)
+		map: [ :a :b :c | Array with: c with: b with: a ].
+
+	self assert: parser parse: #(a b c) to: #(c b a)
+!
+
+testMapFail1
+	self
+		should: [ #any asParser map: [  ] ]
+		raise: Error.
+	self
+		should: [ #any asParser map: [ :a :b | ] ]
+		raise: Error
+!
+
+testMapFail2
+	self
+		should: [ (#any asParser , #any asParser) map: [ :a | ] ]
+		raise: Error.
+	self
+		should: [ (#any asParser , #any asParser) map: [ :a :b :c | ] ]
+		raise: Error
+!
+
+testPermutation
+	| parser |
+	parser := #any asParser , #any asParser , #any asParser.
+
+	self assert: (parser permutation: #()) parse: '123' to: #().
+	self assert: (parser permutation: #(1)) parse: '123' to: #($1).
+	self assert: (parser permutation: #(1 3)) parse: '123' to: #($1 $3).
+	self assert: (parser permutation: #(3 1)) parse: '123' to: #($3 $1).
+	self assert: (parser permutation: #(2 2)) parse: '123' to: #($2 $2).
+	self assert: (parser permutation: #(3 2 1)) parse: '123' to: #($3 $2 $1).
+	
+	self should: [ parser permutation: #(0) ] raise: Error.
+	self should: [ parser permutation: #(4) ] raise: Error.
+	self should: [ parser permutation: #($2) ] raise: Error
+!
+
+testToken
+	| parser |
+	parser := $a asParser token.
+	self assert: parser tokenClass = PPToken.
+	self assert: parser parse: 'a' toToken: 1 stop: 1.	
+	self assert: parser fail: 'b'.
+	self assert: parser fail: ''.
+	
+	parser := $a asParser token: PPToken.
+	self assert: parser tokenClass = PPToken.
+	self assert: parser parse: 'a' toToken: 1 stop: 1.	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'
+!
+
+testTrim
+	| parser |
+	parser := $a asParser token trim.
+	
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: 'a ' toToken: 1 stop: 1.
+	self assert: parser parse: 'a	' toToken: 1 stop: 1.
+	self assert: parser parse: 'a  ' toToken: 1 stop: 1.
+	self assert: parser parse: 'a 
+	 ' toToken: 1 stop: 1.
+		
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: ' a' toToken: 2 stop: 2.
+	self assert: parser parse: '	a' toToken: 2 stop: 2.
+	self assert: parser parse: '    a' toToken: 5 stop: 5.
+	self assert: parser parse: '   
+a' toToken: 5 stop: 5.
+	
+	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
+	self assert: parser parse: 'a	a' toToken: 1 stop: 1 end: 2.
+	self assert: parser parse: 'a  a' toToken: 1 stop: 1 end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'
+!
+
+testTrimBlanks
+	| parser |
+	parser := $a asParser token trimBlanks.
+	
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: 'a ' toToken: 1 stop: 1.
+	self assert: parser parse: 'a	' toToken: 1 stop: 1.
+	self assert: parser parse: 'a  ' toToken: 1 stop: 1.
+	
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: ' a' toToken: 2 stop: 2.
+	self assert: parser parse: '	a' toToken: 2 stop: 2.
+	self assert: parser parse: '    a' toToken: 5 stop: 5.
+	
+	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
+	self assert: parser parse: 'a	a' toToken: 1 stop: 1 end: 2.
+	self assert: parser parse: 'a  a' toToken: 1 stop: 1 end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: '
+'.
+	self assert: parser fail: '
+a'.
+	self assert: parser fail: 'b'.
+!
+
+testTrimCustom
+	| parser |
+	parser := $a asParser token trim: $b asParser.
+	
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: 'ab' toToken: 1 stop: 1.
+	self assert: parser parse: 'abb' toToken: 1 stop: 1.
+		
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: 'ba' toToken: 2 stop: 2.
+	self assert: parser parse: 'bba' toToken: 3 stop: 3.
+	
+	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
+	self assert: parser parse: 'ab' toToken: 1 stop: 1 end: 2.
+	self assert: parser parse: 'abba' toToken: 1 stop: 1 end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'
+!
+
+testTrimSpaces
+	| parser |
+	parser := $a asParser token trimSpaces.
+	
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: 'a ' toToken: 1 stop: 1.
+	self assert: parser parse: 'a	' toToken: 1 stop: 1.
+	self assert: parser parse: 'a  ' toToken: 1 stop: 1.
+	self assert: parser parse: 'a 
+	 ' toToken: 1 stop: 1.
+		
+	self assert: parser parse: 'a' toToken: 1 stop: 1.
+	self assert: parser parse: ' a' toToken: 2 stop: 2.
+	self assert: parser parse: '	a' toToken: 2 stop: 2.
+	self assert: parser parse: '    a' toToken: 5 stop: 5.
+	self assert: parser parse: '   
+a' toToken: 5 stop: 5.
+	
+	self assert: parser parse: 'aa' toToken: 1 stop: 1 end: 1.
+	self assert: parser parse: 'a	a' toToken: 1 stop: 1 end: 2.
+	self assert: parser parse: 'a  a' toToken: 1 stop: 1 end: 3.
+	
+	self assert: parser fail: ''.
+	self assert: parser fail: 'b'
+!
+
+testWrapping
+	| parser result |
+	parser := #digit asParser plus >=> [ :stream :cc | 
+		Array 
+			with: stream position 
+			with: cc value 
+			with: stream position ].
+
+	self assert: parser parse: '1' to: #(0 ($1) 1).
+	self assert: parser parse: '12' to: #(0 ($1 $2) 2).
+	self assert: parser parse: '123' to: #(0 ($1 $2 $3) 3).
+	
+	result := parser parse: 'a'.
+	self assert: result first = 0.
+	self assert: result second isPetitFailure.
+	self assert: result last = 0
+! !
+
+!PPParserTest methodsFor:'testing-properties'!
+
+testHasProperty
+	| parser |
+	parser := PPParser new.
+	self deny: (parser hasProperty: #foo).
+	parser propertyAt: #foo put: 123.
+	self assert: (parser hasProperty: #foo)
+!
+
+testPostCopy
+	| parser copy |
+	parser := PPParser new.
+	parser propertyAt: #foo put: true.
+	copy := parser copy.
+	copy propertyAt: #foo put: false.
+	self assert: (parser propertyAt: #foo).
+	self deny: (copy propertyAt: #foo)
+!
+
+testPropertyAt
+	| parser |
+	parser := PPParser new.
+	self should: [ parser propertyAt: #foo ] raise: Error.
+	parser propertyAt: #foo put: true.
+	self assert: (parser propertyAt: #foo)
+!
+
+testPropertyAtIfAbsent
+	| parser |
+	parser := PPParser new.
+	self assert: (parser propertyAt: #foo ifAbsent: [ true ]).
+	parser propertyAt: #foo put: true.
+	self assert: (parser propertyAt: #foo ifAbsent: [ false ])
+!
+
+testPropertyAtIfAbsentPut
+	| parser |
+	parser := PPParser new.
+	self assert: (parser propertyAt: #foo ifAbsentPut: [ true ]).
+	self assert: (parser propertyAt: #foo ifAbsentPut: [ false ])
+!
+
+testRemoveProperty
+	| parser |
+	parser := PPParser new.
+	self should: [ parser removeProperty: #foo ] raise: Error.
+	parser propertyAt: #foo put: true.
+	self assert: (parser removeProperty: #foo)
+!
+
+testRemovePropertyIfAbsent
+	| parser |
+	parser := PPParser new.
+	self assert: (parser removeProperty: #foo ifAbsent: [ true ]).
+	parser propertyAt: #foo put: true.
+	self assert: (parser removeProperty: #foo ifAbsent: [ false ])
+! !
+
+!PPParserTest methodsFor:'testing-utilities'!
+
+testChildren
+	| p1 p2 p3 |
+	p1 := #lowercase asParser.
+	p2 := p1 ==> #asUppercase.
+	p3 := PPUnresolvedParser new.
+	p3 def: p2 / p3.
+	self assert: p1 children isEmpty.
+	self assert: p2 children size = 1.
+	self assert: p3 children size = 2
+!
+
+testFailure
+	| failure |
+	failure := PPFailure message: 'Error' at: 3.
+	
+	self assert: failure message = 'Error'.
+	self assert: failure position = 3.
+	self assert: failure isPetitFailure.
+
+	self deny: 4 isPetitFailure.
+	self deny: 'foo' isPetitFailure
+!
+
+testListConstructor
+	| p1 p2 p3 |
+	p1 := PPChoiceParser with: $a asParser.
+	p2 := PPChoiceParser with: $a asParser with: $b asParser.
+	p3 := PPChoiceParser withAll: (Array with: $a asParser with: $b asParser with: $c asParser).
+	
+	self assert: p1 children size = 1.
+	self assert: p2 children size = 2.
+	self assert: p3 children size = 3
+!
+
+testMatches
+	| parser |
+	parser := $a asParser.
+	
+	self assert: (parser matches: 'a').
+	self deny: (parser matches: 'b').
+	
+	self assert: (parser matches: 'a' readStream).
+	self deny: (parser matches: 'b' readStream)
+!
+
+testMatchesIn
+	| parser result |
+	parser := $a asParser.
+	
+	result := parser matchesIn: 'abba'.
+	self assert: result size = 2.
+	self assert: result first = $a.
+	self assert: result last = $a.
+	
+	result := parser matchesIn: 'baaah'.
+	self assert: result size = 3.
+	self assert: result first = $a.
+	self assert: result last = $a
+!
+
+testMatchesInEmpty
+	"Empty matches should properly advance and match at each position and at the end."
+
+	| parser result |
+	parser := [ :stream | stream position ] asParser.
+	
+	result := parser matchesIn: '123'.
+	self assert: result asArray = #(0 1 2 3)
+!
+
+testMatchesInOverlapping
+	"Matches that overlap should be properly reported."
+
+	| parser result |
+	parser := #digit asParser , #digit asParser.
+	
+	result := parser matchesIn: 'a123b'.
+	self assert: result size = 2.
+	self assert: result first = #($1 $2).
+	self assert: result last = #($2 $3)
+!
+
+testMatchesSkipIn
+	| parser result |
+	parser := $a asParser.
+	
+	result := parser matchesSkipIn: 'abba'.
+	self assert: result size = 2.
+	self assert: result first = $a.
+	self assert: result last = $a.
+	
+	result := parser matchesSkipIn: 'baaah'.
+	self assert: result size = 3.
+	self assert: result first = $a.
+	self assert: result last = $a
+!
+
+testMatchesSkipInOverlapping
+	"Matches that overlap should be properly reported."
+
+	| parser result |
+	parser := #digit asParser , #digit asParser.
+	
+	result := parser matchesSkipIn: 'a123b'.
+	self assert: result size = 1.
+	self assert: result first = #($1 $2)
+!
+
+testMatchingRangesIn
+	| input parser result |
+	input := 'a12b3'.
+	parser := #digit asParser plus.
+	result := parser matchingRangesIn: input.
+	result := result collect: [ :each | input copyFrom: each first to: each last ].
+	self assert: result size = 3.
+	self assert: result first = '12'.
+	self assert: result second = '2'.
+	self assert: result last = '3'
+!
+
+testMatchingSkipRangesIn
+	| input parser result |
+	input := 'a12b3'.
+	parser := #digit asParser plus.
+	result := parser matchingSkipRangesIn: input.
+	result := result collect: [ :each | input copyFrom: each first to: each last ].
+	self assert: result size = 2.
+	self assert: result first = '12'.
+	self assert: result last = '3'
+!
+
+testParse
+	| parser result |
+	parser := $a asParser.
+	
+	self assert: (parser parse: 'a') = $a.
+	self assert: (result := parser parse: 'b') isPetitFailure.
+	self assert: (result message findString: '$a') > 0.
+	self assert: (result message findString: 'expected') > 0.
+	self assert: (result position = 0).
+	
+	self assert: (parser parse: 'a' readStream) = $a.
+	self assert: (result := parser parse: 'b' readStream) isPetitFailure.
+	self assert: (result message findString: '$a') > 0.
+	self assert: (result message findString: 'expected') > 0.
+	self assert: (result position = 0)
+!
+
+testParseOnError0
+	| parser result seen |
+	parser := $a asParser.
+
+	result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ].
+	self assert: result = $a.
+
+	result := parser parse: 'b' onError: [ seen := true ].
+	self assert: result.
+	self assert: seen
+!
+
+testParseOnError1
+	| parser result seen |
+	parser := $a asParser.
+
+	result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ].
+	self assert: result = $a.
+	
+	result := parser parse: 'b' onError: [ :failure | 
+		self assert: (failure position = 0).
+		self assert: (failure message findString: '$a') > 0.
+		self assert: (failure message findString: 'expected') > 0.
+		seen := true ].
+	self assert: result.
+	self assert: seen
+!
+
+testParseOnError2
+	| parser result seen |
+	parser := $a asParser.
+	
+	result := parser parse: 'a' onError: [ self signalFailure: 'Not supposed to report an error' ].
+	self assert: result = $a.
+
+	result := parser parse: 'b' onError: [ :msg :pos | 
+		self assert: (msg findString: '$a') > 0.
+		self assert: (msg findString: 'expected') > 0.
+		self assert: pos = 0.
+		seen := true ].
+	self assert: result.
+	self assert: seen
+!
+
+testParser
+	| parser |
+	parser := PPParser new.
+	
+	self assert: parser isPetitParser.
+
+	self deny: 4 isPetitParser.
+	self deny: 'foo' isPetitParser
+! !
+
+!PPParserTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserTest.st,v 1.4 2014-03-04 14:34:21 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParserTest.st,v 1.4 2014-03-04 14:34:21 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPParserTest.st,v 1.4 2014-03-04 14:34:21 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPPredicateTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,313 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPPredicateTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPPredicateTest methodsFor:'private'!
+
+charactersDo: aBlock
+    "cg: isn't 256 one too many?"
+
+    Smalltalk isSmalltalkX ifTrue:[
+        0 to: 255 do: [ :index | aBlock value: (Character codePoint: index) ]
+    ] ifFalse:[
+        1 to: 256 do: [ :index | aBlock value: (Character codePoint: index) ]
+    ].
+! !
+
+!PPPredicateTest methodsFor:'testing'!
+
+testOnMessage
+	| block parser |
+	block := [ :char | char = $* ].
+	parser := PPPredicateObjectParser on: block message: 'starlet'.
+	self assert: parser block = block.
+	self assert: parser message = 'starlet'.
+	
+	self assertCharacterSets: parser.
+	self assert: parser parse: '*' to: $*.
+	self assert: parser parse: '**' to: $* end: 1.
+	self assert: parser fail: ''.
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a'
+! !
+
+!PPPredicateTest methodsFor:'testing-chars'!
+
+testBlank
+        | parser cr|
+        parser := #blank asParser.
+        self assertCharacterSets: parser.
+        self assert: parser parse: (String with: Character space) to: Character space.
+        self assert: parser parse: (String with: Character tab) to: Character tab.
+        self assert: parser fail: ''.
+        self assert: parser fail: '1'.
+        cr := Smalltalk isSmalltalkX 
+            ifTrue:[Character return] 
+            ifFalse:[Character cr].
+        self assert: parser fail: (String with: cr)
+!
+
+testChar
+	| parser |
+	parser := $* asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: '*' to: $*.
+	self assert: parser parse: '**' to: $* end: 1.
+	self assert: parser fail: ''.
+	self assert: parser fail: '1'.
+	self assert: parser fail: 'a'
+!
+
+testCr
+        | parser cr |
+
+        cr := Smalltalk isSmalltalkX 
+                ifTrue:[Character return] 
+                ifFalse:[Character cr].
+
+        parser := #cr asParser.
+        self assertCharacterSets: parser.
+        self assert: parser parse: (String with: cr) to: cr
+!
+
+testDigit
+	| parser |
+	parser := #digit asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: '0' to: $0.
+	self assert: parser parse: '9' to: $9.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'
+!
+
+testHex
+	| parser |
+	parser := #hex asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: '0' to: $0.
+	self assert: parser parse: '5' to: $5.
+	self assert: parser parse: '9' to: $9.
+	self assert: parser parse: 'A' to: $A.
+	self assert: parser parse: 'D' to: $D.
+	self assert: parser parse: 'F' to: $F.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'e' to: $e.
+	self assert: parser parse: 'f' to: $f.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'g'
+!
+
+testLetter
+	| parser |
+	parser := #letter asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'Z' to: $Z.
+	self assert: parser fail: ''.
+	self assert: parser fail: '0'
+!
+
+testLf
+	| parser |
+	parser := #lf asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: (String with: Character lf) to: Character lf
+!
+
+testLowercase
+	| parser |
+	parser := #lowercase asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'z' to: $z.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'A'.
+	self assert: parser fail: '0'
+!
+
+testNewline
+        | parser cr|
+        cr := Smalltalk isSmalltalkX 
+                ifTrue:[Character return] 
+                ifFalse:[Character cr].
+        parser := #newline asParser.
+        self assertCharacterSets: parser.
+        self assert: parser parse: (String with: cr) to: cr.
+        self assert: parser parse: (String with: Character lf) to: Character lf.
+        self assert: parser fail: ' '
+!
+
+testPunctuation
+	| parser |
+	parser := #punctuation asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: '.' to: $..
+	self assert: parser parse: ',' to: $,.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: '1'
+!
+
+testSpace
+	| parser |
+	parser := #space asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: (String with: Character tab) to: Character tab.
+	self assert: parser parse: ' ' to: Character space.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'
+!
+
+testTab
+	| parser |
+	parser := #tab asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: (String with: Character tab) to: Character tab
+!
+
+testUppercase
+	| parser |
+	parser := #uppercase asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'A' to: $A.
+	self assert: parser parse: 'Z' to: $Z.
+	self assert: parser fail: ''.
+	self assert: parser fail: 'a'.
+	self assert: parser fail: '0'
+!
+
+testWord
+	| parser |
+	parser := #word asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'A' to: $A.
+	self assert: parser parse: '0' to: $0.
+	self assert: parser fail: ''.
+	self assert: parser fail: '-'
+! !
+
+!PPPredicateTest methodsFor:'testing-objects'!
+
+testAny
+	| parser |
+	parser := #any asParser.
+	self assertCharacterSets: parser.
+	self assert: parser parse: ' ' to: $ .
+	self assert: parser parse: '1' to: $1.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser fail: ''
+!
+
+testAnyExceptAnyOf
+	| parser |
+	parser := PPPredicateObjectParser anyExceptAnyOf: #($: $,).
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'z' to: $z.
+	self assert: parser fail: ':'.
+	self assert: parser fail: ','
+!
+
+testAnyOf
+	| parser |
+	parser := PPPredicateObjectParser anyOf: #($a $z).
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser parse: 'z' to: $z.
+	self assert: parser fail: 'x'
+!
+
+testBetweenAnd
+	| parser |
+	parser := PPPredicateObjectParser between: $b and: $d.
+	self assertCharacterSets: parser.
+	self assert: parser fail: 'a'.
+	self assert: parser parse: 'b' to: $b.
+	self assert: parser parse: 'c' to: $c.
+	self assert: parser parse: 'd' to: $d.
+	self assert: parser fail: 'e'
+!
+
+testExpect
+	| parser |
+	parser := PPPredicateObjectParser expect: $a.
+	self assertCharacterSets: parser.
+	self assert: parser parse: 'a' to: $a.
+	self assert: parser fail: 'b'.
+	self assert: parser fail: ''
+! !
+
+!PPPredicateTest methodsFor:'testing-sequence'!
+
+testSequenceParser
+	| parser |
+	parser := PPPredicateSequenceParser 
+		on: [ :value | value first isUppercase ] 
+		message: 'uppercase 3 letter words'
+		size: 3.
+	self assert: parser size = 3.
+	self assert: parser parse: 'Abc'.
+	self assert: parser parse: 'ABc'.
+	self assert: parser parse: 'ABC'.
+	self assert: parser fail: 'abc'.
+	self assert: parser fail: 'aBC'.
+	self assert: parser fail: 'Ab'.
+	
+	parser := parser negate.
+	self assert: parser size = 3.
+	self assert: parser fail: 'Abc'.
+	self assert: parser fail: 'ABc'.
+	self assert: parser fail: 'ABC'.
+	self assert: parser parse: 'abc'.
+	self assert: parser parse: 'aBC'.
+	self assert: parser fail: 'Ab'
+! !
+
+!PPPredicateTest methodsFor:'utilities'!
+
+assertCharacterSets: aParser
+	"Assert the character set of aParser does not overlap with the character set with the negated parser, and that they both cover the complete character space."
+
+	| positives negatives |
+	positives := self parsedCharacterSet: aParser.
+	negatives := self parsedCharacterSet: aParser negate.
+	self charactersDo: [ :char | 
+		| positive negative |
+		positive := positives includes: char.
+		negative := negatives includes: char.
+		self 
+			assert: ((positive and: [ negative not ])
+				or: [ positive not and: [ negative ] ])
+			description: char printString , ' should be in exactly one set' ]
+!
+
+parsedCharacterSet: aParser
+	| result |
+	result := WriteStream on: String new.
+	self charactersDo: [ :char |
+		(aParser matches: (String with: char))
+			ifTrue: [ result nextPut: char ] ].
+	^ result contents
+! !
+
+!PPPredicateTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPPredicateTest.st,v 1.6 2014-03-04 20:09:46 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPPredicateTest.st,v 1.6 2014-03-04 20:09:46 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPPredicateTest.st,v 1.6 2014-03-04 20:09:46 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPScriptingTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,124 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPScriptingTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+PPScriptingTest comment:'These are some simple demo-scripts of parser combinators for the compiler construction course.
http://www.iam.unibe.ch/~scg/Teaching/CC/index.html'
+!
+
+
+!PPScriptingTest methodsFor:'examples'!
+
+expressionInterpreter
+        "Same as #expressionInterpreter but with semantic actions."
+        
+        | mul prim add dec |
+        add := PPUnresolvedParser new.
+        mul := PPUnresolvedParser new.
+        prim := PPUnresolvedParser new.
+        dec := ($0 to: $9) asParser ==> [ :token | token codePoint - $0 codePoint ].
+        add def: ((mul , $+ asParser , add) ==> [ :nodes | (nodes at: 1) + (nodes at: 3) ])
+                / mul.
+        mul def: ((prim , $* asParser , mul) ==> [ :nodes | (nodes at: 1) * (nodes at: 3) ])
+                / prim.
+        prim def: (($( asParser , add , $) asParser) ==> [ :nodes | nodes at: 2 ])
+                / dec.
+        ^ add end
+!
+
+expressionParser
+        "Simple demo of scripting an expression parser."
+        
+        | mul prim add dec |
+        add := PPUnresolvedParser new.
+        mul := PPUnresolvedParser new.
+        prim := PPUnresolvedParser new.
+        dec := ($0 to: $9) asParser.
+        add def: (mul , $+ asParser , add)
+                / mul.
+        mul def: (prim , $* asParser , mul)
+                / prim.
+        prim def: ($( asParser , add , $) asParser)
+                / dec.
+        ^ add end
+!
+
+straightLineParser
+        | goal stm stmList id char dec exp expList mulExp primExp nonzero num lower upper |
+        goal := PPUnresolvedParser new.
+        stmList := PPUnresolvedParser new.
+        stm := PPUnresolvedParser new.
+        exp := PPUnresolvedParser new.
+        expList := PPUnresolvedParser new.
+        mulExp := PPUnresolvedParser new.
+        primExp := PPUnresolvedParser new.
+        
+        lower := ($a to: $z) asParser.
+        upper := ($A to: $Z) asParser.
+        char := lower / upper.
+        nonzero := ($1 to: $9) asParser.
+        dec := ($0 to: $9) asParser.
+        id := char, ( char / dec ) star.
+        num := $0 asParser / ( nonzero, dec star).
+
+        goal def: stmList end.
+        stmList def: stm , ( $; asParser, stm ) star.
+        stm def: ( id, ':=' asParser, exp )
+                / ( 'print' asParser, $( asParser, expList, $) asParser ). 
+        exp def: mulExp, ( ( $+ asParser / $- asParser ), mulExp ) star.
+        expList def: exp, ( $, asParser, exp ) star.
+        mulExp def: primExp, ( ( $* asParser / $/ asParser ), primExp ) star.
+        primExp def: id
+                / num
+                / ( $( asParser, stmList, $, asParser, exp, $) asParser ).
+        ^ goal
+! !
+
+!PPScriptingTest methodsFor:'tests'!
+
+testExpressionInterpreter
+	self 
+		assert: self expressionInterpreter
+		parse: '2*(3+4)'
+		to: 14
+!
+
+testExpressionParser
+	self
+		assert: self expressionParser
+		parse: '2*(3+4)'
+		to: #($2 $* ($( ($3 $+ $4) $)))
+!
+
+testSLassign
+	
+	self assert: self straightLineParser
+		parse: 'abc:=1'
+		to: #(#($a #($b $c) ':=' #(#(#($1 #()) #()) #())) #())
+!
+
+testSLprint
+	self 
+		assert: self straightLineParser
+		parse: 'print(3,4)'
+		to: #(('print' $( ((($3 ()) ()) () (($, ((($4 ()) ()) ())))) $)) ())
+! !
+
+!PPScriptingTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPScriptingTest.st,v 1.4 2014-03-04 14:34:23 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPScriptingTest.st,v 1.4 2014-03-04 14:34:23 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPScriptingTest.st,v 1.4 2014-03-04 14:34:23 cg Exp $'
+! !
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/PPTokenTest.st	Fri Oct 03 01:36:33 2014 +0100
@@ -0,0 +1,168 @@
+"{ Package: 'stx:goodies/petitparser' }"
+
+PPAbstractParserTest subclass:#PPTokenTest
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitTests-Tests'
+!
+
+
+!PPTokenTest methodsFor:'accessing'!
+
+identifier
+	^ #word asParser plus token
+! !
+
+!PPTokenTest methodsFor:'testing'!
+
+testCollection
+	| input result |
+	input := 'foo    '.
+	result := self 
+		parse: input
+		using: self identifier.
+	self assert: (result collection = input).
+	self assert: (result collection == input)
+!
+
+testInitialize
+	PPToken initialize
+!
+
+testNew
+	self should: [ PPToken new ] raise: Error.
+	
+!
+
+testPrinting
+	| result |
+	result := PPToken on: 'var'.
+	self assert: (result printString findString: 'PPToken[1,3]') > 0
+!
+
+testSize
+	| result |
+	result := self 
+		parse: 'foo'
+		using: self identifier.
+	self assert: result size = 3
+!
+
+testStart
+	| result |
+	result := self 
+		parse: 'foo'
+		using: self identifier.
+	self assert: result start = 1
+!
+
+testStop
+	| result |
+	result := self 
+		parse: 'foo'
+		using: self identifier.
+	self assert: result stop = 3
+!
+
+testValue
+	| result |
+	result := PPToken on: 'var'.
+	self should: [ result value ] raise: Notification
+! !
+
+!PPTokenTest methodsFor:'testing-comparing'!
+
+testEquality
+	| token1 token2 |
+	token1 := self  parse: 'foo' using: self identifier.
+	token2 := self  parse: 'foo' using: self identifier.
+	self deny: token1 == token2.
+	self assert: token1 = token2.
+	self assert: token1 hash = token2 hash.
+! !
+
+!PPTokenTest methodsFor:'testing-copying'!
+
+testCopyFromTo
+	| result other |
+	result := PPToken on: 'abc'.
+	other := result copyFrom: 2 to: 2.
+	
+	self assert: other size = 1.
+	self assert: other start = 2.
+	self assert: other stop = 2.
+	self assert: other collection = result collection
+! !
+
+!PPTokenTest methodsFor:'testing-querying'!
+
+testColumn
+        | input parser result cr |
+
+        cr := Smalltalk isSmalltalkX 
+                ifTrue:[ Character return]
+                ifFalse:[ Character cr ].
+        input := '1' , (String with:cr) , '12' , (String with: cr with: Character lf) , '123' , (String with: Character lf) , '1234'.
+        parser := #any asParser token star.
+        result := parser parse: input.
+        result 
+                with:  #(1 2 1 2 3 4 1 2 3 4 1 2 3 4)
+                do: [ :token :line | self assert: token column = line ]
+!
+
+testLine
+        | input parser result cr|
+
+        cr := Smalltalk isSmalltalkX 
+            ifTrue:[Character return] 
+            ifFalse:[Character cr].
+        input := '1' , (String with: cr) , '12' , (String with: cr with: Character lf) , '123' , (String with: Character lf) , '1234'.
+        parser := #any asParser token star.
+        result := parser parse: input.
+        result 
+                with: #(1 1 2 2 2 2 3 3 3 3 4 4 4 4) 
+                do: [ :token :line | self assert: token line = line ]
+! !
+
+!PPTokenTest methodsFor:'testing-values'!
+
+testInputValue
+	| input result |
+	input := 'foo'.
+	result := self 
+		parse: input
+		using: self identifier.
+	self assert: result inputValue = input.
+	self deny: result inputValue == input
+!
+
+testParsedValue
+	| input result |
+	input := 'foo'.
+	result := self 
+		parse: input
+		using: self identifier.
+	self assert: result parsedValue = #($f $o $o)
+! !
+
+!PPTokenTest methodsFor:'utilities'!
+
+parse: aString using: aParser
+	^ aParser parse: aString
+! !
+
+!PPTokenTest class methodsFor:'documentation'!
+
+version
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPTokenTest.st,v 1.5 2014-03-04 14:34:24 cg Exp $'
+!
+
+version_CVS
+    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPTokenTest.st,v 1.5 2014-03-04 14:34:24 cg Exp $'
+!
+
+version_SVN
+    ^ '$Id: PPTokenTest.st,v 1.5 2014-03-04 14:34:24 cg Exp $'
+! !
+
--- a/tests/stx_goodies_petitparser_tests.st	Fri Oct 03 00:52:34 2014 +0100
+++ b/tests/stx_goodies_petitparser_tests.st	Fri Oct 03 01:36:33 2014 +0100
@@ -65,9 +65,24 @@
 
     ^ #(
         "<className> or (<className> attributes...) in load order"
-        PPAbstractParserTest
+        (PPAbstractParserTest autoload)
         #'stx_goodies_petitparser_tests'
-        PPCompositeParserTest
+        (PPCompositeParserTest autoload)
+        (PPAbstractParseTest autoload)
+        (PPArithmeticParserTest autoload)
+        (PPComposedTest autoload)
+        (PPExtensionTest autoload)
+        (PPLambdaParserTest autoload)
+        (PPObjectTest autoload)
+        (PPParserResource autoload)
+        (PPParserTest autoload)
+        (PPPredicateTest autoload)
+        (PPScriptingTest autoload)
+        (PPTokenTest autoload)
+        (PPExpressionParserTest autoload)
+        (PPMappingTest autoload)
+        (PPArithmeticParser autoload)
+        (PPLambdaParser autoload)
     )
 !