PPCConfiguration refactoring [1/10]: renamed PPCArguments to PPCCompilationOptions
Renamed PPCConfiguration>>#arguments/#arguments: to #options/#options:
"{ Package: 'stx:goodies/petitparser/compiler' }"
"{ NameSpace: Smalltalk }"
PPCConfiguration subclass:#PPCTokenizingConfiguration
instanceVariableNames:'scannerClazz parserClazz idGen'
classVariableNames:''
poolDictionaries:''
category:'PetitCompiler-Core'
!
!PPCTokenizingConfiguration methodsFor:'compiling'!
options: args
super options: args.
!
buildClass: clazz
| builder |
builder := PPCClassBuilder new.
builder compiledClassName: clazz name.
builder compiledSuperclass: clazz superclass.
builder methodDictionary: clazz methodDictionary.
builder constants: clazz constants.
^ builder compileClass.
!
invokePhases
self toPPCIr.
self createTokens.
self cacheFirstFollow.
self createLL1Choices.
self tokenize.
self merge.
self specialize.
self createRecognizingComponents.
self specialize.
self inline.
self merge.
self check.
self cacheFirstFollow.
self buildParserClazz.
self unmarkConsumeTokensForInline.
self createFSAs.
self buildScannerTokens.
self buildScannerScans.
self generateScanner.
self generateParser.
! !
!PPCTokenizingConfiguration methodsFor:'initialization'!
fillInClazzes
parserClazz name: options parserName.
parserClazz superclass: PPTokenizingCompiledParser.
scannerClazz name: options scannerName.
scannerClazz superclass: options scannerSuperclass.
!
initialize
super initialize.
parserClazz := PPCClass new.
scannerClazz := PPCClass new.
idGen := PPCIdGenerator new.
"The parser and scanner share the same id generator in order
to use same names for tokens.
"
parserClazz idGen: idGen.
scannerClazz idGen: idGen.
! !
!PPCTokenizingConfiguration methodsFor:'phases'!
buildParserClazz
| rootMethod |
rootMethod := PPCTokenizingCodeGenerator new
clazz: parserClazz;
options: options;
visit: ir.
parserClazz propertyAt: #rootMethod put: rootMethod
!
buildScannerScans
| fsas generator |
"TODO JK: Perhpas write separate visitor for this?"
fsas := IdentitySet new.
fsas addAll: (ir allNodes select: [ :node | node hasFsa ] thenCollect: [:node | node fsa]).
fsas addAll: (ir allNodes select: [ :node | node hasNextFsa ] thenCollect: [:node | node nextFsa]).
fsas := fsas reject: [ :fsa | fsa hasDistinctRetvals not ].
generator := PPCScannerCodeGenerator new
clazz: scannerClazz;
options: options;
yourself.
fsas do: [ :fsa | generator generate: fsa ].
!
buildScannerTokens
| generator |
generator := PPCTokenCodeGenerator new
clazz: scannerClazz;
options: options;
yourself.
generator visit: ir.
!
createFSAs
ir := PPCFSAVisitor new
idGen: idGen;
visit: ir.
self remember: (self copyTree: ir) as: #withFSAs
!
createLL1Choices
self flag: 'This phase needs revisit and update'.
ir := PPCLL1Visitor new
options: options;
visit: ir.
self remember: (self copyTree: ir) as: #LL1
!
generateParser
| parserClass rootMethod |
options generate ifFalse: [ ^ self ].
rootMethod := parserClazz propertyAt: #rootMethod.
parserClazz name: options parserName.
parserClazz superclass: options parserSuperclass.
parserClass := self buildClass: parserClazz.
parserClass startSymbol: rootMethod methodName.
self remember: parserClass as: #parser.
ir := parserClass new
!
generateScanner
| scanner |
options generate ifFalse: [ ^ self ].
scannerClazz name: options scannerName.
scannerClazz superclass: options scannerSuperclass.
scanner := (self buildClass: scannerClazz).
parserClazz addConstant: scanner as: #scannerClass.
ir := scanner.
self remember: scanner as: #scanner
!
tokenize
"
This will try transform the parser into the tokenizing parser
"
options tokenize ifFalse: [ ^ self ] .
ir := PPCTokenizingVisitor new
options: options;
visit: ir.
self remember: (self copyTree: ir) as: #tokenize
!
unmarkConsumeTokensForInline
"TODO JK: Hack alert, use visitor, or at leas isTokenConsume"
ir allNodesDo: [ :node |
node class == PPCTokenConsumeNode ifTrue: [
node unmarkForInline
]
]
! !