ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
st_fb_translator.h
Go to the documentation of this file.
1#pragma once
2
5#include <functional>
6#include <string>
7
8// -----------------------------------------------------------------------
9// st_fb_translator — minimal IEC 61131-3 Structured Text -> codet translator
10// for user-defined function-block bodies referenced by a Ladder Diagram.
11//
12// Supports the ST subset used by FB bodies in practice:
13// assignment IDENT := expr ;
14// conditional IF cond THEN stmt* END_IF ;
15// loop WHILE cond DO stmt* END_WHILE ; (kept as a real loop so
16// ESBMC's unwinding
17// assertions detect a
18// non-terminating LLB)
19// expr IDENT | INT_LIT | TRUE | FALSE | NOT expr | expr <op> expr
20// boolean OR XOR AND (&), on BOOL operands
21// relop = < <= > >= <>
22// arith + - * /
23// Precedence, lowest first, follows IEC 61131-3: OR, XOR, AND, comparison,
24// + -, * /, NOT.
25// Keywords are case-insensitive. This is deliberately small: it is enough to
26// faithfully translate the function-block bodies that carry Ladder Logic Bombs
27// (comparison/arithmetic guards plus a non-termination payload) so that the
28// bomb logic reaches the GOTO IR. Unsupported constructs throw.
29// -----------------------------------------------------------------------
30
32{
33public:
34 // resolve(name) returns the typed symbol_exprt for an identifier; the caller
35 // (ld_converter) declares one symbol per FB-local variable and supplies this.
36 using resolver_t = std::function<symbol_exprt(const std::string &)>;
37
38 explicit st_fb_translator(resolver_t resolve) : resolve_(std::move(resolve))
39 {
40 }
41
42 // Translate a whole FB body into a code_blockt.
43 code_blockt translate(const std::string &body);
44
45private:
46 resolver_t resolve_;
47 std::string src_;
48 size_t pos_ = 0;
49 int wd_counter_ = 0; // unique scan-watchdog counter id per loop
50
51 // lexer
52 void skip_ws();
53 bool eof();
54 std::string peek_word(); // next identifier/keyword (lowercased), no consume
55 std::string next_word(); // consume identifier/keyword (original case)
56 bool
57 accept_kw(const char *kw); // consume if next word == kw (case-insensitive)
58 void expect_kw(const char *kw);
59 bool accept_sym(const char *s); // consume punctuation/operator if it matches
60 void expect_sym(const char *s);
61
62 // parser -> codet/exprt
63 void parse_stmt_list(code_blockt &out, const char *const *terminators);
64 codet parse_stmt();
65 exprt parse_condition(); // OR, the loosest level
66 exprt parse_xor();
67 exprt parse_and();
68 exprt parse_comparison();
69 exprt parse_expr(); // additive (+ -), left-assoc
70 exprt parse_term(); // multiplicative (* /), binds tighter than + -
71 exprt parse_unary(); // NOT
72 exprt parse_primary();
73};
Definition std_code.h:49
Definition std_code.h:8
Definition expr.h:34
st_fb_translator(resolver_t resolve)
Definition st_fb_translator.h:38
std::function< symbol_exprt(const std::string &)> resolver_t
Definition st_fb_translator.h:36
code_blockt translate(const std::string &body)
Definition st_fb_translator.cpp:701
Definition std_expr.h:58
Definition exception.cpp:51
static size_t skip_ws(const std::vector< token > &toks, size_t idx)
Definition nested_func_transform.cpp:264