1 "{ Package: 'stx:goodies/petitparser/compiler' }" |
1 "{ Package: 'stx:goodies/petitparser/compiler' }" |
|
2 |
|
3 "{ NameSpace: Smalltalk }" |
2 |
4 |
3 Object subclass:#PPCCompiler |
5 Object subclass:#PPCCompiler |
4 instanceVariableNames:'compilerStack compiledParser cache inlining debug profile |
6 instanceVariableNames:'compilerStack compiledParser cache inlining debug profile |
5 currentMethod guards ids tokenMode rootNode' |
7 currentMethod guards ids tokenMode rootNode' |
6 classVariableNames:'' |
8 classVariableNames:'' |
164 smartRestore: parser from: mementoName |
150 smartRestore: parser from: mementoName |
165 parser isContextFree ifTrue: [ |
151 parser isContextFree ifTrue: [ |
166 ^ 'context lwRestore: ', mementoName, '.'. |
152 ^ 'context lwRestore: ', mementoName, '.'. |
167 ]. |
153 ]. |
168 ^ 'context restore: ', mementoName, '.'. |
154 ^ 'context restore: ', mementoName, '.'. |
169 ! |
|
170 |
|
171 startTokenMode |
|
172 tokenMode := true |
|
173 ! |
|
174 |
|
175 stopTokenMode |
|
176 tokenMode := false |
|
177 ! ! |
155 ! ! |
178 |
156 |
179 !PPCCompiler methodsFor:'code generation - ids'! |
157 !PPCCompiler methodsFor:'code generation - ids'! |
180 |
158 |
181 idFor: object prefixed: prefix |
159 idFor: object prefixed: prefix |
431 ^ parser asCompilerTree |
417 ^ parser asCompilerTree |
432 ! ! |
418 ! ! |
433 |
419 |
434 !PPCCompiler methodsFor:'guard'! |
420 !PPCCompiler methodsFor:'guard'! |
435 |
421 |
436 addSequenceGuard: parser |
|
437 |
|
438 | firsts guardSet guardSetId | |
|
439 (self guards not or: [(guardSet := self guardCharSet: parser) isNil]) ifTrue: [ ^ self]. |
|
440 |
|
441 firsts := (parser firstSetSuchThat: [ :e | (e isKindOf: PPTokenParser) or: [ e isTerminal ] ]). |
|
442 |
|
443 "If we start with PPTokenParser, we should invoke the whitespace parser" |
|
444 (firsts allSatisfy: [ :e | e isKindOf: PPTokenParser ]) ifTrue: [ |
|
445 guardSetId := (self idFor: guardSet prefixed: #guard). |
|
446 self addConstant: guardSet as: guardSetId. |
|
447 self add: 'wsParser parseOn: context.'. |
|
448 self add: 'context atEnd ifTrue: [ ^ self error ].'. |
|
449 self add: '(', guardSetId, ' value: context peek) ifFalse: [ ^ self error ].'. |
|
450 ]. |
|
451 |
|
452 (firsts allSatisfy: [ :e | e isTerminal ]) ifTrue: [ |
|
453 guardSetId := (self idFor: guardSet prefixed: #guard). |
|
454 self addConstant: guardSet as: guardSetId. |
|
455 self add: 'context atEnd ifTrue: [ ^ self error ].'. |
|
456 self add: '(', guardSetId, ' value: context peek) ifFalse: [ ^ self error ].'. |
|
457 ]. |
|
458 ! |
|
459 |
|
460 guardCharSet: parser |
|
461 | fs charSet | |
|
462 "No Guards fro trimming parser so far" |
|
463 (parser firstSetSuchThat: [ :e | e isKindOf: PPCTrimNode ]) isEmpty ifFalse: [ ^ nil ]. |
|
464 |
|
465 "Makes no sense to do guard for epsilon parse" |
|
466 (parser acceptsEpsilon) ifTrue: [ ^ nil ]. |
|
467 |
|
468 fs := parser firstSet. |
|
469 fs do: [ :p | |
|
470 "If we can accept epsilon guard does not make sense" |
|
471 p isNullable ifTrue: [ ^ nil ]. |
|
472 ]. |
|
473 |
|
474 charSet := PPCharSetPredicate on: [:char | fs anySatisfy: [:e | (e firstCharParser parse: char asString) isPetitFailure not ]]. |
|
475 ^ charSet |
|
476 ! |
|
477 |
|
478 guards |
422 guards |
479 ^ guards |
423 ^ guards |
480 ! |
424 ! |
481 |
425 |
482 guards: aBoolean |
426 guards: aBoolean |