compiler/PPCTokenizingConfiguration.st
changeset 525 751532c8f3db
parent 516 3b81c9e53352
parent 524 f6f68d32de73
child 529 439c4057517f
--- 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> $'
-! !
-