analyzer/extensions.st
author Jan Vrany <jan.vrany@fit.cvut.cz>
Sun, 05 Oct 2014 00:29:07 +0100
changeset 382 1825151d6455
parent 381 0bbbcf5da2d4
permissions -rw-r--r--
Added target `mcz` to export .mcz package out of Smalltalk/X package.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     1
"{ Package: 'stx:goodies/petitparser/analyzer' }"!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     2
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     3
!PPActionParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     4
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     5
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     6
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     7
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     8
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
     9
!PPDelegateParser methodsFor:'*petitanalyzer-transforming'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    10
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    11
replace: aParser with: anotherParser
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    12
	super replace: aParser with: anotherParser.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    13
	parser == aParser ifTrue: [ parser := anotherParser ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    14
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    15
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    16
!PPEpsilonParser methodsFor:'*petitanalyzer-testing'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    17
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    18
isNullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    19
	^ true
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    20
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    21
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    22
!PPFailingParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    23
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    24
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    25
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self message = aParser message ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    26
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    27
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    28
!PPLimitedRepeatingParser methodsFor:'*petitanalyzer-transforming'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    29
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    30
replace: aParser with: anotherParser
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    31
	super replace: aParser with: anotherParser.
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    32
	limit == aParser ifTrue: [ limit := anotherParser ]
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    33
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    34
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    35
!PPListParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    36
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    37
copyInContext: aDictionary seen: aSeenDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    38
	| copy copies |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    39
	aSeenDictionary at: self ifPresent: [ :value | ^ value ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    40
	copy := aSeenDictionary at: self put: self copy.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    41
	copies := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    42
	parsers do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    43
		| result |
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
    44
		result := each
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    45
			copyInContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    46
			seen: aSeenDictionary.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    47
		result isCollection
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    48
			ifTrue: [ copies addAll: result ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    49
			ifFalse: [ copies add: result ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    50
	^ copy
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    51
		setParsers: copies;
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    52
		yourself
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    53
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    54
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    55
!PPListParser methodsFor:'*petitanalyzer-transforming'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    56
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    57
replace: aParser with: anotherParser
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    58
	super replace: aParser with: anotherParser.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    59
	parsers keysAndValuesDo: [ :index :parser |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    60
		parser == aParser
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    61
			ifTrue: [ parsers at: index put: anotherParser ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    62
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    63
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    64
!PPLiteralParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    65
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    66
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    67
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self literal = aParser literal and: [ self message = aParser message ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    68
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    69
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    70
!PPNotParser methodsFor:'*petitanalyzer-private'!
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    71
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    72
firstSets: aFirstDictionary into: aSet
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
    73
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    74
! !
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    75
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    76
!PPNotParser methodsFor:'*petitanalyzer-testing'!
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    77
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    78
isFirstSetTerminal
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    79
	^ true
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    80
! !
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
    81
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    82
!PPOptionalParser methodsFor:'*petitanalyzer-testing'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    83
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    84
isNullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    85
	^ true
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    86
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    87
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    88
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    89
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    90
allNamedParsers
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    91
	"Answer all the named parse nodes of the receiver."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    92
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    93
	| result |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    94
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    95
	self allNamedParsersDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    96
	^ result
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    97
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    98
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
    99
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   100
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   101
allNamedParsersDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   102
	"Iterate over all the named parse nodes of the receiver."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   103
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   104
	self allParsersDo: [ :each |
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   105
		each name notNil
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   106
			ifTrue: [ aBlock value: each ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   107
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   108
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   109
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   110
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   111
copyInContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   112
	^ self copyInContext: aDictionary seen: IdentityDictionary new
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   113
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   114
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   115
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   116
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   117
copyInContext: aDictionary seen: aSeenDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   118
	| copy |
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   119
	aSeenDictionary
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   120
		at: self
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   121
		ifPresent: [ :value | ^ value ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   122
	copy := aSeenDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   123
		at: self
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   124
		put: self copy.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   125
	copy children do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   126
		copy
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   127
			replace: each
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   128
			with: (each copyInContext: aDictionary seen: aSeenDictionary) ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   129
	^ copy
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   130
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   131
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   132
!PPParser methodsFor:'*petitanalyzer-querying'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   133
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   134
cycleSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   135
	"Answer a set of all nodes that are within one or more cycles of left-recursion. This is generally not a problem if at least one of the nodes is memoized, but it might make the grammar very inefficient and should be avoided if possible."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   136
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   137
	| cycles |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   138
	cycles := IdentitySet new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   139
	self cycleSet: OrderedCollection new firstSets: self firstSets into: cycles.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   140
	^ cycles
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   141
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   142
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   143
!PPParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   144
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   145
cycleSet: aDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   146
	"PRIVATE: Answer the children that could be part of a cycle-set with the receiver, subclasses might restrict the number of children returned. aDictionary is pre-calcualted first-sets."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   147
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   148
	^ self children
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   149
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   150
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   151
!PPParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   152
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   153
cycleSet: aStack firstSets: aDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   154
	"PRIVATE: Try to find a cycle, where aStack contains the previously visited parsers. The method returns quickly when the receiver is a terminal, terminals cannot be part of a cycle. If aStack already contains the receiver, then we are in a cycle. In this case we don't process the children further and add the nodes to aSet."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   155
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   156
	| index |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   157
	self isTerminal
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   158
		ifTrue: [ ^ self ].
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   159
	(index := aStack indexOf: self) > 0
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   160
		ifTrue: [ ^ aSet addAll: (aStack copyFrom: index to: aStack size) ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   161
	aStack addLast: self.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   162
	(self cycleSet: aDictionary)
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   163
		do: [ :each | each cycleSet: aStack firstSets: aDictionary into: aSet ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   164
	aStack removeLast
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   165
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   166
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   167
!PPParser methodsFor:'*petitanalyzer-querying'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   168
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   169
firstSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   170
	"Answer the first-set of the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #firstSets to calculate the first-sets at once."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   171
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   172
	^ self firstSets at: self
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   173
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   174
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   175
!PPParser methodsFor:'*petitanalyzer-querying'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   176
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   177
firstSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   178
	"Answer a dictionary with all the parsers reachable from the receiver as key and their first-set as value. The first-set of a parser is the list of terminal parsers that begin the parser derivable from that parser."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   179
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   180
	| firstSets |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   181
	firstSets := IdentityDictionary new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   182
	self allParsersDo: [ :each |
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   183
		firstSets at: each put: (each isFirstSetTerminal
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   184
			ifTrue: [ IdentitySet with: each ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   185
			ifFalse: [ IdentitySet new ]).
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   186
		each isNullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   187
			ifTrue: [ (firstSets at: each) add: PPSentinel instance ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   188
	[	| changed tally |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   189
		changed := false.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   190
		firstSets keysAndValuesDo: [ :parser :first |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   191
			tally := first size.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   192
			parser firstSets: firstSets into: first.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   193
			changed := changed or: [ tally ~= first size ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   194
		changed ] whileTrue.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   195
	^ firstSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   196
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   197
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   198
!PPParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   199
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   200
firstSets: aFirstDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   201
	"PRIVATE: Try to add additional elements to the first-set aSet of the receiver, use the incomplete aFirstDictionary."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   202
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   203
	self children do: [ :parser | aSet addAll: (aFirstDictionary at: parser) ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   204
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   205
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   206
!PPParser methodsFor:'*petitanalyzer-querying'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   207
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   208
followSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   209
	"Answer the follow-set of the receiver starting at the receiver. Note, this implementation is inefficient when called on different receivers of the same grammar, instead use #followSets to calculate the follow-sets at once."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   210
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   211
	^ self followSets at: self
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   212
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   213
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   214
!PPParser methodsFor:'*petitanalyzer-querying'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   215
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   216
followSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   217
	"Answer a dictionary with all the parsers reachable from the receiver as key and their follow-set as value. The follow-set of a parser is the list of terminal parsers that can appear immediately to the right of that parser."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   218
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   219
	| current previous continue firstSets followSets |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   220
	current := previous := 0.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   221
	firstSets := self firstSets.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   222
	followSets := IdentityDictionary new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   223
	self allParsersDo: [ :each | followSets at: each put: IdentitySet new ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   224
	(followSets at: self) add: PPSentinel instance.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   225
	[	followSets keysAndValuesDo: [ :parser :follow |
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   226
			parser
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   227
				followSets: followSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   228
				firstSets: firstSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   229
				into: follow ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   230
		current := followSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   231
			inject: 0
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   232
			into: [ :result :each | result + each size ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   233
		continue := previous < current.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   234
		previous := current.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   235
		continue ] whileTrue.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   236
	^ followSets
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   237
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   238
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   239
!PPParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   240
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   241
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   242
	"PRIVATE: Try to add additional elements to the follow-set aSet of the receiver, use the incomplete aFollowDictionary and the complete aFirstDictionary."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   243
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   244
	self children do: [ :parser | (aFollowDictionary at: parser) addAll: aSet ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   245
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   246
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   247
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   248
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   249
innerChildren
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   250
	"Answer the inner children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   251
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   252
	| result |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   253
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   254
	self innerChildrenDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   255
	^ result
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   256
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   257
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   258
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   259
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   260
innerChildrenDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   261
	"Iterate over the inner children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   263
	self innerChildrenDo: aBlock seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   264
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   265
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   266
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   267
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   268
innerChildrenDo: aBlock seen: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   269
	"Iterate over the inner children of the receiver."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   270
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   271
	self children do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   272
		(aSet includes: each)
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   273
			ifTrue: [ ^ self ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   274
		aSet add: each.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   275
		each name isNil ifTrue: [
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   276
			aBlock value: each.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   277
			each innerChildrenDo: aBlock seen: aSet ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   278
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   279
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   280
!PPParser methodsFor:'*petitanalyzer-testing'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   281
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   282
isFirstSetTerminal
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   283
	"Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser."
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   284
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   285
	^ self children isEmpty
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   286
! !
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   287
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   288
!PPParser methodsFor:'*petitanalyzer-testing'!
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   289
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   290
isNullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   291
	"Answer true if the receiver is a nullable parser, e.g. it can successfully parse nothing."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   292
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   293
	^ false
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   294
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   295
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   296
!PPParser methodsFor:'*petitanalyzer-testing'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   297
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   298
isTerminal
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   299
	"Answer true if the receiver is a terminal or leaf parser, that means it does not delegate to any other parser."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   300
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   301
	^ self children isEmpty
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   302
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   303
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   304
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   305
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   306
match: aParser inContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   307
	^ self match: aParser inContext: aDictionary seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   308
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   309
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   310
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   311
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   312
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   313
	"This is the default implementation to match two parsers. This code can properly handle recursion. This is code is supposed to be overridden in subclasses that add new state."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   314
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   315
	(self == aParser or: [ anIdentitySet includes: self ])
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   316
		ifTrue: [ ^ true ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   317
	anIdentitySet add: self.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   318
	^ self class = aParser class and: [ self matchList: self children against: aParser children inContext: aDictionary seen: anIdentitySet ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   319
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   320
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   321
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   322
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   323
matchList: matchList against: parserList inContext: aDictionary seen: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   324
	^ self matchList: matchList index: 1 against: parserList index: 1 inContext: aDictionary seen: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   325
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   326
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   327
!PPParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   328
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   329
matchList: matchList index: matchIndex against: parserList index: parserIndex inContext: aDictionary seen: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   330
	| parser currentIndex currentDictionary currentSeen parsers |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   331
	matchList size < matchIndex
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   332
		ifTrue: [ ^ parserList size < parserIndex ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   333
	parser := matchList at: matchIndex.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   334
	parser class = PPListPattern ifTrue: [
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   335
		currentIndex := parserIndex - 1.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   336
		[ currentDictionary := aDictionary copy.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   337
		currentSeen := aSet copy.
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   338
		parserList size < currentIndex or: [
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   339
			parsers := parserList copyFrom: parserIndex to: currentIndex.
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   340
			(currentDictionary at: parser ifAbsentPut: [ parsers ]) = parsers and: [
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   341
				(self
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   342
					matchList: matchList
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   343
					index: matchIndex + 1
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   344
					against: parserList
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   345
					index: currentIndex + 1
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   346
					inContext: currentDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   347
					seen: currentSeen)
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   348
					ifTrue: [
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   349
						currentDictionary keysAndValuesDo: [ :key :value | aDictionary at: key put: value ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   350
						^ true ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   351
				false ] ] ] whileFalse: [ currentIndex := currentIndex + 1 ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   352
		^ false ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   353
	parserList size < parserIndex
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   354
		ifTrue: [ ^ false ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   355
	(parser match: (parserList at: parserIndex) inContext: aDictionary seen: aSet)
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   356
		ifFalse: [ ^ false ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   357
	^ self
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   358
		matchList: matchList
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   359
		index: matchIndex + 1
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   360
		against: parserList
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   361
		index: parserIndex + 1
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   362
		inContext: aDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   363
		seen: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   364
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   365
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   366
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   367
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   368
namedChildren
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   369
	"Answer the named children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   370
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   371
	| result |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   372
	result := OrderedCollection new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   373
	self namedChildrenDo: [ :parser | result addLast: parser ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   374
	^ result
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   375
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   376
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   377
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   378
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   379
namedChildrenDo: aBlock
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   380
	"Iterate over the named children of the receiver."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   381
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   382
	self namedChildrenDo: aBlock seen: IdentitySet new
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   383
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   384
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   385
!PPParser methodsFor:'*petitanalyzer-named'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   386
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   387
namedChildrenDo: aBlock seen: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   388
	"Iterate over the named children of the receiver."
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   389
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   390
	self children do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   391
		(aSet includes: each)
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   392
			ifTrue: [ ^ self ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   393
		aSet add: each.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   394
		each name isNil
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   395
			ifTrue: [ each namedChildrenDo: aBlock seen: aSet ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   396
			ifFalse: [ aBlock value: each ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   397
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   398
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   399
!PPParser methodsFor:'*petitanalyzer-transforming'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   400
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   401
replace: aParser with: anotherParser
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   402
	"Replace the references of the receiver pointing to aParser with anotherParser."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   403
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   404
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   405
!PPParser methodsFor:'*petitanalyzer-transforming'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   406
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   407
transform: aBlock
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   408
	"Answer a copy of all parsers reachable from the receiver transformed using aBlock."
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   409
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   410
	| mapping root |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   411
	mapping := IdentityDictionary new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   412
	self allParsersDo: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   413
		mapping
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   414
			at: each
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   415
			put: (aBlock value: each copy) ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   416
	root := mapping at: self.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   417
	[	| changed |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   418
		changed := false.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   419
		root allParsersDo: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   420
			each children do: [ :old |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   421
				mapping at: old ifPresent: [ :new |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   422
					each replace: old with: new.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   423
					changed := true ] ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   424
		changed ] whileTrue.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   425
	^ root
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   426
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   427
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   428
!PPPluggableParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   429
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   430
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   431
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   432
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   433
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   434
!PPPredicateParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   435
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   436
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   437
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self block = aParser block and: [ self message = aParser message ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   438
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   439
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   440
!PPPredicateSequenceParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   441
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   442
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   443
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self size = aParser size ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   444
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   445
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   446
!PPRepeatingParser methodsFor:'*petitanalyzer-private'!
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   447
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   448
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   449
	| firstSet |
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   450
	super followSets: aFollowDictionary firstSets:  aFirstDictionary into: aSet.
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   451
378
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   452
	firstSet := aFirstDictionary at: self.
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   453
	self children do: [:p | (aFollowDictionary at: p) addAll: (firstSet reject: [:each | each isNullable]) ]
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   454
! !
53d66ecfeb1b Merged in latest version from Moose repository
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 376
diff changeset
   455
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   456
!PPRepeatingParser methodsFor:'*petitanalyzer-testing'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   457
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   458
isNullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   459
	^ min = 0
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   460
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   461
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   462
!PPRepeatingParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   463
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   464
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   465
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self min = aParser min and: [ self max = aParser max ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   466
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   467
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   468
!PPSequenceParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   469
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   470
cycleSet: aDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   471
	| firstSet |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   472
	1 to: parsers size do: [ :index |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   473
		firstSet := aDictionary at: (parsers at: index).
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   474
		(firstSet anySatisfy: [ :each | each isNullable ])
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   475
			ifFalse: [ ^ parsers copyFrom: 1 to: index ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   476
	^ parsers
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   477
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   478
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   479
!PPSequenceParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   480
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   481
firstSets: aFirstDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   482
	| nullable |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   483
	parsers do: [ :parser |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   484
		nullable := false.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   485
		(aFirstDictionary at: parser) do: [ :each |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   486
			each isNullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   487
				ifTrue: [ nullable := true ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   488
				ifFalse: [ aSet add: each ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   489
		nullable
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   490
			ifFalse: [ ^ self ] ].
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   491
	aSet add: PPSentinel instance
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   492
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   493
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   494
!PPSequenceParser methodsFor:'*petitanalyzer-private'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   495
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   496
followSets: aFollowDictionary firstSets: aFirstDictionary into: aSet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   497
	parsers keysAndValuesDo: [ :index :parser |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   498
		| followSet firstSet |
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   499
		followSet := aFollowDictionary at: parser.
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   500
		index = parsers size
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   501
			ifTrue: [ followSet addAll: aSet ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   502
			ifFalse: [
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   503
				(self class withAll: (parsers
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   504
					copyFrom: index + 1 to: parsers size))
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   505
						firstSets: aFirstDictionary
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   506
						into: (firstSet := IdentitySet new).
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   507
				(firstSet anySatisfy: [ :each | each isNullable ])
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   508
					ifTrue: [ followSet addAll: aSet ].
382
1825151d6455 Added target `mcz` to export .mcz package out of Smalltalk/X package.
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 381
diff changeset
   509
				followSet addAll: (firstSet
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   510
					reject: [ :each | each isNullable ]) ] ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   511
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   512
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   513
!PPTokenParser methodsFor:'*petitanalyzer-matching'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   514
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   515
match: aParser inContext: aDictionary seen: anIdentitySet
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   516
	^ (super match: aParser inContext: aDictionary seen: anIdentitySet) and: [ self tokenClass = aParser tokenClass ]
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   517
! !
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   518
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   519
!stx_goodies_petitparser_analyzer class methodsFor:'documentation'!
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   520
376
a2656b27cace Added monticelloName to package definition to ease export to .mcz
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 284
diff changeset
   521
extensionsVersion_HG
a2656b27cace Added monticelloName to package definition to ease export to .mcz
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 284
diff changeset
   522
a2656b27cace Added monticelloName to package definition to ease export to .mcz
Jan Vrany <jan.vrany@fit.cvut.cz>
parents: 284
diff changeset
   523
    ^ '$Changeset: <not expanded> $'
262
Claus Gittinger <cg@exept.de>
parents: 261
diff changeset
   524
! !