PPCompositeParser.st
changeset 182 dad0accb9b2c
parent 28 1194e560eda4
child 502 1e45d3c96ec5
child 640 63fdad4b773d
equal deleted inserted replaced
181:6e0a8571dd88 182:dad0accb9b2c
     1 "{ Package: 'stx:goodies/petitparser' }"
     1 "{ Package: 'stx:goodies/petitparser' }"
     2 
     2 
     3 PPDelegateParser subclass:#PPCompositeParser
     3 PPDelegateParser subclass:#PPCompositeParser
     4 	instanceVariableNames:''
     4 	instanceVariableNames:'dependencies'
     5 	classVariableNames:''
     5 	classVariableNames:''
     6 	poolDictionaries:''
     6 	poolDictionaries:''
     7 	category:'PetitParser-Tools'
     7 	category:'PetitParser-Tools'
     8 !
     8 !
     9 
     9 
    15 
    15 
    16 	^ self newStartingAt: self startSymbol
    16 	^ self newStartingAt: self startSymbol
    17 !
    17 !
    18 
    18 
    19 newStartingAt: aSymbol
    19 newStartingAt: aSymbol
    20 	"Answer a new parser starting at aSymbol."
    20 	"Answer a new parser starting at aSymbol. The code makes sure to resolve all dependent parsers correctly."
    21 
    21 
    22 	^ self basicNew initializeStartingAt: aSymbol
    22 	| parsers remaining |
       
    23 	parsers := IdentityDictionary new.
       
    24 	remaining := OrderedCollection with: self.
       
    25 	[ remaining isEmpty ] whileFalse: [
       
    26 		| dependency |
       
    27 		dependency := remaining removeLast.
       
    28 		(parsers includesKey: dependency) ifFalse: [
       
    29 			parsers at: dependency put: dependency basicNew.
       
    30 			remaining addAll: dependency dependencies ] ].
       
    31 	parsers keysAndValuesDo: [ :class :parser |
       
    32 		| dependencies |
       
    33 		dependencies := IdentityDictionary new.
       
    34 		class dependencies 
       
    35 			do: [ :dependency | dependencies at: dependency put: (parsers at: dependency) ].
       
    36 		parser 
       
    37 			initializeStartingAt: (class == self
       
    38 				ifTrue: [ aSymbol ]
       
    39 				ifFalse: [ class startSymbol ]) 
       
    40 			dependencies: dependencies ].
       
    41 	parsers keysAndValuesDo: [ :class :parser |
       
    42 		parser setParser: (parser perform: parser children first name).
       
    43 		parser productionNames keysAndValuesDo: [ :key :value |
       
    44 			(parser instVarAt: key) setParser: (parser perform: value) ] ].
       
    45 	^ parsers at: self
    23 ! !
    46 ! !
    24 
    47 
    25 !PPCompositeParser class methodsFor:'accessing'!
    48 !PPCompositeParser class methodsFor:'accessing'!
       
    49 
       
    50 dependencies
       
    51 	"Answer a collection of PPCompositeParser classes that this parser directly dependends on. Override this method in subclasses to declare dependent parsers. The default implementation does not depend on other PPCompositeParser."
       
    52 
       
    53 	^ #()
       
    54 !
    26 
    55 
    27 ignoredNames
    56 ignoredNames
    28 	"Answer a collection of instance-variables that should not be automatically initialized with productions, but that are used internal to the composite parser."
    57 	"Answer a collection of instance-variables that should not be automatically initialized with productions, but that are used internal to the composite parser."
    29 
    58 
    30 	^ PPCompositeParser allInstVarNames
    59 	^ PPCompositeParser allInstVarNames
    86 	"resolve unresolved parsers with their actual implementation"
   115 	"resolve unresolved parsers with their actual implementation"
    87 	productionIndexesAndNames do: [ :assoc |
   116 	productionIndexesAndNames do: [ :assoc |
    88 		(self respondsTo: assoc value)
   117 		(self respondsTo: assoc value)
    89 			ifFalse: [ self error: 'Unable to initialize ' , assoc value printString ]
   118 			ifFalse: [ self error: 'Unable to initialize ' , assoc value printString ]
    90 			ifTrue: [ (self instVarAt: assoc key) def: (self perform: assoc value) ] ]
   119 			ifTrue: [ (self instVarAt: assoc key) def: (self perform: assoc value) ] ]
       
   120 !
       
   121 
       
   122 initializeStartingAt: aSymbol dependencies: aDictionary
       
   123 	self initialize.
       
   124 	parser := PPDelegateParser named: aSymbol.
       
   125 	self productionNames keysAndValuesDo: [ :key :value |
       
   126 		self instVarAt: key put: (PPDelegateParser named: value) ].
       
   127 	dependencies := aDictionary
    91 ! !
   128 ! !
    92 
   129 
    93 !PPCompositeParser methodsFor:'querying'!
   130 !PPCompositeParser methodsFor:'querying'!
       
   131 
       
   132 dependencyAt: aClass
       
   133 	"Answer the dependent parser aClass. Throws an error if this parser class is not declared in the method #dependencies on the class-side of the receiver."
       
   134 	
       
   135 	^ dependencies at: aClass ifAbsent: [ self error: 'Undeclared dependency in ' , self class name , ' to ' , aClass name ]
       
   136 !
    94 
   137 
    95 productionAt: aSymbol
   138 productionAt: aSymbol
    96 	"Answer the production named aSymbol."
   139 	"Answer the production named aSymbol."
    97 	
   140 	
    98 	^ self productionAt: aSymbol ifAbsent: [ nil ]
   141 	^ self productionAt: aSymbol ifAbsent: [ nil ]
   106 	(self class startSymbol = aSymbol)
   149 	(self class startSymbol = aSymbol)
   107 		ifTrue: [ ^ parser ].
   150 		ifTrue: [ ^ parser ].
   108 	^ self instVarAt: (self class allInstVarNames
   151 	^ self instVarAt: (self class allInstVarNames
   109 		indexOf: aSymbol asString
   152 		indexOf: aSymbol asString
   110 		ifAbsent: [ ^ aBlock value ])
   153 		ifAbsent: [ ^ aBlock value ])
       
   154 !
       
   155 
       
   156 productionNames
       
   157 	"Answer a dictionary of slot indexes and production names."
       
   158 	
       
   159 	| productionNames ignoredNames |
       
   160 	productionNames := Dictionary new.
       
   161 	ignoredNames := self class ignoredNames
       
   162 		collect: [ :each | each asSymbol ].
       
   163 	self class allInstVarNames keysAndValuesDo: [ :key :value |
       
   164 		(ignoredNames includes: value asSymbol)
       
   165 			ifFalse: [ productionNames at: key put: value asSymbol ] ].
       
   166 	^ productionNames
   111 ! !
   167 ! !
   112 
   168 
   113 !PPCompositeParser class methodsFor:'documentation'!
   169 !PPCompositeParser class methodsFor:'documentation'!
   114 
   170 
   115 version
   171 version
   116     ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPCompositeParser.st,v 1.3 2012-05-04 22:02:49 vrany Exp $'
   172     ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPCompositeParser.st,v 1.4 2014-03-04 14:33:36 cg Exp $'
   117 !
   173 !
   118 
   174 
   119 version_CVS
   175 version_CVS
   120     ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPCompositeParser.st,v 1.3 2012-05-04 22:02:49 vrany Exp $'
   176     ^ '$Header: /cvs/stx/stx/goodies/petitparser/PPCompositeParser.st,v 1.4 2014-03-04 14:33:36 cg Exp $'
   121 !
   177 !
   122 
   178 
   123 version_SVN
   179 version_SVN
   124     ^ '§Id: PPCompositeParser.st 2 2010-12-17 18:44:23Z vranyj1 §'
   180     ^ '$Id: PPCompositeParser.st,v 1.4 2014-03-04 14:33:36 cg Exp $'
   125 ! !
   181 ! !
       
   182