Skip to content

Commit f93ff05

Browse files
committed
wip
1 parent b2ea1db commit f93ff05

File tree

3 files changed

+159
-9
lines changed

3 files changed

+159
-9
lines changed

src/parser/hawk/huppaal/parser.cpp

Lines changed: 154 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,42 @@
2020
#include <fstream>
2121
#include <nlohmann/json.hpp>
2222
#include <spdlog/spdlog.h>
23-
#include "parser/hawk/scoped_template_builder/scoped_template_builder.h"
23+
#include "lsp.pb.h"
2424
#include "plugin_system/plugin_system.h"
2525

2626
namespace aaltitoad::hawk::huppaal {
27+
// TODO: Move the sections into a separate file each
28+
diagnostic json_error(const std::string& filepath, const std::string& err) {
29+
return {
30+
.identifier="json_error",
31+
.title="JSON error in file: " + filepath,
32+
.message="unable to parse json: " + err,
33+
.description="JSON model files must be of a specific format", // TODO: jsomschema validation
34+
.severity=Severity::SEVERITY_ERROR
35+
};
36+
}
37+
38+
static diagnostic no_main{
39+
.identifier="no_main",
40+
.title="No main template",
41+
.message="Could not find a template marked as \"main\"",
42+
.description="A valid network of TTAs must have at least one template marked as the main template",
43+
.severity=Severity::SEVERITY_ERROR
44+
};
45+
46+
/* =============================== */
47+
48+
auto any_errors(const std::vector<Diagnostic>& ds) -> bool {
49+
for(auto& d : ds)
50+
if(d.severity() == Severity::SEVERITY_ERROR)
51+
return true;
52+
return false;
53+
}
54+
2755
auto huppaal_scanner::scan(compiler& ctx, const std::vector<std::string>& filepaths, const std::vector<std::string>& ignore_list) const noexcept -> std::expected<scanner::ok, error_t> {
28-
return std::unexpected(error_t({ctx.diag(not_implemented_yet())}));
29-
scoped_template_builder builder{};
56+
std::vector<Diagnostic> diagnostics{};
57+
std::vector<scanning::template_t> templates{};
58+
std::vector<std::string> extra_declarations{};
3059
for(const auto& filepath : filepaths) {
3160
for(const auto &entry: std::filesystem::directory_iterator(filepath)) {
3261
try {
@@ -42,18 +71,136 @@ namespace aaltitoad::hawk::huppaal {
4271
/* ignore_comments */ true);
4372
if(json_file.contains("name")) {
4473
spdlog::trace("loading file {0}", entry.path().c_str());
45-
builder.add_template(json_file.get<tta_template>());
74+
templates.push_back(scan_template(entry.path(), json_file));
4675
} else if(json_file.contains("parts")) {
4776
spdlog::trace("loading parts file {0}", entry.path().c_str());
48-
builder.add_global_symbols(json_file.at("parts").get<std::vector<part_t>>());
77+
extra_declarations.push_back(scan_parts(json_file));
4978
} else
5079
spdlog::trace("ignoring file {0} (not a valid model file)", entry.path().c_str());
5180
} catch (std::exception& e) {
5281
spdlog::error("unable to parse json file {0}: {1}", entry.path().c_str(), e.what());
53-
throw;
82+
diagnostics.push_back(ctx.get_diagnostic_factory().without_context().create_diagnostic(json_error(entry.path(), e.what())));
5483
}
5584
}
5685
}
86+
87+
if(!extra_declarations.empty()) {
88+
auto main = std::find_if(templates.begin(), templates.end(), [](const scanning::template_t& t) {
89+
return std::find_if(t.modifiers.begin(), t.modifiers.end(), [](const std::string& m) {
90+
return m == "main";
91+
}) != t.modifiers.end();
92+
});
93+
if(main != templates.end())
94+
main->declarations.insert(main->declarations.end(), extra_declarations.begin(), extra_declarations.end());
95+
}
96+
return scanner::ok{
97+
.templates=templates,
98+
.diagnostics=diagnostics
99+
};
100+
}
101+
102+
auto scan_vertex(const nlohmann::json& t) -> scanning::vertex {
103+
std::string type{};
104+
std::vector<std::string> modifiers{};
105+
std::string tt = lower_case(t["type"]);
106+
if(tt == "normal")
107+
type = "location";
108+
if(tt == "initial") {
109+
type = "location";
110+
modifiers.push_back("initial");
111+
}
112+
if(tt == "final") {
113+
type = "location";
114+
modifiers.push_back("final");
115+
}
116+
return scanning::vertex{
117+
.identifer=t["id"],
118+
.type=type,
119+
.modifiers=modifiers,
120+
.debug={
121+
.name=t["nickname"],
122+
.position=position{
123+
.x=t["x"],
124+
.y=t["y"]
125+
}
126+
}
127+
};
128+
}
129+
130+
auto scan_edge(const nlohmann::json& t) -> scanning::edge {
131+
std::optional<std::string> guard{};
132+
if(t["guard"] != "")
133+
guard = t["guard"];
134+
std::optional<std::string> update{};
135+
if(t["update"] != "")
136+
guard = t["update"];
137+
return scanning::edge{
138+
.identifier=t["uuid"],
139+
.source=t["source_location"],
140+
.guard=guard,
141+
.update=update,
142+
.target=t["target_location"],
143+
.debug={}
144+
};
145+
}
146+
147+
auto huppaal_scanner::scan_template(const std::string& filepath, const nlohmann::json& t) const -> scanning::template_t {
148+
std::vector<scanning::vertex> vertices{};
149+
for(auto& v : t["vertices"])
150+
vertices.push_back(scan_vertex(v));
151+
vertices.push_back(scan_vertex(t["initial_location"]));
152+
vertices.push_back(scan_vertex(t["final_location"]));
153+
154+
std::vector<scanning::edge> edges{};
155+
for(auto& e : t["edges"])
156+
edges.push_back(scan_edge(e));
157+
158+
std::vector<std::string> declarations{};
159+
declarations.push_back(t["declarations"]);
160+
161+
std::vector<std::string> modifiers{};
162+
if(t["main"].is_boolean() && t["main"] == true)
163+
modifiers.push_back("main");
164+
165+
return scanning::template_t{
166+
.identifier=ya::uuid_v4(),
167+
.signature=t["name"],
168+
.declarations=declarations,
169+
.vertices=vertices,
170+
.edges=edges,
171+
.modifiers=modifiers,
172+
.debug={
173+
.name=t["name"],
174+
.filepath=filepath
175+
}
176+
};
177+
}
178+
179+
auto scan_part(const nlohmann::json& p) -> std::string {
180+
std::string id = p["ID"];
181+
std::string type = lower_case(p["Type"]);
182+
if(p.contains("ValueType"))
183+
type = lower_case(p["ValueType"]);
184+
nlohmann::json initial_value{};
185+
if(type == "timer")
186+
initial_value = 0;
187+
if(p.contains("Value"))
188+
initial_value = p["Value"];
189+
190+
// TODO: consider adding an "external/extern" keyword to expr.
191+
std::stringstream ss{};
192+
if(type == "timer") // TODO: https://github.com/sillydan1/expr/issues/21
193+
ss << "public " << type << " " << id << " := 0_ms ;";
194+
else
195+
ss << "public " << type << " " << id << " := " << initial_value << " ;";
196+
return ss.str();
197+
}
198+
199+
auto huppaal_scanner::scan_parts(const nlohmann::json& t) const -> std::string {
200+
std::stringstream ss{};
201+
for(auto& p : t["parts"])
202+
ss << scan_part(p) << "\n";
203+
return ss.str();
57204
}
58205

59206
auto huppaal_scanner::should_ignore(const std::filesystem::directory_entry& entry, const std::vector<std::string>& ignore_list) const -> bool {
@@ -109,7 +256,7 @@ extern "C" {
109256
}
110257

111258
const char* get_plugin_version() {
112-
return "v1.1.0";
259+
return "v2.0.0";
113260
}
114261

115262
plugin_type get_plugin_type() {

src/parser/hawk/huppaal/parser.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ namespace aaltitoad::hawk::huppaal {
3333
private:
3434
auto should_ignore(const std::filesystem::directory_entry& entry, const std::vector<std::string>& ignore_list) const -> bool;
3535
auto should_ignore(const std::filesystem::directory_entry& entry, const std::string& ignore_regex) const -> bool;
36+
37+
auto scan_template(const std::string& filepath, const nlohmann::json& t) const -> scanning::template_t;
38+
auto scan_parts(const nlohmann::json& t) const -> std::string;
3639
};
3740

3841
class huppaal_parser : public aaltitoad::hawk::parser {

src/parser/hawk/model.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace aaltitoad::hawk {
3838
struct template_t {
3939
std::string identifier;
4040
std::string signature;
41-
std::optional<std::string> declarations;
41+
std::vector<std::string> declarations;
4242
std::vector<vertex> vertices;
4343
std::vector<edge> edges;
4444
std::vector<std::string> modifiers; // e.g. "MAIN"
@@ -104,7 +104,7 @@ namespace aaltitoad::hawk {
104104
struct template_t {
105105
std::string identifier;
106106
std::string signature;
107-
std::optional<std::string> declarations; // TODO: should be expr compiled tree
107+
std::vector<std::string> declarations; // TODO: should be expr compiled trees
108108
std::vector<location> locations;
109109
std::vector<edge> edges;
110110
std::vector<template_modifier> modifiers;

0 commit comments

Comments
 (0)