compiler/PPCTokenizingConfiguration.st
changeset 524 f6f68d32de73
parent 515 b5316ef15274
child 525 751532c8f3db
equal deleted inserted replaced
515:b5316ef15274 524:f6f68d32de73
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     1 "{ Package: 'stx:goodies/petitparser/compiler' }"
     2 
     2 
     3 "{ NameSpace: Smalltalk }"
     3 "{ NameSpace: Smalltalk }"
     4 
     4 
     5 PPCConfiguration subclass:#PPCTokenizingConfiguration
     5 PPCConfiguration subclass:#PPCTokenizingConfiguration
     6 	instanceVariableNames:'codeGen'
     6 	instanceVariableNames:'scannerClazz parserClazz idGen'
     7 	classVariableNames:''
     7 	classVariableNames:''
     8 	poolDictionaries:''
     8 	poolDictionaries:''
     9 	category:'PetitCompiler-Core'
     9 	category:'PetitCompiler-Core'
    10 !
    10 !
    11 
    11 
    12 !PPCTokenizingConfiguration methodsFor:'compiling'!
    12 !PPCTokenizingConfiguration methodsFor:'compiling'!
    13 
    13 
    14 buildClass: compiler
    14 arguments: args
       
    15     super arguments: args.
       
    16 !
       
    17 
       
    18 buildClass: clazz
    15     |  builder |
    19     |  builder |
    16     builder := PPCClassBuilder new.
    20     builder := PPCClassBuilder new.
    17     
    21     
    18     builder compiledClassName: arguments parserName.
    22     builder compiledClassName: clazz name.
    19     builder compiledSuperclass: PPTokenizingCompiledParser.
    23     builder compiledSuperclass: clazz superclass.
    20     builder methodDictionary: compiler methodDictionary.
    24     builder methodDictionary: clazz methodDictionary.
    21     builder constants: compiler constants.
    25     builder constants: clazz constants.
    22 
    26 
    23     ^ builder compileClass.	
    27     ^ builder compileClass.	
    24 !
    28 !
    25 
    29 
    26 invokePhases
    30 invokePhases
    35     self specialize.
    39     self specialize.
    36     self inline.
    40     self inline.
    37     self merge.
    41     self merge.
    38     self check.	
    42     self check.	
    39     self cacheFirstFollow.
    43     self cacheFirstFollow.
    40     self generateScanner.		"Please note that codeGen is shared between these two phases"
    44     self buildParserClazz.
    41     self generate.
    45     self unmarkConsumeTokensForInline.
       
    46     self createFSAs.
       
    47     self buildScannerTokens.
       
    48     self buildScannerScans.	
       
    49     self generateScanner.
       
    50     self generateParser.
    42 ! !
    51 ! !
    43 
    52 
    44 !PPCTokenizingConfiguration methodsFor:'hooks'!
    53 !PPCTokenizingConfiguration methodsFor:'initialization'!
    45 
    54 
    46 codeCompiler
    55 fillInClazzes
    47     codeGen isNil ifTrue: [ codeGen := PPCTokenizingCodeGen on: arguments ].
    56     parserClazz name: arguments parserName.
    48     ^ codeGen
    57     parserClazz superclass: PPTokenizingCompiledParser.
       
    58     
       
    59     scannerClazz name: arguments scannerName.
       
    60     scannerClazz superclass: arguments scannerSuperclass.
       
    61     
    49 !
    62 !
    50 
    63 
    51 codeCompilerOn: args
    64 initialize
    52     ^ PPCTokenizingCompiler on: args
    65     super initialize.
    53 !
    66     
    54 
    67     parserClazz := PPCClass new.
    55 codeGeneratorVisitorOn: compiler
    68     scannerClazz := PPCClass new.
    56     ^ PPCTokenizingCodeGenerator on: compiler
    69     
       
    70     idGen := PPCIdGenerator new.
       
    71     
       
    72     "The parser and scanner share the same id generator in order
       
    73      to use same names for tokens.
       
    74     "
       
    75     parserClazz idGen: idGen.
       
    76     scannerClazz idGen: idGen.
    57 ! !
    77 ! !
    58 
    78 
    59 !PPCTokenizingConfiguration methodsFor:'phases'!
    79 !PPCTokenizingConfiguration methodsFor:'phases'!
    60 
    80 
    61 createLL1Choices
    81 buildParserClazz
    62     ir :=  PPCLL1Visitor new
    82     | rootMethod |
       
    83     rootMethod := PPCTokenizingCodeGenerator new
       
    84         clazz: parserClazz;
    63         arguments: arguments;
    85         arguments: arguments;
    64         visit: ir.
    86         visit: ir.
    65     self remember: #LL1
    87         
       
    88     parserClazz propertyAt: #rootMethod put: rootMethod
    66 !
    89 !
    67 
    90 
    68 generateScanner
    91 buildScannerScans
    69     | generator scanner |
    92     | fsas  generator |
       
    93     
       
    94     "TODO JK: Perhpas write separate visitor for this?"
       
    95     fsas := IdentitySet new.
       
    96     fsas addAll: (ir allNodes select: [ :node | node hasFsa ] thenCollect: [:node | node fsa]).
       
    97     fsas addAll: (ir allNodes select: [ :node | node hasNextFsa ] thenCollect: [:node | node nextFsa]).
       
    98     fsas := fsas reject: [ :fsa | fsa hasDistinctRetvals not ].
       
    99     
       
   100     generator := PPCScannerCodeGenerator new
       
   101         clazz: scannerClazz;
       
   102         arguments: arguments;
       
   103         yourself.
       
   104         
       
   105     fsas do: [ :fsa | generator generate: fsa ].
       
   106 !
       
   107 
       
   108 buildScannerTokens
       
   109     | generator  |
    70     generator :=  PPCTokenCodeGenerator new
   110     generator :=  PPCTokenCodeGenerator new
    71         compiler: self codeCompiler;
   111         clazz: scannerClazz;
    72         arguments: arguments;
   112         arguments: arguments;
    73         yourself.
   113         yourself.
    74 
   114 
    75     generator visit: ir.
   115     generator visit: ir.
       
   116 !
       
   117 
       
   118 createFSAs
       
   119     ir := PPCFSAVisitor new
       
   120         idGen: idGen;
       
   121         visit: ir.
       
   122 
       
   123     self remember: (self copyTree: ir) as: #withFSAs
       
   124 !
       
   125 
       
   126 createLL1Choices
       
   127     self flag: 'This phase needs revisit and update'.
    76     
   128     
    77     scanner := generator compileScanner.	
   129     ir :=  PPCLL1Visitor new
    78     self codeCompiler addConstant: scanner as: #scannerClass.
   130         arguments: arguments;
       
   131         visit: ir.
       
   132         
       
   133     self remember: (self copyTree: ir) as: #LL1
       
   134 !
       
   135 
       
   136 generateParser
       
   137     | parserClass rootMethod |
       
   138     arguments generate ifFalse: [ ^ self ].
       
   139     rootMethod := parserClazz propertyAt: #rootMethod.
       
   140     
       
   141     parserClazz name: arguments parserName.
       
   142     parserClazz superclass: arguments parserSuperclass.
       
   143     
       
   144     parserClass := self buildClass: parserClazz.
       
   145     parserClass startSymbol: rootMethod methodName.
       
   146 
       
   147     self remember: parserClass as: #parser.
       
   148     ir := parserClass new
       
   149 
       
   150     
       
   151 !
       
   152 
       
   153 generateScanner
       
   154     | scanner |
       
   155     arguments generate ifFalse: [ ^ self ].
       
   156     
       
   157     scannerClazz name: arguments scannerName.
       
   158     scannerClazz superclass: arguments scannerSuperclass.
       
   159     
       
   160     scanner := (self buildClass: scannerClazz).
       
   161     parserClazz addConstant: scanner as: #scannerClass.
       
   162     
       
   163     ir := scanner.
       
   164     
       
   165     self remember: scanner as: #scanner
    79 !
   166 !
    80 
   167 
    81 tokenize
   168 tokenize
    82     "
   169     "
    83         This will try transform the parser into the tokenizing parser
   170         This will try transform the parser into the tokenizing parser
    85     arguments tokenize ifFalse: [ ^ self ] .
   172     arguments tokenize ifFalse: [ ^ self ] .
    86     
   173     
    87     ir :=  PPCTokenizingVisitor new
   174     ir :=  PPCTokenizingVisitor new
    88         arguments: arguments;
   175         arguments: arguments;
    89         visit: ir.
   176         visit: ir.
    90     self remember: #tokenize
   177         
       
   178         
       
   179     self remember: (self copyTree: ir) as: #tokenize
       
   180 !
       
   181 
       
   182 unmarkConsumeTokensForInline
       
   183     "TODO JK: Hack alert, use visitor, or at leas isTokenConsume"
       
   184     ir allNodesDo: [ :node |
       
   185         node class == PPCTokenConsumeNode ifTrue: [ 
       
   186             node unmarkForInline
       
   187         ]
       
   188     ]
    91 ! !
   189 ! !
    92 
   190