PPExpressionParser.st
author convert-repo
Thu, 19 Dec 2019 04:27:47 +0000
changeset 649 6c22f55541f2
parent 646 6e97d8145481
permissions -rw-r--r--
update tags
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
     1
"{ Encoding: utf8 }"
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
     2
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
     3
"{ Package: 'stx:goodies/petitparser' }"
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
     5
"{ NameSpace: Smalltalk }"
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
     6
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
PPDelegateParser subclass:#PPExpressionParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
	instanceVariableNames:'operators'
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
	classVariableNames:''
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
	poolDictionaries:''
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
	category:'PetitParser-Tools'
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
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
!PPExpressionParser methodsFor:'private'!
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
build: aParser left: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
	^ (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
    19
!
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
build: aParser postfix: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    22
	^ 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
    23
!
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
build: aParser prefix: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    26
	^ aChoiceParser star , aParser map: [ :ops :term | ops reversed inject: term into: [ :result :operator | operator first value: operator second value: result ] ]
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
build: aParser right: aChoiceParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
	^ (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
    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
buildOn: aParser
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    34
        ^ self buildSelectors inject: aParser into: [ :term :selector |
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    35
                | list |
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    36
                list := operators at: selector ifAbsent: [ #() ].
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    37
                list isEmpty
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    38
                        ifTrue: [ term ]
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    39
                        ifFalse: [
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    40
                                self
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    41
                                        perform: selector with: term 
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    42
                                        with: (list size == 1
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    43
                                                ifTrue: [ list first first ==> [ :operator | Array with: list first second with: operator ] ]
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    44
                                                ifFalse: [ 
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    45
                                                        list
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    46
                                                                inject: PPChoiceParser new
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
    47
                                                                into: [ :choice :each | choice / (each first ==> [ :operator | Array with: each second with: operator ]) ] ]) ] ]
0
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
buildSelectors
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
	^ #(build:prefix: build:postfix: build:right: build:left:)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
operator: aSymbol parser: aParser do: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
	parser isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
		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
    57
	operators isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
		ifTrue: [ ^ self error: 'Use #group: to define precedence groups in descending order.' ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
	(operators at: aSymbol ifAbsentPut: [ OrderedCollection new ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
		addLast: (Array with: aParser asParser with: aBlock)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
! !
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
!PPExpressionParser methodsFor:'specifying'!
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
group: aOneArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
	"Defines a priority group by evaluating aOneArgumentBlock."
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    67
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
	operators := Dictionary new.
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    69
	parser := [ 
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
		aOneArgumentBlock value: self.
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
    71
	 	self buildOn: parser ]
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
			ensure: [ operators := nil ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
!
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
left: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
	"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
    77
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
	self operator: #build:left: parser: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
postfix: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
	"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
    83
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
	self operator: #build:postfix: parser: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
prefix: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
	"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
    89
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
	self operator: #build:prefix: parser: aParser do: aTwoArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
right: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
	"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
    95
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
	self operator: #build:right: parser: aParser do: aThreeArgumentBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    99
term: aParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
	"Defines the initial term aParser of the receiver."
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   101
	
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
	parser isNil
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
		ifTrue: [ parser := aParser ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
		ifFalse: [ self error: 'Unable to redefine the term.' ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
! !
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
!PPExpressionParser class methodsFor:'documentation'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   109
version
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
   110
    ^ '$Header$'
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   111
!
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   112
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   113
version_CVS
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
   114
    ^ '$Header$'
11
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   115
!
e6e33e8fe655 Checkin from browser
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 4
diff changeset
   116
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
version_SVN
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
   118
    ^ '$Id$'
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
! !
646
6e97d8145481 #TUNING by exept
Claus Gittinger <cg@exept.de>
parents: 11
diff changeset
   120