--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/compiler/tests/PPCNodeFirstFollowNextTests.st Mon Nov 24 00:09:23 2014 +0000
@@ -0,0 +1,559 @@
+"{ 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
+! !
+