-
Notifications
You must be signed in to change notification settings - Fork 2
/
parser.h
98 lines (86 loc) · 2.1 KB
/
parser.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#pragma once
#include "lexer.h"
#include <cstdio>
#include <initializer_list>
#include <memory>
#define PARSER_DEBUG
namespace skan {
class Parser {
private:
std::shared_ptr<Lexer> lexer_;
std::shared_ptr<Token> token_;
std::shared_ptr<SymbolTable> symbol_table_;
std::shared_ptr<IRGenerator> ir_generator_;
void Move() {
token_ = lexer_.Tokenize();
#ifdef PARSER_DEBUG
std::printf("%s\n", token_->ToString().c_str());
std::fflush(stdout);
#endif
}
bool Match(Tag tag) { return token_->GetTag() == tag; }
bool MatchThenMove(Tag tag) {
if (Match(tag)) {
Move();
return true;
} else {
return false;
}
}
bool IsType() { return Token::IsType(token_->GetTag()); }
bool IsTag(std::initializer_list<Tag> tags) {
for (auto tag : tags) {
if (token_->GetTag() == tag)
return true;
}
return false;
}
void RecoverFromError(bool condition, SyntaxError lost_error,
SyntaxError wrong_error) {
if (condition) {
PrintSyntaxError(lost_error, token_);
} else {
PrintSyntaxError(wrong_error, token_);
Move();
}
}
// <program>-><segment><program>
void ParseProgram() {
if (Match(END)) {
return;
} else {
ParseSegment();
ParseProgram();
}
}
// <segment>->kw_extern <type><def> | <type><def>
void ParseSegment() {
bool has_extern = MatchThenMove(KW_EXTERN);
Tag tag = ParseType();
ParseDef(has_extern, tag);
}
// <type>->kw_int | kw_char | kw_void
Tag ParseType() {
if (IsType()) {
Move();
return token_->GetTag();
} else {
RecoverFromError(IsTag({ID,MUL}),TYPE_LOST, TYPE_WRONG);
return KW_INT;
}
}
public:
Parser(const Parser &) = delete;
Parser &operator=(const Parser &) = delete;
~Parser = default;
Parser(std::shared_ptr<Lexer> lexer,
std::shared_ptr<SymbolTable> symbol_table,
std::shared_ptr<IRGenerator> ir_generator)
: lexer_(lexer), symbol_table_(symbol_table),
ir_generator_(ir_generator) {}
void Parse() {
Move();
ParseProgram();
}
};
} // namespace skan