Skip to content

Commit 8aab101

Browse files
committed
feat: add const to states, implemented ParserFSM
1 parent 15dbbfc commit 8aab101

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+393
-52
lines changed

lib/parser/ParserFsm.cpp

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,65 @@
11
#include "ParserFsm.hpp"
22

3-
namespace ovum::compiler::parser {} // namespace ovum::compiler::parser
3+
#include <memory>
4+
#include <utility>
5+
6+
#include "context/ContextParser.hpp"
7+
#include "lib/parser/diagnostics/IDiagnosticSink.hpp"
8+
#include "lib/parser/states/base/IState.hpp"
9+
#include "lib/parser/states/base/StateError.hpp"
10+
#include "lib/parser/states/base/StateRegistry.hpp"
11+
#include "lib/parser/tokens/token_streams/ITokenStream.hpp"
12+
#include "recovery/SimpleRecovery.hpp"
13+
14+
namespace ovum::compiler::parser {
15+
16+
ParserFsm::ParserFsm(std::unique_ptr<IExpressionParser> expr,
17+
std::unique_ptr<ITypeParser> typep,
18+
std::unique_ptr<IAstFactory> factory) :
19+
expr_parser_(std::move(expr)), type_parser_(std::move(typep)), factory_(std::move(factory)) {
20+
}
21+
22+
std::unique_ptr<Module> ParserFsm::Parse(ITokenStream& token_stream, IDiagnosticSink& diagnostics) {
23+
ContextParser context;
24+
context.SetDiagnostics(&diagnostics);
25+
context.SetExpr(expr_parser_.get());
26+
context.SetTypeParser(type_parser_.get());
27+
context.SetFactory(factory_.get());
28+
29+
SimpleRecovery recovery;
30+
31+
context.PushState(StateRegistry::Module());
32+
33+
while (const IState* state = context.CurrentState()) {
34+
auto step = state->TryStep(context, token_stream);
35+
36+
if (!step.has_value()) {
37+
const auto& message = step.error().Message();
38+
diagnostics.Error("P0001", message.empty() ? "parse error" : message);
39+
recovery.SyncToStatementEnd(token_stream);
40+
context.PopState();
41+
continue;
42+
}
43+
44+
if (!*step) {
45+
context.PopState();
46+
}
47+
}
48+
49+
std::unique_ptr<AstNode> root = context.PopNode();
50+
51+
if (!root) {
52+
return std::make_unique<Module>();
53+
}
54+
55+
auto* as_module = dynamic_cast<Module*>(root.get());
56+
57+
if (as_module != nullptr) {
58+
root.release();
59+
return std::unique_ptr<Module>(as_module);
60+
}
61+
62+
return std::make_unique<Module>();
63+
}
64+
65+
} // namespace ovum::compiler::parser

lib/parser/context/ContextParser.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ const IState* ContextParser::CurrentState() const {
5050
if (state_stack_.empty()) {
5151
return nullptr;
5252
}
53-
5453
return state_stack_.back();
5554
}
5655

@@ -62,10 +61,9 @@ std::unique_ptr<AstNode> ContextParser::PopNode() {
6261
if (node_stack_.empty()) {
6362
return nullptr;
6463
}
65-
66-
auto out = node_stack_.back().ReleaseNode();
64+
auto node = node_stack_.back().ReleaseNode();
6765
node_stack_.pop_back();
68-
return out;
66+
return node;
6967
}
7068

7169
bool ContextParser::HasStates() const noexcept {
@@ -79,9 +77,14 @@ bool ContextParser::HasNodes() const noexcept {
7977
void ContextParser::Clear() {
8078
state_stack_.clear();
8179
node_stack_.clear();
82-
diags_ = nullptr;
83-
expr_ = nullptr;
84-
typep_ = nullptr;
80+
}
81+
82+
void ContextParser::SetFactory(IAstFactory* factory) {
83+
factory_ = factory;
84+
}
85+
86+
IAstFactory* ContextParser::Factory() const {
87+
return factory_;
8588
}
8689

8790
} // namespace ovum::compiler::parser

lib/parser/context/ContextParser.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ namespace ovum::compiler::parser {
1414
class AstNode;
1515
class IExpressionParser;
1616
class ITypeParser;
17+
class IAstFactory; // forward
1718

1819
template<class T>
1920
concept AstNodeDerived = std::is_base_of_v<AstNode, T>;
@@ -32,6 +33,9 @@ class ContextParser {
3233
void SetTypeParser(ITypeParser* parser);
3334
ITypeParser* TypeParser() const;
3435

36+
void SetFactory(IAstFactory* factory);
37+
IAstFactory* Factory() const;
38+
3539
void PushState(const IState& state);
3640
void PopState();
3741
const IState* CurrentState() const;
@@ -58,6 +62,7 @@ class ContextParser {
5862
IDiagnosticSink* diags_ = nullptr;
5963
IExpressionParser* expr_ = nullptr;
6064
ITypeParser* typep_ = nullptr;
65+
IAstFactory* factory_ = nullptr;
6166
};
6267

6368
} // namespace ovum::compiler::parser
Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,58 @@
1-
#include "SimpleRecovery.hpp"
1+
#include "lib/parser/recovery/SimpleRecovery.hpp"
22

3-
namespace ovum::compiler::parser {} // namespace ovum::compiler::parser
3+
#include <string_view>
4+
#include <tokens/Token.hpp>
5+
6+
namespace ovum::compiler::parser {
7+
namespace {
8+
bool IsLex(const Token& tok, std::string_view lex) {
9+
return tok.GetLexeme() == lex;
10+
}
11+
} // namespace
12+
13+
void SimpleRecovery::SyncToStmtEnd(ITokenStream& ts) {
14+
while (!ts.IsEof()) {
15+
const auto* look = ts.TryPeek();
16+
if (look == nullptr) {
17+
break;
18+
}
19+
if (IsLex(*look, "\n")) {
20+
ts.Consume();
21+
break;
22+
}
23+
if (IsLex(*look, ";")) {
24+
ts.Consume();
25+
break;
26+
}
27+
if (IsLex(*look, "}")) {
28+
break;
29+
}
30+
ts.Consume();
31+
}
32+
}
33+
34+
void SimpleRecovery::SyncToBlockEnd(ITokenStream& ts) {
35+
int depth = 0;
36+
while (!ts.IsEof()) {
37+
const auto* look = ts.TryPeek();
38+
if (look == nullptr) {
39+
break;
40+
}
41+
if (IsLex(*look, "{")) {
42+
++depth;
43+
ts.Consume();
44+
continue;
45+
}
46+
if (IsLex(*look, "}")) {
47+
ts.Consume();
48+
if (depth == 0) {
49+
break;
50+
}
51+
--depth;
52+
continue;
53+
}
54+
ts.Consume();
55+
}
56+
}
57+
58+
} // namespace ovum::compiler::parser

lib/parser/recovery/SimpleRecovery.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
55

66
namespace ovum::compiler::parser {
77

8-
class SimpleRecovery : IRecoveryStrategy {
8+
class SimpleRecovery : public IRecoveryStrategy {
99
public:
1010
~SimpleRecovery() override = default;
1111

1212
void SyncToStmtEnd(ITokenStream& ts) override;
1313
void SyncToBlockEnd(ITokenStream& ts) override;
14+
15+
void SyncToStatementEnd(ITokenStream& ts) {
16+
SyncToStmtEnd(ts);
17+
} // alias
1418
};
1519

1620
} // namespace ovum::compiler::parser

lib/parser/states/StateBlock.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ovum::compiler::parser {
99
class StateBlock : public StateBase {
1010
public:
1111
std::string_view Name() const override;
12-
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) override;
12+
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) const override;
1313
};
1414

1515
} // namespace ovum::compiler::parser

lib/parser/states/StateCallDeclHdr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ovum::compiler::parser {
99
class StateCallDeclHdr : public StateBase {
1010
public:
1111
std::string_view Name() const override;
12-
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) override;
12+
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) const override;
1313
};
1414

1515
} // namespace ovum::compiler::parser

lib/parser/states/StateDestructorDecl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ovum::compiler::parser {
99
class StateDestructorDecl : public StateBase {
1010
public:
1111
std::string_view Name() const override;
12-
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) override;
12+
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) const override;
1313
};
1414

1515
} // namespace ovum::compiler::parser

lib/parser/states/StateExpr.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ovum::compiler::parser {
99
class StateExpr : public StateBase {
1010
public:
1111
std::string_view Name() const override;
12-
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) override;
12+
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) const override;
1313
};
1414

1515
} // namespace ovum::compiler::parser

lib/parser/states/StateFieldDecl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ovum::compiler::parser {
99
class StateFieldDecl : public StateBase {
1010
public:
1111
std::string_view Name() const override;
12-
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) override;
12+
StepResult TryStep(ContextParser& ctx, ITokenStream& ts) const override;
1313
};
1414

1515
} // namespace ovum::compiler::parser

0 commit comments

Comments
 (0)