--- 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: <not expanded> $'
-! !
-