Newer
Older

Graziano Scalamera
committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
/*
* alarm_grammar.h
*
* $Author: $
*
* $Revision: $
*
* $Log: alarm_grammar.h,v $
*
*
* copyleft: Sincrotrone Trieste S.C.p.A. di interesse nazionale
* Strada Statale 14 - km 163,5 in AREA Science Park
* 34012 Basovizza, Trieste ITALY
*/
#ifndef ALARM_GRAMMAR_H_
#define ALARM_GRAMMAR_H_
//--------------------------NOTE!!---------------------------------
//----if a grammar is intended to be used in multithreaded code----
//----it is required to "#define BOOST_SPIRIT_THREADSAFE" and------
//----to link against Boost.Threads--------------------------------
//-----------------------------------------------------------------
#if BOOST_VERSION < 103600
#ifndef BOOST_SPIRIT_THREADSAFE
#define BOOST_SPIRIT_THREADSAFE
#endif
#ifndef PHOENIX_THREADSAFE
#define PHOENIX_THREADSAFE
#endif
#endif
#if BOOST_VERSION < 103600
#include <boost/spirit/core.hpp>
#include <boost/spirit/actor/assign_actor.hpp> //for assign_a
#include <boost/spirit/actor/push_back_actor.hpp> //for push_back_a
#include <boost/spirit/actor/insert_at_actor.hpp> //for insert_at_a
#include <boost/spirit/actor/clear_actor.hpp> //for clear_a
#include <boost/spirit/symbols/symbols.hpp> //for symbol table
#include <boost/spirit/utility/confix.hpp> //for confix
#include <boost/spirit/phoenix/primitives.hpp> //needed for "var" in group rule
#include <boost/spirit/phoenix/operators.hpp> //needed for "var" in group rule
#include <boost/spirit/phoenix/functions.hpp>
#else
#include <boost/spirit/include/classic_core.hpp>
#include <boost/spirit/include/classic_assign_actor.hpp> //for assign_a
#include <boost/spirit/include/classic_push_back_actor.hpp> //for push_back_a
#include <boost/spirit/include/classic_insert_at_actor.hpp> //for insert_at_a
#include <boost/spirit/include/classic_clear_actor.hpp> //for clear_a
#include <boost/spirit/include/classic_symbols.hpp> //for symbol table
#include <boost/spirit/include/classic_confix.hpp> //for confix
#include <boost/spirit/include/phoenix1_primitives.hpp> //needed for "var" in group rule
#include <boost/spirit/include/phoenix1_operators.hpp> //needed for "var" in group rule
#include <boost/spirit/include/phoenix1_functions.hpp>
#endif
//#include <boost/spirit/attribute.hpp> //for closure
//#include <boost/spirit/tree/ast.hpp> //for ast parse trees (in tree_formula)
#include <iostream>
#include <string>
#include <map>
#include "event_table.h"
#include "formula_grammar.h"

Graziano Scalamera
committed
#define NAME_KEY "tag"
#define FORMULA_KEY "formula"
#define ONDELAY_KEY "on_delay"
#define OFFDELAY_KEY "off_delay"

Graziano Scalamera
committed
#define LEVEL_KEY "priority"
#define SILENT_TIME_KEY "shlvd_time"
#define GROUP_KEY "group"
#define MESSAGE_KEY "message"
#define ON_COMMAND_KEY "on_command"
#define OFF_COMMAND_KEY "off_command"
#define ENABLED_KEY "enabled"
#define SILENT_TIME_REMAINING_KEY "shlvd_end"
#define SHELVED_KEY "shelved"
#define ACKNOWLEDGED_KEY "ack"
#define ATTR_VALUES_KEY "values"

Graziano Scalamera
committed
#define VALUE_KEY "state"
#define ON_COUNTER_KEY "on_counter"
#define OFF_COUNTER_KEY "off_counter"
#define COUNTER_KEY "counter"
#define QUALITY_KEY "quality"
#define EXCEPTION_KEY "exception"
#define AUDIBLE_KEY "audible"
#define FREQ_COUNTER_KEY "freq_counter"

Graziano Scalamera
committed
#define ALARM_TIME_KEY "time"
#define KEY(S_VAL) S_VAL "="
#define SEP ";"

Graziano Scalamera
committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
////////////////////////////////////////////////////////////////////////////
using namespace std;
#if BOOST_VERSION < 103600
using namespace boost::spirit;
#else
using namespace boost::spirit::classic;
#endif
using namespace phoenix; //needed for "var" in group rule
////////////////////////////////////////////////////////////////////////////
//
// Semantic actions for alarm gramamr
//
////////////////////////////////////////////////////////////////////////////
#if 0
struct push_back_impl
{
template <typename Container, typename Item>
struct result
{
typedef void type;
};
template <typename Container, typename Item>
void operator()(Container& c, Item const& item) const
{
c.push_back(item);
}
};
function<push_back_impl> const push_back = push_back_impl();
struct insert_map_impl
{
template <typename Container, typename Item1, typename Item2>
struct result
{
typedef void type;
};
template <typename Container, typename Item1, typename Item2>
void operator()(Container& c, Item1 const& item1, Item2 const& item2) const
{
c.insert(make_pair(item1, item2));
}
};
function<insert_map_impl> const insert_map = insert_map_impl();
#endif
////////////////////////////////////////////////////////////////////////////
//
// alarm grammar
//
////////////////////////////////////////////////////////////////////////////
struct alarm_parse : public grammar<alarm_parse>
{
alarm_t &m_alarm;
symbols<unsigned int> sym_grp;
alarm_parse(alarm_t &a) \
: m_alarm(a)
{
//init symbol table with group defined in alarm_t::grp_str
map<string,unsigned int>::iterator i = m_alarm.grp_str.begin();
while(i != m_alarm.grp_str.end())
{
sym_grp.add(i->first.c_str(), i->second);
i++;
}
}
template <typename ScannerT>
struct definition
{
definition(alarm_parse const& self)
{
//-------BOOST.SPIRIT GLOSSARY-------
// >> : sequence
// | : union (i.e. alternative)
// - : difference
// * : kleene star (matches 0 or more times)
// + : positive (matches 1 or more times)
// ! : optional (matches 0 or 1 time)
// str_p : matches string
// ch_p : matches char
// hex_p :
// alnum_p : matches alpha-numeric characters
// anychar_p : matches any single character (including the null terminator: '\0')
// lexemd_d : turns off white space skipping
// confix : recognize a sequence of: an opening, an expression and a closing
// assign_a :
// push_back_a :
//std::pair<string, vector<string> > temp;
expression
= no_node_d[str_p(KEY(NAME_KEY))] >>
no_node_d

Graziano Scalamera
committed
[

Graziano Scalamera
committed
[
assign_a(self.m_alarm.name) //save name in alarm_t
]
] //discard_node_d
>>
no_node_d[separator]
>>
no_node_d[str_p(KEY(FORMULA_KEY))] >>

Graziano Scalamera
committed
root_node_d
[
formula
[
assign_a(self.m_alarm.formula) //save formula in alarm_t
]
] //root_node_d
>> *(no_node_d[option])

Graziano Scalamera
committed
= no_node_d[separator] >> no_node_d[on_delay] |
no_node_d[separator] >> no_node_d[off_delay] |
no_node_d[separator] >> no_node_d[level] |
no_node_d[separator] >> no_node_d[silent_time] |
no_node_d[separator] >> no_node_d[group] |
no_node_d[separator] >> no_node_d[msg] |
no_node_d[separator] >> no_node_d[on_command] |
no_node_d[separator] >> no_node_d[off_command] |
no_node_d[separator] >> no_node_d[enabled]

Graziano Scalamera
committed
//------------------------------ALARM NAME--------------------------------------
symbol
= alnum_p | '.' | '_' | '-' | '+' //any alpha numeric char plus '.', '_', '-', '+'
;
= alnum_p | '.' | '_' | '-' //any alpha numeric char plus '_'

Graziano Scalamera
committed
name
= (+symbol) >> '/' >> (+symbol)
>> '/' >> (+symbol) >> '/' >> (+symbol_attr_name)
;
name_alm
= (+symbol_attr_name)

Graziano Scalamera
committed
;
//------------------------------LEVEL--------------------------------------
level
= discard_node_d[str_p(KEY(LEVEL_KEY))] >>
//lexeme_d[(+alnum_p)] //match only possible levels?? (fault, log, ...)
//(+(alnum_p-'\t'))
(str_p("fault") | str_p("warning") | str_p("log"))
[
assign_a(self.m_alarm.lev) //save level in alarm_t
]

Graziano Scalamera
committed
;
//------------------------------GROUP--------------------------------------
group
= discard_node_d[str_p(KEY(GROUP_KEY))] >>
self.sym_grp //match only group defined in sym_grp symbol table

Graziano Scalamera
committed
[
var(self.m_alarm.grp) |= arg1 //using phoenix::var
]
>> *(
ch_p('|')
>> self.sym_grp //match only group defined in sym_grp symbol table
[
var(self.m_alarm.grp) |= arg1 //using phoenix::var
]
)
;
//------------------------------MESSAGE--------------------------------------
msg
= discard_node_d[str_p(KEY(MESSAGE_KEY))]
//>> ch_p('"')
>> (+(anychar_p - ';')) //one ore more char except ';'

Graziano Scalamera
committed
[
assign_a(self.m_alarm.msg)
]
//>> '"'

Graziano Scalamera
committed
;
//---------------------------ON DELAY----------------------------------------
on_delay
= discard_node_d[str_p(KEY(ONDELAY_KEY))] >>

Graziano Scalamera
committed
[
assign_a(self.m_alarm.on_delay)
]
| epsilon_p)
;
//---------------------------OFF DELAY---------------------------------------
off_delay
= discard_node_d[str_p(KEY(OFFDELAY_KEY))] >>
(uint_p
[
assign_a(self.m_alarm.off_delay)

Graziano Scalamera
committed
]

Graziano Scalamera
committed
;
//-----------------------------SILENT TIME------------------------------------
silent_time
= discard_node_d[str_p(KEY(SILENT_TIME_KEY))] >>
(int_p

Graziano Scalamera
committed
[
assign_a(self.m_alarm.silent_time)
]
| epsilon_p)
;
//-----------------------------ON COMMAND------------------------------------
on_command
= discard_node_d[str_p(KEY(ON_COMMAND_KEY))] >>
(discard_node_d
[
name
[
assign_a(self.m_alarm.cmd_name_a) //save cmd_name_a in alarm_t
]
] //discard_node_d
| epsilon_p)
;
//-----------------------------OFF COMMAND------------------------------------
off_command
= discard_node_d[str_p(KEY(OFF_COMMAND_KEY))] >>
(discard_node_d
[
name
[
assign_a(self.m_alarm.cmd_name_n) //save cmd_name_a in alarm_t
]
] //discard_node_d
| epsilon_p)

Graziano Scalamera
committed
;
//------------------------------ENABLED----------------------------------------
enabled
= discard_node_d[str_p(KEY(ENABLED_KEY))] >>
//lexeme_d[(+alnum_p)] //match only possible levels?? (fault, log, ...)
//(+(alnum_p-'\t'))
//(ch_p('0') | ch_p('1'))
bin_p
[
assign_a(self.m_alarm.enabled) //save enabled in alarm_t
]
;
//------------------------------SEPARATOR--------------------------------------
separator = ch_p(SEP);

Graziano Scalamera
committed
}
typedef rule<ScannerT> rule_t;
rule_t expression, event, option;
rule<typename lexeme_scanner<ScannerT>::type> symbol; //needed to use lexeme_d in rule name
rule<typename lexeme_scanner<ScannerT>::type> symbol_attr_name; //needed to use lexeme_d in rule name
rule_t name, name_alm, val, token, oper, msg, group, level, on_delay, off_delay, silent_time, on_command, off_command, enabled, separator;