compiler/PEGFsaInterpret.st
changeset 515 b5316ef15274
parent 502 1e45d3c96ec5
child 516 3b81c9e53352
equal deleted inserted replaced
502:1e45d3c96ec5 515:b5316ef15274
     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:#PEGFsaInterpret
     5 Object subclass:#PEGFsaInterpret
     6 	instanceVariableNames:'fsa debug retvals stream maxPriority'
     6 	instanceVariableNames:'fsa debug retvals stream'
     7 	classVariableNames:''
     7 	classVariableNames:''
     8 	poolDictionaries:''
     8 	poolDictionaries:''
     9 	category:'PetitCompiler-FSA'
     9 	category:'PetitCompiler-FSA'
    10 !
    10 !
       
    11 
       
    12 !PEGFsaInterpret class methodsFor:'instance creation'!
       
    13 
       
    14 new
       
    15     "return an initialized instance"
       
    16 
       
    17     ^ self basicNew initialize.
       
    18 ! !
    11 
    19 
    12 !PEGFsaInterpret methodsFor:'accessing'!
    20 !PEGFsaInterpret methodsFor:'accessing'!
    13 
    21 
    14 debug
    22 debug
    15     ^ debug
    23     ^ debug
    19     debug := anObject
    27     debug := anObject
    20 !
    28 !
    21 
    29 
    22 fsa
    30 fsa
    23     ^ fsa
    31     ^ fsa
       
    32 !
       
    33 
       
    34 recordFor: retval
       
    35     ^ retvals at: retval ifAbsentPut: [ PEGFsaInterpretRecord new ]
    24 ! !
    36 ! !
    25 
    37 
    26 !PEGFsaInterpret methodsFor:'debugging'!
    38 !PEGFsaInterpret methodsFor:'debugging'!
    27 
    39 
    28 reportFsa: anFsa
    40 reportFsa: anFsa
    52 
    64 
    53 !PEGFsaInterpret methodsFor:'running'!
    65 !PEGFsaInterpret methodsFor:'running'!
    54 
    66 
    55 interpret
    67 interpret
    56     | states newStates character run  |
    68     | states newStates character run  |
    57     maxPriority := SmallInteger minVal.
       
    58     newStates := IdentitySet with: fsa startState.
    69     newStates := IdentitySet with: fsa startState.
    59     retvals := IdentityDictionary new.
    70     retvals := IdentityDictionary new.
    60     
    71     
    61     self recordNewState: fsa startState position: 0.
    72     self recordNewState: fsa startState position: 0.
    62     
    73     
    63     self reportStart.
    74     self reportStart.
    64     self reportFsa: fsa.
    75     self reportFsa: fsa.
    65     
    76     
    66     run := stream atEnd not.
    77     run := "stream atEnd not" true.
    67     
    78     
    68     [run] whileTrue: [  
    79     [run] whileTrue: [  
    69         states := newStates.
    80         states := newStates.
    70         newStates := IdentitySet new.
    81         newStates := IdentitySet new.
    71         character := stream peek.
    82         character := stream peek codePoint.
    72 
    83 
    73         self reportStates: states.
    84         self reportStates: states.
    74 
    85 
    75         states do: [ :state |
    86         states do: [ :state |
    76             self expand: state on: character into: newStates.
    87             self expand: state on: character into: newStates.
    77         ].
    88         ].
    78         
    89         
    79         newStates isEmpty ifFalse: [ stream next ].
    90         newStates isEmpty ifFalse: [ stream next ].
    80         run := stream atEnd not and: [ newStates isEmpty not ].
    91         run := "stream atEnd not and: [ "newStates isEmpty not" ]".
    81     ].
    92     ].
    82 
    93     ^ self return: states
    83     ^ self return: newStates
       
    84 !
    94 !
    85 
    95 
    86 interpret: anFsa on: aStream
    96 interpret: anFsa on: aStream
    87     fsa := anFsa.
    97     fsa := anFsa.
    88     stream := aStream.
    98     stream := aStream.
   102         ^ transitionsTaken anyOne priority <= t priority.
   112         ^ transitionsTaken anyOne priority <= t priority.
   103 "	"]."
   113 "	"]."
   104     ^ true
   114     ^ true
   105 !
   115 !
   106 
   116 
   107 expand: state on: character into: newStates "transitionsTaken: transitionsTaken"
   117 expand: state on: codePoint into: newStates
   108     | transitions transitionsTaken |
   118     state transitions do: [ :t | 
       
   119         t isEpsilon ifTrue: [  
       
   120             (t destination isFinal) ifTrue: [ 
       
   121                 newStates add: t destination.
       
   122                 self recordNewState: t destination position: stream position.
       
   123             ].
   109 
   124 
   110     transitionsTaken := OrderedCollection new.
   125             "Descent into the next state"
   111     transitions := self sortedTransitionsFor: state.
   126             self 	expand: t destination 
   112     transitions do: [ :t | 
   127                     on: codePoint 
   113         (self allowsTransition: t from: state transitionsTaken: transitionsTaken) ifTrue: [ 
   128                     into: newStates.
   114             t isEpsilon ifTrue: [  
   129         ] ifFalse: [  
   115                 (t destination isFinal) ifTrue: [ 
   130             (t acceptsCodePoint: codePoint) ifTrue: [ 
   116                     newStates add: t destination.
   131                 newStates add: t destination.
   117                     self recordNewState: t destination position: stream position.
   132                 self recordNewState: t destination.
   118                 ].
   133             ]
   119 
   134         ] 
   120                 "Descent into the next state"
       
   121                 self 	expand: t destination 
       
   122                         on: character 
       
   123                         into: newStates.
       
   124 
       
   125                 newStates isEmpty ifFalse: [ 
       
   126                     transitionsTaken add: t.
       
   127                 ].
       
   128 
       
   129             ] ifFalse: [  
       
   130                 (t accepts: character) ifTrue: [ 
       
   131                     transitionsTaken add: t.
       
   132                     newStates add: t destination.
       
   133                     self recordNewState: t destination.
       
   134                 ]
       
   135             ] 
       
   136         ]
       
   137     ]
   135     ]
   138 !
   136 !
   139 
   137 
   140 recordNewState: state
   138 recordNewState: state
   141     ^ self recordNewState: state position: stream position + 1
   139     ^ self recordNewState: state position: stream position + 1
   142 !
   140 !
   143 
   141 
   144 recordNewState: state position: position
   142 recordNewState: state position: position
   145     (state isFinal) ifFalse: [ ^ self ].
   143     | currentRecord |
   146     (maxPriority > state priority) ifTrue: [ ^ true ].
   144     (state isFinal) ifFalse: [ 
   147         
   145         ^ self 
   148     self assert: state hasPriority description: 'final state must have priority'.
       
   149     (maxPriority < state priority) ifTrue: [ 
       
   150         retvals := IdentityDictionary new.
       
   151         maxPriority := state priority.
       
   152     ].
   146     ].
   153 
   147 
       
   148     (state isFinal) ifFalse: [ self error: 'should not happen' ].
       
   149     self assert: state hasPriority description: 'final state must have priority'.
   154 
   150 
   155     state retvalAsCollection do: [ :r |
   151     state retvalsAndInfosDo: [ :retval :info |
   156         retvals at: r put: position
   152         currentRecord := self recordFor: retval.
       
   153         info isFsaFailure ifTrue: [ 
       
   154             "JK: hack, nil refers to failure!! :( Refactor!!"
       
   155             currentRecord position: nil
       
   156         ] ifFalse: [ 
       
   157      		currentRecord position: position	
       
   158         ]
   157     ].
   159     ].
   158 !
   160 !
   159 
   161 
   160 return: states
   162 return: states
   161     | priority priorities |
   163     | return |
   162     priorities := (states select: #hasPriority thenCollect: #priority).
   164     return := IdentityDictionary new.
   163     priorities isEmpty ifTrue: [  
   165     retvals keysAndValuesRemove: [ :key :record | record position isNil ].
   164         ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ] 
   166 
       
   167     retvals keysAndValuesDo: [ :key :value |
       
   168         return at: key put: value position
   165     ].
   169     ].
   166     
   170     ^ return
   167     priority := priorities max.
       
   168     
       
   169     (maxPriority < priority) ifTrue: [ ^ IdentityDictionary new ].
       
   170     ^ retvals keysAndValuesRemove: [ :key :value | key class == PEGFsaFailure ]
       
   171 !
   171 !
   172 
   172 
   173 sortedTransitionsFor: state
   173 sortedTransitionsFor: state
       
   174     self error: 'deprecated!!'.
   174     ^ (fsa transitionsFor: state) asOrderedCollection
   175     ^ (fsa transitionsFor: state) asOrderedCollection
   175         "Dear future me, enjoy this:"
   176         "Dear future me, enjoy this:"
   176 "		sort: [ :e1 :e2 | (e1 isEpsilon not and: [e2 isEpsilon]) not ])"
   177 "		sort: [ :e1 :e2 | (e1 isEpsilon not and: [e2 isEpsilon]) not ])"
   177         sort: [ :e1 :e2 | e1 priority > e2 priority ]
   178         sort: [ :e1 :e2 | e1 priority > e2 priority ]
   178             
   179