PPCompositeParser.st
author Claus Gittinger <cg@exept.de>
Fri, 13 Jan 2012 12:59:40 +0100
changeset 6 84f5c7d57fcb
parent 4 90de244a7fa2
child 28 1194e560eda4
permissions -rw-r--r--
*** empty log message ***
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
     1
"{ Package: 'stx:goodies/petitparser' }"
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
PPDelegateParser subclass:#PPCompositeParser
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
	instanceVariableNames:''
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-Tools'
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
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
    10
PPCompositeParser comment:'A PPCompositeParser is composed parser built from various primitive parsers.
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
Every production in the receiver is specified as a method that returns its parser. Note that every production requires an instance variable of the same name, otherwise the production is not cached and cannot be used in recursive grammars. Productions should refer to each other by reading the respective inst-var. Note: these inst-vars are typically not written, as the assignment happens in the initialize method using reflection.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
The start production is defined in the method start. It is aliased to the inst-var parser defined in the superclass of PPCompositeParser.'
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
!PPCompositeParser 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
new
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
	"Answer a new parser starting at the default start symbol."
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
	^ self newStartingAt: self startSymbol
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    24
newStartingAt: aSymbol
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    25
	"Answer a new parser starting at aSymbol."
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
	^ self basicNew initializeStartingAt: aSymbol
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
!PPCompositeParser class methodsFor:'accessing'!
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
ignoredNames
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
	"Answer a collection of instance-variables that should not be automatically initialized with productions, but that are used internal to the composite parser."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
	^ PPCompositeParser allInstVarNames
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
startSymbol
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    39
	"Answer the method that represents the default start symbol."
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    40
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    41
	^ #start
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
!PPCompositeParser class methodsFor:'parsing'!
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
parse: anObject
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
	^ self parse: anObject startingAt: self startSymbol
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
parse: anObject onError: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
	^ self parse: anObject startingAt: self startSymbol onError: aBlock
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
parse: anObject startingAt: aSymbol
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
	^ (self newStartingAt: aSymbol) parse: anObject
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
parse: anObject startingAt: aSymbol onError: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
	^ (self newStartingAt: aSymbol) parse: anObject onError: 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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
!PPCompositeParser methodsFor:'accessing'!
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
start
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
	"Answer the production to start this parser with."
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
    66
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
	self subclassResponsibility
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
!PPCompositeParser methodsFor:'initialization'!
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
initializeStartingAt: aSymbol
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
	| allVariableNames ignoredVariableNames productionIndexesAndNames |
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
    74
	self initialize.
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    75
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
	"find all the productions that need to be initialized"
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
	allVariableNames := self class allInstVarNames
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
		collect: [ :each | each asSymbol ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
	ignoredVariableNames := self class ignoredNames
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
		collect: [ :each | each asSymbol ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
	productionIndexesAndNames := ((1 to: self class instSize)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
		collect: [ :index | index -> (allVariableNames at: index) ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
		reject: [ :assoc | ignoredVariableNames includes: assoc value ].
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
    84
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
	"initialize productions with an undefined parser to be replaced later"
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
	parser := PPUnresolvedParser named: aSymbol.
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
	productionIndexesAndNames do: [ :assoc |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
		self instVarAt: assoc key put: (PPUnresolvedParser named: assoc value) ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
	parser def: (self perform: aSymbol).
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
    90
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
	"resolve unresolved parsers with their actual implementation"
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
	productionIndexesAndNames do: [ :assoc |
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
		(self respondsTo: assoc value)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
			ifFalse: [ self error: 'Unable to initialize ' , assoc value printString ]
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
			ifTrue: [ (self instVarAt: assoc key) def: (self perform: assoc value) ] ]
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
!PPCompositeParser methodsFor:'querying'!
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
productionAt: aSymbol
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
	"Answer the production named aSymbol."
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
   102
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
	^ self productionAt: aSymbol ifAbsent: [ nil ]
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
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
productionAt: aSymbol ifAbsent: aBlock
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
	"Answer the production named aSymbol, if there is no such production answer the result of evaluating aBlock."
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
   108
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
	(self class ignoredNames includes: aSymbol asString)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
		ifTrue: [ ^ aBlock value ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
	(self class startSymbol = aSymbol)
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
		ifTrue: [ ^ parser ].
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
	^ self instVarAt: (self class allInstVarNames
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
		indexOf: aSymbol asString
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
		ifAbsent: [ ^ aBlock value ])
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
! !
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
!PPCompositeParser class methodsFor:'documentation'!
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
version_SVN
4
90de244a7fa2 move to package
Claus Gittinger <cg@exept.de>
parents: 0
diff changeset
   121
    ^ '$Id: PPCompositeParser.st,v 1.2 2012-01-13 11:22:50 cg Exp $'
0
739fe9b7253e *** empty log message ***
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
! !