summaryrefslogtreecommitdiff
path: root/src/tools/parser.cpp
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2010-10-12 06:09:48 +0000
committerMike Buland <eichlan@xagasoft.com>2010-10-12 06:09:48 +0000
commit1ee5f374ed986333d5cdbbf41390f1c4c755a8e3 (patch)
tree67b02598d3dca87a82263629a1290bd7b7a79006 /src/tools/parser.cpp
parent313e28df2a8776c82f5493aef6fe44ad40f1935a (diff)
downloadlibbu++-1ee5f374ed986333d5cdbbf41390f1c4c755a8e3.tar.gz
libbu++-1ee5f374ed986333d5cdbbf41390f1c4c755a8e3.tar.bz2
libbu++-1ee5f374ed986333d5cdbbf41390f1c4c755a8e3.tar.xz
libbu++-1ee5f374ed986333d5cdbbf41390f1c4c755a8e3.zip
This commit has a minor tweak to the variant class to make it easier to use,
and introduces the parser and lexer classes. I also made a test for parser and put it in the tools directory. That is silly, it shouldn't be. However, it's necesarry right now, because I don't want to do a full build to compile all the parser tests. However, this commit doesn't actually build yet. It will soon, I just wanted to get it all committed.
Diffstat (limited to 'src/tools/parser.cpp')
-rw-r--r--src/tools/parser.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/tools/parser.cpp b/src/tools/parser.cpp
new file mode 100644
index 0000000..a70dfa4
--- /dev/null
+++ b/src/tools/parser.cpp
@@ -0,0 +1,164 @@
1#include <bu/parser.h>
2#include <bu/lexer.h>
3#include <bu/file.h>
4#include <bu/sio.h>
5#include <bu/queuebuf.h>
6#include <stdlib.h>
7
8using namespace Bu;
9
10enum Tok
11{
12 tokNumber,
13 tokPlus,
14 tokMinus,
15 tokDivide,
16 tokMultiply,
17 tokOpenParen,
18 tokCloseParen,
19 tokCompute,
20 tokEndOfInput=-1
21};
22
23Bu::Formatter &operator<<( Bu::Formatter &f, Tok e )
24{
25 switch( e )
26 {
27 case tokNumber: return f << "tokNumber";
28 case tokPlus: return f << "tokPlus";
29 case tokMinus: return f << "tokMinus";
30 case tokDivide: return f << "tokDivide";
31 case tokMultiply: return f << "tokMultiply";
32 case tokOpenParen: return f << "tokOpenParen";
33 case tokCloseParen: return f << "tokCloseParen";
34 case tokCompute: return f << "tokCompute";
35 case tokEndOfInput: return f << "tokEndOfInput";
36 }
37
38 return f << "***error***";
39}
40
41class MathLexer : public Lexer
42{
43public:
44 MathLexer( Bu::Stream &rSrc ) :
45 rSrc( rSrc )
46 {
47 }
48
49 virtual ~MathLexer()
50 {
51 }
52
53 enum TokenTypes
54 {
55 tokStuff
56 };
57
58 virtual Token *nextToken()
59 {
60 for(;;)
61 {
62 if( qbIn.getSize() == 0 )
63 {
64 char buf[4096];
65 qbIn.write( buf, rSrc.read( buf, 4096 ) );
66
67 if( rSrc.isEos() && qbIn.getSize() == 0 )
68 return new Token( tokEndOfInput );
69 }
70
71 char b;
72 qbIn.peek( &b, 1 );
73 switch( b )
74 {
75 case '+':
76 qbIn.seek( 1 );
77 return new Token( tokPlus );
78
79 case '-':
80 qbIn.seek( 1 );
81 return new Token( tokMinus );
82
83 case '/':
84 qbIn.seek( 1 );
85 return new Token( tokDivide );
86
87 case '*':
88 qbIn.seek( 1 );
89 return new Token( tokMultiply );
90
91 case ' ':
92 case '\t':
93 case '\n':
94 qbIn.seek( 1 );
95 break;
96
97 case '=':
98 qbIn.seek( 1 );
99 return new Token( tokCompute );
100
101 case '(':
102 qbIn.seek( 1 );
103 return new Token( tokOpenParen );
104
105 case ')':
106 qbIn.seek( 1 );
107 return new Token( tokCloseParen );
108
109 case '.':
110 case '0':
111 case '1':
112 case '2':
113 case '3':
114 case '4':
115 case '5':
116 case '6':
117 case '7':
118 case '8':
119 case '9':
120 {
121 Bu::FString sTmp;
122 sTmp += b;
123 qbIn.seek( 1 );
124 for(;;)
125 {
126 qbIn.peek( &b, 1 );
127 if( b != '.' && (b < '0' || b > '9') )
128 {
129 sio << "!! Convert '" << sTmp << "' to "
130 << strtod( sTmp.getStr(), NULL ) << sio.nl;
131 return new Token(
132 tokNumber, strtod( sTmp.getStr(), NULL )
133 );
134 }
135 qbIn.seek( 1 );
136 sTmp += b;
137 }
138 }
139 break;
140
141 default:
142 throw Bu::ExceptionBase("Unexpected character '%c'.", b );
143 }
144 }
145 }
146
147private:
148 Bu::Stream &rSrc;
149 QueueBuf qbIn;
150};
151
152int main( int argc, char *argv[] )
153{
154 File fIn( argv[1], File::Read );
155
156 Parser p;
157
158 p.pushLexer( new MathLexer( fIn ) );
159
160 p.parse();
161
162 return 0;
163}
164