PPParser.st
author Claus Gittinger <cg@exept.de>
Mon, 12 Sep 2011 19:47:59 +0200
changeset 2 acb3822c73db
parent 0 739fe9b7253e
child 4 90de244a7fa2
permissions -rw-r--r--
initial checkin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     1
"{ Package: 'squeak:petitparser' }"
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
PPParser comment:'An abstract parser for all parsers in PetitParser. Subclasses implement #parseOn: to perform the actual recursive-descent parsing. All parsers support a variety of methods to perform an actual parse, see the methods in the #parsing protocol. Parsers are combined with a series of operators that can be found in the #operations protocol.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
Instance Variables:
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
	properties	<Dictionary>	Stores additional state in the parser object.'
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    14
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
!PPParser class methodsFor:'instance creation'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    17
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
named: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
	^ self new name: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    21
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    22
new
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    23
	^ self basicNew initialize
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    24
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    25
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    26
!PPParser methodsFor:'accessing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    27
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    28
children
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
	"Answer a set of child parsers that could follow the receiver."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    31
	^ #()
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    32
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
name
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
	"Answer the production name of the receiver."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    36
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    37
	^ self propertyAt: #name ifAbsent: [ nil ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    39
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    40
name: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    41
	self propertyAt: #name put: aString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    42
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    43
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    44
!PPParser methodsFor:'accessing-properties'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    45
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    46
hasProperty: aKey
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
	"Test if the property aKey is present."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
	^ properties notNil and: [ properties includesKey: aKey ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
propertyAt: aKey
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
	"Answer the property value associated with aKey."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
	^ self propertyAt: aKey ifAbsent: [ self error: 'Property not found' ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
propertyAt: aKey ifAbsent: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
	"Answer the property value associated with aKey or, if aKey isn't found, answer the result of evaluating aBlock."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
	^ properties isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
		ifTrue: [ aBlock value ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
		ifFalse: [ properties at: aKey ifAbsent: aBlock ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
propertyAt: aKey ifAbsentPut: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
	"Answer the property associated with aKey or, if aKey isn't found store the result of evaluating aBlock as new value."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    69
	^ self propertyAt: aKey ifAbsent: [ self propertyAt: aKey put: aBlock value ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
propertyAt: aKey put: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
	"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
    74
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    75
	^ (properties ifNil: [ properties := Dictionary new: 1 ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
		at: aKey put: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
removeProperty: aKey
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
	"Remove the property with aKey. Answer the property or raise an error if aKey isn't found."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
	^ self removeProperty: aKey ifAbsent: [ self error: 'Property not found' ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
removeProperty: aKey ifAbsent: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
	"Remove the property with aKey. Answer the value or, if aKey isn't found, answer the result of evaluating aBlock."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
	| answer |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
	properties isNil ifTrue: [ ^ aBlock value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
	answer := properties removeKey: aKey ifAbsent: aBlock.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
	properties isEmpty ifTrue: [ properties := nil ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
	^ answer
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
!PPParser methodsFor:'converting'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
asParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
	^ self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    99
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
!PPParser methodsFor:'copying'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
postCopy
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
	super postCopy.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
	properties := properties copy
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
!PPParser methodsFor:'initialization'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
initialize
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
!PPParser methodsFor:'operations'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
, aParser 
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
	"Answer a new parser that parses the receiver followed by aParser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   118
	^ PPSequenceParser with: self with: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
/ aParser 
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
	"Answer a new parser that parses the receiver, if the receiver fails try with aParser (ordered-choice)."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   123
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   124
	^ PPChoiceParser with: self with: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   125
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   126
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
and
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
	"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
   129
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
	^ PPAndParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
def: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
	"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
   135
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   136
	^ self becomeForward: (aParser name: self name)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   137
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   138
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   139
end
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   140
	"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
   141
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   142
	^ PPEndOfInputParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   143
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   144
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   145
max: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   146
	"Answer a new parser that parses the receiver at most anInteger times."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   148
	^ PPRepeatingParser on: self max: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   150
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
memoized
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   152
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   153
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   154
	^ PPMemoizedParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   155
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   156
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   157
min: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   158
	"Answer a new parser that parses the receiver at least anInteger times."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   159
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   160
	^ PPRepeatingParser on: self min: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   161
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   162
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   163
min: aMinInteger max: aMaxInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   164
	"Answer a new parser that parses the receiver at least aMinInteger and at most aMaxInteger times."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   165
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   166
	^ PPRepeatingParser on: self min: aMinInteger max: aMaxInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   167
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   168
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   169
negate
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   170
	"Answer a new parser consumes any input token but the receiver."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   171
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   172
	^ self not , #any asParser ==> #second
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   173
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   174
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   175
not
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   176
	"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
   177
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   178
	^ PPNotParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   179
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   180
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   181
optional
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   182
	"Answer a new parser that parses the receiver, if possible."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   183
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   184
	^ PPOptionalParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   185
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   186
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   187
plus
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   188
	"Answer a new parser that parses the receiver one or more times."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   189
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   190
	^ self min: 1
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   191
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   192
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   193
plusGreedy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   194
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   195
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   196
	^ self , (self starGreedy: aParser) map: [ :first :rest | rest copyWithFirst: first ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   197
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   198
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   199
plusLazy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   200
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   201
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   202
	^ self , (self starLazy: aParser) map: [ :first :rest | rest copyWithFirst: first ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   203
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   204
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   205
star
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   206
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   207
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   208
	^ PPRepeatingParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   209
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   210
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   211
starGreedy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   212
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   213
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   214
	| parser |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   215
	parser := PPChoiceParser new.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   216
	parser setParsers: (Array
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   217
		with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   218
		with: (aParser and ==> [ :each | OrderedCollection new ])).
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   219
	^ parser ==> [ :rest | rest asArray ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   220
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   221
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   222
starLazy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   223
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   224
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   225
	| parser |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   226
	parser := PPChoiceParser new.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   227
	parser setParsers: (Array
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   228
		with: (aParser and ==> [ :each | OrderedCollection new ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   229
		with: (self , parser map: [ :each :rest | rest addFirst: each; yourself ])).
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   230
	^ parser ==> [ :rest | rest asArray ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   231
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   232
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   233
times: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   234
	"Answer a new parser that parses the receiver exactly anInteger times."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   235
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   236
	^ self min: anInteger max: anInteger
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   237
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   238
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   239
wrapped
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   240
	"Answer a new parser that is simply wrapped."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   241
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   242
	^ PPDelegateParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   243
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   244
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   245
| aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   246
	"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
   247
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   248
	^ (self not , aParser) / (aParser not , self) ==> #second
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   249
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   250
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   251
!PPParser methodsFor:'operations-convenience'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   252
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   253
delimitedBy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   254
	"Answer a new parser that parses the receiver one or more times, separated and possibly ended by aParser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   255
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   256
	^ (self separatedBy: aParser) , (aParser optional) ==> [ :node |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   257
		node second isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   258
			ifTrue: [ node first ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   259
			ifFalse: [ node first copyWith: node second ] ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   260
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   261
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   262
separatedBy: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   263
	"Answer a new parser that parses the receiver one or more times, separated by aParser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   264
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   265
	^ (PPSequenceParser with: self with: (PPSequenceParser with: aParser with: self) star) ==> [ :nodes |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   266
		| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   267
		result := Array new: 2 * nodes second size + 1.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   268
		result at: 1 put: nodes first.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   269
		nodes second 
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   270
			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
   271
		result ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   272
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   273
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   274
!PPParser methodsFor:'operations-mapping'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   275
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   276
==> aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   277
	"Answer a new parser that performs aBlock as action handler on success."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   278
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   279
	^ PPActionParser on: self block: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   280
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   281
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   282
>=> aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   283
	"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
   284
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   285
	^ PPWrappingParser on: self block: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   286
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   287
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   288
answer: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   289
	"Answer a new parser that always returns anObject from a successful parse."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   290
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   291
	^ self ==> [ :nodes | anObject ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   292
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   293
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   294
flatten
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   295
	"Answer a new parser that flattens the underlying collection."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   296
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   297
	^ PPFlattenParser on: self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   298
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   299
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   300
foldLeft: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   301
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   302
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   303
	| size args |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   304
	size := aBlock numArgs.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   305
	args := Array new: size.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   306
	^ self ==> [ :nodes |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   307
		args at: 1 put: (nodes at: 1).
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   308
		2 to: nodes size by: size - 1 do: [ :index |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   309
			args
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   310
				replaceFrom: 2 to: size with: nodes startingAt: index;
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   311
				at: 1 put: (aBlock valueWithArguments: args) ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   312
		args at: 1 ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   313
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   314
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   315
foldRight: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   316
	"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."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   317
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   318
	| size args |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   319
	size := aBlock numArgs.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   320
	args := Array new: size.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   321
	^ self ==> [ :nodes |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   322
		args at: size put: (nodes at: nodes size).
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   323
		nodes size - size + 1 to: 1 by: 1 - size do: [ :index |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   324
			args
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   325
				replaceFrom: 1 to: size - 1 with: nodes startingAt: index;
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   326
				at: size put: (aBlock valueWithArguments: args) ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   327
		args at: size ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   328
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   329
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   330
map: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   331
	"Answer a new parser that works on the receiving sequence an passes in each element as a block argument."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   332
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   333
	^ self ==> aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   334
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   335
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   336
token
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   337
	"Answer a new parser that transforms the input to a token."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   338
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   339
	^ PPTokenParser on: self
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   342
token: aTokenClass
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   343
	"Answer a new parser that transforms the input to a token of class aTokenClass."
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
	^ self token tokenClass: aTokenClass
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   348
trim
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   349
	"Answer a new parser that consumes spaces before and after the receiving parser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   350
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   351
	^ self trimSpaces
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   354
trimBlanks
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   355
	"Answer a new parser that consumes blanks before and after the receiving parser."
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
	^ PPTrimmingParser on: self trimmer: #blank asParser
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   360
trimSpaces
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   361
	"Answer a new parser that consumes spaces before and after the receiving parser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   362
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   363
	^ PPTrimmingParser on: self trimmer: #space asParser
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   366
!PPParser methodsFor:'parsing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   367
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   368
matches: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   369
	"Answer if anObject can be parsed by the receiver."
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
	^ (self parse: anObject) isPetitFailure not
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   372
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   373
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   374
matchesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   375
	"Search anObject repeatedly for the matches of the receiver."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   376
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   377
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   378
	result := OrderedCollection new.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   379
	self 
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   380
		matchesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   381
		do: [ :each | result addLast: each ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   382
	^ result
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
matchesIn: anObject do: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   386
	"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
   387
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   388
	((self and ==> aBlock , #any asParser) / #any asParser) star parse: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   389
!
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
matchingRangesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   392
	"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)."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   393
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   394
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   395
	result := OrderedCollection new.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   396
	self
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   397
		matchingRangesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   398
		do: [ :value | result addLast: value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   399
	^ result
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   400
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   401
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   402
matchingRangesIn: anObject do: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   403
	"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)."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   404
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   405
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   406
	result := OrderedCollection new.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   407
	[ :stream | stream position + 1 ] asParser , self , [ :stream | stream position ] asParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   408
		matchesIn: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   409
		do: [ :value | aBlock value: (value first to: value last) ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   410
	^ result
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   411
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   412
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   413
parse: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   414
	"Parse anObject with the receiving parser and answer the parse-result or an instance of PPFailure."
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
	^ self parseOn: anObject asPetitStream
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   419
parse: anObject onError: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   420
	"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."
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
	| result |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   423
	result := self parse: anObject.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   424
	result isPetitFailure
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   425
		ifFalse: [ ^ result ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   426
	aBlock numArgs = 0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   427
		ifTrue: [ ^ aBlock value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   428
	aBlock numArgs = 1
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   429
		ifTrue: [ ^ aBlock value: result ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   430
	^ aBlock value: result message value: result position
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   431
!
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
parseOn: aStream
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   434
	"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:."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   435
	
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   436
	self subclassResponsibility
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   437
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   438
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   439
!PPParser methodsFor:'printing'!
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
printNameOn: aStream
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   442
	self name isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   443
		ifTrue: [ aStream print: self hash ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   444
		ifFalse: [ aStream nextPutAll: self name ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   445
!
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
printOn: aStream
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   448
	super printOn: aStream.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   449
	aStream nextPut: $(.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   450
	self printNameOn: aStream.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   451
	aStream nextPut: $)
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
!PPParser methodsFor:'testing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   455
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   456
isPetitParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   457
	^ true
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
isUnresolved
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   461
	^ false
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   462
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   463
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   464
!PPParser class methodsFor:'documentation'!
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
version_SVN
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   467
    ^ '$Id: PPParser.st,v 1.1 2011-08-18 18:56:17 cg Exp $'
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   468
! !