PetitCommonMark/software/petitcompiler/PPCTokenizingVisitor.class.st

128 lines
2.9 KiB
Smalltalk

"
I am capable of creating PPCTokenizingParserNode.
This is a node that
- has all all the tokens collected,
- identifies the whitespace
- replaces all the token reads with token consume
"
Class {
#name : 'PPCTokenizingVisitor',
#superclass : 'PPCRewritingVisitor',
#instVars : [
'tokens'
],
#category : 'PetitCompiler-Visitors'
}
{ #category : 'tokens' }
PPCTokenizingVisitor >> addToken: token [
(tokens contains: [:e | e = token] ) ifFalse: [
tokens addLast: token
]
]
{ #category : 'hooks' }
PPCTokenizingVisitor >> afterAccept: node retval: retval [
| newRetval |
self isRoot ifTrue: [
| tokensNode whitespaceNode |
tokens do: [ :token | token unmarkForInline ].
whitespaceNode := tokens detect: [ :e | e isTrimmingTokenNode ] ifNone: [ nil ].
whitespaceNode notNil ifTrue: [
whitespaceNode := whitespaceNode whitespace copy
unmarkForInline;
name: 'consumeWhitespace';
yourself.
"whitespaceNode := PPCTokenWhitespaceNode new
child: whitespaceNode;
yourself"
] ifFalse: [
whitespaceNode := PPCNilNode new
name: 'consumeWhitespace';
yourself
].
tokensNode := PPCListNode new
children: tokens asArray;
name: 'nextToken';
yourself.
newRetval := PPCTokenizingParserNode new
parser: retval;
whitespace: whitespaceNode;
tokens: tokensNode;
name: (retval name isNil ifTrue: [ #mainParser ] ifFalse: [ retval name ]);
yourself
] ifFalse: [
newRetval := retval
].
^ super afterAccept: node retval: newRetval
"Modified: / 12-05-2015 / 01:37:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
]
{ #category : 'hooks' }
PPCTokenizingVisitor >> eofToken [
| ws |
self error: 'deprecated?'.
ws := PPCStarNode new
child: (PPCMessagePredicateNode new
message: #isSeparator;
yourself);
yourself.
^ PPCTrimmingTokenNode new
child: PPCEndOfFileNode new;
whitespace: ws;
tokenClass: PPToken;
name: 'eof';
yourself.
]
{ #category : 'initialization' }
PPCTokenizingVisitor >> initialize [
super initialize.
tokens := OrderedCollection new.
]
{ #category : 'testing' }
PPCTokenizingVisitor >> isRoot [
^ openSet size = 1
]
{ #category : 'visiting' }
PPCTokenizingVisitor >> visitTokenConsumeNode: node [
"
Seems, it might happen, that if I create the consume node,
I will ge to it later. This would create a token consume node for the
child, thus having tokenConsumNode with tokenConsumNode as a child...
"
^ node
]
{ #category : 'visiting' }
PPCTokenizingVisitor >> visitTokenNode: node [
self addToken: node.
self assert: node acceptsEpsilon not description: 'Sorry, but the epsilon tokens are not allowed'.
^ PPCTokenConsumeNode new
child: node;
name: node name;
yourself.
]
{ #category : 'visiting' }
PPCTokenizingVisitor >> visitTrimmingTokenNode: node [
self addToken: node.
^ PPCTokenConsumeNode new
child: node;
name: node name;
yourself.
]