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 |