Skip to content

Commit 3060b54

Browse files
author
Dwight Guth
authored
Write streaming event parser for proof hints (#1069)
This is a pretty straightforward diff. We can reuse the code for parsing events and the proof trace header, so we just need to create an entry point to the streaming parser that invokes the relevant parsing logic and returns events one at a time, and then write code to test it. We test it by modifying lit tests that test the proof hints so that they test both parsers. This means we get the advantage of the entire coverage set of tests that we imported from the math proof repo.
1 parent 6a33aa0 commit 3060b54

File tree

4 files changed

+104
-0
lines changed

4 files changed

+104
-0
lines changed

include/kllvm/binary/ProofTraceParser.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,13 @@ class llvm_event {
234234
unsigned indent = 0U) const;
235235
};
236236

237+
enum class llvm_event_type { PreTrace, InitialConfig, Trace };
238+
239+
struct annotated_llvm_event {
240+
llvm_event_type type{};
241+
llvm_event event;
242+
};
243+
237244
class llvm_rewrite_trace {
238245
private:
239246
uint32_t version_{};
@@ -651,6 +658,23 @@ class proof_trace_parser {
651658
std::optional<llvm_rewrite_trace>
652659
parse_proof_trace_from_file(std::string const &filename);
653660
std::optional<llvm_rewrite_trace> parse_proof_trace(std::string const &data);
661+
662+
friend class llvm_rewrite_trace_iterator;
663+
};
664+
665+
class llvm_rewrite_trace_iterator {
666+
private:
667+
uint32_t version_{};
668+
proof_trace_buffer &buffer_;
669+
llvm_event_type type_ = llvm_event_type::PreTrace;
670+
proof_trace_parser parser_;
671+
672+
public:
673+
llvm_rewrite_trace_iterator(
674+
proof_trace_buffer &buffer, kore_header const &header);
675+
[[nodiscard]] uint32_t get_version() const { return version_; }
676+
std::optional<annotated_llvm_event> get_next_event();
677+
void print(std::ostream &out, bool expand_terms, unsigned indent = 0U);
654678
};
655679

656680
} // namespace kllvm

lib/binary/ProofTraceParser.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,59 @@ void llvm_event::print(
115115
}
116116
}
117117

118+
llvm_rewrite_trace_iterator::llvm_rewrite_trace_iterator(
119+
proof_trace_buffer &buffer, kore_header const &header)
120+
: buffer_(buffer)
121+
, parser_(false, false, header) {
122+
if (!proof_trace_parser::parse_header(buffer_, version_)) {
123+
throw std::runtime_error("invalid header");
124+
}
125+
}
126+
127+
std::optional<annotated_llvm_event>
128+
llvm_rewrite_trace_iterator::get_next_event() {
129+
if (buffer_.eof()) {
130+
return std::nullopt;
131+
}
132+
switch (type_) {
133+
case llvm_event_type::PreTrace: {
134+
if (buffer_.has_word() && buffer_.peek_word() != config_sentinel) {
135+
llvm_event event;
136+
if (!parser_.parse_event(buffer_, event)) {
137+
throw std::runtime_error("could not parse pre-trace event");
138+
}
139+
return {{type_, event}};
140+
}
141+
uint64_t pattern_len = 0;
142+
auto config = parser_.parse_config(buffer_, pattern_len);
143+
if (!config) {
144+
throw std::runtime_error("could not parse config event");
145+
}
146+
llvm_event config_event;
147+
config_event.setkore_pattern(config, pattern_len);
148+
type_ = llvm_event_type::Trace;
149+
return {{llvm_event_type::InitialConfig, config_event}};
150+
}
151+
case llvm_event_type::Trace: {
152+
llvm_event event;
153+
if (!parser_.parse_event(buffer_, event)) {
154+
throw std::runtime_error("could not parse trace event");
155+
}
156+
return {{type_, event}};
157+
}
158+
default: throw std::runtime_error("should be unreachable");
159+
}
160+
}
161+
162+
void llvm_rewrite_trace_iterator::print(
163+
std::ostream &out, bool expand_terms, unsigned ind) {
164+
std::string indent(ind * indent_size, ' ');
165+
out << fmt::format("{}version: {}\n", indent, version_);
166+
while (auto event = get_next_event()) {
167+
event.value().event.print(out, expand_terms, false, ind);
168+
}
169+
}
170+
118171
void llvm_rewrite_trace::print(
119172
std::ostream &out, bool expand_terms, unsigned ind) const {
120173
std::string indent(ind * indent_size, ' ');

test/lit.cfg.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,12 @@ def one_line(s):
160160
echo "kore-proof-trace error while parsing proof hint trace with expanded kore terms"
161161
exit 1
162162
fi
163+
%kore-proof-trace --streaming-parser --verbose --expand-terms %t.header.bin %t.out.bin | diff - %test-proof-diff-out -q
164+
result="$?"
165+
if [ "$result" -ne 0 ]; then
166+
echo "kore-proof-trace error while parsing proof hint trace with expanded kore terms and streaming parser"
167+
exit 1
168+
fi
163169
''')),
164170

165171
('%check-dir-proof-out', one_line('''
@@ -175,6 +181,12 @@ def one_line(s):
175181
echo "kore-proof-trace error while parsing proof hint trace with expanded kore terms"
176182
exit 1
177183
fi
184+
%kore-proof-trace --streaming-parser --verbose --expand-terms %t.header.bin $hint | diff - $out
185+
result="$?"
186+
if [ "$result" -ne 0 ]; then
187+
echo "kore-proof-trace error while parsing proof hint trace with expanded kore terms and streaming parser"
188+
exit 1
189+
fi
178190
done
179191
''')),
180192

tools/kore-proof-trace/main.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ cl::opt<bool> expand_terms_in_output(
2727
"expand-terms", llvm::cl::desc("Expand KORE terms in the verbose output"),
2828
llvm::cl::cat(kore_proof_trace_cat));
2929

30+
cl::opt<bool> use_streaming_parser(
31+
"streaming-parser",
32+
llvm::cl::desc("Use streaming event parser to parse trace"),
33+
llvm::cl::cat(kore_proof_trace_cat));
34+
3035
int main(int argc, char **argv) {
3136
cl::HideUnrelatedOptions({&kore_proof_trace_cat});
3237
cl::ParseCommandLineOptions(argc, argv);
@@ -35,6 +40,16 @@ int main(int argc, char **argv) {
3540
kore_header header(in);
3641
fclose(in);
3742

43+
if (use_streaming_parser) {
44+
std::ifstream file(input_filename, std::ios_base::binary);
45+
proof_trace_file_buffer buffer(file);
46+
llvm_rewrite_trace_iterator it(buffer, header);
47+
if (verbose_output) {
48+
it.print(std::cout, expand_terms_in_output);
49+
}
50+
return 0;
51+
}
52+
3853
proof_trace_parser parser(verbose_output, expand_terms_in_output, header);
3954
auto trace = parser.parse_proof_trace_from_file(input_filename);
4055
if (trace.has_value()) {

0 commit comments

Comments
 (0)