diff -r a409905f7f2d -r e2b2ccaa4de6 islands/tests/FirstFollowNextTests.st --- /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']. + + +! ! +