152 lines
3.7 KiB
Smalltalk
152 lines
3.7 KiB
Smalltalk
"
|
|
I create following:
|
|
- FSAs equivalents for tokens
|
|
- FSAs for followSetsWithTokens
|
|
|
|
"
|
|
Class {
|
|
#name : 'PPCFSAVisitor',
|
|
#superclass : 'PPCPassVisitor',
|
|
#instVars : [
|
|
'fsaCache',
|
|
'idGen'
|
|
],
|
|
#category : 'PetitCompiler-Visitors'
|
|
}
|
|
|
|
{ #category : 'accessing' }
|
|
PPCFSAVisitor >> idGen: anObject [
|
|
idGen := anObject
|
|
]
|
|
|
|
{ #category : 'initialization' }
|
|
PPCFSAVisitor >> initialize [
|
|
super initialize.
|
|
|
|
"for the given set of nodes, remember the unordered choice fsa
|
|
see `unorderedChoiceFromFollowSet:`
|
|
"
|
|
fsaCache := Dictionary new.
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> unorderedChoiceFromFsas: fsas [
|
|
| result startState |
|
|
result := PEGFsa new.
|
|
startState := PEGFsaState new.
|
|
|
|
result addState: startState.
|
|
result startState: startState.
|
|
|
|
fsas do: [ :fsa |
|
|
result adopt: fsa.
|
|
result addTransitionFrom: startState to: fsa startState.
|
|
].
|
|
|
|
result determinizeStandard.
|
|
^ result
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> unorderedChoiceFromSet: aSet [
|
|
| followFsas |
|
|
|
|
^ fsaCache at: aSet ifAbsentPut: [
|
|
followFsas := aSet collect: [ :followNode |
|
|
followNode asFsa
|
|
name: (context idGenerator idFor: followNode);
|
|
retval: (context idGenerator idFor: followNode);
|
|
yourself
|
|
].
|
|
self unorderedChoiceFromFsas: followFsas.
|
|
]
|
|
|
|
"Modified: / 03-09-2015 / 21:28:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitChoiceNode: node [
|
|
| anFsa firstSet |
|
|
super visitChoiceNode: node.
|
|
|
|
firstSet := node firstSetWithTokens.
|
|
anFsa := self unorderedChoiceFromSet: firstSet.
|
|
anFsa name: (context idGenerator idFor: anFsa defaultName: node defaultName prefix: 'firstOf').
|
|
node firstFsa: anFsa.
|
|
|
|
node children do: [ :child |
|
|
firstSet := child firstSetWithTokens.
|
|
|
|
anFsa := self unorderedChoiceFromSet: firstSet.
|
|
anFsa name: 'firstOf_', (context idGenerator idFor: anFsa defaultName: child defaultName prefix: 'firstOf').
|
|
|
|
child firstFsa: anFsa.
|
|
].
|
|
|
|
^ node
|
|
|
|
"Modified: / 03-09-2015 / 21:27:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitToken: tokenNode [
|
|
| anFsa |
|
|
|
|
anFsa := tokenNode asFsa determinize.
|
|
anFsa name: (context idGenerator idFor: tokenNode).
|
|
anFsa retval: (context idGenerator idFor: tokenNode).
|
|
|
|
tokenNode fsa: anFsa.
|
|
^ tokenNode
|
|
|
|
"Modified: / 03-09-2015 / 21:27:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitTokenConsumeNode: node [
|
|
| epsilon anFsa followSet |
|
|
followSet := node followSetWithTokens.
|
|
|
|
epsilon := followSet anySatisfy: [ :e | e acceptsEpsilon ].
|
|
followSet := followSet reject: [ :e | e acceptsEpsilon ].
|
|
epsilon ifTrue: [ followSet add: PPCEndOfFileNode instance ].
|
|
|
|
anFsa := self unorderedChoiceFromSet: followSet.
|
|
anFsa name: (context idGenerator idFor: anFsa defaultName: node defaultName prefix: 'nextToken').
|
|
|
|
node nextFsa: anFsa.
|
|
|
|
"Modified: / 03-09-2015 / 21:27:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitTokenNode: node [
|
|
^ self visitToken: node
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitTokenizingParserNode: node [
|
|
"TODO JK: hack alert, change the handling of WS!"
|
|
self visitWhitespace: node whitespace.
|
|
|
|
self visit: node tokens.
|
|
self visit: node parser.
|
|
^ node
|
|
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitTrimmingTokenNode: node [
|
|
^ self visitToken: node
|
|
]
|
|
|
|
{ #category : 'as yet unclassified' }
|
|
PPCFSAVisitor >> visitWhitespace: node [
|
|
"JK HACK: treat ws as token -> create FSA for whitespace"
|
|
| retval |
|
|
retval := self visitToken: node.
|
|
"we don't care about the finals of whitespace"
|
|
node fsa removeFinals.
|
|
^ retval
|
|
]
|