diff options
Diffstat (limited to '')
-rw-r--r-- | src/experimental/parser.cpp | 342 |
1 files changed, 171 insertions, 171 deletions
diff --git a/src/experimental/parser.cpp b/src/experimental/parser.cpp index 9f10256..5d0d7eb 100644 --- a/src/experimental/parser.cpp +++ b/src/experimental/parser.cpp | |||
@@ -21,231 +21,231 @@ Bu::Parser::~Parser() | |||
21 | 21 | ||
22 | void Bu::Parser::pushLexer( Lexer *pLex ) | 22 | void Bu::Parser::pushLexer( Lexer *pLex ) |
23 | { | 23 | { |
24 | sLexer.push( pLex ); | 24 | sLexer.push( pLex ); |
25 | } | 25 | } |
26 | 26 | ||
27 | void Bu::Parser::popLexer() | 27 | void Bu::Parser::popLexer() |
28 | { | 28 | { |
29 | delete sLexer.peekPop(); | 29 | delete sLexer.peekPop(); |
30 | } | 30 | } |
31 | 31 | ||
32 | Lexer::Token *Bu::Parser::popToken() | 32 | Lexer::Token *Bu::Parser::popToken() |
33 | { | 33 | { |
34 | return sToken.peekPop(); | 34 | return sToken.peekPop(); |
35 | } | 35 | } |
36 | 36 | ||
37 | void Bu::Parser::pushToken( Lexer::Token *pTok ) | 37 | void Bu::Parser::pushToken( Lexer::Token *pTok ) |
38 | { | 38 | { |
39 | sToken.push( pTok ); | 39 | sToken.push( pTok ); |
40 | } | 40 | } |
41 | 41 | ||
42 | void Bu::Parser::parse() | 42 | void Bu::Parser::parse() |
43 | { | 43 | { |
44 | int iCurNt = iRootNonTerminal; | 44 | int iCurNt = iRootNonTerminal; |
45 | Lexer::Token *ptCur = sLexer.peek()->nextToken(); | 45 | Lexer::Token *ptCur = sLexer.peek()->nextToken(); |
46 | sio << "Token(a): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; | 46 | sio << "Token(a): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; |
47 | selectProduction( iCurNt, ptCur ); | 47 | selectProduction( iCurNt, ptCur ); |
48 | 48 | ||
49 | while( !sState.isEmpty() ) | 49 | while( !sState.isEmpty() ) |
50 | { | 50 | { |
51 | switch( (*sState.peek()).eType ) | 51 | switch( (*sState.peek()).eType ) |
52 | { | 52 | { |
53 | case State::typeTerminal: | 53 | case State::typeTerminal: |
54 | sio << "terminal: " << ptCur->iToken << " == " | 54 | sio << "terminal: " << ptCur->iToken << " == " |
55 | << (*sState.peek()).iIndex << sio.nl; | 55 | << (*sState.peek()).iIndex << sio.nl; |
56 | if( ptCur->iToken == (*sState.peek()).iIndex ) | 56 | if( ptCur->iToken == (*sState.peek()).iIndex ) |
57 | { | 57 | { |
58 | advanceState(); | 58 | advanceState(); |
59 | delete ptCur; | 59 | delete ptCur; |
60 | ptCur = sLexer.peek()->nextToken(); | 60 | ptCur = sLexer.peek()->nextToken(); |
61 | sio << "Token(b): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; | 61 | sio << "Token(b): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; |
62 | } | 62 | } |
63 | else | 63 | else |
64 | { | 64 | { |
65 | throw Bu::ExceptionBase("Error parsing code."); | 65 | throw Bu::ExceptionBase("Error parsing code."); |
66 | } | 66 | } |
67 | break; | 67 | break; |
68 | 68 | ||
69 | case State::typeTerminalPush: | 69 | case State::typeTerminalPush: |
70 | sio << "terminalpush: " << ptCur->iToken << " == " | 70 | sio << "terminalpush: " << ptCur->iToken << " == " |
71 | << (*sState.peek()).iIndex << sio.nl; | 71 | << (*sState.peek()).iIndex << sio.nl; |
72 | if( ptCur->iToken == (*sState.peek()).iIndex ) | 72 | if( ptCur->iToken == (*sState.peek()).iIndex ) |
73 | { | 73 | { |
74 | advanceState(); | 74 | advanceState(); |
75 | sToken.push( ptCur ); | 75 | sToken.push( ptCur ); |
76 | 76 | ||
77 | ptCur = sLexer.peek()->nextToken(); | 77 | ptCur = sLexer.peek()->nextToken(); |
78 | sio << "Token(c): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; | 78 | sio << "Token(c): " << sLexer.peek()->tokenToString( *ptCur ) << sio.nl; |
79 | } | 79 | } |
80 | else | 80 | else |
81 | { | 81 | { |
82 | throw Bu::ExceptionBase("Error parsing code."); | 82 | throw Bu::ExceptionBase("Error parsing code."); |
83 | } | 83 | } |
84 | break; | 84 | break; |
85 | 85 | ||
86 | case State::typeNonTerminal: | 86 | case State::typeNonTerminal: |
87 | sio << "nonterminal: " << ptCur->iToken << " --> " | 87 | sio << "nonterminal: " << ptCur->iToken << " --> " |
88 | << (*sState.peek()).iIndex << sio.nl; | 88 | << (*sState.peek()).iIndex << sio.nl; |
89 | { | 89 | { |
90 | int iNt = (*sState.peek()).iIndex; | 90 | int iNt = (*sState.peek()).iIndex; |
91 | sio << "Current state: " << *sState.peek() << sio.nl; | 91 | sio << "Current state: " << *sState.peek() << sio.nl; |
92 | if( !selectProduction( iNt, ptCur ) ) | 92 | if( !selectProduction( iNt, ptCur ) ) |
93 | { | 93 | { |
94 | throw Bu::ExceptionBase("Error parsing code."); | 94 | throw Bu::ExceptionBase("Error parsing code."); |
95 | } | 95 | } |
96 | } | 96 | } |
97 | break; | 97 | break; |
98 | 98 | ||
99 | case State::typeReduction: | 99 | case State::typeReduction: |
100 | sio << "reduction" << sio.nl; | 100 | sio << "reduction" << sio.nl; |
101 | aReduction[(*sState.peek()).iIndex]( *this ); | 101 | aReduction[(*sState.peek()).iIndex]( *this ); |
102 | advanceState(); | 102 | advanceState(); |
103 | break; | 103 | break; |
104 | } | 104 | } |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | bool Bu::Parser::selectProduction( int iNt, Lexer::Token *ptCur ) | 108 | bool Bu::Parser::selectProduction( int iNt, Lexer::Token *ptCur ) |
109 | { | 109 | { |
110 | NonTerminal &nt = aNonTerminal[iNt]; | 110 | NonTerminal &nt = aNonTerminal[iNt]; |
111 | int j = 0; | 111 | int j = 0; |
112 | for( NonTerminal::ProductionList::iterator i = nt.lProduction.begin(); | 112 | for( NonTerminal::ProductionList::iterator i = nt.lProduction.begin(); |
113 | i; i++,j++ ) | 113 | i; i++,j++ ) |
114 | { | 114 | { |
115 | if( (*i).isEmpty() ) | 115 | if( (*i).isEmpty() ) |
116 | continue; | 116 | continue; |
117 | sio << "-->(Attempting production " << iNt << ":" << j << ": " | 117 | sio << "-->(Attempting production " << iNt << ":" << j << ": " |
118 | << (*i).first() << ")" << sio.nl; | 118 | << (*i).first() << ")" << sio.nl; |
119 | if( (*i).first().eType == State::typeTerminal || | 119 | if( (*i).first().eType == State::typeTerminal || |
120 | (*i).first().eType == State::typeTerminalPush ) | 120 | (*i).first().eType == State::typeTerminalPush ) |
121 | { | 121 | { |
122 | if( (*i).first().iIndex == ptCur->iToken ) | 122 | if( (*i).first().iIndex == ptCur->iToken ) |
123 | { | 123 | { |
124 | sState.push( (*i).begin() ); | 124 | sState.push( (*i).begin() ); |
125 | sio.incIndent(); | 125 | sio.incIndent(); |
126 | sio << "Pushing production " << j << " from nt " << iNt | 126 | sio << "Pushing production " << j << " from nt " << iNt |
127 | << sio.nl; | 127 | << sio.nl; |
128 | return true; | 128 | return true; |
129 | } | 129 | } |
130 | } | 130 | } |
131 | else if( (*i).first().eType == State::typeNonTerminal ) | 131 | else if( (*i).first().eType == State::typeNonTerminal ) |
132 | { | 132 | { |
133 | sState.push( (*i).begin() ); | 133 | sState.push( (*i).begin() ); |
134 | sio.incIndent(); | 134 | sio.incIndent(); |
135 | sio << "Pushing production " << j << " from nt " << iNt | 135 | sio << "Pushing production " << j << " from nt " << iNt |
136 | << " as test." << sio.nl; | 136 | << " as test." << sio.nl; |
137 | if( !selectProduction( (*i).first().iIndex, ptCur ) ) | 137 | if( !selectProduction( (*i).first().iIndex, ptCur ) ) |
138 | { | 138 | { |
139 | sio.decIndent(); | 139 | sio.decIndent(); |
140 | sState.pop(); | 140 | sState.pop(); |
141 | sio << "Production " << j << " from nt " << iNt | 141 | sio << "Production " << j << " from nt " << iNt |
142 | << " didn't work out." << sio.nl; | 142 | << " didn't work out." << sio.nl; |
143 | } | 143 | } |
144 | else | 144 | else |
145 | { | 145 | { |
146 | return true; | 146 | return true; |
147 | } | 147 | } |
148 | } | 148 | } |
149 | } | 149 | } |
150 | if( nt.bCanSkip ) | 150 | if( nt.bCanSkip ) |
151 | { | 151 | { |
152 | sio << "Nothing matches, skipping non-terminal." << sio.nl; | 152 | sio << "Nothing matches, skipping non-terminal." << sio.nl; |
153 | advanceState(); | 153 | advanceState(); |
154 | return true; | 154 | return true; |
155 | } | 155 | } |
156 | sio << "-->(Found nothing)" << sio.nl; | 156 | sio << "-->(Found nothing)" << sio.nl; |
157 | return false; | 157 | return false; |
158 | } | 158 | } |
159 | 159 | ||
160 | void Bu::Parser::advanceState() | 160 | void Bu::Parser::advanceState() |
161 | { | 161 | { |
162 | if( sState.isEmpty() ) | 162 | if( sState.isEmpty() ) |
163 | return; | 163 | return; |
164 | 164 | ||
165 | sState.peek()++; | 165 | sState.peek()++; |
166 | if( !sState.peek() ) | 166 | if( !sState.peek() ) |
167 | { | 167 | { |
168 | sio.decIndent(); | 168 | sio.decIndent(); |
169 | sState.pop(); | 169 | sState.pop(); |
170 | sio << "State advanced, End of production." << sio.nl; | 170 | sio << "State advanced, End of production." << sio.nl; |
171 | advanceState(); | 171 | advanceState(); |
172 | return; | 172 | return; |
173 | } | 173 | } |
174 | sio << "State advanced, now: " << *(sState.peek()) << sio.nl; | 174 | sio << "State advanced, now: " << *(sState.peek()) << sio.nl; |
175 | } | 175 | } |
176 | 176 | ||
177 | void Bu::Parser::setRootNonTerminal( int iRoot ) | 177 | void Bu::Parser::setRootNonTerminal( int iRoot ) |
178 | { | 178 | { |
179 | iRootNonTerminal = iRoot; | 179 | iRootNonTerminal = iRoot; |
180 | } | 180 | } |
181 | 181 | ||
182 | void Bu::Parser::setRootNonTerminal( const Bu::String &sRoot ) | 182 | void Bu::Parser::setRootNonTerminal( const Bu::String &sRoot ) |
183 | { | 183 | { |
184 | setRootNonTerminal( hNonTerminalName.get( sRoot ) ); | 184 | setRootNonTerminal( hNonTerminalName.get( sRoot ) ); |
185 | } | 185 | } |
186 | 186 | ||
187 | int Bu::Parser::addNonTerminal( const Bu::String &sName, NonTerminal &nt ) | 187 | int Bu::Parser::addNonTerminal( const Bu::String &sName, NonTerminal &nt ) |
188 | { | 188 | { |
189 | int iId = aNonTerminal.getSize(); | 189 | int iId = aNonTerminal.getSize(); |
190 | aNonTerminal.append( nt ); | 190 | aNonTerminal.append( nt ); |
191 | hNonTerminalName.insert( sName, iId ); | 191 | hNonTerminalName.insert( sName, iId ); |
192 | sio << "nt '" << sName << "' = " << iId << sio.nl; | 192 | sio << "nt '" << sName << "' = " << iId << sio.nl; |
193 | return iId; | 193 | return iId; |
194 | } | 194 | } |
195 | 195 | ||
196 | int Bu::Parser::addNonTerminal( const Bu::String &sName ) | 196 | int Bu::Parser::addNonTerminal( const Bu::String &sName ) |
197 | { | 197 | { |
198 | int iId = aNonTerminal.getSize(); | 198 | int iId = aNonTerminal.getSize(); |
199 | aNonTerminal.append( NonTerminal() ); | 199 | aNonTerminal.append( NonTerminal() ); |
200 | hNonTerminalName.insert( sName, iId ); | 200 | hNonTerminalName.insert( sName, iId ); |
201 | sio << "nt '" << sName << "' = " << iId << sio.nl; | 201 | sio << "nt '" << sName << "' = " << iId << sio.nl; |
202 | return iId; | 202 | return iId; |
203 | } | 203 | } |
204 | 204 | ||
205 | void Bu::Parser::setNonTerminal( const Bu::String &sName, NonTerminal &nt ) | 205 | void Bu::Parser::setNonTerminal( const Bu::String &sName, NonTerminal &nt ) |
206 | { | 206 | { |
207 | aNonTerminal[hNonTerminalName.get(sName)] = nt; | 207 | aNonTerminal[hNonTerminalName.get(sName)] = nt; |
208 | } | 208 | } |
209 | 209 | ||
210 | int Bu::Parser::getNonTerminalId( const Bu::String &sName ) | 210 | int Bu::Parser::getNonTerminalId( const Bu::String &sName ) |
211 | { | 211 | { |
212 | return hNonTerminalName.get( sName ); | 212 | return hNonTerminalName.get( sName ); |
213 | } | 213 | } |
214 | 214 | ||
215 | bool Bu::Parser::hasNonTerminal( const Bu::String &sName ) | 215 | bool Bu::Parser::hasNonTerminal( const Bu::String &sName ) |
216 | { | 216 | { |
217 | return hNonTerminalName.has( sName ); | 217 | return hNonTerminalName.has( sName ); |
218 | } | 218 | } |
219 | 219 | ||
220 | int Bu::Parser::addReduction( const Bu::String &sName, const Reduction &r ) | 220 | int Bu::Parser::addReduction( const Bu::String &sName, const Reduction &r ) |
221 | { | 221 | { |
222 | int iId = aReduction.getSize(); | 222 | int iId = aReduction.getSize(); |
223 | aReduction.append( r ); | 223 | aReduction.append( r ); |
224 | hReductionName.insert( sName, iId ); | 224 | hReductionName.insert( sName, iId ); |
225 | return iId; | 225 | return iId; |
226 | } | 226 | } |
227 | 227 | ||
228 | int Bu::Parser::addReduction( const Bu::String &sName ) | 228 | int Bu::Parser::addReduction( const Bu::String &sName ) |
229 | { | 229 | { |
230 | int iId = aReduction.getSize(); | 230 | int iId = aReduction.getSize(); |
231 | aReduction.append( Reduction() ); | 231 | aReduction.append( Reduction() ); |
232 | hReductionName.insert( sName, iId ); | 232 | hReductionName.insert( sName, iId ); |
233 | return iId; | 233 | return iId; |
234 | } | 234 | } |
235 | 235 | ||
236 | void Bu::Parser::setReduction( const Bu::String &sName, const Reduction &r ) | 236 | void Bu::Parser::setReduction( const Bu::String &sName, const Reduction &r ) |
237 | { | 237 | { |
238 | aReduction[hReductionName.get(sName)] = r; | 238 | aReduction[hReductionName.get(sName)] = r; |
239 | } | 239 | } |
240 | 240 | ||
241 | int Bu::Parser::getReductionId( const Bu::String &sName ) | 241 | int Bu::Parser::getReductionId( const Bu::String &sName ) |
242 | { | 242 | { |
243 | return hReductionName.get( sName ); | 243 | return hReductionName.get( sName ); |
244 | } | 244 | } |
245 | 245 | ||
246 | bool Bu::Parser::hasReduction( const Bu::String &sName ) | 246 | bool Bu::Parser::hasReduction( const Bu::String &sName ) |
247 | { | 247 | { |
248 | return hReductionName.has( sName ); | 248 | return hReductionName.has( sName ); |
249 | } | 249 | } |
250 | 250 | ||
251 | // | 251 | // |
@@ -253,8 +253,8 @@ bool Bu::Parser::hasReduction( const Bu::String &sName ) | |||
253 | // | 253 | // |
254 | 254 | ||
255 | Bu::Parser::State::State( Bu::Parser::State::Type eType, int iIndex ) : | 255 | Bu::Parser::State::State( Bu::Parser::State::Type eType, int iIndex ) : |
256 | eType( eType ), | 256 | eType( eType ), |
257 | iIndex( iIndex ) | 257 | iIndex( iIndex ) |
258 | { | 258 | { |
259 | } | 259 | } |
260 | 260 | ||
@@ -267,7 +267,7 @@ Bu::Parser::State::~State() | |||
267 | // | 267 | // |
268 | 268 | ||
269 | Bu::Parser::NonTerminal::NonTerminal() : | 269 | Bu::Parser::NonTerminal::NonTerminal() : |
270 | bCanSkip( false ) | 270 | bCanSkip( false ) |
271 | { | 271 | { |
272 | } | 272 | } |
273 | 273 | ||
@@ -277,35 +277,35 @@ Bu::Parser::NonTerminal::~NonTerminal() | |||
277 | 277 | ||
278 | void Bu::Parser::NonTerminal::addProduction( Production p ) | 278 | void Bu::Parser::NonTerminal::addProduction( Production p ) |
279 | { | 279 | { |
280 | lProduction.append( p ); | 280 | lProduction.append( p ); |
281 | } | 281 | } |
282 | 282 | ||
283 | void Bu::Parser::NonTerminal::setCanSkip() | 283 | void Bu::Parser::NonTerminal::setCanSkip() |
284 | { | 284 | { |
285 | bCanSkip = true; | 285 | bCanSkip = true; |
286 | } | 286 | } |
287 | 287 | ||
288 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Parser::State::Type t ) | 288 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Parser::State::Type t ) |
289 | { | 289 | { |
290 | switch( t ) | 290 | switch( t ) |
291 | { | 291 | { |
292 | case Bu::Parser::State::typeTerminal: | 292 | case Bu::Parser::State::typeTerminal: |
293 | return f << "typeTerminal"; | 293 | return f << "typeTerminal"; |
294 | 294 | ||
295 | case Bu::Parser::State::typeTerminalPush: | 295 | case Bu::Parser::State::typeTerminalPush: |
296 | return f << "typeTerminalPush"; | 296 | return f << "typeTerminalPush"; |
297 | 297 | ||
298 | case Bu::Parser::State::typeNonTerminal: | 298 | case Bu::Parser::State::typeNonTerminal: |
299 | return f << "typeNonTerminal"; | 299 | return f << "typeNonTerminal"; |
300 | 300 | ||
301 | case Bu::Parser::State::typeReduction: | 301 | case Bu::Parser::State::typeReduction: |
302 | return f << "typeReduction"; | 302 | return f << "typeReduction"; |
303 | } | 303 | } |
304 | return f << "***error***"; | 304 | return f << "***error***"; |
305 | } | 305 | } |
306 | 306 | ||
307 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Parser::State &s ) | 307 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Parser::State &s ) |
308 | { | 308 | { |
309 | return f << "{" << s.eType << ": " << s.iIndex << "}"; | 309 | return f << "{" << s.eType << ": " << s.iIndex << "}"; |
310 | } | 310 | } |
311 | 311 | ||