mirror of
https://github.com/jezhiggins/arabica
synced 2024-12-27 21:58:30 +01:00
425 lines
19 KiB
C++
425 lines
19 KiB
C++
#ifndef ARABICA_XPATHIC_XPATH_GRAMMER_HPP
|
|
#define ARABICA_XPATHIC_XPATH_GRAMMER_HPP
|
|
|
|
#ifndef BOOST_SPIRIT_THREADSAFE
|
|
#define BOOST_SPIRIT_THREADSAFE
|
|
#endif
|
|
|
|
#include <boost/spirit/core.hpp>
|
|
#include <boost/spirit/symbols/symbols.hpp>
|
|
#include <boost/spirit/utility/chset.hpp>
|
|
|
|
#include "xpath_ast_ids.hpp"
|
|
|
|
namespace Arabica
|
|
{
|
|
namespace XPath
|
|
{
|
|
namespace impl
|
|
{
|
|
|
|
template<typename ScannerT>
|
|
struct xpath_grammar_definition
|
|
{
|
|
xpath_grammar_definition()
|
|
{
|
|
using namespace boost::spirit;
|
|
|
|
// [1]
|
|
LocationPath = AbsoluteLocationPath | RelativeLocationPath;
|
|
// [2]
|
|
AbsoluteLocationPath = AbbreviatedAbsoluteLocationPath
|
|
| (Slash >> !RelativeLocationPath);
|
|
// [3]
|
|
RelativeLocationPath = Step >> *((SlashSlash | discard_node_d[Slash]) >> Step);
|
|
|
|
// [4], [5]
|
|
Step = AxisSpecifier >> NodeTest >> *Predicate | AbbreviatedStep;
|
|
AxisSpecifier = S >> ( AxisName >> S >> "::" | AbbreviatedAxisSpecifier ) >> S;
|
|
|
|
// [6]
|
|
AxisName = AncestorOrSelf
|
|
| Ancestor
|
|
| Attribute
|
|
| Child
|
|
| DescendantOrSelf
|
|
| Descendant
|
|
| FollowingSibling
|
|
| Following
|
|
| Namespace
|
|
| Parent
|
|
| PrecedingSibling
|
|
| Preceding
|
|
| Self;
|
|
|
|
// [7]
|
|
NodeTest = S >>(ProcessingInstruction >> S >> discard_node_d[LeftBracket] >> S >> Literal >> S >> discard_node_d[RightBracket]
|
|
| NodeType >> S >> discard_node_d[LeftBracket] >> S >> discard_node_d[RightBracket]
|
|
| NameTest )
|
|
>> S;
|
|
|
|
// [8], [9]
|
|
Predicate = S >> LeftSquare >> PredicateExpr >> RightSquare >> S;
|
|
PredicateExpr = Expr;
|
|
|
|
// [10]
|
|
AbbreviatedAbsoluteLocationPath = SlashSlash >> RelativeLocationPath;
|
|
// [11] AbbreviatedRelativeLocationPath eliminated
|
|
// [12], [13]
|
|
AbbreviatedStep = ParentSelect | SelfSelect;
|
|
AbbreviatedAxisSpecifier = !ch_p('@');
|
|
|
|
// [14], [15]
|
|
Expr = OrExpr;
|
|
PrimaryExpr = discard_node_d[S] >>
|
|
(VariableReference
|
|
| Number
|
|
| FunctionCall
|
|
| discard_node_d[LeftBracket] >> S >> Expr >> S >> discard_node_d[RightBracket]
|
|
| Literal) >>
|
|
discard_node_d[S];
|
|
|
|
// [16], [17]
|
|
FunctionCall = FunctionName >> S >> LeftBracket >> !(Argument >> *(discard_node_d[ch_p(',')] >> S >> Argument)) >> S >> RightBracket >> S;
|
|
Argument = Expr;
|
|
|
|
// [18], [19], [20]
|
|
// UnionExpr ::= PathExpr | UnionExpr '|' PathExpr
|
|
UnionExpr = PathExpr >> *(UnionOperator >> PathExpr);
|
|
/*
|
|
LocationPath
|
|
| FilterExpr
|
|
| FilterExpr '/' RelativeLocationPath
|
|
| FilterExpr '//' RelativeLocationPath */
|
|
PathExpr = discard_node_d[S] >>
|
|
(FilterExpr >> !((SlashSlash | Slash) >> RelativeLocationPath)
|
|
| LocationPath) >>
|
|
discard_node_d[S];
|
|
// FilterExpr ::= PrimaryExpr | FilterExpr Predicate
|
|
FilterExpr = PrimaryExpr >> *Predicate;
|
|
|
|
// [21], [22], [23], [24]
|
|
OrExpr = AndExpr >> *(OrOperator >> AndExpr);
|
|
AndExpr = EqualityExpr >> *(AndOperator >> EqualityExpr);
|
|
EqualityExpr = RelationalExpr >> *((EqualsOperator | NotEqualsOperator) >> RelationalExpr);
|
|
RelationalExpr = AdditiveExpr >> *((LessThanEqualsOperator | GreaterThanEqualsOperator | LessThanOperator |GreaterThanOperator) >> AdditiveExpr);
|
|
|
|
// [25], [26], [27]
|
|
AdditiveExpr = MultiplicativeExpr >> *((PlusOperator | MinusOperator) >> MultiplicativeExpr);
|
|
MultiplicativeExpr = UnaryExpr >> *((MultiplyOperator | DivOperator | ModOperator) >> UnaryExpr);
|
|
UnaryExpr = discard_node_d[S] >> *(UnaryMinusOperator) >> UnionExpr;
|
|
|
|
// [28] ExprToken not actually used
|
|
|
|
//[29], [30], [31],
|
|
Literal = discard_node_d[ch_p('\"')] >> token_node_d[*~ch_p('\"')] >> discard_node_d[ch_p('\"')]
|
|
| discard_node_d[ch_p('\'')] >> token_node_d[*~ch_p('\'')] >> discard_node_d[ch_p('\'')];
|
|
Number = token_node_d[ch_p('.') >> Digits | Digits >> !('.' >> *Digits)];
|
|
Digits = token_node_d[+digit_p];
|
|
// [32] Operator not actually used
|
|
// [33] OperatorName not actually used
|
|
// [34], [35], [36], [37], [38], [39]
|
|
MultiplyOperator = ch_p('*');
|
|
FunctionName = QName - NodeType;
|
|
VariableReference = ch_p('$') >> QName;
|
|
NameTest = AnyName
|
|
| NCName >> discard_node_d[ch_p(':')] >> AnyName
|
|
| QName;
|
|
NodeType = Comment
|
|
| Text
|
|
| ProcessingInstruction
|
|
| Node;
|
|
|
|
// These aren't correct to spec yet :)
|
|
S = *space_p;
|
|
QName = !(Prefix >> discard_node_d[ch_p(':')]) >> LocalPart;
|
|
Prefix = NCName;
|
|
LocalPart = NCName;
|
|
NCName = token_node_d[(alpha_p | '_') >> *NCNameChar];
|
|
NCNameChar = alpha_p | digit_p | '.' | '-' | '_';
|
|
|
|
// things not defined in the spec, but which are just kind of handy :)
|
|
Slash = ch_p('/');
|
|
SlashSlash = str_p("//");
|
|
|
|
AncestorOrSelf = str_p("ancestor-or-self");
|
|
Ancestor = str_p("ancestor");
|
|
Attribute = str_p("attribute");
|
|
Child = str_p("child");
|
|
DescendantOrSelf = str_p("descendant-or-self");
|
|
Descendant = str_p("descendant");
|
|
FollowingSibling = str_p("following-sibling");
|
|
Following = str_p("following");
|
|
Namespace = str_p("namespace");
|
|
Parent = str_p("parent");
|
|
PrecedingSibling = str_p("preceding-sibling");
|
|
Preceding = str_p("preceding");
|
|
Self = str_p("self");
|
|
|
|
Comment = str_p("comment");
|
|
Text = str_p("text");
|
|
ProcessingInstruction = str_p("processing-instruction");
|
|
Node = str_p("node");
|
|
AnyName = ch_p('*');
|
|
|
|
SelfSelect = ch_p('.');
|
|
ParentSelect = str_p("..");
|
|
|
|
LeftSquare = ch_p('[');
|
|
RightSquare = ch_p(']');
|
|
|
|
LeftBracket = ch_p('(');
|
|
RightBracket = ch_p(')');
|
|
|
|
PlusOperator = ch_p('+');
|
|
MinusOperator = ch_p('-');
|
|
ModOperator = str_p("mod");
|
|
DivOperator = str_p("div");
|
|
EqualsOperator = ch_p('=');
|
|
NotEqualsOperator = str_p("!=");
|
|
LessThanOperator = ch_p('<');
|
|
LessThanEqualsOperator = str_p("<=");
|
|
GreaterThanOperator = ch_p('>');
|
|
GreaterThanEqualsOperator = str_p(">=");
|
|
|
|
OrOperator = str_p("or");
|
|
AndOperator = str_p("and");
|
|
UnionOperator = ch_p('|');
|
|
UnaryMinusOperator = ch_p('-');
|
|
} // xpath_grammar_definition
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<QName_id> > QName;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Prefix_id> > Prefix;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LocalPart_id> > LocalPart;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NCName_id> > NCName;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NCNameChar_id> > NCNameChar;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AxisName_id> > AxisName;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NodeType_id> > NodeType;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LocationPath_id> > LocationPath;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AbsoluteLocationPath_id> > AbsoluteLocationPath;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<RelativeLocationPath_id> > RelativeLocationPath;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Step_id> > Step;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AxisSpecifier_id> > AxisSpecifier;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NodeTest_id> > NodeTest;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Predicate_id> > Predicate;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<PredicateExpr_id> > PredicateExpr;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AbbreviatedAbsoluteLocationPath_id> > AbbreviatedAbsoluteLocationPath;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AbbreviatedStep_id> > AbbreviatedStep;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AbbreviatedAxisSpecifier_id> > AbbreviatedAxisSpecifier;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Expr_id> > Expr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<PrimaryExpr_id> > PrimaryExpr;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<FunctionCall_id> > FunctionCall;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Argument_id> > Argument;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<UnionExpr_id> > UnionExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<PathExpr_id> > PathExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<FilterExpr_id> > FilterExpr;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<OrExpr_id> > OrExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AndExpr_id> > AndExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<EqualityExpr_id> > EqualityExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<RelationalExpr_id> > RelationalExpr;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AdditiveExpr_id> > AdditiveExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<MultiplicativeExpr_id> > MultiplicativeExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<UnaryExpr_id> > UnaryExpr;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Literal_id> > Literal;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Number_id> > Number;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Digits_id> > Digits;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<MultiplyOperator_id> > MultiplyOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<FunctionName_id> > FunctionName;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<VariableReference_id> > VariableReference;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NameTest_id> > NameTest;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<S_id> > S; // ExprWhitespace
|
|
|
|
// bonus bits
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Slash_id> > Slash;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<SlashSlash_id> > SlashSlash;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AncestorOrSelf_id> > AncestorOrSelf;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Ancestor_id> > Ancestor;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Attribute_id> > Attribute;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Child_id> > Child;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<DescendantOrSelf_id> > DescendantOrSelf;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Descendant_id> > Descendant;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<FollowingSibling_id> > FollowingSibling;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Following_id> > Following;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Namespace_id> > Namespace;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Parent_id> > Parent;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<PrecedingSibling_id> > PrecedingSibling;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Preceding_id> > Preceding;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Self_id> > Self;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Comment_id> > Comment;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Text_id> > Text;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<ProcessingInstruction_id> > ProcessingInstruction;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Node_id> > Node;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AnyName_id> > AnyName;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<SelfSelect_id> > SelfSelect;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<ParentSelect_id> > ParentSelect;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LeftSquare_id> > LeftSquare;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<RightSquare_id> > RightSquare;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LeftBracket_id> > LeftBracket;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<RightBracket_id> > RightBracket;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<PlusOperator_id> > PlusOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<MinusOperator_id> > MinusOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<ModOperator_id> > ModOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<DivOperator_id> > DivOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<EqualsOperator_id> > EqualsOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NotEqualsOperator_id> > NotEqualsOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LessThanOperator_id> > LessThanOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LessThanEqualsOperator_id> > LessThanEqualsOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<GreaterThanOperator_id> > GreaterThanOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<GreaterThanEqualsOperator_id> > GreaterThanEqualsOperator;
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<OrOperator_id> > OrOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AndOperator_id> > AndOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<UnionOperator_id> > UnionOperator;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<UnaryMinusOperator_id> > UnaryMinusOperator;
|
|
}; // xpath_grammar_definition
|
|
|
|
|
|
struct xpath_grammar : public boost::spirit::grammar<xpath_grammar>
|
|
{
|
|
template<typename ScannerT>
|
|
struct definition : public xpath_grammar_definition<ScannerT>
|
|
{
|
|
definition(xpath_grammar const& /* self */)
|
|
{
|
|
} // definition
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LocationPath_id> > const&
|
|
start() const
|
|
{
|
|
return xpath_grammar_definition<ScannerT>::LocationPath;
|
|
} // start
|
|
}; // definition<ScannerT>
|
|
}; // xpath_grammar
|
|
|
|
struct xpath_grammar_expr : public boost::spirit::grammar<xpath_grammar_expr>
|
|
{
|
|
template<typename ScannerT>
|
|
struct definition : public xpath_grammar_definition<ScannerT>
|
|
{
|
|
definition(xpath_grammar_expr const& /* self */)
|
|
{
|
|
} // definition
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Expr_id> > const&
|
|
start() const
|
|
{
|
|
return xpath_grammar_definition<ScannerT>::Expr;
|
|
} // start
|
|
}; // definition<ScannerT>
|
|
}; // xpath_grammar_expr
|
|
|
|
struct xpath_grammar_match : public boost::spirit::grammar<xpath_grammar_match>
|
|
{
|
|
template<typename ScannerT>
|
|
struct definition : public xpath_grammar_definition<ScannerT>
|
|
{
|
|
definition(xpath_grammar_match const& /* self */)
|
|
{
|
|
using namespace boost::spirit;
|
|
typedef xpath_grammar_definition<ScannerT> base;
|
|
|
|
// [1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern
|
|
Pattern = discard_node_d[base::S] >> LocationPathPattern >> discard_node_d[base::S] >> *(base::UnionOperator >> discard_node_d[base::S] >> LocationPathPattern >> discard_node_d[base::S]);
|
|
|
|
// [2] LocationPathPattern ::= '/' RelativePathPattern?
|
|
// | IdKeyPattern (('/' | '//') RelativePathPattern)?
|
|
// | '//'? RelativePathPattern
|
|
LocationPathPattern = IdKeyPattern >> !((base::SlashSlash | base::Slash) >> RelativePathPattern) |
|
|
!base::SlashSlash >> RelativePathPattern |
|
|
base::Slash >> !RelativePathPattern;
|
|
|
|
|
|
// [3] IdKeyPattern ::= 'id' '(' Literal ')' | 'key' '(' Literal ',' Literal ')'
|
|
IdKeyPattern = (str_p("id") >> base::LeftBracket >> discard_node_d[base::S] >> base::Literal >> discard_node_d[base::S] >> base::RightBracket) |
|
|
(str_p("key") >> base::LeftBracket >> discard_node_d[base::S] >> base::Literal >> discard_node_d[base::S] >> discard_node_d[ch_p(',')] >>discard_node_d[base::S] >> base::Literal >> discard_node_d[base::S] >> base::RightBracket);
|
|
|
|
// [4] RelativePathPattern ::= StepPattern
|
|
// | RelativePathPattern '/' StepPattern
|
|
// | RelativePathPattern '//' StepPattern
|
|
RelativePathPattern = StepPattern >> *((base::SlashSlash | base::Slash) >> StepPattern);
|
|
|
|
// [5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate*
|
|
StepPattern = ChildOrAttributeAxisSpecifier >> (NodeMatchPattern|base::NodeTest) >> *base::Predicate;
|
|
|
|
// [6] ChildOrAttributeAxisSpecifier ::= AbbreviatedAxisSpecifier | ('child' | 'attribute') '::'
|
|
ChildOrAttributeAxisSpecifier = ((base::Child | base::Attribute) >> discard_node_d[str_p("::")]) | base::AbbreviatedAxisSpecifier;
|
|
|
|
NodeMatchPattern = str_p("node()");
|
|
} // definition
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Pattern_id> > const&
|
|
start() const
|
|
{
|
|
return Pattern;
|
|
} // start
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<Pattern_id> > Pattern;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LocationPathPattern_id> > LocationPathPattern;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<IdKeyPattern_id> > IdKeyPattern;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<RelativePathPattern_id> > RelativePathPattern;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<StepPattern_id> > StepPattern;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<ChildOrAttributeAxisSpecifier_id> > ChildOrAttributeAxisSpecifier;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<NodeMatchPattern_id> > NodeMatchPattern;
|
|
}; // definition<ScannerT>
|
|
}; // xpath_grammar_match
|
|
|
|
struct xpath_grammar_attribute_value : public boost::spirit::grammar<xpath_grammar_attribute_value>
|
|
{
|
|
template<typename ScannerT>
|
|
struct definition : public xpath_grammar_definition<ScannerT>
|
|
{
|
|
definition(xpath_grammar_attribute_value const& /* self */)
|
|
{
|
|
using namespace boost::spirit;
|
|
typedef xpath_grammar_definition<ScannerT> base;
|
|
|
|
AttributeValueTemplate = (DoubleLeftCurly | DoubleRightCurly | EmbeddedExpr | AttrLiteral) >>
|
|
*(DoubleLeftCurly | DoubleRightCurly | EmbeddedExpr | AttrLiteral);
|
|
DoubleLeftCurly = str_p("{{");
|
|
DoubleRightCurly = str_p("}}");
|
|
LeftCurly = ch_p('{');
|
|
RightCurly = ch_p('}');
|
|
EmbeddedExpr = LeftCurly >> base::Expr >> RightCurly;
|
|
chset<> brackets("{}");
|
|
AttrLiteral = token_node_d[~brackets >> *~brackets];
|
|
} // definition
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AttributeValueTemplate_id> > const&
|
|
start() const
|
|
{
|
|
return AttributeValueTemplate;
|
|
} // start
|
|
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AttributeValueTemplate_id> > AttributeValueTemplate;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<DoubleLeftCurly_id> > DoubleLeftCurly;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<DoubleRightCurly_id> > DoubleRightCurly;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<LeftCurly_id> > LeftCurly;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<RightCurly_id> > RightCurly;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<EmbeddedExpr_id> > EmbeddedExpr;
|
|
boost::spirit::rule<ScannerT, boost::spirit::parser_tag<AttrLiteral_id> > AttrLiteral;
|
|
}; // definition
|
|
}; // xpath_grammar_attribute_value
|
|
|
|
} // namespace impl
|
|
} // namespace XPath
|
|
} // namespace Arabica
|
|
|
|
#endif
|