PPParser.st
author Claus Gittinger <cg@exept.de>
Tue, 04 Mar 2014 22:15:55 +0100
changeset 340 51d23338b32e
parent 173 44b2dcba820e
child 366 225737f7f83f
permissions -rw-r--r--
initial checkin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
     1
"{ Package: 'stx:goodies/petitparser' }"
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
Object subclass:#PPParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
	instanceVariableNames:'properties'
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
	classVariableNames:''
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	poolDictionaries:''
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	category:'PetitParser-Parsers'
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
!PPParser class methodsFor:'instance creation'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
named: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    14
	^ self new name: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    15
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    16
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    17
new
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
	^ self basicNew initialize
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    21
!PPParser methodsFor:'*petitanalyzer-enumerating'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    22
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    23
allParsers
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    24
	"Answer all the parse nodes of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    25
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    26
	| result |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    27
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    28
	self allParsersDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    29
	^ result
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    30
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    31
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    32
allParsersDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    33
	"Iterate over all the parse nodes of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    34
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    35
	self allParsersDo: aBlock seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    36
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    37
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    38
allParsersDo: aBlock seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    39
	"Iterate over all the parse nodes of the receiver, do not visit and follow the ones contained in aSet."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    40
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    41
	(aSet includes: self)
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    42
		ifTrue: [ ^ self ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    43
	aSet add: self.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    44
	aBlock value: self.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    45
	self children
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    46
		do: [ :each | each allParsersDo: aBlock seen: aSet ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    47
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    48
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    49
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    50
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    51
copyInContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    52
	^ self copyInContext: aDictionary seen: IdentityDictionary new
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    53
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    54
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    55
copyInContext: aDictionary seen: aSeenDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    56
	| copy |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    57
	aSeenDictionary 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    58
		at: self 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    59
		ifPresent: [ :value | ^ value ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    60
	copy := aSeenDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    61
		at: self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    62
		put: self copy.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    63
	copy children do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    64
		copy
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    65
			replace: each
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    66
			with: (each copyInContext: aDictionary seen: aSeenDictionary) ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    67
	^ copy
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    68
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    69
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    70
match: aParser inContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    71
	^ self match: aParser inContext: aDictionary seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    72
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    73
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    74
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    75
	"This is the default implementation to match two parsers. This code can properly handle recursion. This is code is supposed to be overridden in subclasses that add new state."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    76
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    77
	(self == aParser or: [ anIdentitySet includes: self ])
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    78
		ifTrue: [ ^ true ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    79
	anIdentitySet add: self.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    80
	^ self class = aParser class and: [ self matchList: self children against: aParser children inContext: aDictionary seen: anIdentitySet ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    81
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    82
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    83
matchList: matchList against: parserList inContext: aDictionary seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    84
	^ self matchList: matchList index: 1 against: parserList index: 1 inContext: aDictionary seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    85
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    86
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    87
matchList: matchList index: matchIndex against: parserList index: parserIndex inContext: aDictionary seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    88
	| parser currentIndex currentDictionary currentSeen parsers |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    89
	matchList size < matchIndex
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    90
		ifTrue: [ ^ parserList size < parserIndex ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    91
	parser := matchList at: matchIndex.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    92
	parser class = PPListPattern ifTrue: [
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    93
		currentIndex := parserIndex - 1.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    94
		[ currentDictionary := aDictionary copy.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    95
		currentSeen := aSet copy.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    96
		parserList size < currentIndex or: [ 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    97
			parsers := parserList copyFrom: parserIndex to: currentIndex.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    98
			(currentDictionary at: parser ifAbsentPut: [ parsers ]) = parsers and: [ 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
    99
				(self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   100
					matchList: matchList
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   101
					index: matchIndex + 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   102
					against: parserList
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   103
					index: currentIndex + 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   104
					inContext: currentDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   105
					seen: currentSeen)
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   106
					ifTrue: [ 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   107
						currentDictionary keysAndValuesDo: [ :key :value | aDictionary at: key put: value ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   108
						^ true ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   109
				false ] ] ] whileFalse: [ currentIndex := currentIndex + 1 ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   110
		^ false ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   111
	parserList size < parserIndex
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   112
		ifTrue: [ ^ false ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   113
	(parser match: (parserList at: parserIndex) inContext: aDictionary seen: aSet)
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   114
		ifFalse: [ ^ false ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   115
	^ self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   116
		matchList: matchList
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   117
		index: matchIndex + 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   118
		against: parserList
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   119
		index: parserIndex + 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   120
		inContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   121
		seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   122
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   123
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   124
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   125
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   126
allNamedParsers
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   127
	"Answer all the named parse nodes of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   128
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   129
	| result |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   130
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   131
	self allNamedParsersDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   132
	^ result
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   133
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   134
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   135
allNamedParsersDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   136
	"Iterate over all the named parse nodes of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   137
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   138
	self allParsersDo: [ :each | 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   139
		each name notNil
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   140
			ifTrue: [ aBlock value: each ] ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   141
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   142
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   143
innerChildren
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   144
	"Answer the inner children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   145
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   146
	| result |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   147
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   148
	self innerChildrenDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   149
	^ result
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   150
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   151
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   152
innerChildrenDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   153
	"Iterate over the inner children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   154
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   155
	self innerChildrenDo: aBlock seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   156
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   157
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   158
innerChildrenDo: aBlock seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   159
	"Iterate over the inner children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   160
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   161
	self children do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   162
		(aSet includes: each)
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   163
			ifTrue: [ ^ self ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   164
		aSet add: each.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   165
		each name isNil ifTrue: [
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   166
			aBlock value: each.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   167
			each innerChildrenDo: aBlock seen: aSet ] ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   168
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   169
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   170
namedChildren
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   171
	"Answer the named children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   172
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   173
	| result |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   174
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   175
	self namedChildrenDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   176
	^ result
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   177
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   178
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   179
namedChildrenDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   180
	"Iterate over the named children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   181
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   182
	self namedChildrenDo: aBlock seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   183
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   184
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   185
namedChildrenDo: aBlock seen: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   186
	"Iterate over the named children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   187
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   188
	self children do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   189
		(aSet includes: each)
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   190
			ifTrue: [ ^ self ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   191
		aSet add: each.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   192
		each name isNil
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   193
			ifTrue: [ each namedChildrenDo: aBlock seen: aSet ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   194
			ifFalse: [ aBlock value: each ] ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   195
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   196
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   197
!PPParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   198
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   199
cycleSet: aDictionary
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   200
	"PRIVATE: Answer the children that could be part of a cycle-set with the receiver, subclasses might restrict the number of children returned. aDictionary is pre-calcualted first-sets."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   201
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   202
	^ self children
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   203
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   204
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   205
cycleSet: aStack firstSets: aDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   206
	"PRIVATE: Try to find a cycle, where aStack contains the previously visited parsers. The method returns quickly when the receiver is a terminal, terminals cannot be part of a cycle. If aStack already contains the receiver, then we are in a cycle. In this case we don't process the children further and add the nodes to aSet."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   207
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   208
	| index |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   209
	self isTerminal
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   210
		ifTrue: [ ^ self ].	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   211
	(index := aStack indexOf: self) > 0
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   212
		ifTrue: [ ^ aSet addAll: (aStack copyFrom: index to: aStack size) ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   213
	aStack addLast: self.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   214
	(self cycleSet: aDictionary)
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   215
		do: [ :each | each cycleSet: aStack firstSets: aDictionary into: aSet ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   216
	aStack removeLast
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   217
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   218
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   219
firstSets: aFirstDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   220
	"PRIVATE: Try to add additional elements to the first-set aSet of the receiver, use the incomplete aFirstDictionary."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   221
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   222
	self children do: [ :parser | aSet addAll: (aFirstDictionary at: parser) ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   223
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   224
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   225
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   226
	"PRIVATE: Try to add additional elements to the follow-set aSet of the receiver, use the incomplete aFollowDictionary and the complete aFirstDictionary."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   227
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   228
	self children do: [ :parser | (aFollowDictionary at: parser) addAll: aSet ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   229
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   230
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   231
!PPParser methodsFor:'*petitanalyzer-querying'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   232
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   233
cycleSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   234
	"Answer a set of all nodes that are within one or more cycles of left-recursion. This is generally not a problem if at least one of the nodes is memoized, but it might make the grammar very inefficient and should be avoided if possible."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   235
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   236
	| cycles |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   237
	cycles := IdentitySet new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   238
	self cycleSet: OrderedCollection new firstSets: self firstSets into: cycles.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   239
	^ cycles
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   240
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   241
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   242
firstSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   243
	"Answer the first-set of the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #firstSets to calculate the first-sets at once."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   244
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   245
	^ self firstSets at: self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   246
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   247
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   248
firstSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   249
	"Answer a dictionary with all the parsers reachable from the receiver as key and their first-set as value. The first-set of a parser is the list of terminal parsers that begin the parser derivable from that parser."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   250
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   251
	| firstSets |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   252
	firstSets := IdentityDictionary new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   253
	self allParsersDo: [ :each |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   254
		firstSets at: each put: (each isTerminal
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   255
			ifTrue: [ IdentitySet with: each ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   256
			ifFalse: [ IdentitySet new ]).
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   257
		each isNullable
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   258
			ifTrue: [ (firstSets at: each) add: PPSentinel instance ] ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   259
	[	| changed tally |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   260
		changed := false.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   261
		firstSets keysAndValuesDo: [ :parser :first |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   262
			tally := first size.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   263
			parser firstSets: firstSets into: first.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   264
			changed := changed or: [ tally ~= first size ] ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   265
		changed ] whileTrue.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   266
	^ firstSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   267
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   268
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   269
followSet
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   270
	"Answer the follow-set of the receiver starting at the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #followSets to calculate the follow-sets at once."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   271
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   272
	^ self followSets at: self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   273
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   274
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   275
followSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   276
	"Answer a dictionary with all the parsers reachable from the receiver as key and their follow-set as value. The follow-set of a parser is the list of terminal parsers that can appear immediately to the right of that parser."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   277
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   278
	| current previous continue firstSets followSets |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   279
	current := previous := 0.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   280
	firstSets := self firstSets.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   281
	followSets := IdentityDictionary new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   282
	self allParsersDo: [ :each | followSets at: each put: IdentitySet new ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   283
	(followSets at: self) add: PPSentinel instance.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   284
	[	followSets keysAndValuesDo: [ :parser :follow |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   285
			parser 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   286
				followSets: followSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   287
				firstSets: firstSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   288
				into: follow ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   289
		current := followSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   290
			inject: 0
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   291
			into: [ :result :each | result + each size ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   292
		continue := previous < current.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   293
		previous := current.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   294
		continue ] whileTrue.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   295
	^ followSets
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   296
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   297
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   298
!PPParser methodsFor:'*petitanalyzer-testing'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   299
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   300
isNullable
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   301
	"Answer true if the receiver is a nullable parser, e.g. it can successfully parse nothing."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   302
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   303
	^ false
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   304
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   305
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   306
isTerminal
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   307
	"Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   308
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   309
	^ self children isEmpty
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   310
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   311
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   312
!PPParser methodsFor:'*petitanalyzer-transforming'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   313
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   314
replace: aParser with: anotherParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   315
	"Replace the references of the receiver pointing to aParser with anotherParser."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   316
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   317
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   318
transform: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   319
	"Answer a copy of all parsers reachable from the receiver transformed using aBlock."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   320
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   321
	| mapping root |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   322
	mapping := IdentityDictionary new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   323
	self allParsersDo: [ :each |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   324
		mapping
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   325
			at: each
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   326
			put: (aBlock value: each copy) ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   327
	root := mapping at: self.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   328
	[	| changed |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   329
		changed := false.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   330
		root allParsersDo: [ :each |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   331
			each children do: [ :old |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   332
				mapping at: old ifPresent: [ :new |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   333
					each replace: old with: new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   334
					changed := true ] ] ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   335
		changed ] whileTrue.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   336
	^ root
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   337
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   338
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   339
!PPParser methodsFor:'accessing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   340
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   341
children
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   342
	"Answer a set of child parsers that could follow the receiver."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   343
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   344
	^ #()
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   345
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   346
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   347
name
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   348
	"Answer the production name of the receiver."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   349
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   350
	^ self propertyAt: #name ifAbsent: [ nil ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   351
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   352
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   353
name: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   354
	self propertyAt: #name put: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   355
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   356
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   357
!PPParser methodsFor:'accessing-properties'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   358
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   359
hasProperty: aKey
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   360
	"Test if the property aKey is present."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   361
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   362
	^ properties notNil and: [ properties includesKey: aKey ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   363
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   364
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   365
propertyAt: aKey
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   366
	"Answer the property value associated with aKey."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   367
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   368
	^ self propertyAt: aKey ifAbsent: [ self error: 'Property not found' ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   369
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   370
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   371
propertyAt: aKey ifAbsent: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   372
	"Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   373
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   374
	^ properties isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   375
		ifTrue: [ aBlock value ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   376
		ifFalse: [ properties at: aKey ifAbsent: aBlock ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   377
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   378
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   379
propertyAt: aKey ifAbsentPut: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   380
	"Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   381
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   382
	^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   383
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   384
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   385
propertyAt: aKey put: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   386
	"Set the property at aKey to be anObject. If aKey is not found, create a new entry for aKey and set is value to anObject. Answer anObject."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   387
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   388
	^ (properties ifNil: [ properties := Dictionary new: 1 ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   389
		at: aKey put: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   390
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   391
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   392
removeProperty: aKey
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   393
	"Remove the property with aKey. Answer the property or raise an error if aKey isn't found."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   394
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   395
	^ self removeProperty: aKey ifAbsent: [ self error: 'Property not found' ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   396
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   397
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   398
removeProperty: aKey ifAbsent: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   399
	"Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   400
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   401
	| answer |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   402
	properties isNil ifTrue: [ ^ aBlock value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   403
	answer := properties removeKey: aKey ifAbsent: aBlock.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   404
	properties isEmpty ifTrue: [ properties := nil ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   405
	^ answer
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   406
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   407
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   408
!PPParser methodsFor:'converting'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   409
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   410
asParser
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   411
	"Answer the receiving parser."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   412
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   413
	^ self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   414
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   415
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   416
!PPParser methodsFor:'copying'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   417
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   418
postCopy
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   419
	super postCopy.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   420
	properties := properties copy
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   421
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   422
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   423
!PPParser methodsFor:'initialization'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   424
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   425
initialize
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   426
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   427
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   428
!PPParser methodsFor:'operations'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   429
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   430
, aParser 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   431
	"Answer a new parser that parses the receiver followed by aParser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   432
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   433
	^ PPSequenceParser with: self with: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   434
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   435
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   436
/ aParser 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   437
	"Answer a new parser that parses the receiver, if the receiver fails try with aParser (ordered-choice)."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   438
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   439
	^ PPChoiceParser with: self with: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   440
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   441
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   442
and
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   443
	"Answer a new parser (logical and-predicate) that succeeds whenever the receiver does, but never consumes input."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   444
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   445
	^ PPAndParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   446
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   447
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   448
def: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   449
	"Redefine the receiver as the argument aParser. This method is useful when defining recursive parsers: instantiate a PPUnresolvedParser and later redefine it with another one."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   450
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   451
	^ self becomeForward: (aParser name: self name)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   452
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   453
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   454
end
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   455
	"Answer a new parser that succeeds at the end of the input and return the result of the receiver."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   456
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   457
	^ PPEndOfInputParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   458
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   459
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   460
memoized
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   461
	"Answer a new memoized parser, for refraining redundant computations. This ensures polynomial time O(n^4) for left-recursive grammars and O(n^3) for non left-recursive grammars in the worst case. Not necessary for most grammars that are carefully written and in O(n) anyway."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   462
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   463
	^ PPMemoizedParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   464
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   465
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   466
negate
92
a95137a3ab6a class: PPToken
Claus Gittinger <cg@exept.de>
parents: 22
diff changeset
   467
        "Answer a new parser consumes any input token but the receiver."
a95137a3ab6a class: PPToken
Claus Gittinger <cg@exept.de>
parents: 22
diff changeset
   468
        
a95137a3ab6a class: PPToken
Claus Gittinger <cg@exept.de>
parents: 22
diff changeset
   469
        ^ self not , #any asParser ==> #second
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   470
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   471
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   472
not
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   473
	"Answer a new parser (logical not-predicate) that succeeds whenever the receiver fails, but never consumes input."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   474
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   475
	^ PPNotParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   476
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   477
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   478
optional
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   479
	"Answer a new parser that parses the receiver, if possible."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   480
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   481
	^ PPOptionalParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   482
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   483
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   484
times: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   485
	"Answer a new parser that parses the receiver exactly anInteger times."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   486
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   487
	^ self min: anInteger max: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   488
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   489
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   490
wrapped
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   491
	"Answer a new parser that is simply wrapped."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   492
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   493
	^ PPDelegateParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   494
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   495
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   496
| aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   497
	"Answer a new parser that either parses the receiver or aParser. Fail if both pass or fail (exclusive choice, unordered choice)."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   498
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   499
	^ (self not , aParser) / (aParser not , self) ==> #second
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   500
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   501
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   502
!PPParser methodsFor:'operations-convenience'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   503
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   504
delimitedBy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   505
	"Answer a new parser that parses the receiver one or more times, separated and possibly ended by aParser."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   506
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   507
	^ (self separatedBy: aParser) , (aParser optional) ==> [ :node |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   508
		node second isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   509
			ifTrue: [ node first ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   510
			ifFalse: [ node first copyWith: node second ] ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   511
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   512
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   513
separatedBy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   514
	"Answer a new parser that parses the receiver one or more times, separated by aParser."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   515
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   516
	^ (PPSequenceParser with: self with: (PPSequenceParser with: aParser with: self) star) ==> [ :nodes |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   517
		| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   518
		result := Array new: 2 * nodes second size + 1.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   519
		result at: 1 put: nodes first.
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   520
		nodes second 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   521
			keysAndValuesDo: [ :index :pair | result replaceFrom: 2 * index to: 2 * index + 1 with: pair startingAt: 1 ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   522
		result ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   523
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   524
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   525
!PPParser methodsFor:'operations-mapping'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   526
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   527
==> aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   528
	"Answer a new parser that performs aBlock as action handler on success."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   529
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   530
	^ PPActionParser on: self block: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   531
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   532
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   533
>=> aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   534
	"Answer a new parser that wraps the receiving parser with a two argument block. The first argument is the parsed stream, the second argument a continuation block on the delegate parser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   535
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   536
	^ PPWrappingParser on: self block: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   537
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   538
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   539
answer: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   540
	"Answer a new parser that always returns anObject from a successful parse."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   541
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   542
	^ self ==> [ :nodes | anObject ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   543
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   544
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   545
flatten
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   546
	"Answer a new parser that flattens the underlying collection."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   547
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   548
	^ PPFlattenParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   549
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   550
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   551
token
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   552
	"Answer a new parser that transforms the input to a token."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   553
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   554
	^ PPTokenParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   555
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   556
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   557
token: aTokenClass
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   558
	"Answer a new parser that transforms the input to a token of class aTokenClass."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   559
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   560
	^ self token tokenClass: aTokenClass
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   561
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   562
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   563
trim
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   564
	"Answer a new parser that consumes spaces before and after the receiving parser."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   565
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   566
	^ self trimSpaces
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   567
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   568
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   569
!PPParser methodsFor:'operators-convenience'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   570
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   571
withoutSeparators
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   572
	"Filters out the separators from a parse result produced by one of the productions #delimitedBy: or #separatedBy:."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   573
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   574
	^ self ==> [ :items |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   575
		| result |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   576
		result := Array new: items size + 1 // 2.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   577
		1 to: result size do: [ :index | result at: index put: (items at: 2 * index - 1) ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   578
		result ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   579
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   580
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   581
!PPParser methodsFor:'operators-mapping'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   582
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   583
foldLeft: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   584
	"Answer a new parser that that folds the result of the receiver from left-to-right into aBlock. The argument aBlock must take two or more arguments."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   585
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   586
	| size args |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   587
	size := aBlock numArgs.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   588
	args := Array new: size.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   589
	^ self ==> [ :nodes |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   590
		args at: 1 put: nodes first.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   591
		2 to: nodes size by: size - 1 do: [ :index |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   592
			args
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   593
				replaceFrom: 2 to: size with: nodes startingAt: index;
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   594
				at: 1 put: (aBlock valueWithArguments: args) ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   595
		args first ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   596
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   597
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   598
foldRight: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   599
	"Answer a new parser that that folds the result of the receiver from right-to-left into aBlock. The argument aBlock must take two or more arguments."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   600
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   601
	| size args |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   602
	size := aBlock numArgs.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   603
	args := Array new: size.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   604
	^ self ==> [ :nodes |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   605
		args at: size put: nodes last.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   606
		nodes size - size + 1 to: 1 by: 1 - size do: [ :index |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   607
			args
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   608
				replaceFrom: 1 to: size - 1 with: nodes startingAt: index;
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   609
				at: size put: (aBlock valueWithArguments: args) ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   610
		args at: size ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   611
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   612
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   613
map: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   614
	"Answer a new parser that works on the receiving sequence an passes in each element as a block argument."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   615
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   616
	^ aBlock numArgs = 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   617
		ifTrue: [ self ==> aBlock ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   618
		ifFalse: [ self error: aBlock numArgs asString , ' arguments expected.' ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   619
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   620
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   621
trim: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   622
	"Answer a new parser that consumes and ignores aParser repeatedly before and after the receiving parser."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   623
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   624
	^ PPTrimmingParser on: self trimmer: aParser
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   625
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   626
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   627
trimBlanks
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   628
	"Answer a new parser that consumes blanks before and after the receiving parser."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   629
	
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   630
	^ self trim: #blank asParser
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   631
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   632
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   633
trimSpaces
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   634
	"Answer a new parser that consumes spaces before and after the receiving parser."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   635
	
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   636
	^ self trim: #space asParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   637
! !
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   638
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   639
!PPParser methodsFor:'operators-repeating'!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   640
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   641
max: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   642
	"Answer a new parser that parses the receiver at most anInteger times."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   643
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   644
	^ self star setMax: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   645
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   646
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   647
max: anInteger greedy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   648
	"Answer a new parser that parses the receiver at most anInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   649
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   650
	^ (self starGreedy: aParser) setMax: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   651
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   652
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   653
max: anInteger lazy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   654
	"Answer a new parser that parses the receiver at most anInteger times until it reaches aParser. This is a lazy non-blind implementation. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   655
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   656
	^ (self starLazy: aParser) setMax: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   657
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   658
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   659
min: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   660
	"Answer a new parser that parses the receiver at least anInteger times."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   661
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   662
	^ self star setMin: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   663
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   664
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   665
min: anInteger greedy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   666
	"Answer a new parser that parses the receiver at least anInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   667
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   668
	^ (self starGreedy: aParser) setMin: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   669
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   670
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   671
min: anInteger lazy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   672
	"Answer a new parser that parses the receiver at least anInteger times until it reaches aParser. This is a lazy non-blind implementation. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   673
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   674
	^ (self starLazy: aParser) setMin: anInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   675
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   676
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   677
min: aMinInteger max: aMaxInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   678
	"Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   679
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   680
	^ self star setMin: aMinInteger; setMax: aMaxInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   681
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   682
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   683
min: aMinInteger max: aMaxInteger greedy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   684
	"Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   685
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   686
	^ (self starGreedy: aParser) setMin: aMinInteger; setMax: aMaxInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   687
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   688
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   689
min: aMinInteger max: aMaxInteger lazy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   690
	"Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times until it reaches aParser. This is a greedy non-blind implementation. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   691
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   692
	^ (self starLazy: aParser) setMin: aMinInteger; setMax: aMaxInteger
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   693
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   694
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   695
plus
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   696
	"Answer a new parser that parses the receiver one or more times."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   697
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   698
	^ self star setMin: 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   699
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   700
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   701
plusGreedy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   702
	"Answer a new parser that parses the receiver one or more times until it reaches aParser. This is a greedy non-blind implementation of the star operator. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   703
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   704
	^ (self starGreedy: aParser) setMin: 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   705
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   706
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   707
plusLazy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   708
	"Answer a new parser that parses the receiver one or more times until it reaches aParser. This is a lazy non-blind implementation of the star operator. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   709
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   710
	^ (self starLazy: aParser) setMin: 1
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   711
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   712
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   713
star
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   714
	"Answer a new parser that parses the receiver zero or more times. This is a greedy and blind implementation that tries to consume as much input as possible and it does not consider what comes afterwards."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   715
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   716
	^ PPPossessiveRepeatingParser on: self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   717
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   718
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   719
starGreedy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   720
	"Answer a new parser that parses the receiver zero or more times until it reaches aParser. This is a greedy non-blind implementation of the star operator. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   721
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   722
	^ PPGreedyRepeatingParser on: self limit: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   723
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   724
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   725
starLazy: aParser
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   726
	"Answer a new parser that parses the receiver zero or more times until it reaches aParser. This is a lazy non-blind implementation of the star operator. aParser is not consumed."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   727
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   728
	^ PPLazyRepeatingParser on: self limit: aParser
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   729
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   730
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   731
!PPParser methodsFor:'parsing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   732
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   733
matches: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   734
	"Answer if anObject can be parsed by the receiver."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   735
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   736
	^ (self parse: anObject) isPetitFailure not
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   737
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   738
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   739
matchesIn: anObject
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   740
	"Search anObject repeatedly for the matches of the receiver. Answered an OrderedCollection of the matched parse-trees."
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   741
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   742
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   743
	result := OrderedCollection new.
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   744
	self 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   745
		matchesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   746
		do: [ :each | result addLast: each ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   747
	^ result
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   748
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   749
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   750
matchesIn: anObject do: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   751
	"Search anObject repeatedly for the matches of the receiver. Evaluate aBlock for each match with the matched parse-tree as the argument. Make sure to always consume exactly one character with each step, to not miss any match."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   752
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   753
	((self and ==> aBlock , #any asParser) / #any asParser) star parse: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   754
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   755
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   756
matchesSkipIn: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   757
	"Search anObject repeatedly for the matches of the receiver. Answer an OrderedCollection of the matched parse-trees. Skip over matches."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   758
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   759
	| result |
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   760
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   761
	self 
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   762
		matchesSkipIn: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   763
		do: [ :each | result addLast: each ].
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   764
	^ result
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   765
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   766
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   767
matchesSkipIn: anObject do: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   768
	"Search anObject repeatedly for the matches of the receiver. Evaluate aBlock for each match with the matched parse-tree as the argument. Skip over matches."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   769
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   770
	(self ==> aBlock / #any asParser) star parse: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   771
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   772
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   773
matchingRangesIn: anObject
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   774
	"Search anObject repeatedly for the matches of the receiver. Answer an OrderedCollection of ranges of each match (index of first character to: index of last character)."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   775
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   776
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   777
	result := OrderedCollection new.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   778
	self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   779
		matchingRangesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   780
		do: [ :value | result addLast: value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   781
	^ result
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   782
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   783
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   784
matchingRangesIn: anObject do: aBlock
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   785
	"Search anObject repeatedly for the matches of the receiver. Evaluate aBlock with the range of each match (index of first character to: index of last character)."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   786
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   787
	self token
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   788
		matchesIn: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   789
		do: [ :token | aBlock value: (token start to: token stop) ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   790
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   791
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   792
matchingSkipRangesIn: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   793
	"Search anObject repeatedly for the matches of the receiver. Skip over matches. Answer an OrderedCollection of ranges of each match (index of first character to: index of last character)."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   794
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   795
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   796
	result := OrderedCollection new.
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   797
	self
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   798
		matchingSkipRangesIn: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   799
		do: [ :value | result addLast: value ].
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   800
	^ result
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   801
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   802
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   803
matchingSkipRangesIn: anObject do: aBlock
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   804
	"Search anObject repeatedly for the matches of the receiver. Skip over matches. Evaluate aBlock with the range of each match (index of first character to: index of last character)."
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   805
	
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   806
	self token
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   807
		matchesSkipIn: anObject
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   808
		do: [ :token | aBlock value: (token start to: token stop) ]
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   809
!
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   810
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   811
parse: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   812
	"Parse anObject with the receiving parser and answer the parse-result or an instance of PPFailure."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   813
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   814
	^ self parseOn: anObject asPetitStream
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   815
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   816
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   817
parse: anObject onError: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   818
	"Parse anObject with the receiving parser and answer the parse-result or answer the result of evaluating aBlock. Depending on the number of arguments of the block it is simply evaluated, evaluated with the failure object, or evaluated with the error message and position."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   819
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   820
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   821
	result := self parse: anObject.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   822
	result isPetitFailure
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   823
		ifFalse: [ ^ result ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   824
	aBlock numArgs = 0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   825
		ifTrue: [ ^ aBlock value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   826
	aBlock numArgs = 1
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   827
		ifTrue: [ ^ aBlock value: result ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   828
	^ aBlock value: result message value: result position
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   829
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   830
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   831
parseOn: aStream
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   832
	"Parse aStream with the receiving parser and answer the parse-result or an instance of PPFailure. Override this method in subclasses to specify custom parse behavior. Do not call this method from outside, instead use #parse:."
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   833
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   834
	self subclassResponsibility
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   835
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   836
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   837
!PPParser methodsFor:'printing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   838
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   839
printNameOn: aStream
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   840
	self name isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   841
		ifTrue: [ aStream print: self hash ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   842
		ifFalse: [ aStream nextPutAll: self name ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   843
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   844
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   845
printOn: aStream
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   846
	super printOn: aStream.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   847
	aStream nextPut: $(.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   848
	self printNameOn: aStream.
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   849
	aStream nextPut: $)
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   850
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   851
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   852
!PPParser methodsFor:'testing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   853
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   854
isPetitParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   855
	^ true
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   856
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   857
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   858
isUnresolved
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   859
	^ false
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   860
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   861
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   862
!PPParser class methodsFor:'documentation'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   863
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   864
version
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   865
    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParser.st,v 1.6 2014-03-04 14:33:11 cg Exp $'
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   866
!
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   867
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   868
version_CVS
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   869
    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPParser.st,v 1.6 2014-03-04 14:33:11 cg Exp $'
22
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   870
!
c540c8649226 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   871
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   872
version_SVN
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   873
    ^ '$Id: PPParser.st,v 1.6 2014-03-04 14:33:11 cg Exp $'
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   874
! !
173
Claus Gittinger <cg@exept.de>
parents: 126
diff changeset
   875