" I do specialize some nodes, so that they can emit optimized code for them. e.g. #any star can be optimized to simple jump to the end of the input. " Class { #name : 'PPCSpecializingVisitor', #superclass : 'PPCRewritingVisitor', #category : 'PetitCompiler-Visitors' } { #category : 'visiting' } PPCSpecializingVisitor >> rejectDuplicateChildren: node [ | seen newChildren | seen := IdentitySet new. newChildren := OrderedCollection new. node children do: [ :child | (seen includes: child) ifFalse: [ newChildren add: child ]. seen add: child ]. ^ newChildren ] { #category : 'visiting' } PPCSpecializingVisitor >> visitActionNode: node [ (node block isSymbol) ifTrue: [ | newNode | newNode := PPCSymbolActionNode new block: node block; name: node name; child: node child; properties: node properties copy; yourself. ^ super visitActionNode: newNode ]. ^ super visitActionNode: node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitChoiceNode: node [ self visitChildren: node. (node children size = 1) ifTrue: [ ^ node "firstChild " ]. "Remove the identical children" "node children: (self rejectDuplicateChildren: node)." ^ node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitForwardNode: node [ node name ifNil: [ self cache: node value: node child. ^ self visit: node child. ]. node child name ifNil: [ node child name: node name. self cache: node value: node child. ^ self visit: node child. ]. (node child name = node name) ifTrue: [ self cache: node value: node child. ^ self visit: node child. ]. ^ super visitForwardNode: node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitIslandNode: node [ (context options useContextFreeSeas and: [ node island isContextFree ]) ifTrue: [ node parser: node parser asLightweightMemoizingSea ]. ^ super visitIslandNode: node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitNonEmptyNode: node [ self visitChildren: node. (node child alwaysConsumes) ifTrue: [ ^ node child ]. ^ node "Modified: / 23-04-2015 / 12:02:15 / Jan Vrany " ] { #category : 'visiting' } PPCSpecializingVisitor >> visitNotNode: node [ self visitChildren: node. (node child isKindOf: PPCAbstractLiteralNode) ifTrue: [ ^ PPCNotLiteralNode new name: node name; literal: node child literal; yourself ]. (node child isKindOf: PPCMessagePredicateNode) ifTrue: [ ^ PPCNotMessagePredicateNode new name: node name; predicate: node child predicate; message: node child message; yourself ]. (node child isKindOf: PPCCharSetPredicateNode) ifTrue: [ ^ PPCNotCharSetPredicateNode new name: node name; predicate: node child predicate; yourself ]. (node child isKindOf: PPCCharacterNode) ifTrue: [ ^ PPCNotCharacterNode new name: node name; character: node child character; yourself ]. ^ node "Modified: / 23-04-2015 / 12:02:15 / Jan Vrany " ] { #category : 'visiting' } PPCSpecializingVisitor >> visitPlusNode: node [ self visitChildren: node. (node child isKindOf: PPCMessagePredicateNode) ifTrue: [ ^ PPCPlusMessagePredicateNode new name: node name; child: node child; message: node child message; yourself ]. ^ node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitPredicateNode: node [ | charSet | (node predicate class == PPCharSetPredicate) ifTrue: [ charSet := node predicate. ]. charSet := PPCharSetPredicate on: node predicate. (charSet equals: (PPCharSetPredicate on: [ :char | char isLetter])) ifTrue: [ ^ PPCMessagePredicateNode new name: node name; message: #isLetter; predicate: node predicate; yourself ]. (charSet equals: (PPCharSetPredicate on: [ :char | char isDigit])) ifTrue: [ ^ PPCMessagePredicateNode new name: node name; message: #isDigit; predicate: node predicate; yourself ]. (charSet equals: (PPCharSetPredicate on: [ :char | char isAlphaNumeric])) ifTrue: [ ^ PPCMessagePredicateNode new name: node name; message: #isAlphaNumeric; predicate: node predicate; yourself ]. (charSet equals: (PPCharSetPredicate on: [ :char | char isSeparator])) ifTrue: [ ^ PPCMessagePredicateNode new name: node name; message: #isSeparator; predicate: node predicate; yourself ]. (charSet equals: (PPCharSetPredicate on: [ :char | true ])) ifTrue: [ ^ PPCAnyNode new name: node name; yourself ]. ^ PPCCharSetPredicateNode new name: node name; predicate: charSet; yourself. ] { #category : 'visiting' } PPCSpecializingVisitor >> visitStarNode: node [ self visitChildren: node. (node child isKindOf: PPCMessagePredicateNode) ifTrue: [ ^ PPCStarMessagePredicateNode new name: node name; child: node child; message: node child message; yourself ]. (node child isKindOf: PPCAnyNode) ifTrue: [ ^ PPCStarAnyNode new name: node name; child: node child; yourself ]. (node child isKindOf: PPCCharSetPredicateNode) ifTrue: [ ^ PPCStarCharSetPredicateNode new name: node name; predicate: node child predicate; child: node child; yourself ]. ^ node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitTokenConsumeNode: node [ "Let the Scanner to handle this stuff" ^ node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitTokenizingParserNode: node [ self visitChild: node parser of: node. ^ node ] { #category : 'visiting' } PPCSpecializingVisitor >> visitTrimmingTokenNode: node [ self visitChildren: node. (node child isKindOf: PPCCharacterNode) ifTrue: [ ^ PPCTrimmingCharacterTokenNode new child: node child; whitespace: node whitespace; tokenClass: node tokenClass; character: node child character; name: node name; yourself ]. ^ node "Modified: / 21-05-2015 / 14:41:53 / Jan Vrany " ]