Skip to content

Commit 226ee04

Browse files
committed
完成 part_1 的 exercise
1 parent 625d61f commit 226ee04

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

part_1/calc.cpp

+35-9
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@
99
#include <stdexcept>
1010
#include <limits>
1111
#include <string>
12+
#include <unordered_set>
1213

13-
enum TokenType { INTEGER, PLUS, END };
14+
enum TokenType { INTEGER, PLUS, MINUS, END };
1415

1516
class Token {
1617
friend std::ostream &operator<<(std::ostream &, const Token &);
@@ -38,8 +39,17 @@ class Interpreter {
3839

3940
inline void throwError() { throw std::runtime_error("Error parsing input"); }
4041

42+
// 跳过空格
43+
void eatWhitespace() {
44+
// 跳过符号开头部分的空格
45+
while (_pos < _text.size() && _text[_pos] == ' ') {
46+
++_pos;
47+
}
48+
}
49+
4150
// 一个简单的词法分析器(lexer)
4251
Token getNextToken() {
52+
eatWhitespace();
4353
if (_pos >= _text.size()) {
4454
return Token(END);
4555
}
@@ -54,15 +64,18 @@ class Interpreter {
5464
} else if (_text[start_pos] == '+') {
5565
++_pos;
5666
return Token(PLUS);
67+
} else if (_text[start_pos] == '-') {
68+
++_pos;
69+
return Token(MINUS);
5770
}
5871
throwError();
5972
// should not be here
6073
return Token(END);
6174
}
6275

6376
// 确保当前 token 的 type 为指定的 token_type,并且获取下一个 token
64-
void eatToken(const TokenType &token_type) {
65-
if (_current_token._type == token_type) {
77+
void eatToken(const std::unordered_set<TokenType> &types) {
78+
if (types.find(_current_token._type) != types.end()) {
6679
_current_token = getNextToken();
6780
return;
6881
}
@@ -77,22 +90,35 @@ class Interpreter {
7790
_current_token = getNextToken();
7891

7992
auto left = _current_token;
80-
eatToken(INTEGER);
93+
#ifdef DEBUG
94+
std::cout << "left: " << left << std::endl;
95+
#endif
96+
eatToken({INTEGER});
8197

8298
auto op = _current_token;
83-
eatToken(PLUS);
99+
#ifdef DEBUG
100+
std::cout << "op: " << op << std::endl;
101+
#endif
102+
eatToken({PLUS, MINUS});
84103

85104
auto right = _current_token;
86-
eatToken(INTEGER);
87-
88-
return left._value + right._value;
105+
#ifdef DEBUG
106+
std::cout << "right: " << right << std::endl;
107+
#endif
108+
eatToken({INTEGER});
109+
if (op._type == PLUS) {
110+
return left._value + right._value;
111+
} else if (op._type == MINUS) {
112+
return left._value - right._value;
113+
}
114+
return std::numeric_limits<int>::infinity();
89115
}
90116
};
91117

92118
int main() {
93119
std::string text;
94120

95-
while (std::cin >> text) {
121+
while (getline(std::cin, text)) {
96122
auto interpreter = Interpreter(text);
97123
std::cout << interpreter.expr() << std::endl;
98124
}

0 commit comments

Comments
 (0)