CBMC
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
statement_list_parser.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: Statement List Language Parser
4
5Author: Matthias Weiss, matthias.weiss@diffblue.com
6
7\*******************************************************************/
8
11
13
14#include <util/std_code.h>
16
19
20#include <algorithm>
21#include <iostream>
22#include <iterator>
23
25
31static irep_idt find_name(const exprt &root)
32{
33 for(const exprt &op : root.operands())
34 {
36 return op.get(ID_value);
37 }
38 UNREACHABLE; // Root expression should always have a name
39}
40
42{
43 const exprt::operandst &ops = tag_list.operands();
45 begin(ops),
46 end(ops),
47 std::back_inserter(parse_tree.tags),
48 static_cast<const symbol_exprt &(*)(const exprt &)>(to_symbol_expr));
49}
50
56static std::string find_version(const exprt &root)
57{
58 for(const exprt &op : root.operands())
59 {
61 {
62 const string_constantt &constant{to_string_constant(op)};
63 return id2string(constant.value());
64 }
65 }
66 UNREACHABLE; // Root expression should always have a version
67}
68
74static typet find_return_value(const exprt &root)
75{
78 "Expression ID should be statement_list_function");
79
80 for(const exprt &op : root.operands())
81 {
83 return op.type();
84 }
85
86 UNREACHABLE; // Root expression of FC should always have a return value
87}
88
94static exprt find_variable_list(const exprt &root)
95{
96 for(const exprt &op : root.operands())
97 {
98 if(op.id() == ID_statement_list_var_decls)
99 return op;
100 }
101 UNREACHABLE; // Root expression should always have a variable list
102}
103
111 const exprt &var_list)
112{
113 for(const exprt &entry : var_list.operands())
114 {
115 std::vector<symbol_exprt> symbols;
116 exprt default_value = nil_exprt();
117 for(const exprt &part : entry.operands())
118 {
119 const symbol_exprt *const symbol =
121 if(symbol)
122 symbols.push_back(*symbol);
123 else
124 default_value = part;
125 }
126
127 for(const symbol_exprt &symbol : symbols)
128 {
130 if(default_value.is_not_nil())
131 declaration.default_value = default_value;
132 parse_tree_list.push_back(declaration);
133 }
134 }
135}
136
141static void fill_temp_vars(
143 const exprt &temp_vars)
144{
145 for(const exprt &entry : temp_vars.operands())
146 {
147 for(const exprt &part : entry.operands())
148 {
149 const symbol_exprt *const symbol =
151 if(symbol)
152 {
154 parse_tree_list.push_back(declaration);
155 }
156 else
157 UNREACHABLE; // Temp variables should not have an initial value.
158 }
159 }
160}
161
165static void find_variables(
167 const exprt &var_decls)
168{
169 for(const exprt &decls : var_decls.operands())
170 {
173 else if(decls.id() == ID_statement_list_var_inout)
175 else if(decls.id() == ID_statement_list_var_output)
179 else if(decls.id() == ID_statement_list_var_temp)
180 fill_temp_vars(function.var_temp, decls);
181 }
182}
183
207
213static exprt find_network_list(const exprt &root)
214{
215 for(const exprt &op : root.operands())
216 {
217 if(op.id() == ID_statement_list_networks)
218 return op;
219 }
220 UNREACHABLE; // Root expression should always have a network list
221}
222
227static std::string find_network_title(const exprt &network)
228{
229 for(const exprt &network_element : network.operands())
230 {
232 return network_element.get(ID_value).c_str();
233 }
234 UNREACHABLE; // Network expression should always have a title
235}
236
243{
244 for(const exprt &network_element : network.operands())
245 {
247 return network_element;
248 }
249 UNREACHABLE; // Network expression should always have an instruction list
250}
251
257 const exprt &instructions)
258{
259 for(const exprt &instruction_expr : instructions.operands())
260 {
262
265 for(auto op_it = std::next(instruction_expr.operands().begin());
266 op_it != end(instruction_expr.operands());
267 ++op_it)
268 {
270 label = to_string_constant(*op_it);
271 else if(op_it->is_not_nil())
272 code_token.add_to_operands(*op_it);
273 }
274
275 if(label.value() == ID_nil)
276 instruction.add_token(code_token);
277 else
278 instruction.add_token(code_labelt{label.value(), code_token});
279
280 network.add_instruction(instruction);
281 }
282}
283
288static void find_networks(
290 const exprt &network_list)
291{
292 for(const exprt &expr_network : network_list.operands())
293 {
294 const std::string title(find_network_title(expr_network));
296 const exprt instructions = find_network_instructions(expr_network);
297 find_instructions(network, instructions);
298 module.add_network(network);
299 }
300}
301
303{
304 INVARIANT(
306 "Root expression ID should be ID_statement_list_function_block");
307
308 // Generate new function block.
310 find_version(block)};
311
312 // Fill the block with networks and variables.
315
317}
318
320{
321 INVARIANT(
322 function.id() == ID_statement_list_function,
323 "Expression ID should be statement_list_function");
324
325 // Generate new function.
327 find_name(function), find_version(function), find_return_value(function)};
328
329 // Fill the function with networks and variables.
332
334}
335
342
344{
345 void *scanner;
347#ifdef STATEMENT_LIST_DEBUG
349#endif
350 bool parse_fail = yystatement_listparse(*this, scanner) != 0;
352 return parse_fail;
353}
354
355void statement_list_parsert::print_tree(std::ostream &out) const
356{
358}
359
static abstract_object_pointert transform(const exprt &expr, const std::vector< abstract_object_pointert > &operands, const abstract_environmentt &environment, const namespacet &ns)
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
Definition ai.h:562
codet representation of a label for branch targets.
Definition std_code.h:959
Data structure for representing an arbitrary statement in a program.
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition dstring.h:38
Base class for all expressions.
Definition expr.h:56
std::vector< exprt > operandst
Definition expr.h:58
operandst & operands()
Definition expr.h:94
bool is_not_nil() const
Definition irep.h:372
const irep_idt & id() const
Definition irep.h:388
The NIL expression.
Definition std_expr.h:3208
Intermediate representation of a parsed Statement List file before converting it into a goto program.
std::list< var_declarationt > var_declarationst
void add_function_block(function_blockt &block)
Adds a function block to the parse tree.
std::vector< symbol_exprt > tags
List of tags that were included in the source.
void add_function(functiont &function)
Adds a function to the parse tree.
void swap(statement_list_parse_treet &other)
Swaps the contents of the parse tree with the parameter.
Responsible for starting the parse process and to translate the result into a statement_list_parse_tr...
statement_list_parse_treet parse_tree
Tree that is being filled by the parsing process.
void add_tag_list(const exprt &tag_list)
Adds a tag list to the parse tree by converting the tag_list expression tree.
void add_function_block(const exprt &block)
Adds a function block to the parse tree by converting the block expression tree.
void print_tree(std::ostream &out) const
Prints the parse tree of this instance to the given output stream.
void add_function(const exprt &function)
Adds a function to the parse tree by converting the function expression tree.
void swap_tree(statement_list_parse_treet &other)
Swaps the contents of the parse tree of this instance with other.
bool parse() override
Starts the parsing process and saves the result inside of this instance's parse tree.
Expression to hold a symbol (variable)
Definition std_expr.h:131
The type of an expression, extends irept.
Definition type.h:29
std::unordered_set< symbol_exprt, irep_hash > find_variables(const std::vector< exprt > &src)
Returns the set of program variables (as identified by object_address expressions) in the given expre...
const std::string & id2string(const irep_idt &d)
Definition irep.h:44
#define UNREACHABLE
This should be used to mark dead code.
Definition invariant.h:525
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.
Definition invariant.h:423
Statement List Language Parse Tree.
void output_parse_tree(std::ostream &out, const statement_list_parse_treet &parse_tree)
Prints the given Statement List parse tree in a human-readable form to the given output stream.
Statement List Language Parse Tree Output.
static void find_variables(statement_list_parse_treet::functiont &function, const exprt &var_decls)
Adds all valid variable declarations to the given function.
static std::string find_version(const exprt &root)
Searches for the version of the TIA module inside of its root expression.
void yystatement_listset_debug(int, void *)
static exprt find_network_instructions(const exprt &network)
Searches for the instruction list of a network inside of its root expression.
static void find_instructions(statement_list_parse_treet::networkt &network, const exprt &instructions)
Adds all valid instructions to the given network.
static void find_networks(statement_list_parse_treet::tia_modulet &module, const exprt &network_list)
Adds all valid networks and their instructions to the given function element.
static exprt find_network_list(const exprt &root)
Searches for the network list of the TIA element inside of its root expression.
static std::string find_network_title(const exprt &network)
Searches for the title of a network inside of its root expression.
int yystatement_listlex_init_extra(statement_list_parsert *, void **)
static exprt find_variable_list(const exprt &root)
Searches for the variable list of the TIA module inside of its root expression.
int yystatement_listparse(statement_list_parsert &, void *)
Defined in statement_list_y.tab.cpp.
static irep_idt find_name(const exprt &root)
Searches for the name of the TIA module inside of its root expression.
static void fill_temp_vars(statement_list_parse_treet::var_declarationst &parse_tree_list, const exprt &temp_vars)
Adds all temp variable declarations (variable declarations which can't have a default value) to the g...
static typet find_return_value(const exprt &root)
Searches for the return type of a function inside of its root expression.
static void fill_vars_with_default_values(statement_list_parse_treet::var_declarationst &parse_tree_list, const exprt &var_list)
Adds all variable declarations (which can have a default value) to the given list.
int yystatement_listlex_destroy(void *)
Statement List Language Parser.
const multi_ary_exprt & to_multi_ary_expr(const exprt &expr)
Cast an exprt to a multi_ary_exprt.
Definition std_expr.h:987
const symbol_exprt & to_symbol_expr(const exprt &expr)
Cast an exprt to a symbol_exprt.
Definition std_expr.h:272
const string_constantt & to_string_constant(const exprt &expr)
Structure for a simple function block in Statement List.
var_declarationst var_static
FB-exclusive static variable declarations.
Structure for a simple function in Statement List.
Represents a regular Statement List instruction which consists out of one or more codet tokens.
void add_token(const codet &token)
Adds a codet element to the list of all tokens.
Representation of a network in Siemens TIA.
Base element of all modules in the Totally Integrated Automation (TIA) portal by Siemens.
var_declarationst var_constant
Constant variable declarations.
var_declarationst var_input
Input variable declarations.
var_declarationst var_inout
Inout variable declarations.
var_declarationst var_temp
Temp variable declarations.
var_declarationst var_output
Output variable declarations.
Struct for a single variable declaration in Statement List.
std::optional< exprt > default_value
Optional default value of the variable.