compiler/PPCFSACodeGen.st
changeset 516 3b81c9e53352
parent 515 b5316ef15274
child 524 f6f68d32de73
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 PPCCodeGen subclass:#PPCFSACodeGen
     5 PPCCodeGen subclass:#PPCFSACodeGen
     6 	instanceVariableNames:'fsa backlinkStates'
     6 	instanceVariableNames:'fsa backlinkStates compiler'
     7 	classVariableNames:''
     7 	classVariableNames:''
     8 	poolDictionaries:''
     8 	poolDictionaries:''
     9 	category:'PetitCompiler-Scanner'
     9 	category:'PetitCompiler-Scanner'
    10 !
    10 !
    11 
    11 
    13 
    13 
    14 methodCategory
    14 methodCategory
    15     ^ 'generated - scanning'
    15     ^ 'generated - scanning'
    16 ! !
    16 ! !
    17 
    17 
    18 !PPCFSACodeGen methodsFor:'analysis'!
       
    19 
       
    20 beginOfRange: characterSet
       
    21     characterSet withIndexDo: [ :e :index | 
       
    22         e ifTrue: [ ^ index ]
       
    23     ].
       
    24     self error: 'should not happend'
       
    25 !
       
    26 
       
    27 endOfRange: characterSet
       
    28     | change |
       
    29     change := false.
       
    30     characterSet withIndexDo: [ :e :index | 
       
    31         e ifTrue: [ change := true ].
       
    32         (e not and: [ change ]) ifTrue: [ ^ index - 1]
       
    33     ].
       
    34     ^ characterSet size
       
    35 !
       
    36 
       
    37 isLetter: characterSet
       
    38     | changes previous |
       
    39     changes := 0.
       
    40     previous := false.
       
    41     characterSet withIndexDo: [ :e :index |
       
    42         (e == (Character codePoint: index) isLetter) ifFalse: [ ^ false ].
       
    43     ].
       
    44     ^ true
       
    45 !
       
    46 
       
    47 isSingleCharacter: characterSet
       
    48     ^ (characterSet select: [ :e | e ]) size = 1
       
    49 !
       
    50 
       
    51 isSingleRange: characterSet
       
    52     | changes previous |
       
    53     changes := 0.
       
    54     previous := false.
       
    55     characterSet do: [ :e | 
       
    56         (e == previous) ifFalse: [ changes := changes + 1 ].
       
    57         previous := e.
       
    58     ].
       
    59     ^ changes < 3
       
    60 ! !
       
    61 
       
    62 !PPCFSACodeGen methodsFor:'coding'!
    18 !PPCFSACodeGen methodsFor:'coding'!
    63 
    19 
    64 codeAbsoluteReturn: code
    20 codeAbsoluteReturn: code
    65     self add: '^ ', code
    21     self add: '^ ', code
    66 !
    22 !
    67 
    23 
    68 codeAssertPeek: characterSet
    24 codeAssertPeek: t
    69     | character id extendedCharacterSet |
    25     |   id  |
    70     
    26     self assert: (t isKindOf: PEGFsaTransition).
    71     (self isSingleCharacter: characterSet) ifTrue: [ 
    27 
    72         character := self character: characterSet.
    28     (t isPredicateTransition and: [t isEOF]) ifTrue: [ 
    73         self addOnLine: 'self peek == ', character storeString.
    29         self addOnLine: 'currentChar isNil'.
    74         ^ self
    30         ^ self
    75     ].
    31     ].
    76 
    32 
    77     (self isLetter: characterSet) ifTrue: [ 
    33     
    78         self addOnLine: 'self peek isLetter'.
    34     (t isPredicateTransition) ifTrue: [ 
    79         ^ self
    35         self addOnLine: t predicate asString, ' value: currentChar codePoint'.
    80     ].
    36         ^ self
    81 
    37     ].
    82     (self isSingleRange: characterSet) ifTrue: [ 
    38 
       
    39     (t isAny) ifTrue: [ 
       
    40         self addOnLine: 'true'.
       
    41         ^ self
       
    42     ].
       
    43 
       
    44     
       
    45     (t isSingleCharacter) ifTrue: [ 
       
    46         self addOnLine: 'currentChar == ', t character storeString.
       
    47         ^ self
       
    48     ].
       
    49 
       
    50     (t isNotSingleCharacter) ifTrue: [ 
       
    51         self addOnLine: 'currentChar ~~ ', t notCharacter storeString.
       
    52         ^ self
       
    53     ].
       
    54 
       
    55     (t isLetter) ifTrue: [ 
       
    56         self addOnLine: 'currentChar isLetter'.
       
    57         ^ self
       
    58     ].
       
    59 
       
    60     (t isWord) ifTrue: [ 
       
    61         self addOnLine: 'currentChar isAlphaNumeric'.
       
    62         ^ self
       
    63     ].
       
    64 
       
    65     (t isDigit) ifTrue: [ 
       
    66         self addOnLine: 'currentChar isDigit'.
       
    67         ^ self
       
    68     ].
       
    69 
       
    70     (t isSingleRange) ifTrue: [ 
    83         | begin end |
    71         | begin end |
    84         begin := self beginOfRange: characterSet.
    72         begin := t beginOfRange.
    85         end := self endOfRange: characterSet.
    73         end := t endOfRange.
    86         self addOnLine: 'self peekBetween: ', begin asString, ' and: ', end asString.
    74         self addOnLine: 'self peekBetween: ', begin asString, ' and: ', end asString.
    87         ^ self
    75         ^ self
    88     ].
    76     ].
    89 
    77 
    90     extendedCharacterSet := (characterSet asOrderedCollection addLast: false; yourself) asArray.
    78     
    91     id := self idFor: characterSet prefixed: 'characterSet'.
    79     id := idGen cachedSuchThat: [ :e | e = t characterSet ] 
    92     
    80                     ifNone: [ self idFor: t characterSet defaultName: 'characterSet' ].
    93     self addConstant: extendedCharacterSet as: id.
    81     
    94     self addOnLine: id, ' at: self peek asInteger'.
    82     self addConstant: t characterSet as: id.
    95 !
    83     self addOnLine: '(currentChar isNotNil) and: [',  id, ' at: currentChar codePoint ]'.
    96 
    84 !
    97 codeAssertPeek: characterSet ifTrue: block
    85 
       
    86 codeAssertPeek: transition ifFalse: falseBlock
       
    87     self add: '('.
       
    88     self codeAssertPeek: transition.
       
    89     self addOnLine: ') ifFalse: [ '.
       
    90     falseBlock value.
       
    91     self addOnLine: ']'.
       
    92     self codeDot.
       
    93 !
       
    94 
       
    95 codeAssertPeek: t ifTrue: block
    98     self addOnLine: '('.
    96     self addOnLine: '('.
    99     self codeAssertPeek: characterSet.
    97     self codeAssertPeek: t.
   100     self addOnLine: ') ifTrue: ['.
    98     self addOnLine: ') ifTrue: ['.
   101     self indent.
    99     self indent.
   102     self code: block.
   100     self code: block.
   103     self dedent.
   101     self dedent.
   104     self add: ']'.
   102     self add: ']'.
   105 !
   103 !
   106 
   104 
   107 codeAssertPeek: characterSet orReturn: priority
   105 codeAssertPeek: transition orReturn: priority
       
   106     self error: 'deprecated'.
   108     self add: '('.
   107     self add: '('.
   109     self codeAssertPeek: characterSet.
   108     self codeAssertPeek: transition.
   110     self addOnLine: ') ifFalse: [ '.
   109     self addOnLine: ') ifFalse: [ '.
   111     self codeReturnResult: priority.
   110     self codeReturnResult: priority.
   112     self addOnLine: ']'.
   111     self addOnLine: ']'.
   113     self codeDot.
   112     self codeDot.
   114 !
   113 !
   115 
   114 
   116 codeAssertPeek: characterSet whileTrue: block
   115 codeAssertPeek: transition whileTrue: block
   117     self add: '['.
   116     self add: '['.
   118     self codeAssertPeek: characterSet.
   117     self codeAssertPeek: transition.
   119     self addOnLine: '] whileTrue: ['.
   118     self addOnLine: '] whileTrue: ['.
   120     self indent.
   119     self indent.
   121     self code: block.
   120     self code: block.
   122     self dedent.
   121     self dedent.
   123     self add: '].'.
   122     self add: '].'.
   160         ^ self codeNlReturnResult
   159         ^ self codeNlReturnResult
   161     ].
   160     ].
   162     self add: '^ self returnPriority: ', priority asString, '.'
   161     self add: '^ self returnPriority: ', priority asString, '.'
   163 !
   162 !
   164 
   163 
   165 codeRecordMatch: state
   164 codeRecordDistinctMatch: retval offset: value
   166     self add: 'self recordMatch: ', state storeString, '.'
   165     self add: 'self recordDistinctMatch: ', retval storeString, ' offset: ', value storeString, '.'
   167 !
   166 !
   168 
   167 
   169 codeRecordMatch: state priority: priority
   168 codeRecordMatch: state priority: priority
   170     priority isNil ifTrue: [ 
   169     priority isNil ifTrue: [ 
   171         ^ self codeRecordMatch: state
   170         ^ self codeRecordMatch: state
   189 codeStartBlock
   188 codeStartBlock
   190     self add: '['.
   189     self add: '['.
   191     self indent.
   190     self indent.
   192 ! !
   191 ! !
   193 
   192 
   194 !PPCFSACodeGen methodsFor:'helpers'!
   193 !PPCFSACodeGen methodsFor:'coding - results'!
   195 
   194 
   196 character: characterSet
   195 codeRecordDistinctMatch: retval
   197     self assert: (self isSingleCharacter: characterSet).
   196     self add: 'self recordDistinctMatch: ', retval storeString, '.'
   198     characterSet withIndexDo: [ :e :index | e ifTrue: [ ^ Character codePoint: index ] ].
   197 !
   199     
   198 
   200     self error: 'should not happen'
   199 codeRecordFailure: index
       
   200     self assert: index isInteger.
       
   201     self add: 'self recordFailure: ', index asString, '.'
       
   202 !
       
   203 
       
   204 codeRecordMatch: retval
       
   205     self add: 'self recordMatch: ', retval storeString, '.'
       
   206 !
       
   207 
       
   208 codeRecordMatch: retval offset: offset
       
   209     self add: 'self recordMatch: ', retval storeString, ' offset: ', offset storeString, '.'
       
   210 !
       
   211 
       
   212 codeReturn
       
   213     self addOnLine: '^ self'
       
   214 !
       
   215 
       
   216 codeReturnDistinct
       
   217     self addOnLine: '^ self returnDistinct.'
   201 ! !
   218 ! !
   202 
   219 
   203 !PPCFSACodeGen methodsFor:'intitialization'!
   220 !PPCFSACodeGen methodsFor:'intitialization'!
   204 
   221 
   205 initialize
   222 initialize
   206     super initialize.
   223     super initialize.
       
   224     
       
   225     compiler := PPCCodeGen new.
   207     backlinkStates := IdentityDictionary new.
   226     backlinkStates := IdentityDictionary new.
   208 
   227 ! !
   209     "Modified: / 24-07-2015 / 15:03:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   228 
   210 ! !
       
   211