Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
common/advice/binding.cpp
Go to the documentation of this file.
1/*
2 Binding - pattern defining a specific attachment to the Advice system
3
4 Copyright (C)
5 2010, Hermann Vosseler <Ichthyostega@web.de>
6
7  **Lumiera** is free software; you can redistribute it and/or modify it
8  under the terms of the GNU General Public License as published by the
9  Free Software Foundation; either version 2 of the License, or (at your
10  option) any later version. See the file COPYING for further details.
11
12* *****************************************************************/
13
14
25#include "lib/symbol.hpp"
26#include "lib/util.hpp"
27
28#include <boost/functional/hash.hpp>
29#include <boost/lexical_cast.hpp>
30#include <regex>
31
32
33using lib::Literal;
34using util::isnil;
35
36using std::regex;
37using std::smatch;
38using std::sregex_iterator;
39using std::regex_constants::match_continuous;
40using boost::hash_combine;
41using boost::lexical_cast;
42
43
44namespace lumiera{
45namespace advice {
46
47 LUMIERA_ERROR_DEFINE (BINDING_PATTERN_SYNTAX, "Unable to parse the given binding pattern definition");
48
49
50
51
52
54 namespace{ // Implementation details
55
56 const string matchSym = "(\\w+(?:[\\.\\-]\\w+)*)";
57 const string matchArg = "\\(\\s*"+matchSym+"?\\s*\\)";
58 regex findPredicate ("\\s*"+matchSym+"("+matchArg+")?\\s*,?");
59
64 inline uint
65 detectArity (smatch const& match)
66 {
67 if (!match[2].matched) return 0; // no parenthesis at all
68 if (!match[3].matched) return 0; // empty parenthesis
69
70 // later we could analyse the argument in detail here...
71 return 1; // but now we just accept a single constant symbol
72 }
73 }
74
75
76 void
78 {
79 string def(lit);
80 string::const_iterator end_of_last_match = def.begin();
81
82 sregex_iterator end;
83 sregex_iterator pos (def.begin(),def.end(), findPredicate,
84 match_continuous); // continuous: don't allow garbage *not* matched by the RegExp
85 while (pos != end)
86 {
87 smatch match = *pos;
88 atoms_.insert (Atom (match[1], detectArity(match), match[3]));
89 end_of_last_match = match[0].second;
90 ++pos;
91 }
92
93 if ( end_of_last_match !=def.end()
94 and *end_of_last_match !='.'
95 ) // if the match did *not stop at the end of the pattern definition list
96 throw lumiera::error::Invalid ("Trailing garbage in binding pattern definition"
97 , LUMIERA_ERROR_BINDING_PATTERN_SYNTAX);
98 }
99
100
102 : atoms_()
103 { }
104
106 {
107 if (!isnil(spec))
108 parse_and_append (spec);
109 }
110
111
112 void
114 {
115 REQUIRE (spec);
116 parse_and_append (spec);
117 }
118
119
120
121 Binding::operator string() const
122 {
123 string repr("Binding[");
124 typedef NormalisedAtoms::const_iterator AIter;
125 AIter end = atoms_.end();
126 AIter pos = atoms_.begin();
127 for ( ; pos!=end ; ++pos)
128 repr += string(*pos)+", ";
129
130 if (0 < atoms_.size())
131 repr.resize(repr.size()-2);
132
133 repr += "]";
134 return repr;
135 }
136
137
138 Binding::Atom::operator string() const
139 {
140 return sym_+"/"+lexical_cast<string> (ari_)
141 +"("+arg_+")";
142 }
143
144
145 HashVal
147 {
148 HashVal hash=0;
149
150 typedef NormalisedAtoms::const_iterator AIter;
151 AIter pos = atoms_.begin();
152 AIter end = atoms_.end();
153 for ( ; pos!=end ; ++pos)
154 {
155 hash_combine (hash, pos->sym());
156 hash_combine (hash, pos->arity());
157 hash_combine (hash, pos->arg());
158 }
159
160 return hash;
161 }
162
163
172 bool
173 operator== (Binding const& b1, Binding const& b2)
174 {
175 if (b1.atoms_.size() != b2.atoms_.size())
176 return false;
177
178 ASSERT (b1.atoms_.size() == b2.atoms_.size());
179
180 typedef Binding::NormalisedAtoms::const_iterator Iter;
181 Iter end = b1.atoms_.end();
182 Iter p1 = b1.atoms_.begin();
183 Iter p2 = b2.atoms_.begin();
184
185 for ( ; p1!=end; ++p1, ++p2 )
186 if (! p1->identical(*p2))
187 return false;
188
189 return true;
190 }
191
192
193
194}} // namespace lumiera::advice
Inline string literal.
Definition symbol.hpp:78
single predicate as part of an advice binding pattern
Conjunction of predicates to be matched against a collaboration partner for establishing an Advice co...
Binding()
create the empty binding, equivalent to true
void addPredicate(Literal spec)
extend the definition of this binding by adding a predicate according to the given textual definition
void parse_and_append(Literal def)
internal: parse into atoms, and insert them
A pattern to define and identify a specific attachment to the Advice system.
#define LUMIERA_ERROR_DEFINE(err, msg)
Definition and initialisation of an error constant.
Definition error.h:71
#define hash
unsigned int uint
Definition integral.hpp:29
regex findPredicate("\\s*"+matchSym+"("+matchArg+")?\\s*,?")
sym(arg), groups: [symbol, parenthesis, argument symbol]
uint detectArity(smatch const &match)
detect the arity of an predicate, as matched by findPredicate.
bool operator==(Binding const &b1, Binding const &b2)
bindings are considered equivalent if, after normalisation, their respective definitions are identica...
LumieraError< LERR_(INVALID)> Invalid
Definition error.hpp:211
Lumiera public interface.
Definition advice.hpp:102
bool isnil(lib::time::Duration const &dur)
Marker types to indicate a literal string and a Symbol.
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...