diff -r 09afcf28ed60 -r 751532c8f3db compiler/PPCTokenizingConfiguration.st --- a/compiler/PPCTokenizingConfiguration.st Tue Aug 18 22:46:10 2015 +0100 +++ b/compiler/PPCTokenizingConfiguration.st Mon Aug 24 15:56:20 2015 +0100 @@ -3,23 +3,26 @@ "{ NameSpace: Smalltalk }" PPCConfiguration subclass:#PPCTokenizingConfiguration - instanceVariableNames:'codeGen' + instanceVariableNames:'scannerClazz parserClazz idGen' classVariableNames:'' poolDictionaries:'' category:'PetitCompiler-Core' ! - !PPCTokenizingConfiguration methodsFor:'compiling'! -buildClass: compiler +arguments: args + super arguments: args. +! + +buildClass: clazz | builder | builder := PPCClassBuilder new. - builder compiledClassName: arguments parserName. - builder compiledSuperclass: PPTokenizingCompiledParser. - builder methodDictionary: compiler methodDictionary. - builder constants: compiler constants. + builder compiledClassName: clazz name. + builder compiledSuperclass: clazz superclass. + builder methodDictionary: clazz methodDictionary. + builder constants: clazz constants. ^ builder compileClass. ! @@ -38,45 +41,128 @@ self merge. self check. self cacheFirstFollow. - self generateScanner. "Please note that codeGen is shared between these two phases" - self generate. + self buildParserClazz. + self unmarkConsumeTokensForInline. + self createFSAs. + self buildScannerTokens. + self buildScannerScans. + self generateScanner. + self generateParser. ! ! -!PPCTokenizingConfiguration methodsFor:'hooks'! +!PPCTokenizingConfiguration methodsFor:'initialization'! -codeCompiler - codeGen isNil ifTrue: [ codeGen := PPCTokenizingCodeGen on: arguments ]. - ^ codeGen +fillInClazzes + parserClazz name: arguments parserName. + parserClazz superclass: PPTokenizingCompiledParser. + + scannerClazz name: arguments scannerName. + scannerClazz superclass: arguments scannerSuperclass. + ! -codeCompilerOn: args - ^ PPCTokenizingCompiler on: args -! - -codeGeneratorVisitorOn: compiler - ^ PPCTokenizingCodeGenerator on: compiler +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'! -createLL1Choices - ir := PPCLL1Visitor new +buildParserClazz + | rootMethod | + rootMethod := PPCTokenizingCodeGenerator new + clazz: parserClazz; arguments: arguments; visit: ir. - self remember: #LL1 + + parserClazz propertyAt: #rootMethod put: rootMethod ! -generateScanner - | generator scanner | +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; + arguments: arguments; + yourself. + + fsas do: [ :fsa | generator generate: fsa ]. +! + +buildScannerTokens + | generator | generator := PPCTokenCodeGenerator new - compiler: self codeCompiler; + clazz: scannerClazz; arguments: arguments; 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'. - scanner := generator compileScanner. - self codeCompiler addConstant: scanner as: #scannerClass. + ir := PPCLL1Visitor new + arguments: arguments; + visit: ir. + + self remember: (self copyTree: ir) as: #LL1 +! + +generateParser + | parserClass rootMethod | + arguments generate ifFalse: [ ^ self ]. + rootMethod := parserClazz propertyAt: #rootMethod. + + parserClazz name: arguments parserName. + parserClazz superclass: arguments parserSuperclass. + + parserClass := self buildClass: parserClazz. + parserClass startSymbol: rootMethod methodName. + + self remember: parserClass as: #parser. + ir := parserClass new + + +! + +generateScanner + | scanner | + arguments generate ifFalse: [ ^ self ]. + + scannerClazz name: arguments scannerName. + scannerClazz superclass: arguments scannerSuperclass. + + scanner := (self buildClass: scannerClazz). + parserClazz addConstant: scanner as: #scannerClass. + + ir := scanner. + + self remember: scanner as: #scanner ! tokenize @@ -88,13 +174,17 @@ ir := PPCTokenizingVisitor new arguments: arguments; visit: ir. - self remember: #tokenize + + + 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 + ] + ] ! ! -!PPCTokenizingConfiguration class methodsFor:'documentation'! - -version_HG - - ^ '$Changeset: $' -! ! -