Advice binding pattern finished, passing unit test

now detecting a lot of syntax errors
This commit is contained in:
Fischlurch 2010-04-16 04:28:02 +02:00
parent 6bc78064d1
commit 0514c24487
5 changed files with 64 additions and 34 deletions

View file

@ -42,13 +42,16 @@ using boost::lexical_cast;
namespace lib {
namespace advice {
LUMIERA_ERROR_DEFINE (BINDING_PATTERN_SYNTAX, "Unable to parse the given binding pattern definition");
/////////////////////TICKET #613 : centralise generally useful RegExps
namespace{ // Implementation details
const string matchSym = "(\\w[\\w_\\.\\-]*)";
const string matchSym = "(\\w+(?:[\\.\\-]\\w+)*)";
const string matchArg = "\\(\\s*"+matchSym+"?\\s*\\)";
regex findPredicate ("\\s*"+matchSym+"("+matchArg+")?\\s*,?"); ///< \c sym(arg), groups: [symbol, parenthesis, argument symbol]
@ -72,6 +75,8 @@ namespace advice {
Binding::parse_and_append (Literal lit)
{
string def(lit);
string::const_iterator end_of_last_match = def.begin();
sregex_iterator end;
sregex_iterator pos (def.begin(),def.end(), findPredicate,
match_continuous); // continuous: don't allow garbage *not* matched by the RegExp
@ -79,8 +84,15 @@ namespace advice {
{
smatch match = *pos;
atoms_.insert (Atom (match[1], detectArity(match), match[3]));
end_of_last_match = match[0].second;
++pos;
}
if ( end_of_last_match !=def.end()
&& *end_of_last_match !='.'
) // if the match did *not stop at the end of the pattern definition list
throw lumiera::error::Invalid ("Trailing garbage in binding pattern definition" ///////////////TICKET #197 should include the garbage, i.e. where the parsing stops
, LUMIERA_ERROR_BINDING_PATTERN_SYNTAX);
}
@ -147,13 +159,13 @@ namespace advice {
}
/** bindings are considered equivalent if, after normalisation,
* their respective definitions are identical.
/** bindings are considered equivalent if,
* after normalisation, their respective definitions are identical.
* @note for bindings without variable arguments, equivalence and matching
* always yield the same results. Contrary to this, two bindings with
* some variable arguments could match, without being defined identically.
* For example \c pred(X) matches \c pred(u) or any other binding of the
* form \c pred(<constant_value>)
* form \c pred(<constant_value>) ////TICKET #615 not yet implemented
*/
bool
operator== (Binding const& b1, Binding const& b2)

View file

@ -27,10 +27,10 @@
** against a similar pattern associated with the attachment of a possible collaboration partner.
** Semantically, this list of atoms forms an conjunction of predicates to be resolved against
** similar predicates of the partner. Informally, when two entities attach to the Advice system,
** each specifying a binding, they can be paired up if, when combining, the expressions in their
** bindings all evaluate to true.
** each specifying a binding, they can be paired up if any condition included into the binding
** holds true for both sides.
**
** Typically, a binding includes a \em type-guard predicate \c adviceType(xx) where \c xx is an
** Typically, a binding includes a \em type-guard predicate \c advice.type.xx where \c xx is an
** identifier denoting a type used within an instantiation of the Advice collaboration, i.e. a type
** used as advice value in a instantiation of the PointOfAdvice<AD> template. Besides the type guard,
** a binding may narrow down the topic of the advice by providing further predicates. This allows for
@ -41,14 +41,27 @@
** the advice type, and another client entity (the advised entity) could pick up this value
** without the need to now anything about the advisor.
**
** Any binding can be normalised into a hash value, which plays a crucial role within the
** implementation of the advice system.
** \par implementation notes
** Any binding will be normalised prior to further processing. This normalisation is based
** on ordering by predicate symbol and arity. Patterns just comprised of constant symbols
** (nullary atoms) can even be condensed into a single hash value, which allows for fast
** match checking. For each pattern, we provide a matcher functor, allowing to check
** a match against this pattern. In case of the mentioned symbol-only patterns,
** this matcher will just hold the hash value of the normalised pattern.
**
** TODO WIP-WIP
** The advice system uses a binding index datastructure to keep track of any participating
** patterns and especially of the matching pairs. Actually, this datastructure needs to store
** only these matcher functors; thus, for a new binding to be used within the advice system,
** the symbolic definition is parsed, then normalised and finally, after creating the matcher
** functor, the full pattern definition can be discarded.
**
** @note as of 4/2010 this is an experimental setup and implemented just enough to work out
** the interfaces. Ichthyo expects this collaboration service to play a central role
** at various places within proc-layer.
** @todo for now, \em only the case of a completely constant (ground) pattern is implemented.
** Later we may consider to extend the binding patterns to allow variables, which, on match
** could be fed as parameters to the bound advice. But this extension requires to extend
** the simple hash-based match check to an actual unification of the patterns. ///TICKET #615
**
** @see configrules.hpp
** @see typed-lookup.cpp corresponding implementation
@ -76,6 +89,8 @@ namespace advice {
typedef size_t HashVal;
LUMIERA_ERROR_DECLARE (BINDING_PATTERN_SYNTAX); ///< Unable to parse the given binding pattern definition
/**

View file

@ -3,7 +3,7 @@ TESTING "Component Test Suite: common and basic components" ./test-lib --group=c
TEST "Hello test world" HelloWorld_test 3 <<END
out: ^This is how the world ends\.\.\.$
out-lit: This is how the world ends...
return: 0
END
@ -38,22 +38,21 @@ return: 0
END
PLANNED "Advice binding patterns" AdviceBindingPattern_test <<END
out: --->Binding[]
out: aSymbol --->Binding[aSymbol/0()]
out: aSymbol followed by Garbage §&Ω%€GΩ%€ar☠☠☠bäaäääge --->Binding[Garbage/0(), aSymbol/0(), by/0(), followed/0()]
out: §&Ω%€GΩ%€ar☠☠☠baäääääge --->Binding[]
out: a, list , of ,symbols. --->Binding[a/0(), list/0(), of/0(), symbols./0()]
out: nullary(). --->Binding[nullary/0()]
out: nullary( ) --->Binding[nullary/0()]
out: nothing () --->Binding[nothing/0()]
out: predicate( with-argument ) --->Binding[predicate/1(with-argument)]
out: no (valid definition here) --->Binding[no/0()]
out: Binding[advice.type.n3lib6advice4test12_GLOBAL__N_111DummyAdviceE/0(), one/0(), three/1(four), two/0()]
out: b0==Binding[]
out: b1==Binding[cat1/0(), cat2/0()]
out: b2==Binding[cat1/0(), cat2/0()]
out: b2==Binding[advice.type.n7lumiera4TimeE/0(), cat1/0(), cat2/0(), cat3/1(zzz)]
TEST "Advice binding patterns" AdviceBindingPattern_test <<END
out-lit: --->Binding[]
out-lit: aSymbol --->Binding[aSymbol/0()]
out-lit: a.compound_Symbol-with-various.parts --->Binding[a.compound_Symbol-with-various.parts/0()]
out-lit: trailing Garbage allowed. ☢☢ eat ☠☠☠ atomic ☠☠☠ waste ☢☢ --->Binding[Garbage/0(), allowed/0(), trailing/0()]
out-lit: a, list , of ,symbols. --->Binding[a/0(), list/0(), of/0(), symbols/0()]
out-lit: nullary(). --->Binding[nullary/0()]
out-lit: nullary( ) --->Binding[nullary/0()]
out-lit: nullary . --->Binding[nullary/0()]
out-lit: predicate( with-argument ) --->Binding[predicate/1(with-argument)]
out-lit: Binding[advice.type.n3lib6advice4test12_GLOBAL__N_111DummyAdviceE/0(), one/0(), three/1(four), two/0()]
out-lit: b0==Binding[]
out-lit: b1==Binding[cat1/0(), cat2/0()]
out-lit: b2==Binding[cat1/0(), cat2/0()]
out-lit: b2==Binding[advice.type.n7lumiera4TimeE/0(), cat1/0(), cat2/0(), cat3/1(zzz)]
return: 0
END

View file

@ -12,8 +12,8 @@ END
TEST "normalise ID" QueryUtils_test normaliseID <<END
out: ..original : a A AA dufte 1a _1 A_A BÄH White space §&Ω%€GΩ%€ar Ω baäääääge!!!!! :
out: normalised : a a aA dufte o1a o_1 a_A bH o white_space gar_bage :
out-lit: ..original : a A AA dufte 1a _1 A_A BÄH White space §&Ω%€GΩ%€ar ☠☠☠ baäääääge!!!!! :
out-lit: normalised : a a aA dufte o1a o_1 a_A bH o white_space gar_bage :
END

View file

@ -22,6 +22,7 @@
#include "lib/test/run.hpp"
#include "lib/test/test-helper.hpp"
#include "lib/advice.hpp"
#include "lib/time.h"
@ -82,14 +83,17 @@ namespace test {
_PARSE_AND_SHOW ("");
_PARSE_AND_SHOW ("aSymbol");
_PARSE_AND_SHOW ("aSymbol followed by Garbage §&Ω%€GΩ%€ar☠☠☠bäaäääge");
_PARSE_AND_SHOW ("§&Ω%€GΩ%€ar☠☠☠baäääääge");
_PARSE_AND_SHOW ("a.compound_Symbol-with-various.parts");
_PARSE_AND_SHOW ("trailing Garbage allowed. ☢☢ eat ☠☠☠ atomic ☠☠☠ waste ☢☢");
_PARSE_AND_SHOW ("a, list , of ,symbols.");
_PARSE_AND_SHOW ("nullary().");
_PARSE_AND_SHOW ("nullary( )");
_PARSE_AND_SHOW ("nothing ()");
_PARSE_AND_SHOW ("nullary .");
_PARSE_AND_SHOW ("predicate( with-argument )");
_PARSE_AND_SHOW ("no (valid definition here)");
VERIFY_ERROR (BINDING_PATTERN_SYNTAX, Binding("no (valid definition here)"));
VERIFY_ERROR (BINDING_PATTERN_SYNTAX, Binding("predicate(with ☠☠☠ Garbage ☠☠☠"));
VERIFY_ERROR (BINDING_PATTERN_SYNTAX, Binding("§&Ω%€GΩ%€ar☠☠☠baäääääge"));
Binding testBinding;
testBinding.addTypeGuard<DummyAdvice>();
@ -104,7 +108,7 @@ namespace test {
{
Binding b0, b00;
Binding b1 ("cat1(), cat2().");
Binding b2 (" cat2 cat1 ***");
Binding b2 (" cat2 cat1 ....");
cout << "b0==" << b0 << endl;
cout << "b1==" << b1 << endl;