--- a/compiler/PPCSequenceNode.st Wed Nov 19 10:52:37 2014 +0000
+++ b/compiler/PPCSequenceNode.st Mon Nov 24 00:09:23 2014 +0000
@@ -35,6 +35,21 @@
child acceptsEpsilon ifFalse: [ ^ aCollection ]
].
^ aCollection
+!
+
+firstSets: aFirstDictionary into: aSet suchThat: aBlock
+ | nullable |
+
+ "TODO JK: aBlock is ignored by now"
+ children do: [ :node |
+ nullable := false.
+ (aFirstDictionary at: node) do: [ :each |
+ each isNullable
+ ifTrue: [ nullable := true ]
+ ifFalse: [ aSet add: each ] ].
+ nullable
+ ifFalse: [ ^ self ] ].
+ aSet add: PPCSentinelNode instance
! !
!PPCSequenceNode methodsFor:'compiling'!
@@ -73,6 +88,8 @@
compiler add: 'retval := Array new: ', children size asString, '.'.
self addGuard: compiler id: id.
+" Halt if: [ self name = #qualifiedName ]."
+
(1 to: children size) do: [ :idx | |child|
child := children at: idx.
compiler add: 'element := '.
@@ -85,12 +102,33 @@
^ compiler stopMethod.
! !
+!PPCSequenceNode methodsFor:'first follow next'!
+
+followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet suchThat: aBlock
+ children keysAndValuesDo: [ :index :node |
+ | follow first |
+ follow := aFollowDictionary at: node.
+ index = children size
+ ifTrue: [ follow addAll: aSet ]
+ ifFalse: [
+ (self class withAll: (children
+ copyFrom: index + 1 to: children size))
+ firstSets: aFirstDictionary
+ into: (first := IdentitySet new)
+ suchThat: aBlock.
+ (first anySatisfy: [ :each | each isNullable ])
+ ifTrue: [ follow addAll: aSet ].
+ follow addAll: (first
+ reject: [ :each | each isNullable ]) ] ]
+! !
+
!PPCSequenceNode methodsFor:'optimizing'!
asFast
^ PPCTokenSequenceNode new
children: children;
name: self name;
+ properties: properties;
yourself
! !