aboutsummaryrefslogtreecommitdiff
path: root/src/parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/parser.cpp160
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
25void Bu::Parser::parse() 25void 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
93bool 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
135void 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
44void Bu::Parser::setRootNonTerminal( int iRoot ) 150void 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
124Bu::Parser::NonTerminal::NonTerminal() 232Bu::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
246void Bu::Parser::NonTerminal::setCanSkip()
247{
248 bCanSkip = true;
249}
250
251Bu::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
270Bu::Formatter &Bu::operator<<( Bu::Formatter &f, const Bu::Parser::State &s )
271{
272 return f << "{" << s.eType << ": " << s.iIndex << "}";
273}
274