summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lexer.cpp2
-rw-r--r--src/lexer.h8
-rw-r--r--src/parser.cpp93
-rw-r--r--src/parser.h70
-rw-r--r--src/tools/parser.cpp79
5 files changed, 246 insertions, 6 deletions
diff --git a/src/lexer.cpp b/src/lexer.cpp
index c7a6fcb..af9a23f 100644
--- a/src/lexer.cpp
+++ b/src/lexer.cpp
@@ -13,7 +13,7 @@ Bu::Lexer::Token::Token() :
13{ 13{
14} 14}
15 15
16Bu::Lexer::Token::Token( int iToken ) : 16Bu::Lexer::Token::Token( Bu::Lexer::TokenType iToken ) :
17 iToken( iToken ) 17 iToken( iToken )
18{ 18{
19} 19}
diff --git a/src/lexer.h b/src/lexer.h
index 37d268f..5847269 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -19,19 +19,21 @@ namespace Bu
19 Lexer(); 19 Lexer();
20 virtual ~Lexer(); 20 virtual ~Lexer();
21 21
22 typedef int32_t TokenType;
23
22 class Token 24 class Token
23 { 25 {
24 public: 26 public:
25 Token(); 27 Token();
26 Token( int iToken ); 28 Token( TokenType iToken );
27 29
28 template<class t> 30 template<class t>
29 Token( int iToken, const t &v ) : 31 Token( TokenType iToken, const t &v ) :
30 iToken( iToken ), 32 iToken( iToken ),
31 vExtra( v ) 33 vExtra( v )
32 { 34 {
33 } 35 }
34 int iToken; 36 TokenType iToken;
35 Bu::Variant vExtra; 37 Bu::Variant vExtra;
36 }; 38 };
37 39
diff --git a/src/parser.cpp b/src/parser.cpp
index 7015070..e8e8ff2 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -41,3 +41,96 @@ void Bu::Parser::parse()
41 } 41 }
42} 42}
43 43
44void Bu::Parser::setRootNonTerminal( int iRoot )
45{
46 iRootNonTerminal = iRoot;
47}
48
49void Bu::Parser::setRootNonTerminal( const Bu::FString &sRoot )
50{
51 setRootNonTerminal( hNonTerminalName.get( sRoot ) );
52}
53
54int Bu::Parser::addNonTerminal( const Bu::FString &sName, NonTerminal &nt )
55{
56 int iId = aNonTerminal.getSize();
57 aNonTerminal.append( nt );
58 hNonTerminalName.insert( sName, iId );
59 return iId;
60}
61
62int Bu::Parser::addNonTerminal( const Bu::FString &sName )
63{
64 int iId = aNonTerminal.getSize();
65 aNonTerminal.append( NonTerminal() );
66 hNonTerminalName.insert( sName, iId );
67 return iId;
68}
69
70void Bu::Parser::setNonTerminal( const Bu::FString &sName, NonTerminal &nt )
71{
72 aNonTerminal[hNonTerminalName.get(sName)] = nt;
73}
74
75int Bu::Parser::getNonTerminalId( const Bu::FString &sName )
76{
77 return hNonTerminalName.get( sName );
78}
79
80int Bu::Parser::addReduction( const Bu::FString &sName, const Reduction &r )
81{
82 int iId = aReduction.getSize();
83 aReduction.append( r );
84 hReductionName.insert( sName, iId );
85 return iId;
86}
87
88int Bu::Parser::addReduction( const Bu::FString &sName )
89{
90 int iId = aReduction.getSize();
91 aReduction.append( Reduction() );
92 hReductionName.insert( sName, iId );
93 return iId;
94}
95
96void Bu::Parser::setReduction( const Bu::FString &sName, const Reduction &r )
97{
98 aReduction[hReductionName.get(sName)] = r;
99}
100
101int Bu::Parser::getReductionId( const Bu::FString &sName )
102{
103 return hReductionName.get( sName );
104}
105
106//
107// Bu::Parser::State
108//
109
110Bu::Parser::State::State( Bu::Parser::State::Type eType, int iIndex ) :
111 eType( eType ),
112 iIndex( iIndex )
113{
114}
115
116Bu::Parser::State::~State()
117{
118}
119
120//
121// Bu::Parser::NonTerminal
122//
123
124Bu::Parser::NonTerminal::NonTerminal()
125{
126}
127
128Bu::Parser::NonTerminal::~NonTerminal()
129{
130}
131
132void Bu::Parser::NonTerminal::addProduction( Production p )
133{
134 lProduction.append( p );
135}
136
diff --git a/src/parser.h b/src/parser.h
index 26b15a6..e720e54 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -1,8 +1,12 @@
1#ifndef BU_PARSER_H 1#ifndef BU_PARSER_H
2#define BU_PARSER_H 2#define BU_PARSER_H
3 3
4#include "bu/list.h"
5#include "bu/fstring.h" 4#include "bu/fstring.h"
5#include "bu/list.h"
6#include "bu/array.h"
7#include "bu/hash.h"
8#include "bu/signals.h"
9
6#include "bu/lexer.h" 10#include "bu/lexer.h"
7 11
8namespace Bu 12namespace Bu
@@ -35,13 +39,75 @@ namespace Bu
35 */ 39 */
36 void parse(); 40 void parse();
37 41
42 void setRootNonTerminal( int iRoot );
43 void setRootNonTerminal( const Bu::FString &sRoot );
44
45 typedef Bu::Signal1<void, Parser &> Reduction;
46
47 /**
48 * Represents a possible state, either a terminal or non-terminal symbol
49 * in a Production.
50 */
51 class State
52 {
53 public:
54 enum Type
55 {
56 typeTerminal,
57 typeTerminalPush,
58 typeNonTerminal,
59 typeReduction
60 };
61
62 State( Type eType, int iIndex );
63 virtual ~State();
64
65 private:
66 Type eType;
67 int iIndex;
68 };
69
70 typedef Bu::List<State> Production;
71
72 class NonTerminal
73 {
74 public:
75 NonTerminal();
76 virtual ~NonTerminal();
77
78 void addProduction( Production p );
79
80 private:
81 typedef Bu::List<Production> ProductionList;
82 ProductionList lProduction;
83 };
84
85 int addNonTerminal( const Bu::FString &sName, NonTerminal &nt );
86 int addNonTerminal( const Bu::FString &sName );
87 void setNonTerminal( const Bu::FString &sName, NonTerminal &nt );
88 int getNonTerminalId( const Bu::FString &sName );
89
90 int addReduction( const Bu::FString &sName, const Reduction &r );
91 int addReduction( const Bu::FString &sName );
92 void setReduction( const Bu::FString &sName, const Reduction &r );
93 int getReductionId( const Bu::FString &sName );
94
38 private: 95 private:
39 typedef Bu::List<Lexer *> LexerStack; 96 typedef Bu::List<Lexer *> LexerStack;
40 typedef Bu::List<Lexer::Token *> TokenStack; 97 typedef Bu::List<Lexer::Token *> TokenStack;
41 typedef Bu::List<State *> StateStack; 98 typedef Bu::List<Production::const_iterator> StateStack;
99 typedef Bu::Array<Reduction> ReductionArray;
100 typedef Bu::Hash<Bu::FString,int> NameIndexHash;
101 typedef Bu::Array<NonTerminal> NonTerminalArray;
102
42 LexerStack sLexer; 103 LexerStack sLexer;
43 TokenStack sToken; 104 TokenStack sToken;
44 StateStack sState; 105 StateStack sState;
106 ReductionArray aReduction;
107 NameIndexHash hReductionName;
108 NonTerminalArray aNonTerminal;
109 NameIndexHash hNonTerminalName;
110 int iRootNonTerminal;
45 }; 111 };
46}; 112};
47 113
diff --git a/src/tools/parser.cpp b/src/tools/parser.cpp
index a70dfa4..e4fc95f 100644
--- a/src/tools/parser.cpp
+++ b/src/tools/parser.cpp
@@ -149,12 +149,91 @@ private:
149 QueueBuf qbIn; 149 QueueBuf qbIn;
150}; 150};
151 151
152void redAdd( Bu::Parser &p )
153{
154}
155
156void redPrint( Bu::Parser &p )
157{
158}
159
152int main( int argc, char *argv[] ) 160int main( int argc, char *argv[] )
153{ 161{
154 File fIn( argv[1], File::Read ); 162 File fIn( argv[1], File::Read );
155 163
156 Parser p; 164 Parser p;
157 165
166 {
167 Parser::NonTerminal nt;
168 int iSelf = p.addNonTerminal("expr");
169 nt.addProduction(
170 Parser::Production(
171 Parser::State(
172 Parser::State::typeTerminal,
173 tokPlus
174 )
175 ).append(
176 Parser::State(
177 Parser::State::typeNonTerminal,
178 iSelf
179 )
180 ).append(
181 Parser::State(
182 Parser::State::typeReduction,
183 p.addReduction("add")
184 )
185 )
186 );
187 nt.addProduction(
188 Parser::Production()
189 );
190 p.addNonTerminal( "expr", nt );
191 }
192 {
193 Parser::NonTerminal nt;
194 nt.addProduction(
195 Parser::Production(
196 Parser::State(
197 Parser::State::typeTerminalPush,
198 tokNumber
199 )
200 ).append(
201 Parser::State(
202 Parser::State::typeNonTerminal,
203 p.getNonTerminalId("expr")
204 )
205 )
206 );
207 p.addNonTerminal( "expr'", nt );
208 }
209 {
210 Parser::NonTerminal nt;
211 nt.addProduction(
212 Parser::Production(
213 Parser::State(
214 Parser::State::typeNonTerminal,
215 p.getNonTerminalId("expr'")
216 )
217 ).append(
218 Parser::State(
219 Parser::State::typeTerminal,
220 tokCompute
221 )
222 ).append(
223 Parser::State(
224 Parser::State::typeReduction,
225 p.addReduction("print")
226 )
227 )
228 );
229 p.addNonTerminal("input", nt );
230 }
231
232 p.setRootNonTerminal("input");
233
234 p.setReduction("add", Bu::slot( &redAdd ) );
235 p.setReduction("print", Bu::slot( &redPrint ) );
236
158 p.pushLexer( new MathLexer( fIn ) ); 237 p.pushLexer( new MathLexer( fIn ) );
159 238
160 p.parse(); 239 p.parse();