diff options
Diffstat (limited to '')
-rw-r--r-- | src/parser.cpp | 160 |
1 files changed, 149 insertions, 11 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index e8e8ff2..b563691 100644 --- a/src/parser.cpp +++ b/src/parser.cpp | |||
@@ -24,21 +24,127 @@ void Bu::Parser::popLexer() | |||
24 | 24 | ||
25 | void Bu::Parser::parse() | 25 | void Bu::Parser::parse() |
26 | { | 26 | { |
27 | for(;;) | 27 | int iCurNt = iRootNonTerminal; |
28 | Lexer::Token *ptCur = sLexer.peek()->nextToken(); | ||
29 | //Lexer::Token *ptNext = sLexer.peek()->nextToken(); | ||
30 | selectProduction( iCurNt, ptCur ); | ||
31 | sio << "Token: " << *ptCur << sio.nl; | ||
32 | |||
33 | while( !sState.isEmpty() ) | ||
28 | { | 34 | { |
29 | Bu::Lexer::Token *pToken = sLexer.peek()->nextToken(); | 35 | sio << "Currently: " << *sState.peek() << sio.nl; |
30 | sio << sLexer.peek()->tokenToString( *pToken ) << sio.nl; | 36 | switch( (*sState.peek()).eType ) |
31 | if( pToken->iToken < 0 ) | ||
32 | { | 37 | { |
33 | delete sLexer.peekPop(); | 38 | case State::typeTerminal: |
34 | if( sLexer.isEmpty() ) | 39 | sio << "terminal: " << ptCur->iToken << " == " |
40 | << (*sState.peek()).iIndex << sio.nl; | ||
41 | if( ptCur->iToken == (*sState.peek()).iIndex ) | ||
42 | { | ||
43 | advanceState(); | ||
44 | delete ptCur; | ||
45 | ptCur = sLexer.peek()->nextToken(); | ||
46 | sio << "Token: " << *ptCur << sio.nl; | ||
47 | } | ||
48 | else | ||
49 | { | ||
50 | throw Bu::ExceptionBase("Error parsing code."); | ||
51 | } | ||
52 | break; | ||
53 | |||
54 | case State::typeTerminalPush: | ||
55 | sio << "terminalpush: " << ptCur->iToken << " == " | ||
56 | << (*sState.peek()).iIndex << sio.nl; | ||
57 | if( ptCur->iToken == (*sState.peek()).iIndex ) | ||
58 | { | ||
59 | advanceState(); | ||
60 | sToken.push( ptCur ); | ||
61 | |||
62 | ptCur = sLexer.peek()->nextToken(); | ||
63 | sio << "Token: " << *ptCur << sio.nl; | ||
64 | } | ||
65 | else | ||
66 | { | ||
67 | throw Bu::ExceptionBase("Error parsing code."); | ||
68 | } | ||
69 | break; | ||
70 | |||
71 | case State::typeNonTerminal: | ||
72 | sio << "nonterminal: " << ptCur->iToken << " --> " | ||
73 | << (*sState.peek()).iIndex << sio.nl; | ||
74 | { | ||
75 | int iNt = (*sState.peek()).iIndex; | ||
76 | advanceState(); | ||
77 | if( !selectProduction( iNt, ptCur ) ) | ||
78 | { | ||
79 | throw Bu::ExceptionBase("Error parsing code."); | ||
80 | } | ||
81 | } | ||
82 | break; | ||
83 | |||
84 | case State::typeReduction: | ||
85 | sio << "reduction" << sio.nl; | ||
86 | aReduction[(*sState.peek()).iIndex]( *this ); | ||
87 | advanceState(); | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | bool Bu::Parser::selectProduction( int iNt, Lexer::Token *ptCur ) | ||
94 | { | ||
95 | NonTerminal &nt = aNonTerminal[iNt]; | ||
96 | int j = 0; | ||
97 | for( NonTerminal::ProductionList::iterator i = nt.lProduction.begin(); | ||
98 | i; i++,j++ ) | ||
99 | { | ||
100 | if( (*i).isEmpty() ) | ||
101 | continue; | ||
102 | if( (*i).first().eType == State::typeTerminal || | ||
103 | (*i).first().eType == State::typeTerminalPush ) | ||
104 | { | ||
105 | if( (*i).first().iIndex == ptCur->iToken ) | ||
35 | { | 106 | { |
36 | delete pToken; | 107 | sState.push( (*i).begin() ); |
37 | return; | 108 | sio << "Pushing production " << j << " from nt " << iNt |
109 | << sio.nl; | ||
110 | return true; | ||
38 | } | 111 | } |
39 | } | 112 | } |
40 | delete pToken; | 113 | else if( (*i).first().eType == State::typeNonTerminal ) |
41 | } | 114 | { |
115 | sState.push( (*i).begin() ); | ||
116 | sio << "Pushing production " << j << " from nt " << iNt | ||
117 | << " as test." << sio.nl; | ||
118 | if( !selectProduction( (*i).first().iIndex, ptCur ) ) | ||
119 | { | ||
120 | sState.pop(); | ||
121 | sio << "Production " << j << " from nt " << iNt | ||
122 | << " didn't work out." << sio.nl; | ||
123 | } | ||
124 | else | ||
125 | { | ||
126 | return true; | ||
127 | } | ||
128 | } | ||
129 | } | ||
130 | if( nt.bCanSkip ) | ||
131 | return true; | ||
132 | return false; | ||
133 | } | ||
134 | |||
135 | void Bu::Parser::advanceState() | ||
136 | { | ||
137 | if( sState.isEmpty() ) | ||
138 | return; | ||
139 | |||
140 | sState.peek()++; | ||
141 | if( !sState.peek() ) | ||
142 | { | ||
143 | sState.pop(); | ||
144 | sio << "State advanced, End of production." << sio.nl; | ||
145 | return; | ||
146 | } | ||
147 | sio << "State advanced, now: " << *(sState.peek()) << sio.nl; | ||
42 | } | 148 | } |
43 | 149 | ||
44 | void Bu::Parser::setRootNonTerminal( int iRoot ) | 150 | void Bu::Parser::setRootNonTerminal( int iRoot ) |
@@ -56,6 +162,7 @@ int Bu::Parser::addNonTerminal( const Bu::FString &sName, NonTerminal &nt ) | |||
56 | int iId = aNonTerminal.getSize(); | 162 | int iId = aNonTerminal.getSize(); |
57 | aNonTerminal.append( nt ); | 163 | aNonTerminal.append( nt ); |
58 | hNonTerminalName.insert( sName, iId ); | 164 | hNonTerminalName.insert( sName, iId ); |
165 | sio << "nt '" << sName << "' = " << iId << sio.nl; | ||
59 | return iId; | 166 | return iId; |
60 | } | 167 | } |
61 | 168 | ||
@@ -64,6 +171,7 @@ int Bu::Parser::addNonTerminal( const Bu::FString &sName ) | |||
64 | int iId = aNonTerminal.getSize(); | 171 | int iId = aNonTerminal.getSize(); |
65 | aNonTerminal.append( NonTerminal() ); | 172 | aNonTerminal.append( NonTerminal() ); |
66 | hNonTerminalName.insert( sName, iId ); | 173 | hNonTerminalName.insert( sName, iId ); |
174 | sio << "nt '" << sName << "' = " << iId << sio.nl; | ||
67 | return iId; | 175 | return iId; |
68 | } | 176 | } |
69 | 177 | ||
@@ -121,7 +229,8 @@ Bu::Parser::State::~State() | |||
121 | // Bu::Parser::NonTerminal | 229 | // Bu::Parser::NonTerminal |
122 | // | 230 | // |
123 | 231 | ||
124 | Bu::Parser::NonTerminal::NonTerminal() | 232 | Bu::Parser::NonTerminal::NonTerminal() : |
233 | bCanSkip( false ) | ||
125 | { | 234 | { |
126 | } | 235 | } |
127 | 236 | ||
@@ -134,3 +243,32 @@ void Bu::Parser::NonTerminal::addProduction( Production p ) | |||
134 | lProduction.append( p ); | 243 | lProduction.append( p ); |
135 | } | 244 | } |
136 | 245 | ||
246 | void Bu::Parser::NonTerminal::setCanSkip() | ||
247 | { | ||
248 | bCanSkip = true; | ||
249 | } | ||
250 | |||
251 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, Bu::Parser::State::Type t ) | ||
252 | { | ||
253 | switch( t ) | ||
254 | { | ||
255 | case Bu::Parser::State::typeTerminal: | ||
256 | return f << "typeTerminal"; | ||
257 | |||
258 | case Bu::Parser::State::typeTerminalPush: | ||
259 | return f << "typeTerminalPush"; | ||
260 | |||
261 | case Bu::Parser::State::typeNonTerminal: | ||
262 | return f << "typeNonTerminal"; | ||
263 | |||
264 | case Bu::Parser::State::typeReduction: | ||
265 | return f << "typeReduction"; | ||
266 | } | ||
267 | return f << "***error***"; | ||
268 | } | ||
269 | |||
270 | Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Parser::State &s ) | ||
271 | { | ||
272 | return f << "{" << s.eType << ": " << s.iIndex << "}"; | ||
273 | } | ||
274 | |||