compiler/tests/PPCNodeFirstFollowNextTests.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Mon, 24 Nov 2014 00:09:23 +0000
changeset 421 7e08b31e0dae
child 422 116d2b2af905
permissions -rw-r--r--
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
! !