diff options
author | Mike Buland <eichlan@xagasoft.com> | 2007-02-17 16:31:55 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2007-02-17 16:31:55 +0000 |
commit | 89eeeff54f0b3ce30be5b046fc3899fdeb5ebb40 (patch) | |
tree | a4a8fc2e184df736f61c1dea1e8627dd3667b071 /src/formula.cpp | |
parent | 27c626112a7114f9bdc4f7739f9ec05ae9fcbee1 (diff) | |
download | libbu++-89eeeff54f0b3ce30be5b046fc3899fdeb5ebb40.tar.gz libbu++-89eeeff54f0b3ce30be5b046fc3899fdeb5ebb40.tar.bz2 libbu++-89eeeff54f0b3ce30be5b046fc3899fdeb5ebb40.tar.xz libbu++-89eeeff54f0b3ce30be5b046fc3899fdeb5ebb40.zip |
Tweaked the stream classes, added an example, and the begining of a formula
parser.
Diffstat (limited to 'src/formula.cpp')
-rw-r--r-- | src/formula.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/src/formula.cpp b/src/formula.cpp new file mode 100644 index 0000000..7cc1804 --- /dev/null +++ b/src/formula.cpp | |||
@@ -0,0 +1,157 @@ | |||
1 | #include "formula.h" | ||
2 | |||
3 | subExceptionDef( ParseException ); | ||
4 | |||
5 | Formula::Formula() | ||
6 | { | ||
7 | } | ||
8 | |||
9 | Formula::~Formula() | ||
10 | { | ||
11 | } | ||
12 | |||
13 | double Formula::run( const char *sFormula ) | ||
14 | { | ||
15 | sBuf.write( sFormula, strlen( sFormula ) ); | ||
16 | sBuf.setPos( 0 ); | ||
17 | |||
18 | nState = 0; | ||
19 | for(;;) | ||
20 | { | ||
21 | tLook = nextToken(); | ||
22 | if( tLook.nSym == symEOS ) | ||
23 | break; | ||
24 | state(); | ||
25 | } | ||
26 | printf("\n"); | ||
27 | return 0.0; | ||
28 | } | ||
29 | |||
30 | void Formula::state() | ||
31 | { | ||
32 | switch( nState ) | ||
33 | { | ||
34 | case 0: // initial expr | ||
35 | switch( tLook.nSym ) | ||
36 | { | ||
37 | case symNumber: | ||
38 | push(); | ||
39 | nState = 1; | ||
40 | break; | ||
41 | } | ||
42 | break; | ||
43 | |||
44 | case 1: // binary operator | ||
45 | switch( tLook.nSym ) | ||
46 | { | ||
47 | case symAdd: | ||
48 | case symSubtract: | ||
49 | push(); | ||
50 | nState = 2; | ||
51 | break; | ||
52 | |||
53 | case symMultiply: | ||
54 | case symDivide: | ||
55 | push(); | ||
56 | nState = 3; | ||
57 | break; | ||
58 | } | ||
59 | break; | ||
60 | |||
61 | case 2: // add/subtract | ||
62 | break; | ||
63 | } | ||
64 | } | ||
65 | |||
66 | void Formula::push() | ||
67 | { | ||
68 | printToken( tLook ); | ||
69 | sToken.push( tLook ); | ||
70 | } | ||
71 | |||
72 | Formula::Token Formula::nextToken() | ||
73 | { | ||
74 | char cbuf; | ||
75 | for(;;) | ||
76 | { | ||
77 | if( sBuf.isEOS() ) | ||
78 | return Token( symEOS ); | ||
79 | |||
80 | sBuf.read( &cbuf, 1 ); | ||
81 | switch( cbuf ) | ||
82 | { | ||
83 | case '+': | ||
84 | return Token( symAdd ); | ||
85 | |||
86 | case '-': | ||
87 | return Token( symSubtract ); | ||
88 | |||
89 | case '*': | ||
90 | return Token( symMultiply ); | ||
91 | |||
92 | case '/': | ||
93 | return Token( symDivide ); | ||
94 | |||
95 | case '(': | ||
96 | return Token( symOpenParen ); | ||
97 | |||
98 | case ')': | ||
99 | return Token( symCloseParen ); | ||
100 | |||
101 | case ' ': | ||
102 | case '\t': | ||
103 | case '\n': | ||
104 | case '\r': | ||
105 | break; | ||
106 | |||
107 | default: | ||
108 | if( cbuf == '.' || (cbuf >= '0' && cbuf <= '9') ) | ||
109 | { | ||
110 | char num[50]; | ||
111 | int nPos = 0; | ||
112 | bool bDot = false; | ||
113 | |||
114 | for(;;) | ||
115 | { | ||
116 | num[nPos++] = cbuf; | ||
117 | if( cbuf == '.' ) | ||
118 | { | ||
119 | if( bDot == false ) | ||
120 | bDot = true; | ||
121 | else | ||
122 | throw ParseException( | ||
123 | "Numbers cannot have more than one " | ||
124 | ". in them." | ||
125 | ); | ||
126 | } | ||
127 | sBuf.read( &cbuf, 1 ); | ||
128 | if( (cbuf != '.' && (cbuf < '0' || cbuf > '9')) || | ||
129 | sBuf.isEOS() ) | ||
130 | { | ||
131 | if( !sBuf.isEOS() ) sBuf.seek( -1 ); | ||
132 | num[nPos] = '\0'; | ||
133 | return Token( symNumber, strtod( num, NULL ) ); | ||
134 | } | ||
135 | } | ||
136 | } | ||
137 | break; | ||
138 | } | ||
139 | } | ||
140 | } | ||
141 | |||
142 | void Formula::printToken( Token &tok ) | ||
143 | { | ||
144 | switch( tok.nSym ) | ||
145 | { | ||
146 | case symEOS: printf("[EOS] "); break; | ||
147 | case symAdd: printf("+ "); break; | ||
148 | case symSubtract: printf("- "); break; | ||
149 | case symMultiply: printf("* "); break; | ||
150 | case symDivide: printf("/ "); break; | ||
151 | case symOpenParen: printf("( "); break; | ||
152 | case symCloseParen: printf(") "); break; | ||
153 | case symNumber: printf("%f ", tok.val.num ); break; | ||
154 | default: printf("??? "); break; | ||
155 | } | ||
156 | } | ||
157 | |||