islands/tests/FirstFollowNextTests.st
changeset 387 e2b2ccaa4de6
child 389 009c2e13973c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/islands/tests/FirstFollowNextTests.st	Wed Oct 08 00:33:44 2014 +0100
@@ -0,0 +1,1058 @@
+"{ Package: 'stx:goodies/petitparser/islands/tests' }"
+
+TestCase subclass:#FirstFollowNextTests
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	category:'PetitIslands-Tests'
+!
+
+FirstFollowNextTests comment:''
+!
+
+!FirstFollowNextTests methodsFor:'support'!
+
+assert: set allMatches: string
+	self assert: (set allSatisfy: [:e | e end matches: string])
+!
+
+assert: set allSatisfy: aBlock
+	self assert: (set allSatisfy: aBlock)
+!
+
+assert: set anyMatches: string
+	self assert: (set anySatisfy: [:e | e end matches: string])
+!
+
+assert: set anySatisfy: aBlock
+	self assert: (set anySatisfy: aBlock)
+!
+
+assert: set noneMatches: string
+	self assert: (set noneSatisfy: [:e | e end matches: string])
+!
+
+assert: set noneSatisfy: aBlock
+	self assert: (set noneSatisfy: aBlock)	
+!
+
+assert: set size: anInteger
+	self assert: (set size = anInteger )
+!
+
+first: aParser 
+	^ aParser firstSet
+!
+
+first: aParser terminalPredicate: predicate
+	^ aParser firstSetPredicate: predicate
+!
+
+follow: aParser in: rootParser
+	^ rootParser followSets at: aParser
+	
+!
+
+identifier
+	^ ((#letter asParser / $# asParser), (#letter asParser / #digit asParser) star) flatten 
+!
+
+next: aParser in: rootParser
+	^ rootParser nextSets at: aParser
+	
+! !
+
+!FirstFollowNextTests methodsFor:'test first'!
+
+testFirst1
+	| p first |
+	p := nil asParser / 'a' asParser.
+	
+	self assert: (self first: p) anyMatches: ''.
+	self assert: (self first: p) anyMatches: 'a'.
+!
+
+testFirst2
+	| p first |
+	p := 'a' asParser optional, 'b' asParser.
+	
+	self assert: (self first: p) anyMatches: 'a'.
+	self assert: (self first: p) anyMatches: 'b'.
+!
+
+testFirst3
+	| p first |
+	p := ('a' asParser optional, 'b' asParser asParser optional), 'c' asParser.
+	
+	self assert: (self first: p) anyMatches: 'a'.
+	self assert: (self first: p) anyMatches: 'b'.
+!
+
+testFirst4
+	| p first |
+	p := ('a' asParser plus) optional, 'b' asParser.
+	
+	self assert: (self first: p) anyMatches: 'a'.
+	self assert: (self first: p) anyMatches: 'b'.
+!
+
+testFirstChoice1
+	| p first |
+	p := nil asParser / '' asParser.
+	
+	self assert: (self first: p) anySatisfy: [:e | e matches: ''].
+!
+
+testFirstChoice2
+	| p first |
+	p := 'a' asParser / nil asParser.
+	
+	first := (self first: p).
+	
+	self assert: first anySatisfy: [:e | e matches: 'a'].
+	self assert: first anySatisfy: [:e | e matches: ''].
+!
+
+testFirstChoice3
+	| p first |
+	p := 'a' asParser / nil asParser / 'b' asParser.
+	
+	first := (self first: p).
+	
+	self assert: first anySatisfy: [:e | e matches: 'a'].
+	self assert: first anySatisfy: [:e | e matches: 'b'].
+	self assert: first anySatisfy: [:e | e matches: ''].
+!
+
+testFirstComplex1
+	| p first root |
+
+	p := 'a' asParser / nil asParser.
+	root := p, 'c' asParser.
+	
+	first := (self first: root).
+	
+	self assert: first size: 2.
+	self assert: first anySatisfy: [:e | e matches: 'a'].
+	self assert: first anySatisfy: [:e | e matches: 'c'].
+	self assert: first noneSatisfy: [:e | e matches: ''].
+!
+
+testFirstComplex2
+	| p first root |
+
+	p := 'a' asParser / nil asParser / 'b' asParser.
+	root := p, 'c' asParser.
+	
+	first := (self first: root).
+	
+	self assert: first size: 3.
+	self assert: first anySatisfy: [:e | e matches: 'a'].
+	self assert: first anySatisfy: [:e | e matches: 'b'].
+	self assert: first anySatisfy: [:e | e matches: 'c'].
+!
+
+testFirstComplex3
+	| p first root |
+
+	p := 'a' asParser / nil asParser / 'b' asParser.
+	root := p, 'c' asParser not.
+	
+	first := (self first: root).
+	
+	self assert: first anySatisfy: [:e | e matches: 'a'].
+	self assert: first anySatisfy: [:e | e matches: 'b'].
+	self assert: first anySatisfy: [:e | e matches: ''].
+	self assert: first noneSatisfy: [:e | e end matches: 'c'].
+!
+
+testFirstComplex4
+	| p first root |
+
+	p := 'a' asParser / nil asParser / 'b' asParser.
+	root := (p, 'c' asParser not) wrapped.
+	
+	first := (self first: root).
+	
+	self assert: first anySatisfy: [:e | e matches: 'a'].
+	self assert: first anySatisfy: [:e | e matches: 'b'].
+	self assert: first anySatisfy: [:e | e matches: ''].
+	self assert: first noneSatisfy: [:e | e end matches: 'c'].
+!
+
+testFirstNegate1
+	| p first |
+	p := 'a' asParser negate, 'b' asParser.
+	
+	self assert: (p parse: 'bb') isPetitFailure not.
+	self assert: (p parse: 'cb') isPetitFailure not.
+	
+	self assert: (self first: p) noneSatisfy: [:each | each matches: 'a' ].
+	self assert: (self first: p) anySatisfy:  [:each | each matches: 'b' ].
+	self assert: (self first: p) anySatisfy: [:each | each matches: 'c' ].
+!
+
+testFirstNot
+	| p |
+	p := 'a' asParser not, 'b' asParser.
+	
+	self assert: (p parse: 'b') isPetitFailure not.
+	
+	self assert: (self first: p) noneSatisfy: [:each | each matches: 'a' ].
+	self assert: (self first: p) anySatisfy:  [:each | each matches: 'b' ].
+	self assert: (self first: p) anySatisfy: [:each | each matches: 'c' ].
+!
+
+testFirstOptional
+	| p first result |
+	p := 'a' asParser optional.
+	
+	result := (self first: p).
+	
+	self assert: result anySatisfy: [:e | e matches: '' ].
+	self assert: result anySatisfy: [:e | e matches: 'a'].
+!
+
+testFirstRepeat1
+	| p first |
+	p := ('a' asParser / nil asParser) plus.
+	
+	first := self first: p.
+
+	self assert: first anyMatches: 'a'.
+	self assert: first anyMatches: ''.	
+!
+
+testFirstSequence1
+	| p first |
+	p := 'a' asParser, 'b' asParser .
+	
+	first := self first: p.
+	self assert: first size: 1.
+	self assert: first allMatches: 'a'.
+	self assert: first noneMatches: 'b'.	
+!
+
+testFirstSequence2
+	| p first |
+	p := nil asParser, 'a' asParser, 'b' asParser .
+	
+	first := self first: p.
+	self assert: first size: 1.
+	self assert: first allMatches: 'a'.
+	self assert: first noneMatches: 'b'.	
+	self assert: first noneMatches: ''.		
+!
+
+testFirstSequence3
+	| p first |
+	p := nil asParser, nil asParser.
+	
+	self assert: (self first: p) anySatisfy: [:e | e end matches: ''].
+!
+
+testFirstSequence4
+	| p first |
+	p := ((nil asParser / 'a' asParser) plus), 'b' asParser.
+	
+	first := self first: p.
+	self assert: first anyMatches: 'b'.
+	self assert: first anyMatches: 'a'.
+	self assert: first noneMatches: ''.
+!
+
+testFirstSequence5
+	| p first |
+	p := ((nil asParser / 'a' asParser) star), 'b' asParser.
+	
+	first := self first: p.
+	self assert: first anyMatches: 'b'.
+	self assert: first anyMatches: 'a'.
+	self assert: first noneMatches: ''.
+!
+
+testFirstTerminal2
+	| p |
+	p := 'a' asParser not.
+	
+	self assert: (self first: p) noneMatches: 'a'.
+!
+
+testFirstTerminal3
+	| p |
+	p := 'a' asParser and.
+	
+	self assert: (self first: p) anyMatches: 'a'
+!
+
+testFirstTerminal4
+	| p |
+	p := nil asParser.
+	
+	self assert: (self first: p) anySatisfy: [:e | e end matches: ''].
+! !
+
+!FirstFollowNextTests methodsFor:'test follow'!
+
+testFollowNot1
+	| p followSet terminal |
+
+	terminal := 'a' asParser.
+	p := terminal, 'b' asParser not.
+	followSet := self follow: terminal in: p.
+	
+	self assert: followSet anySatisfy: [:e | e matches: 'c' ].
+	self assert: followSet anySatisfy: [:e | (e matches: 'b') not ].
+!
+
+testFollowSet1
+	| result p root followSet |
+
+
+	p := 'a' asParser.
+	root := (p star, 'b' asParser).
+	
+	followSet := self follow: p in: root.
+	
+	self assert: followSet anySatisfy: [:e | e literal = 'a'].
+	self assert: followSet anySatisfy: [:e | e literal = 'b'].
+!
+
+testFollowSet10
+	|  island1 followSet p root island2 block |
+
+	island1 := ('class' asParser, self identifier) island.
+	island2 := ('extends' asParser, self identifier) island.
+	block := '{}' asParser island.	
+
+	root := (island1, island2 optional, block) star.
+	
+	followSet := self follow: block in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'class'].
+	self assert: followSet anySatisfy: [:e | e end matches: ''].
+!
+
+testFollowSet11
+	|  island1 followSet p root island2 block |
+
+	island1 := ('class' asParser, self identifier) island.
+	island2 := ('extends' asParser, self identifier) island.
+	block := '{}' asParser island.	
+
+	root := (island1, island2 optional, block) plus.
+	
+	followSet := self follow: block in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'class'].
+	self assert: followSet anySatisfy: [:e | e end matches: ''].
+!
+
+testFollowSet12
+	| parser followSet |
+	
+	
+
+	parser := 'a' asParser.
+	followSet := self follow: parser in: parser.
+
+	self assert: followSet anySatisfy: [:e | e end matches: '' ].
+!
+
+testFollowSet13
+	| parser followSet a b c |
+	
+	a := 'a' asParser.
+	b := 'b' asParser optional.
+	c := 'c' asParser.
+	
+	
+	parser := a, b, c.
+	followSet := self follow: c in: parser.
+	self assert: followSet anySatisfy: [:e | e end matches: '' ].
+	
+	followSet := self follow: b in: parser.
+	self assert: followSet anySatisfy: [:e | e end matches: 'c' ].
+
+	followSet := self follow: a in: parser.
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'c' ].
+!
+
+testFollowSet14
+	| parser followSet a b c |
+	
+	a := 'a' asParser.
+	b := 'b' asParser optional.
+	c := 'c' asParser.
+	
+	
+	parser := a plus, b, c.
+
+	followSet := self follow: a in: parser.
+	self assert: followSet anySatisfy: [:e | e end matches: 'a' ].	
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'c' ].
+	self assert: followSet noneSatisfy: [:e | e end matches: '' ].
+!
+
+testFollowSet2
+	| result p follow root followSets followSet |
+
+	p := 'a' asParser.
+	follow := 'b' asParser, 'c' asParser.
+	
+	root := (p, follow).
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet size: 1.
+	self assert: followSet anySatisfy: [:e | e  end matches: 'b'].
+	self assert: followSet noneSatisfy: [:e | e matches: 'c'].	
+!
+
+testFollowSet3
+	| result p follow root followSets followSet |
+
+	p := 'a' asParser.
+	follow := ('b' asParser, 'c' asParser) / ('d' asParser).
+	
+	
+	root := (p, follow).
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'd' ].
+!
+
+testFollowSet4
+	| result p follow root followSets followSet |
+
+	p := 'a' asParser.
+	follow := ('b' asParser, 'c' asParser).
+	
+	
+	root := (p star, follow).
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'a' ].
+!
+
+testFollowSet5
+	| result p root followSets followSet follow1 follow2 |
+
+	p := 'a' asParser.
+	follow1 := ('b' asParser, 'c' asParser) / nil asParser.
+	follow2 := 'd' asParser.
+	
+	
+	root := (p, follow1, follow2).
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'd' ].
+!
+
+testFollowSet6
+	| result p root followSets followSet follow follow1 follow2 |
+
+	p := 'a' asParser.
+	follow1 := ('b' asParser, 'c' asParser) / nil asParser.
+	follow2 := 'd' asParser.
+	
+	follow := (follow1, follow2).
+	
+	root  := (p, follow).
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'd' ].
+!
+
+testFollowSet7
+	| result p root followSets followSet r1 r2 follow1 follow2 |
+
+	p := 'a' asParser.
+	follow1 := ('b' asParser, 'c' asParser) / nil asParser.
+	follow2 := 'd' asParser / nil asParser .
+	
+	r1 := (p, follow1).
+	r2 := (r1, follow2).
+	
+	root  := r2.
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'b' ].
+	self assert: followSet anySatisfy: [:e | e end matches: 'd' ].
+!
+
+testFollowSet8
+	| result p root followSets followSet follow |
+
+	p := 'a' asParser.
+	follow := PPInputEnds new.
+	
+	root := p, follow.
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: ''].
+!
+
+testFollowSet9
+	|  island1 followSet p root island2 block |
+
+	island1 := ('class' asParser, self identifier) island.
+	island2 := (':' asParser, self identifier) island.
+	block := '{' asParser, '}' asParser island.	
+
+	root := (island1, island2 optional, block) island.
+	
+	followSet := self follow: island1 in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: '{'].
+	self assert: followSet anySatisfy: [:e | e end matches: ':'].
+!
+
+testFollowSetChoice1
+	| result p root followSets followSet follow |
+
+	p := 'a' asParser.
+	follow := 'b' asParser / 'c' asParser .
+	
+	root := p, follow.
+
+	followSet := self follow: p in: root.
+	
+	self assert: followSet anySatisfy: [:e | (e parse: 'b') isPetitFailure not].
+	self assert: followSet anySatisfy: [:e | (e parse: 'c') isPetitFailure not].
+	self assert: followSet noneSatisfy: [:e | (e parse: 'a') isPetitFailure not].
+!
+
+testFollowSetChoice2
+	| result p root followSet follow b c |
+
+	follow := 'a' asParser / 'd' asParser.
+	b := 'b' asParser.
+	c := 'c' asParser.
+	p := b / c.
+	
+	root := p, follow.
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | (e parse: 'a') isPetitFailure not].
+	self assert: followSet anySatisfy: [:e | (e parse: 'd') isPetitFailure not].
+
+	followSet := self follow: p in: root.
+	
+	self assert: followSet anySatisfy: [:e | (e parse: 'a') isPetitFailure not].
+	self assert: followSet noneSatisfy: [:e | (e parse: 'c') isPetitFailure not].
+!
+
+testFollowSetOptional1
+	| result p root followSets followSet follow follow1 follow2 |
+
+	p := 'a' asParser.
+	follow1 := 'b' asParser optional.
+	follow2 := 'c' asParser.
+	
+	root := p, follow1, follow2.
+
+	followSet := self follow: p in: root.
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'b'].
+	self assert: followSet anySatisfy: [:e | e end matches: 'c'].
+	self assert: followSet noneSatisfy: [:e | e end matches: ''].
+!
+
+testFollowSetRepeat1
+	| p followSet terminal |
+
+	terminal := 'a' asParser.
+	p := terminal plus.
+	
+	followSet := self follow: terminal in: p.
+	self assert: followSet anySatisfy: [:e | e end matches: 'a' ].
+	self assert: followSet anySatisfy: [:e | e end matches: '' ].
+
+	followSet := self follow: p in: p.
+	self assert: followSet anySatisfy: [:e | e end matches: '' ].
+!
+
+testFollowSetStar1
+	| a b p followSet |
+
+	a := 'a' asParser star.
+	b := 'b' asParser.
+	p := a, b.
+	followSet := self follow: a in: p.
+	
+	self assert: followSet size: 1.
+	self assert: followSet anySatisfy: [:e | e end matches: 'b'].
+	self assert: followSet noneSatisfy: [:e | e end matches: ''].
+!
+
+testFollowSetStar3
+	| a b p followSet n |
+
+	a := 'a' asParser star.
+	p := a.
+	followSet := self follow: a in: p.
+	
+	self assert: followSet noneSatisfy: [:e | e end matches: 'a'].
+	self assert: followSet anySatisfy: [:e | e end matches: ''].
+!
+
+testFollowSetStar4
+	| a b p followSet |
+
+	a := 'a' asParser.
+	b := 'b' asParser.
+	p := a star, b.
+	followSet := self follow: a in: p.
+	
+	self assert: followSet size: 2.
+	self assert: followSet anySatisfy: [:e | e end matches: 'a'].
+	self assert: followSet anySatisfy: [:e | e end matches: 'b'].
+	self assert: followSet noneSatisfy: [:e | e end matches: ''].
+!
+
+testFollowSetStar5
+	| a b p followSet n |
+
+	a := 'a' asParser.
+	b := 'b' asParser.
+	n := nil asParser.
+	p := a star, (b / n).
+	followSet := self follow: a in: p.
+	
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'a'].
+	self assert: followSet anySatisfy: [:e | e end matches: 'b'].
+	self assert: followSet anySatisfy: [:e | e end matches: ''].
+!
+
+testFollowSetStar6
+	| a b p followSet n |
+
+	a := 'a' asParser.
+	p := a star.
+	followSet := self follow: a in: p.
+	
+
+	self assert: followSet anySatisfy: [:e | e end matches: 'a'].
+	self assert: followSet anySatisfy: [:e | e end matches: ''].
+! !
+
+!FirstFollowNextTests methodsFor:'test isNullable'!
+
+testIsNullable01
+	self assert:	'a' asParser acceptsEpsilon not.
+!
+
+testIsNullable02
+	self assert:	'a' asParser wrapped acceptsEpsilon not.
+!
+
+testIsNullable03
+	self assert:	nil asParser acceptsEpsilon.
+!
+
+testIsNullable04
+	self assert:	nil asParser wrapped acceptsEpsilon.
+!
+
+testIsNullable05
+	self assert:	 'a' asParser not acceptsEpsilon not.
+!
+
+testIsNullable06
+	self assert:	 'a' asParser and acceptsEpsilon not.
+!
+
+testIsNullable07
+	self assert:	 'a' asParser wrapped not acceptsEpsilon not.
+!
+
+testIsNullable08
+	self assert:	 'a' asParser wrapped and acceptsEpsilon not.
+!
+
+testIsNullable09
+	self assert:	 'a' asParser optional acceptsEpsilon.
+!
+
+testIsNullable10
+	self assert:	 'a' asParser wrapped optional acceptsEpsilon.
+!
+
+testIsNullable11
+	self assert:	 'a' asParser wrapped not optional acceptsEpsilon.
+!
+
+testIsNullable12
+	self assert:	 'a' asParser optional wrapped acceptsEpsilon.
+!
+
+testIsNullableChoice1
+	| a b c p |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	c := 'c' asParser.
+	
+	p := a / b / c.
+	
+	self assert: p acceptsEpsilon not.
+!
+
+testIsNullableChoice2
+	| a b c p |
+	a := 'a' asParser.
+	b := 'b' asParser optional.
+	c := 'c' asParser.
+	
+	p := a / b / c.
+	
+	self assert: p acceptsEpsilon.
+!
+
+testIsNullableChoice3
+	| a b c p |
+	a := 'a' asParser optional.
+	b := 'b' asParser optional.
+	c := 'c' asParser optional.
+	
+	p := a / b / c.
+	
+	self assert: p acceptsEpsilon.
+!
+
+testIsNullableChoice4
+	| a b c p |
+	a := 'a' asParser optional wrapped.
+	b := 'b' asParser optional wrapped.
+	c := 'c' asParser optional wrapped.
+	
+	p := a / b / c.
+	
+	self assert: p acceptsEpsilon.
+!
+
+testIsNullableCycle1
+	| a p |
+	a := 'a' asParser.
+	p := PPDelegateParser new.
+	
+	p setParser: a / p.
+	self assert: p acceptsEpsilon not.
+!
+
+testIsNullableCycle2
+	| a p e |
+	a := 'a' asParser.
+	e := nil asParser.
+	p := PPDelegateParser new.
+	
+	p setParser: (a, p) / e.
+	
+	self assert: p acceptsEpsilon.
+!
+
+testIsNullableCycle3
+	| a p e |
+	a := 'a' asParser.
+	e := nil asParser.
+	p := PPDelegateParser new.
+	
+	p setParser: (a, p), e.
+	
+	self assert: p acceptsEpsilon not.
+!
+
+testIsNullableSeq1
+	| a b c p |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	c := 'c' asParser.
+	
+	p := a, b, c.
+	
+	self assert: p acceptsEpsilon not.
+!
+
+testIsNullableSeq2
+	| a b c p |
+	a := 'a' asParser.
+	b := 'b' asParser optional.
+	c := 'c' asParser.
+	
+	p := a, b, c.
+	
+	self assert: p acceptsEpsilon not.
+!
+
+testIsNullableSeq3
+	| a b c p |
+	a := 'a' asParser optional.
+	b := 'b' asParser optional.
+	c := 'c' asParser optional.
+	
+	p := a, b, c.
+	
+	self assert: p acceptsEpsilon.
+!
+
+testIsNullableSeq4
+	| a b c p |
+	a := 'a' asParser optional wrapped.
+	b := 'b' asParser optional wrapped.
+	c := 'c' asParser wrapped optional.
+	
+	p := a, b, c.
+	
+	self assert: p acceptsEpsilon.
+! !
+
+!FirstFollowNextTests methodsFor:'test next'!
+
+testNext1
+	| p nextSet |
+	p := 'a' asParser.
+	
+	nextSet := (self next: p in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+!
+
+testNext2
+	| p nextSet a b |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	
+	p := a, b.
+	
+	nextSet := (self next: a in: p).
+	self assert: nextSet size: 1.
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	
+	nextSet := (self next: b in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+	
+	nextSet := (self next: p in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+!
+
+testNext3
+	| p nextSet a b |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	
+	p := a / b.
+	
+	nextSet := (self next: a in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+	
+	nextSet := (self next: b in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+	
+	nextSet := (self next: p in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+!
+
+testNext4
+	| p nextSet a b n |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	n := nil asParser.
+	
+	p := a, n, b.
+	
+	nextSet := (self next: a in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	
+	nextSet := (self next: n in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	
+	nextSet := (self next: b in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+!
+
+testNext5
+	| p nextSet a b n a1 a2 |
+	a1 := 'a1' asParser wrapped.
+	a2 := 'a2' asParser wrapped.
+	a := (a1 asParser, a2 asParser) wrapped.
+	b := 'b' asParser.
+	n := 'n' asParser optional.
+	
+	p := a, n, b.
+	
+	nextSet := (self next: a1 in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'a2'].
+
+	nextSet := (self next: a2 in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	"Might be test to match nb -- not sure, what is better"
+	self assert: nextSet anySatisfy: [:e | e end matches: 'n'].
+
+
+
+	nextSet := (self next: a in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	"Might be test to match nb -- not sure, what is better"
+	self assert: nextSet anySatisfy: [:e | e end matches: 'n'].
+	
+	nextSet := (self next: n in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	
+	nextSet := (self next: b in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+	self assert: nextSet noneSatisfy: [:e | e end matches: 'b'].	
+!
+
+testNext6
+	| p nextSet a b n a1 a2 |
+	a1 := 'a1' asParser wrapped.
+	a2 := 'a2' asParser wrapped / nil asParser.
+	a := (a1 asParser, a2 asParser) wrapped.
+	b := 'b' asParser.
+	n := 'nil' asParser optional.
+	
+	p := a, n, b.
+	
+	nextSet := (self next: a1 in: p).
+	self assert: nextSet anySatisfy: [:e | e matches: 'a2'].
+	self assert: nextSet anySatisfy: [:e | e matches: 'nilb'].
+	self assert: nextSet anySatisfy: [:e | e matches: 'b'].
+
+	nextSet := (self next: a2 in: p).
+	self assert: nextSet anySatisfy: [:e | e matches: 'nilb'].
+	self assert: nextSet anySatisfy: [:e | e matches: 'b'].
+
+
+	nextSet := (self next: a in: p).
+	self assert: nextSet anySatisfy: [:e | e matches: 'nilb'].
+	self assert: nextSet anySatisfy: [:e | e matches: 'b'].
+	
+	nextSet := (self next: n in: p).
+	self assert: nextSet anySatisfy: [:e | e matches: 'b'].
+	
+	nextSet := (self next: b in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+!
+
+testNext7
+	| p nextSet a b n  c |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	c := 'c' asParser.
+	n := nil asParser.
+	
+	p := a, b, a, n, c.
+	
+	nextSet := (self next: a in: p).
+
+	self assert: nextSet anySatisfy: [:e | e matches: 'b'].
+	self assert: nextSet anySatisfy: [:e | e matches: 'c'].
+
+!
+
+testNext8
+	| p nextSet a b n  c |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	c := 'c' asParser.
+	n := nil asParser.
+	
+	p := a, n, a, b, c.
+	
+	nextSet := (self next: a in: p).
+	self assert: nextSet anySatisfy: [:e | e matches: 'a'].
+	self assert: nextSet anySatisfy: [:e | e matches: 'b'].
+
+!
+
+testNext9
+	| a nextSet |
+	a := 'a' asParser.
+	
+	nextSet := (self next: a in: a).
+	self assert: nextSet anySatisfy: [:e | e end matches: ''].
+
+
+!
+
+testNextDelegate1
+
+	| a nextSet b c p |
+	a := 'a' asParser optional wrapped.
+	b := 'b' asParser optional wrapped.
+	c := 'c' asParser optional wrapped.
+	p := a, b, c.
+
+	nextSet := (self next: a in: p).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	self assert: nextSet anySatisfy: [:e | e end matches: 'c'].
+
+
+!
+
+testNextRepeat1
+	| p nextSet a b n  c |
+	a := 'a' asParser star.
+	
+	nextSet := (self next: a in: a).
+	self assert: nextSet size: 1.
+	self assert: nextSet anySatisfy: [:e | e end matches: '']
+!
+
+testNextRepeat2
+	| p nextSet a b astar |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	astar := a star.
+	
+	p := astar, b.
+	
+	nextSet := (self next: astar in: p).
+
+	self assert: nextSet size: 1.
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+
+
+!
+
+testNextRepeat3
+	| p nextSet a b astar |
+	a := 'a' asParser.
+	b := 'b' asParser.
+	
+	p := a star, b.
+	
+	nextSet := (self next: a in: p).
+
+	self assert: nextSet size: 2.
+	self assert: nextSet anySatisfy: [:e | e end matches: 'b'].
+	self assert: nextSet anySatisfy: [:e | e end matches: 'a'].
+!
+
+testNextRepeat4
+	| a nextSet b p root |
+	a := 'a' asParser.
+	b := 'b' asParser optional.
+	
+	p := a, b.
+	root := p plus.
+	
+	nextSet := (self next: a in: root).
+	self assert: nextSet anySatisfy: [:e | e end matches: 'a'].
+
+
+! !
+