PPExpressionParser.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Tue, 08 Sep 2015 02:23:45 +0100
changeset 540 694ad2f97c65
parent 427 a7f5e6de19d2
child 642 77d5fddb6462
permissions -rw-r--r--
Merge
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
427
a7f5e6de19d2 Merged JK's version from Monticello
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 11
diff changeset
     3
"{ NameSpace: Smalltalk }"
a7f5e6de19d2 Merged JK's version from Monticello
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 11
diff changeset
     4
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
PPDelegateParser subclass:#PPExpressionParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	instanceVariableNames:'operators'
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	classVariableNames:''
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
	poolDictionaries:''
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
	category:'PetitParser-Tools'
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
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
!PPExpressionParser methodsFor:'private'!
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
build: aParser left: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    16
	^ (aParser separatedBy: aChoiceParser) foldLeft: [ :a :op :b | op first value: a value: op second value: b ]
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
build: aParser postfix: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
	^ aParser , aChoiceParser star map: [ :term :ops | ops inject: term into: [ :result :operator | operator first value: result value: operator second ] ]
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    23
build: aParser prefix: aChoiceParser
427
a7f5e6de19d2 Merged JK's version from Monticello
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 11
diff changeset
    24
	^ aChoiceParser star , aParser map: [ :ops :term | ops reverse inject: term into: [ :result :operator | operator first value: operator second value: result ] ]
0
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    27
build: aParser right: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    28
	^ (aParser separatedBy: aChoiceParser) foldRight: [ :a :op :b | op first value: a value: op second value: b ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
!
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
buildOn: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    32
	^ self buildSelectors inject: aParser into: [ :term :selector |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
		| list |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
		list := operators at: selector ifAbsent: [ #() ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
		list isEmpty
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    36
			ifTrue: [ term ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    37
			ifFalse: [
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
				self
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    39
					perform: selector with: term 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    40
					with: (list size = 1
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    41
						ifTrue: [ list first first ==> [ :operator | Array with: list first second with: operator ] ]
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    42
						ifFalse: [ 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    43
							list
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    44
								inject: PPChoiceParser new
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    45
								into: [ :choice :each | choice / (each first ==> [ :operator | Array with: each second with: operator ]) ] ]) ] ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    46
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
buildSelectors
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
	^ #(build:prefix: build:postfix: build:right: build:left:)
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
operator: aSymbol parser: aParser do: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
	parser isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
		ifTrue: [ ^ self error: 'You did not specify a term when creating the receiver.' ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
	operators isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
		ifTrue: [ ^ self error: 'Use #group: to define precedence groups in descending order.' ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
	(operators at: aSymbol ifAbsentPut: [ OrderedCollection new ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
		addLast: (Array with: aParser asParser with: aBlock)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
! !
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
!PPExpressionParser methodsFor:'specifying'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
group: aOneArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
	"Defines a priority group by evaluating aOneArgumentBlock."
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    65
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
	operators := Dictionary new.
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    67
	parser := [ 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
		aOneArgumentBlock value: self.
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    69
	 	self buildOn: parser ]
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
			ensure: [ operators := nil ]
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
left: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    74
	"Define an operator aParser that is left-associative. Evaluate aThreeArgumentBlock with the first term, the operator, and the second term."
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    75
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
	self operator: #build:left: parser: aParser do: aThreeArgumentBlock
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
postfix: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
	"Define a postfix operator aParser. Evaluate aTwoArgumentBlock with the term and the operator."
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 operator: #build:postfix: parser: aParser do: aTwoArgumentBlock
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
prefix: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
	"Define a prefix operator aParser. Evaluate aTwoArgumentBlock with the operator and the term."
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
	self operator: #build:prefix: parser: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
right: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
	"Define an operator aParser that is right-associative. Evaluate aThreeArgumentBlock with the first term, the operator, and the second term."
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    93
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
	self operator: #build:right: parser: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
!
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
term: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
	"Defines the initial term aParser of the receiver."
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    99
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
	parser isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
		ifTrue: [ parser := aParser ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
		ifFalse: [ self error: 'Unable to redefine the term.' ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
! !
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
!PPExpressionParser class methodsFor:'documentation'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   107
version
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   108
    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExpressionParser.st,v 1.3 2012-05-04 21:59:01 vrany Exp $'
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   109
!
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   110
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   111
version_CVS
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   112
    ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPExpressionParser.st,v 1.3 2012-05-04 21:59:01 vrany Exp $'
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   113
!
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   114
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
version_SVN
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   116
    ^ '§Id: PPExpressionParser.st 2 2010-12-17 18:44:23Z vranyj1 §'
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
! !
427
a7f5e6de19d2 Merged JK's version from Monticello
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 11
diff changeset
   118