Portability: fixed RBLiteralValueNode>>isLiteralNumber to work under both - Pharo and Smalltalk/X
"{ Package: 'stx:goodies/petitparser/compiler' }"
"{ NameSpace: Smalltalk }"
Object subclass:#PPCScanner
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
!
stream: anObject
stream := anObject
! !
!PPCScanner methodsFor:'initialization'!
initialize
super initialize.
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'!
next
self error: 'deprecated?'.
stream next
!
peek
^ currentChar
!
peekBetween: start and: stop
(currentChar == nil) ifTrue: [ ^ false ].
^ (start <= currentChar codePoint) and: [ currentChar codePoint <= stop ]
!
step
currentChar := stream next
! !
!PPCScanner methodsFor:'testing'!
isSingleMatch
^ (matchPosition == nil) not
! !