-
Graziano Scalamera authorede4004294
Forked from
cs / ds / alarm-handler
47 commits behind the upstream repository.
alarm_grammar.h 11.59 KiB
/*
* 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"
#define NAME_KEY "tag"
#define FORMULA_KEY "formula"
#define ONDELAY_KEY "on_delay"
#define OFFDELAY_KEY "off_delay"
#define LEVEL_KEY "priority"
#define SILENT_TIME_KEY "shlvd_time"
#define GROUP_KEY "group"
#define MESSAGE_KEY "message"
#define URL_KEY "url"
#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"
#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"
#define ALARM_TIME_KEY "time"
#define EVENT_KEY "event"
#define EVENT_TIME_KEY ALARM_TIME_KEY
#define KEY(S_VAL) S_VAL "="
#define SEP ";"
////////////////////////////////////////////////////////////////////////////
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
[
name_alm
[
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))] >>
root_node_d
[
formula
[
assign_a(self.m_alarm.formula) //save formula in alarm_t
]
] //root_node_d
>> *(no_node_d[option])
;
option
= 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[url] |
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]
;
//------------------------------ALARM NAME--------------------------------------
symbol
= alnum_p | '.' | '_' | '-' | '+' //any alpha numeric char plus '.', '_', '-', '+'
;
symbol_attr_name
= alnum_p | '.' | '_' | '-' //any alpha numeric char plus '_'
;
name
= (+symbol) >> '/' >> (+symbol)
>> '/' >> (+symbol) >> '/' >> (+symbol_attr_name)
;
name_alm
= (+symbol_attr_name)
;
//------------------------------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("highest") | str_p("high") | str_p("medium") | str_p("lowest") | str_p("low") | str_p("fault") | str_p("warning") | str_p("log"))//TODO
[
assign_a(self.m_alarm.lev) //save level in alarm_t
]
;
//------------------------------GROUP--------------------------------------
group
= discard_node_d[str_p(KEY(GROUP_KEY))] >>
self.sym_grp //match only group defined in sym_grp symbol table
[
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--------------------------------------
escChar = (ch_p('\\') | ch_p(';')) >> ch_p(';'); //escaped semicolon: "\;" or ";;"
msg
= discard_node_d[str_p(KEY(MESSAGE_KEY))]
//>> ch_p('"')
>> (+(escChar | (anychar_p - ';'))) //one ore more char except ';'
[
assign_a(self.m_alarm.msg)
]
//>> '"'
;
//------------------------------URL--------------------------------------
url
= discard_node_d[str_p(KEY(URL_KEY))]
//>> ch_p('"')
>> (*(escChar | (anychar_p - ';'))) //zero ore more char except ';'
[
assign_a(self.m_alarm.url)
]
//>> '"'
;
//---------------------------ON DELAY----------------------------------------
on_delay
= discard_node_d[str_p(KEY(ONDELAY_KEY))] >>
(uint_p
[
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)
]
| epsilon_p)
;
//-----------------------------SILENT TIME------------------------------------
silent_time
= discard_node_d[str_p(KEY(SILENT_TIME_KEY))] >>
(int_p
[
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)
;
//------------------------------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);
}
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, url, group, level, on_delay, off_delay, silent_time, on_command, off_command, enabled, separator,escChar;
formula_grammar formula;
rule_t const&
start() const { return expression; }
};
};
#endif /*ALARM_GRAMMAR_H_*/