compiler/PEGFsaGenerator.st
changeset 503 ff58cd9f1f3c
parent 502 1e45d3c96ec5
child 515 b5316ef15274
equal deleted inserted replaced
501:e29bd90f388e 503:ff58cd9f1f3c
       
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
       
     2 
       
     3 "{ NameSpace: Smalltalk }"
       
     4 
       
     5 PPCNodeVisitor subclass:#PEGFsaGenerator
       
     6 	instanceVariableNames:''
       
     7 	classVariableNames:''
       
     8 	poolDictionaries:''
       
     9 	category:'PetitCompiler-FSA'
       
    10 !
       
    11 
       
    12 !PEGFsaGenerator methodsFor:'as yet unclassified'!
       
    13 
       
    14 visitCharSetPredicateNode: node
       
    15     | stop start fsa |
       
    16     start := PEGFsaState new.
       
    17     stop := PEGFsaState new.
       
    18     
       
    19     fsa := PEGFsa new
       
    20         addState: start;
       
    21         addState: stop;
       
    22         
       
    23         startState: start;
       
    24         finalState: stop;
       
    25         yourself.
       
    26     
       
    27     fsa addTransitionFrom: start to: stop onCharacterSet: (node predicate classification).
       
    28         
       
    29     ^ fsa
       
    30 !
       
    31 
       
    32 visitCharacterNode: node
       
    33     | stop start |
       
    34     start := PEGFsaState new.
       
    35     stop := PEGFsaState new.
       
    36     stop name: node character storeString.
       
    37     
       
    38     ^ PEGFsa new
       
    39         addState: start;
       
    40         addState: stop;
       
    41         
       
    42         startState: start;
       
    43         finalState: stop;
       
    44 
       
    45         addTransitionFrom: start to: stop on: node character;
       
    46         yourself
       
    47 !
       
    48 
       
    49 visitChoiceNode: node
       
    50     | priority childrenFsa fsa start |
       
    51     
       
    52     childrenFsa := node children collect: [ :child | child accept: self ].
       
    53     fsa := PEGFsa new.
       
    54     start := PEGFsaState new.
       
    55     
       
    56     fsa addState: start.
       
    57     fsa startState: start.
       
    58 
       
    59     priority := 0.
       
    60     childrenFsa do: [ :childFsa |
       
    61         fsa adopt: childFsa.
       
    62         fsa addTransitionFrom: start to: childFsa startState priority: priority.
       
    63         priority := priority + childFsa minPriority.
       
    64     ].
       
    65 
       
    66     ^ fsa
       
    67 !
       
    68 
       
    69 visitLiteralNode: node
       
    70     | states fsa |
       
    71 
       
    72     states := OrderedCollection new.
       
    73     (node literal size + 1) timesRepeat: [
       
    74         states add: PEGFsaState new
       
    75     ].
       
    76 
       
    77     fsa := PEGFsa new.
       
    78     states do: [ :state | fsa addState: state ].	
       
    79     fsa	 startState: states first;
       
    80          finalState: states last;
       
    81          yourself.
       
    82         
       
    83     (1 to: (states size - 1)) do: [ :index |
       
    84         fsa addTransitionFrom: (states at: index)
       
    85          	 to: (states at: index + 1)
       
    86              on: (node literal at: index).
       
    87         "set the name"
       
    88         (states at: (index + 1)) name: (node literal at: index). 
       
    89     ].
       
    90 
       
    91     fsa name: node literal.
       
    92     ^ fsa
       
    93 !
       
    94 
       
    95 visitNode: node
       
    96     self error: 'node not supported'
       
    97 !
       
    98 
       
    99 visitNotNode: node
       
   100     | fsa finalState |
       
   101     fsa := node child accept: self.
       
   102     finalState := PEGFsaState new
       
   103         name: '!!', fsa name asString;
       
   104         yourself.
       
   105     
       
   106     fsa finalStates do: [ :fs |
       
   107         fs retval: PEGFsaFailure new.
       
   108     ].
       
   109     
       
   110     fsa addState: finalState.
       
   111     fsa finalState: finalState.
       
   112 
       
   113     fsa addTransitionFrom: fsa startState to: finalState priority: -1.
       
   114     ^ fsa
       
   115 !
       
   116 
       
   117 visitOptionalNode: node
       
   118     | fsa startState finalState |
       
   119 
       
   120     fsa := node child accept: self.
       
   121     startState := PEGFsaState new
       
   122         yourself.
       
   123 
       
   124     finalState := PEGFsaState new
       
   125         final: true;
       
   126         yourself.
       
   127 
       
   128     fsa addState: startState.
       
   129     fsa addState: finalState.
       
   130     
       
   131     fsa addTransitionFrom: startState to: fsa startState priority: 0.
       
   132     fsa addTransitionFrom: startState to: finalState priority: fsa minPriority.
       
   133 
       
   134     fsa startState: startState.
       
   135 
       
   136     ^ fsa
       
   137 !
       
   138 
       
   139 visitPlusNode: node
       
   140     | fsa finalState |
       
   141 
       
   142     finalState := PEGFsaState new.
       
   143     fsa := node child accept: self.
       
   144     fsa addState: finalState.
       
   145     
       
   146     fsa finalStates do: [ :state |
       
   147         fsa addTransitionFrom: state to: (fsa startState).
       
   148         fsa addTransitionFrom: state to: finalState priority: -1.
       
   149         self assert: (state hasPriority not).
       
   150         state priority: 0.
       
   151         state final: false.
       
   152     ].
       
   153 
       
   154     fsa finalState: finalState.	
       
   155     
       
   156     ^ fsa
       
   157 !
       
   158 
       
   159 visitPredicateNode: node
       
   160     | stop start fsa  |
       
   161     start := PEGFsaState new.
       
   162     stop := PEGFsaState new.
       
   163     
       
   164     fsa := PEGFsa new
       
   165         addState: start;
       
   166         addState: stop;
       
   167         
       
   168         startState: start;
       
   169         finalState: stop;
       
   170         yourself.
       
   171     
       
   172     fsa addTransitionFrom: start to: stop onCharacterSet: (node predicate classification).
       
   173         
       
   174     ^ fsa
       
   175 !
       
   176 
       
   177 visitSequenceNode: node
       
   178     | childrenFsa fsa start previousFinalStates  |
       
   179 
       
   180     childrenFsa := node children collect: [ :child | child accept: self ].
       
   181 
       
   182     fsa := PEGFsa new.
       
   183     start := PEGFsaState new name: 'start'; yourself.
       
   184     fsa addState: start.
       
   185     fsa startState: start.
       
   186 
       
   187     fsa adopt: childrenFsa first.	
       
   188     fsa addTransitionFrom: start to: childrenFsa first startState.
       
   189 
       
   190     previousFinalStates := childrenFsa first finalStates.
       
   191     childrenFsa allButFirst do: [ :childFsa | 
       
   192         | newFinalStates |
       
   193         newFinalStates := IdentitySet new.
       
   194         previousFinalStates do: [ :state |
       
   195             | copy |
       
   196             copy := childFsa copy.
       
   197             fsa adopt: copy.
       
   198             
       
   199             state isFailure ifFalse: [ 
       
   200                 state final: false.
       
   201                 fsa addTransitionFrom: state to: copy startState.
       
   202             ].
       
   203             newFinalStates addAll: copy finalStates.
       
   204         ].
       
   205         previousFinalStates := newFinalStates.
       
   206     ].
       
   207     ^ fsa
       
   208 !
       
   209 
       
   210 visitStarNode: node
       
   211     | fsa finalState |
       
   212 
       
   213     finalState := PEGFsaState new.
       
   214     fsa := node child accept: self.
       
   215     fsa addState: finalState.
       
   216     
       
   217     fsa finalStates do: [ :state |
       
   218         fsa addTransitionFrom: state to: (fsa startState).
       
   219         self assert: (state hasPriority not).
       
   220         state priority: 0.
       
   221         state final: false.
       
   222     ].
       
   223 
       
   224     fsa addTransitionFrom: fsa startState to: finalState priority: -1.
       
   225     fsa finalState: finalState.
       
   226 
       
   227     ^ fsa
       
   228 ! !
       
   229