--- a/compiler/PPCScanner.st Fri Jul 31 14:07:31 2015 +0100
+++ b/compiler/PPCScanner.st Mon Aug 17 12:56:02 2015 +0100
@@ -3,14 +3,35 @@
"{ NameSpace: Smalltalk }"
Object subclass:#PPCScanner
- instanceVariableNames:'matches stream maxPriority currentChar'
+ instanceVariableNames:'match matchPosition matches tokens stream currentChar
+ maxSymbolNumber position'
classVariableNames:''
poolDictionaries:''
category:'PetitCompiler-Scanner'
!
+!PPCScanner class methodsFor:'as yet unclassified'!
+
+acceptsLoggingOfCompilation
+" ^ self == PPCScanner"
+ ^ true
+! !
+
!PPCScanner methodsFor:'accessing'!
+maxSymbolNumber
+ ^ maxSymbolNumber
+!
+
+maxSymbolNumber: value
+ maxSymbolNumber := value
+!
+
+position
+ "returns the start position before the scan method..."
+ ^ position
+!
+
stream
^ stream
!
@@ -19,49 +40,185 @@
stream := anObject
! !
-!PPCScanner methodsFor:'as yet unclassified'!
-
-recordMatch: match
- ^ self recordMatch: match priority: 0
-!
-
-recordMatch: match priority: currentPriority
- (maxPriority < currentPriority) ifTrue: [
- matches := IdentityDictionary new.
- maxPriority := currentPriority.
- ].
-
- (maxPriority == currentPriority) ifTrue: [
- matches at: match put: stream position
- ].
-!
-
-return
- ^ self returnPriority: SmallInteger minVal.
-!
-
-returnPriority: priority
- (maxPriority < priority) ifTrue: [
- ^ IdentityDictionary new
- ].
- ^ matches keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ]
-! !
-
!PPCScanner methodsFor:'initialization'!
initialize
super initialize.
- matches := IdentityDictionary new.
- maxPriority := SmallInteger minVal.
+
+ maxSymbolNumber := self class classVarNamed: #MaxSymbolNumber.
+ tokens := self class classVarNamed: #Tokens.
+
+ matches := Array new: maxSymbolNumber withAll: -2.
+ position := 0.
+!
+
+reset
+ matchPosition := nil. "This flag says that multimode run the last time"
+
+ position := stream position.
+" matches := Array new: maxSymbolNumber."
+!
+
+reset: tokenList
+ "Method should not be used, it is here for debugging and testing purposes"
+ self error: 'deprecated'.
+
+ matchPosition := nil. "This flag says that multimode run the last time"
+
+ tokens := tokenList.
+ matches := Array new: tokens size.
+
+!
+
+resetDistinct
+" matches := IdentityDictionary new. "
+ match := nil.
+ matchPosition := -1. "this is a flag that the distnict mode was running"
+" matches := nil."
+
+ position := stream position.
+
+! !
+
+!PPCScanner methodsFor:'results'!
+
+backtrack
+ matchPosition := nil.
+ match := nil.
+ matches := Array new: maxSymbolNumber withAll: -2.
+ position := 0.
+!
+
+backtrackDistinct
+ matchPosition := nil.
+ match := nil.
+ position := 0.
+!
+
+backtracked
+ ^ position == 0
+!
+
+indexOf: symbol
+ (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [^ index ] ].
+!
+
+match
+" ^ match isNil not."
+ ^ match isNotNil
+" ^ matchPosition isNil not"
+!
+
+match: symbolNumber
+" matches isNil ifTrue: [ ^ false ]."
+
+ "
+ The general idea here is optimization. I cannot initialize
+ the matches before each token, it would be too expensive.
+ "
+ ^ (matches at: symbolNumber) > position
+!
+
+matchSymbol: symbol
+ matches isNil ifTrue: [ ^ false ].
+ (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [
+ ^ (matches at: index) > position
+ ] ].
+!
+
+polyResult
+ | dictionary |
+ "TODO JK: refactor"
+ self isSingleMatch ifFalse: [
+ dictionary := IdentityDictionary new.
+ (1 to: matches size) do: [ :index |
+ (self match: index) ifTrue: [
+ dictionary
+ at: (tokens at: index)
+ put: (matches at: index)
+ ]
+ ].
+ ^ dictionary
+ ].
+
+ dictionary := IdentityDictionary new.
+ match isNil ifFalse: [
+ dictionary at: match put: matchPosition.
+ ].
+
+ ^ dictionary
+!
+
+result
+ ^ match
+!
+
+resultPosition
+ ^ matchPosition
+!
+
+resultPosition: symbolNumber
+ ^ matches at: symbolNumber
+!
+
+resultPositionForSymbol: symbol
+ tokens isNil ifTrue: [ ^ false ].
+ (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [
+ ^ matches at: index
+ ] ].
+! !
+
+!PPCScanner methodsFor:'results - distinct'!
+
+recordDistinctMatch: matchValue
+ match := matchValue.
+ matchPosition := stream position.
+!
+
+recordDistinctMatch: matchValue offset: offset
+ match := matchValue.
+ currentChar isNil ifFalse: [
+ matchPosition := stream position - offset.
+ ] ifTrue: [
+ matchPosition := stream position.
+ ]
+!
+
+returnDistinct
+ ^ match isNotNil
+! !
+
+!PPCScanner methodsFor:'results - universal'!
+
+recordFailure: index
+ matches at: index put: -1.
+!
+
+recordFailure: index offset: offset
+ matches at: index put: -1.
+!
+
+recordMatch: index
+ matches at: index put: stream position.
+!
+
+recordMatch: index offset: offset
+ currentChar isNil ifFalse: [
+ matches at: index put: stream position - offset.
+ ] ifTrue: [
+ matches at: index put: stream position.
+ ].
+
+!
+
+return
+ ^ matches
! !
!PPCScanner methodsFor:'scanning'!
-consumeConditionally: character
- (stream peek == character) ifTrue: [ stream next. ^ true ] ifFalse: [ ^ false ]
-!
-
next
+ self error: 'deprecated?'.
stream next
!
@@ -71,10 +228,16 @@
peekBetween: start and: stop
(currentChar == nil) ifTrue: [ ^ false ].
- ^ start <= currentChar codePoint and: [ currentChar codePoint <= stop ]
+ ^ (start <= currentChar codePoint) and: [ currentChar codePoint <= stop ]
!
step
currentChar := stream next
! !
+!PPCScanner methodsFor:'testing'!
+
+isSingleMatch
+ ^ (matchPosition == nil) not
+! !
+