compiler/PPCScanner.st
changeset 516 3b81c9e53352
parent 507 c5773c25eedc
parent 515 b5316ef15274
child 525 751532c8f3db
equal deleted inserted replaced
514:46dd1237b20a 516:3b81c9e53352
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     2 
     2 
     3 "{ NameSpace: Smalltalk }"
     3 "{ NameSpace: Smalltalk }"
     4 
     4 
     5 Object subclass:#PPCScanner
     5 Object subclass:#PPCScanner
     6 	instanceVariableNames:'matches stream maxPriority currentChar'
     6 	instanceVariableNames:'match matchPosition matches tokens stream currentChar
       
     7 		maxSymbolNumber position'
     7 	classVariableNames:''
     8 	classVariableNames:''
     8 	poolDictionaries:''
     9 	poolDictionaries:''
     9 	category:'PetitCompiler-Scanner'
    10 	category:'PetitCompiler-Scanner'
    10 !
    11 !
    11 
    12 
       
    13 !PPCScanner class methodsFor:'as yet unclassified'!
       
    14 
       
    15 acceptsLoggingOfCompilation
       
    16 "	^ self == PPCScanner"
       
    17     ^ true
       
    18 ! !
       
    19 
    12 !PPCScanner methodsFor:'accessing'!
    20 !PPCScanner methodsFor:'accessing'!
       
    21 
       
    22 maxSymbolNumber
       
    23     ^ maxSymbolNumber
       
    24 !
       
    25 
       
    26 maxSymbolNumber: value
       
    27     maxSymbolNumber := value
       
    28 !
       
    29 
       
    30 position
       
    31     "returns the start position before the scan method..."
       
    32     ^ position
       
    33 !
    13 
    34 
    14 stream
    35 stream
    15     ^ stream
    36     ^ stream
    16 !
    37 !
    17 
    38 
    18 stream: anObject
    39 stream: anObject
    19     stream := anObject
    40     stream := anObject
    20 ! !
    41 ! !
    21 
    42 
    22 !PPCScanner methodsFor:'as yet unclassified'!
       
    23 
       
    24 recordMatch: match 
       
    25  	^ self recordMatch: match priority: 0
       
    26 !
       
    27 
       
    28 recordMatch: match priority: currentPriority
       
    29     (maxPriority < currentPriority) ifTrue: [ 
       
    30         matches := IdentityDictionary new.
       
    31         maxPriority := currentPriority.
       
    32     ].
       
    33          
       
    34     (maxPriority == currentPriority) ifTrue: [ 
       
    35      	matches at: match put: stream position
       
    36  	].
       
    37 !
       
    38 
       
    39 return
       
    40     ^ self returnPriority: SmallInteger minVal.
       
    41 !
       
    42 
       
    43 returnPriority: priority
       
    44     (maxPriority < priority) ifTrue: [ 
       
    45         ^ IdentityDictionary new
       
    46     ].
       
    47     ^ matches keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ]
       
    48 ! !
       
    49 
       
    50 !PPCScanner methodsFor:'initialization'!
    43 !PPCScanner methodsFor:'initialization'!
    51 
    44 
    52 initialize
    45 initialize
    53     super initialize.
    46     super initialize.
    54     matches := IdentityDictionary new.	
    47     
    55     maxPriority := SmallInteger minVal.
    48     maxSymbolNumber := self class classVarNamed: #MaxSymbolNumber.
       
    49     tokens := self class classVarNamed: #Tokens.
       
    50     
       
    51     matches := Array new: maxSymbolNumber withAll: -2.
       
    52     position := 0.
       
    53 !
       
    54 
       
    55 reset
       
    56     matchPosition := nil. "This flag says that multimode run the last time"
       
    57 
       
    58     position := stream position.
       
    59 "	matches := Array new: maxSymbolNumber."
       
    60 !
       
    61 
       
    62 reset: tokenList
       
    63     "Method should not be used, it is here for debugging and testing purposes"
       
    64     self error: 'deprecated'.
       
    65     
       
    66     matchPosition := nil. "This flag says that multimode run the last time"
       
    67     
       
    68     tokens := tokenList.
       
    69     matches := Array new: tokens size.
       
    70     
       
    71 !
       
    72 
       
    73 resetDistinct
       
    74 "	matches := IdentityDictionary new.	"
       
    75     match := nil.
       
    76     matchPosition := -1.						"this is a flag that the distnict mode was running"
       
    77 "	matches := nil."
       
    78 
       
    79     position := stream position.
       
    80     
       
    81 ! !
       
    82 
       
    83 !PPCScanner methodsFor:'results'!
       
    84 
       
    85 backtrack
       
    86     matchPosition := nil.
       
    87     match := nil.
       
    88     matches := Array new: maxSymbolNumber withAll: -2.
       
    89     position := 0.
       
    90 !
       
    91 
       
    92 backtrackDistinct
       
    93     matchPosition := nil.
       
    94     match := nil.
       
    95     position := 0.
       
    96 !
       
    97 
       
    98 backtracked
       
    99     ^ position == 0
       
   100 !
       
   101 
       
   102 indexOf: symbol
       
   103     (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [^ index ] ]. 
       
   104 !
       
   105 
       
   106 match
       
   107 "	^ match isNil not."
       
   108     ^ match isNotNil
       
   109 "	^ matchPosition isNil not"
       
   110 !
       
   111 
       
   112 match: symbolNumber
       
   113 "	matches isNil ifTrue: [ ^ false ]."
       
   114     
       
   115     "
       
   116         The general idea here is optimization. I cannot initialize 
       
   117         the matches before each token, it would be too expensive.
       
   118     "
       
   119     ^ (matches at: symbolNumber) > position
       
   120 !
       
   121 
       
   122 matchSymbol: symbol
       
   123     matches isNil ifTrue: [ ^ false ].
       
   124     (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [
       
   125         ^ (matches at: index) > position
       
   126     ] ]. 
       
   127 !
       
   128 
       
   129 polyResult
       
   130     | dictionary |
       
   131     "TODO JK: refactor"	
       
   132     self isSingleMatch ifFalse: [ 
       
   133         dictionary := IdentityDictionary new.
       
   134         (1 to: matches size) do: [ :index | 
       
   135             (self match: index) ifTrue: [ 
       
   136                 dictionary 
       
   137                     at: (tokens at: index)
       
   138                     put: (matches at: index)
       
   139             ]
       
   140         ].
       
   141         ^ dictionary
       
   142     ].
       
   143 
       
   144     dictionary := IdentityDictionary new.
       
   145     match isNil ifFalse: [ 
       
   146         dictionary at: match put: matchPosition.
       
   147     ].
       
   148 
       
   149     ^ dictionary
       
   150 !
       
   151 
       
   152 result
       
   153     ^ match
       
   154 !
       
   155 
       
   156 resultPosition
       
   157     ^ matchPosition
       
   158 !
       
   159 
       
   160 resultPosition: symbolNumber
       
   161     ^ matches at: symbolNumber
       
   162 !
       
   163 
       
   164 resultPositionForSymbol: symbol
       
   165     tokens isNil ifTrue: [ ^ false ].
       
   166     (1 to: tokens size) do: [ :index | (tokens at: index) == symbol ifTrue: [
       
   167         ^ matches at: index
       
   168     ] ]. 
       
   169 ! !
       
   170 
       
   171 !PPCScanner methodsFor:'results - distinct'!
       
   172 
       
   173 recordDistinctMatch: matchValue
       
   174     match := matchValue.
       
   175     matchPosition := stream position.
       
   176 !
       
   177 
       
   178 recordDistinctMatch: matchValue offset: offset
       
   179     match := matchValue.
       
   180     currentChar isNil ifFalse: [ 
       
   181         matchPosition := stream position - offset.
       
   182     ] ifTrue: [ 
       
   183         matchPosition := stream position.
       
   184     ]
       
   185 !
       
   186 
       
   187 returnDistinct
       
   188     ^ match isNotNil
       
   189 ! !
       
   190 
       
   191 !PPCScanner methodsFor:'results - universal'!
       
   192 
       
   193 recordFailure: index
       
   194     matches at: index put: -1.
       
   195 !
       
   196 
       
   197 recordFailure: index offset: offset
       
   198     matches at: index put: -1.
       
   199 !
       
   200 
       
   201 recordMatch: index
       
   202  	matches at: index put: stream position.
       
   203 !
       
   204 
       
   205 recordMatch: index offset: offset
       
   206     currentChar isNil ifFalse: [ 
       
   207         matches at: index put: stream position - offset.
       
   208     ] ifTrue: [ 
       
   209         matches at: index put: stream position.
       
   210     ].
       
   211  
       
   212 !
       
   213 
       
   214 return
       
   215     ^ matches
    56 ! !
   216 ! !
    57 
   217 
    58 !PPCScanner methodsFor:'scanning'!
   218 !PPCScanner methodsFor:'scanning'!
    59 
   219 
    60 consumeConditionally: character
       
    61     (stream peek == character) ifTrue: [ stream next. ^ true ] ifFalse: [ ^ false ]
       
    62 !
       
    63 
       
    64 next
   220 next
       
   221     self error: 'deprecated?'.
    65     stream next
   222     stream next
    66 !
   223 !
    67 
   224 
    68 peek
   225 peek
    69     ^ currentChar
   226     ^ currentChar
    70 !
   227 !
    71 
   228 
    72 peekBetween: start and: stop
   229 peekBetween: start and: stop
    73     (currentChar == nil) ifTrue: [ ^ false ].
   230     (currentChar == nil) ifTrue: [ ^ false ].
    74     ^ start <= currentChar codePoint and: [ currentChar codePoint <= stop ]
   231     ^ (start <= currentChar codePoint) and: [ currentChar codePoint <= stop ]
    75 !
   232 !
    76 
   233 
    77 step
   234 step
    78     currentChar := stream next
   235     currentChar := stream next
    79 ! !
   236 ! !
    80 
   237 
       
   238 !PPCScanner methodsFor:'testing'!
       
   239 
       
   240 isSingleMatch
       
   241     ^ (matchPosition == nil) not
       
   242 ! !
       
   243