compiler/PEGFsaInterpret.st
changeset 515 b5316ef15274
parent 502 1e45d3c96ec5
child 516 3b81c9e53352
--- a/compiler/PEGFsaInterpret.st	Fri Jul 24 15:06:54 2015 +0100
+++ b/compiler/PEGFsaInterpret.st	Mon Aug 17 12:13:16 2015 +0100
@@ -3,12 +3,20 @@
 "{ NameSpace: Smalltalk }"
 
 Object subclass:#PEGFsaInterpret
-	instanceVariableNames:'fsa debug retvals stream maxPriority'
+	instanceVariableNames:'fsa debug retvals stream'
 	classVariableNames:''
 	poolDictionaries:''
 	category:'PetitCompiler-FSA'
 !
 
+!PEGFsaInterpret class methodsFor:'instance creation'!
+
+new
+    "return an initialized instance"
+
+    ^ self basicNew initialize.
+! !
+
 !PEGFsaInterpret methodsFor:'accessing'!
 
 debug
@@ -21,6 +29,10 @@
 
 fsa
     ^ fsa
+!
+
+recordFor: retval
+    ^ retvals at: retval ifAbsentPut: [ PEGFsaInterpretRecord new ]
 ! !
 
 !PEGFsaInterpret methodsFor:'debugging'!
@@ -54,7 +66,6 @@
 
 interpret
     | states newStates character run  |
-    maxPriority := SmallInteger minVal.
     newStates := IdentitySet with: fsa startState.
     retvals := IdentityDictionary new.
     
@@ -63,12 +74,12 @@
     self reportStart.
     self reportFsa: fsa.
     
-    run := stream atEnd not.
+    run := "stream atEnd not" true.
     
     [run] whileTrue: [  
         states := newStates.
         newStates := IdentitySet new.
-        character := stream peek.
+        character := stream peek codePoint.
 
         self reportStates: states.
 
@@ -77,10 +88,9 @@
         ].
         
         newStates isEmpty ifFalse: [ stream next ].
-        run := stream atEnd not and: [ newStates isEmpty not ].
+        run := "stream atEnd not and: [ "newStates isEmpty not" ]".
     ].
-
-    ^ self return: newStates
+    ^ self return: states
 !
 
 interpret: anFsa on: aStream
@@ -104,36 +114,24 @@
     ^ true
 !
 
-expand: state on: character into: newStates "transitionsTaken: transitionsTaken"
-    | transitions transitionsTaken |
-
-    transitionsTaken := OrderedCollection new.
-    transitions := self sortedTransitionsFor: state.
-    transitions do: [ :t | 
-        (self allowsTransition: t from: state transitionsTaken: transitionsTaken) ifTrue: [ 
-            t isEpsilon ifTrue: [  
-                (t destination isFinal) ifTrue: [ 
-                    newStates add: t destination.
-                    self recordNewState: t destination position: stream position.
-                ].
+expand: state on: codePoint into: newStates
+    state transitions do: [ :t | 
+        t isEpsilon ifTrue: [  
+            (t destination isFinal) ifTrue: [ 
+                newStates add: t destination.
+                self recordNewState: t destination position: stream position.
+            ].
 
-                "Descent into the next state"
-                self 	expand: t destination 
-                        on: character 
-                        into: newStates.
-
-                newStates isEmpty ifFalse: [ 
-                    transitionsTaken add: t.
-                ].
-
-            ] ifFalse: [  
-                (t accepts: character) ifTrue: [ 
-                    transitionsTaken add: t.
-                    newStates add: t destination.
-                    self recordNewState: t destination.
-                ]
-            ] 
-        ]
+            "Descent into the next state"
+            self 	expand: t destination 
+                    on: codePoint 
+                    into: newStates.
+        ] ifFalse: [  
+            (t acceptsCodePoint: codePoint) ifTrue: [ 
+                newStates add: t destination.
+                self recordNewState: t destination.
+            ]
+        ] 
     ]
 !
 
@@ -142,35 +140,38 @@
 !
 
 recordNewState: state position: position
-    (state isFinal) ifFalse: [ ^ self ].
-    (maxPriority > state priority) ifTrue: [ ^ true ].
-        
-    self assert: state hasPriority description: 'final state must have priority'.
-    (maxPriority < state priority) ifTrue: [ 
-        retvals := IdentityDictionary new.
-        maxPriority := state priority.
+    | currentRecord |
+    (state isFinal) ifFalse: [ 
+        ^ self 
     ].
 
+    (state isFinal) ifFalse: [ self error: 'should not happen' ].
+    self assert: state hasPriority description: 'final state must have priority'.
 
-    state retvalAsCollection do: [ :r |
-        retvals at: r put: position
+    state retvalsAndInfosDo: [ :retval :info |
+        currentRecord := self recordFor: retval.
+        info isFsaFailure ifTrue: [ 
+            "JK: hack, nil refers to failure!! :( Refactor!!"
+            currentRecord position: nil
+        ] ifFalse: [ 
+     		currentRecord position: position	
+        ]
     ].
 !
 
 return: states
-    | priority priorities |
-    priorities := (states select: #hasPriority thenCollect: #priority).
-    priorities isEmpty ifTrue: [  
-        ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ] 
+    | return |
+    return := IdentityDictionary new.
+    retvals keysAndValuesRemove: [ :key :record | record position isNil ].
+
+    retvals keysAndValuesDo: [ :key :value |
+        return at: key put: value position
     ].
-    
-    priority := priorities max.
-    
-    (maxPriority < priority) ifTrue: [ ^ IdentityDictionary new ].
-    ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ]
+    ^ return
 !
 
 sortedTransitionsFor: state
+    self error: 'deprecated!!'.
     ^ (fsa transitionsFor: state) asOrderedCollection
         "Dear future me, enjoy this:"
 "		sort: [ :e1 :e2 | (e1 isEpsilon not and: [e2 isEpsilon]) not ])"