Merged JK's version from Monticello
Name: PetitParser-JanKurs.260
Author: JanKurs
Time: 17-11-2014, 12:09:05.490 PM
UUID: 07411cef-ef69-40db-9d93-d4018a9b34ef
Name: PetitTests-JanKurs.65
Author: JanKurs
Time: 17-11-2014, 12:09:04.530 PM
UUID: f98d613f-f4ce-4e0e-a7e9-310ee7c7e7a6
Name: PetitSmalltalk-JanKurs.78
Author: JanKurs
Time: 14-11-2014, 05:05:07.765 PM
UUID: 3d68330d-44d5-46c3-9705-97f627b3edbc
Name: PetitCompiler-JanKurs.71
Author: JanKurs
Time: 18-11-2014, 09:48:35.425 AM
UUID: 06352c33-3c76-4382-8536-0cc48e225117
Name: PetitCompiler-Tests-JanKurs.21
Author: JanKurs
Time: 17-11-2014, 05:51:53.134 PM
UUID: 8d6c0799-14e7-4871-8d91-8b0f9886db83
Name: PetitCompiler-Benchmarks-JanKurs.2
Author: JanKurs
Time: 17-11-2014, 05:51:07.887 PM
UUID: d5e3a980-7871-487a-a232-e3ca93fc2483
"{ Package: 'stx:goodies/petitparser/compiler/tests' }"
TestCase subclass:#PPCNodeFirstFollowNextTests
instanceVariableNames:'tree first node followSet'
classVariableNames:''
poolDictionaries:''
category:'PetitCompiler-Tests-Nodes'
!
!PPCNodeFirstFollowNextTests methodsFor:'as yet unclassified'!
assert: set anyMatchesType: whatever
self assert: (set anySatisfy: [:e | e isKindOf: whatever ])
!
assert: set anySatisfy: whateverBlock
self assert: (set anySatisfy: [:e | [whateverBlock value: e] on: Error do: [ false ] ])
!
assert: set noneMatchesType: whatever
self assert: (set noneSatisfy: [:e | e isKindOf: whatever ])
!
assert: set noneSatisfy: whateverBlock
self assert: (set noneSatisfy: [:e | [whateverBlock value: e] on: Error do: [ false ] ])
!
assert: set size: anInteger
self assert: (set size = anInteger )
!
first: aNode
^ aNode firstSet
!
first: aNode suchThat: aBlock
^ (aNode firstSetsSuchThat: aBlock) at: aNode
!
followOf: name in: rootNode
node := (rootNode allNodes select: [ :n | n name = name ] )anyOne.
^ rootNode followSets at: node
!
followOf: name in: rootNode suchThat: aBlock
node := (rootNode allNodes select: [ :n | n name = name ] )anyOne.
^ (rootNode followSetsSuchThat: aBlock) at: node
!
followOfNodeIn: rootNode
^ self followOf: 'node' in: rootNode
!
testFirst1
tree := self treeFrom: nil asParser / 'a' asParser.
self assert: (self first: tree) anyMatchesType: PPCNilNode.
self assert: (self first: tree) anyMatchesType: PPCAbstractLiteralNode.
!
testFirst2
tree := self treeFrom: 'a' asParser optional, 'b' asParser.
self assert: (self first: tree) anySatisfy: [ :e | e literal = 'a' ].
self assert: (self first: tree) anySatisfy: [ :e | e literal = 'b' ].
!
testFirst3
tree := ('a' asParser optional, 'b' asParser asParser optional), 'c' asParser.
self assert: (self first: tree) anySatisfy: [ :e | e literal = 'a' ].
self assert: (self first: tree) anySatisfy: [ :e | e literal = 'b' ].
self assert: (self first: tree) anySatisfy: [ :e | e literal = 'c' ].
!
testFirstChoice1
tree := self treeFrom: nil asParser / '' asParser.
self assert: (self first: tree) anySatisfy: [:e | e literal = ''].
self assert: (self first: tree) anyMatchesType: PPCNilNode.
!
testFirstChoice2
tree := self treeFrom: 'a' asParser / nil asParser / 'b' asParser.
first := (self first: tree).
self assert: first anySatisfy: [:e | e literal = 'a'].
self assert: first anySatisfy: [:e | e literal = 'b'].
self assert: first anyMatchesType: PPCNilNode.
!
testFirstComplex1
tree := self treeFrom: ('a' asParser / nil asParser), 'c' asParser.
first := (self first: tree).
self assert: first size: 2.
self assert: first anySatisfy: [:e | e literal = 'a'].
self assert: first anySatisfy: [:e | e literal = 'c'].
self assert: first noneMatchesType: PPCNilNode.
!
testFirstComplex2
tree := self treeFrom: ('a' asParser / nil asParser / 'b' asParser), 'c' asParser.
first := (self first: tree).
self assert: first size: 3.
self assert: first anySatisfy: [:e | e literal = 'a'].
self assert: first anySatisfy: [:e | e literal = 'b'].
self assert: first anySatisfy: [:e | e literal = 'c'].
!
testFirstComplex3
tree := self treeFrom: ('a' asParser / nil asParser / 'b' asParser), 'c' asParser not.
first := (self first: tree).
self assert: first anySatisfy: [:e | e literal = 'a'].
self assert: first anySatisfy: [:e | e literal = 'b'].
self assert: first anySatisfy: [:e | (e isKindOf: PPCNotLiteralNode) and: [e literal = 'c']].
!
testFirstComplex4
tree := (('a' asParser / nil asParser / 'b' asParser), 'c' asParser not) wrapped asCompilerTree.
first := (self first: tree).
self assert: first anySatisfy: [:e | e literal = 'a'].
self assert: first anySatisfy: [:e | e literal = 'b'].
self assert: first anySatisfy: [:e | (e isKindOf: PPCNotNode) and: [ e child literal = 'c' ]].
self assert: first noneMatchesType: PPCNilNode.
!
testFirstNegate1
tree := ('a' asParser negate, 'b' asParser) asCompilerTree.
first := self first: tree.
self assert: first size: 1.
self assert: first anyMatchesType: PPCNotNode
!
testFirstNot
tree := ('a' asParser not star, 'b' asParser) asCompilerTree.
first := self first: tree.
self assert: first size: 2.
self assert: first anyMatchesType: PPCNotNode.
!
testFirstNot2
tree := ('a' asParser not star, 'b' asParser) asCompilerTree optimizeTree.
first := self first: tree.
self assert: first size: 2.
self assert: first anyMatchesType: PPCNotLiteralNode.
self assert: first anyMatchesType: PPCLiteralNode.
!
testFirstNot3
tree := (#letter asParser not star, #letter asParser) asCompilerTree optimizeTree.
first := self first: tree.
self assert: first size: 2.
self assert: first anyMatchesType: PPCNotMessagePredicateNode.
self assert: first anyMatchesType: PPCMessagePredicateNode.
!
testFirstNot4
tree := (#letter asParser negate plus, #letter asParser) asCompilerTree optimizeTree.
first := self first: tree.
self assert: first size: 1.
self assert: (first anyOne predicate value: $a) not.
self assert: (first anyOne predicate value: $1).
!
testFirstNot5
tree := (#letter asParser negate star, #letter asParser) asCompilerTree optimizeTree.
first := self first: tree.
self assert: first size: 2.
self assert: first anySatisfy: [ :e | (e predicate value: $a) not ].
self assert: first anySatisfy: [ :e | (e predicate value: $1) ].
self assert: first anySatisfy: [ :e | (e predicate value: $a) ].
self assert: first anySatisfy: [ :e | (e predicate value: $1) not ].
!
testFirstOptional
tree := 'a' asParser optional asCompilerTree.
first := (self first: tree).
self assert: first anyMatchesType: PPCNilNode.
self assert: first anyMatchesType: PPCLiteralNode.
!
testFirstOptional2
tree := ('a' asParser optional, 'b' asParser) asCompilerTree.
first := (self first: tree).
self assert: first size: 2.
self assert: first anySatisfy: [ :e | e literal = 'a' ].
self assert: first anySatisfy: [ :e | e literal = 'b' ].
!
testFirstRepeat1
tree := ('a' asParser / nil asParser) plus asCompilerTree.
first := self first: tree.
self assert: first anySatisfy: [:e | e literal = 'a' ].
self assert: first anyMatchesType: PPCNilNode.
!
testFirstRepeat2
tree := ('a' asParser star, 'b' asParser) asCompilerTree.
first := self first: tree.
self assert: first anySatisfy: [:e | e literal = 'a' ].
self assert: first anySatisfy: [:e | e literal = 'b' ].
!
testFirstRepeat3
tree := ('a' asParser negate plus, 'b' asParser) asCompilerTree.
first := self first: tree.
self assert: first size: 1.
self assert: first anyMatchesType: PPCNotNode.
!
testFirstRepeat4
tree := ('a' asParser negate star, 'b' asParser) asCompilerTree.
first := self first: tree.
self assert: first size: 2.
self assert: first anySatisfy: [:e | (e isKindOf: PPCNotNode) and: [e child literal = 'a']].
self assert: first anySatisfy: [ :e | e literal = 'b' ]
!
testFirstSequence1
tree := self treeFrom: 'a' asParser, 'b' asParser .
first := self first: tree.
self assert: first size: 1.
self assert: first anySatisfy: [ :e | e literal = 'a' ].
!
testFirstSequence2
tree := nil asParser, 'a' asParser, 'b' asParser .
first := self first: tree.
self assert: first size: 1.
self assert: first anySatisfy: [ :e | e literal = 'a' ].
!
testFirstSequence3
tree := self treeFrom: nil asParser, nil asParser.
first := self first: tree.
self assert: first size: 1.
self assert: first anyMatchesType: PPCNilNode.
!
testFirstSequence4
tree := self treeFrom: ((nil asParser / 'a' asParser) plus), 'b' asParser.
first := self first: tree.
self assert: first size: 2.
self assert: first anySatisfy: [ :e | e literal = 'a' ].
self assert: first anySatisfy: [ :e | e literal = 'b' ].
self assert: first noneMatchesType: PPCNilNode.
!
testFirstSequence5
tree := ((nil asParser / 'a' asParser) star), 'b' asParser.
first := self first: tree.
self assert: first size: 2.
self assert: first anySatisfy: [ :e | e literal = 'a' ].
self assert: first anySatisfy: [ :e | e literal = 'b' ].
self assert: first noneMatchesType: PPCNilNode.
!
testFirstTerminal
tree := self treeFrom: 'a' asParser not.
first := self first: tree.
self assert: first size: 1.
self assert: (self first: tree) anyMatchesType: PPCNotLiteralNode.
!
testFirstTerminal2
tree := self treeFrom: 'a' asParser and.
first := self first: tree.
self assert: first size: 1.
self assert: first anySatisfy: [: e | e literal = 'a' ]
!
testFirstTrimmingToken
tree := self treeFrom: 'a' asParser trimmingToken.
first := self first: tree
suchThat: [:e | (e isKindOf: PPCTrimmingTokenNode) or: [e isFirstSetTerminal]].
self assert: first size: 1.
self assert: first anyMatchesType: PPCTrimmingTokenNode
!
testFollowSet1
node := 'a' asParser name: 'node'; yourself.
tree := self treeFrom: (node star, 'b' asParser).
followSet := self followOfNodeIn: tree.
self assert: followSet size: 2.
self assert: followSet anySatisfy: [:e | e literal = 'a'].
self assert: followSet anySatisfy: [:e | e literal = 'b'].
!
testFollowSet10
| a b c |
a := 'a' asParser name: 'a'; yourself.
b := 'b' asParser optional name: 'b'; yourself.
c := 'c' asParser name: 'c'; yourself.
tree := self treeFrom: a plus, b, c.
followSet := self followOf: 'a' in: tree.
self assert: followSet size: 3.
self assert: followSet anySatisfy: [:e | e literal = 'a' ].
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'c' ].
!
testFollowSet2
| follow |
node := 'a' asParser name: 'node'; yourself.
follow := 'b' asParser, 'c' asParser.
tree := self treeFrom: (node, follow).
followSet := self followOfNodeIn: tree.
self assert: followSet size: 1.
self assert: followSet anySatisfy: [:e | e literal = 'b'].
self assert: followSet noneSatisfy: [:e | e literal = 'c'].
!
testFollowSet3
| follow |
node := 'a' asParser name: 'node'; yourself.
follow := ('b' asParser, 'c' asParser) / ('d' asParser).
tree := self treeFrom: (node, follow).
followSet := self followOfNodeIn: tree.
self assert: followSet size: 2.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'd' ].
!
testFollowSet4
| follow |
node := 'a' asParser name: 'node'; yourself.
follow := ('b' asParser, 'c' asParser).
tree := self treeFrom: (node star, follow).
followSet := self followOfNodeIn: tree.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'a' ].
!
testFollowSet5
| follow1 follow2 |
node := 'a' asParser name: 'node'; yourself.
follow1 := ('b' asParser, 'c' asParser) / nil asParser.
follow2 := 'd' asParser.
tree := self treeFrom: (node, follow1, follow2).
followSet := self followOfNodeIn: tree.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'd' ].
!
testFollowSet6
| follow follow1 follow2 |
node := 'a' asParser name: 'node'; yourself.
follow1 := ('b' asParser, 'c' asParser) / nil asParser.
follow2 := 'd' asParser.
follow := (follow1, follow2).
tree := self treeFrom: (node, follow).
followSet := self followOfNodeIn: tree.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'd' ].
!
testFollowSet7
| r1 r2 follow1 follow2 |
node := 'a' asParser name: 'node'; yourself.
follow1 := ('b' asParser, 'c' asParser) / nil asParser.
follow2 := 'd' asParser / nil asParser .
r1 := (node, follow1).
r2 := (r1, follow2).
tree := self treeFrom: r2.
followSet := self followOfNodeIn: tree.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'd' ].
!
testFollowSet8
node := 'a' asParser name: 'node'; yourself.
tree := self treeFrom: node.
followSet := self followOfNodeIn: tree.
self assert: followSet anyMatchesType: PPCNilNode.
!
testFollowSet9
| a b c |
a := 'a' asParser name: 'a'; yourself.
b := 'b' asParser optional name: 'b'; yourself.
c := 'c' asParser name: 'c'; yourself.
tree := self treeFrom: a, b, c.
followSet := self followOf: 'c' in: tree.
self assert: followSet anyMatchesType: PPCNilNode.
followSet := self followOf: 'b' in: tree.
self assert: followSet anySatisfy: [:e | e literal = 'c' ].
followSet := self followOf: 'a' in: tree.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'c' ].
!
testFollowSetChoice1
| follow |
node := 'a' asParser name: 'node'; yourself.
follow := 'b' asParser / 'c' asParser .
tree := self treeFrom: node, follow.
followSet := self followOfNodeIn: tree.
self assert: followSet size: 2.
self assert: followSet anySatisfy: [:e | e literal = 'b' ].
self assert: followSet anySatisfy: [:e | e literal = 'c' ].
!
testFollowSetOptional1
| follow1 follow2 |
node := 'a' asParser name: 'node'; yourself.
follow1 := 'b' asParser optional.
follow2 := 'c' asParser.
tree := self treeFrom: node, follow1, follow2.
followSet := self followOfNodeIn: tree.
self assert: followSet size: 2.
self assert: followSet anySatisfy: [:e | e literal = 'b'].
self assert: followSet anySatisfy: [:e | e literal = 'c'].
!
testFollowSetRepeat1
node := 'a' asParser name: 'node'; yourself.
tree := self treeFrom: node plus.
followSet := self followOfNodeIn: tree.
self assert: followSet anySatisfy: [:e | e literal = 'a' ].
self assert: followSet anyMatchesType: PPCNilNode
!
testFollowSetRepeat2
node := 'a' asParser.
tree := self treeFrom: (node plus name: 'node'; yourself).
followSet := self followOfNodeIn: tree.
self assert: followSet size: 1.
self assert: followSet anyMatchesType: PPCNilNode
!
testFollowTrimmingToken
| token1 token2 |
token1 := #letter asParser plus trimmingToken name: 'token1'; yourself.
token2 := #letter asParser plus trimmingToken name: 'token2'; yourself.
tree := self treeFrom: token1, token2.
followSet := self followOf: 'token1'
in: tree
suchThat: [:e | e isFirstSetTerminal or: [e isKindOf: PPCTrimmingTokenNode ]].
self assert: followSet size: 1.
self assert: followSet anyMatchesType: PPCTrimmingTokenNode.
!
treeFrom: parser
^ parser asCompilerTree optimizeTree
! !