8#ifndef PXR_USD_SDF_PREDICATE_EXPRESSION_PARSER_H
9#define PXR_USD_SDF_PREDICATE_EXPRESSION_PARSER_H
12#include "pxr/usd/sdf/api.h"
15#include "pxr/base/vt/value.h"
17#include "pxr/base/pegtl/pegtl.hpp"
21PXR_NAMESPACE_OPEN_SCOPE
25Sdf_EvalQuotedString(
const char* x,
size_t n,
26 size_t trimBothSides,
unsigned int* numLines=NULL);
28struct SdfPredicateExprBuilder
30 SdfPredicateExprBuilder() { OpenGroup(); }
35 _stacks.back().PushCall(
36 kind, std::move(_funcName), std::move(_funcArgs));
41 void SetFuncName(std::string
const &name) {
45 void AddFuncArg(
VtValue const &val) {
46 _funcArgs.push_back({ std::move(_funcKwArgName), val });
47 _funcKwArgName.clear();
50 void SetFuncArgKWName(std::string
const &kw) {
54 void OpenGroup() { _stacks.emplace_back(); }
59 _stacks.back().PushExpr(std::move(innerExpr));
75 auto higherPrec = [](Op left, Op right) {
76 return (left < right) || (left == right && left != Op::Not);
79 while (!opStack.empty() && higherPrec(opStack.back(), op)) {
82 opStack.push_back(op);
87 std::vector<SdfPredicateExpression::FnArg> &&args) {
90 kind, std::move(name), std::move(args) }));
94 exprStack.push_back(std::move(expr));
98 while (!opStack.empty()) {
111 exprStack.pop_back();
113 if (op == SdfPredicateExpression::Not) {
121 exprStack.pop_back();
124 op, std::move(left), std::move(right))
130 std::vector<SdfPredicateExpression::Op> opStack;
131 std::vector<SdfPredicateExpression> exprStack;
134 std::vector<_Stack> _stacks;
136 std::string _funcName;
137 std::string _funcKwArgName;
138 std::vector<SdfPredicateExpression::FnArg> _funcArgs;
146namespace SdfPredicateExpressionParser {
148using namespace PXR_PEGTL_NAMESPACE;
150template <
class Rule>
using OptSpaced = pad<Rule, blank>;
152using OptSpacedComma = OptSpaced<one<
','>>;
157struct NotKW : PXR_PEGTL_KEYWORD("not") {};
158struct AndKW : PXR_PEGTL_KEYWORD("and") {};
159struct OrKW : PXR_PEGTL_KEYWORD("or") {};
160struct Inf : PXR_PEGTL_KEYWORD("inf") {};
161struct True : PXR_PEGTL_KEYWORD("true") {};
162struct False : PXR_PEGTL_KEYWORD("false") {};
163struct ImpliedAnd : plus<blank> {};
165struct ReservedWord : sor<
166 NotKW, AndKW, OrKW, Inf, True, False> {};
168struct Digits : plus<range<'0','9'>> {};
170struct Exp : seq<one<'e','E'>, opt<one<'-','+'>>, must<Digits>> {};
171struct Frac : if_must<one<'.'>, Digits> {};
172struct PredArgFloat : seq<
173 opt<one<'-'>>, sor<Inf, seq<Digits, if_then_else<Frac, opt<Exp>, Exp>>>
175struct PredArgInt : seq<opt<one<'-'>>, Digits> {};
177struct PredArgBool : sor<True, False> {};
179template <
class Quote>
180struct Escaped : sor<Quote, one<'\\', 'b', 'f', 'n', 'r', 't'>> {};
181template <
class Quote>
182struct Unescaped : minus<utf8::range<0x20, 0x10FFFF>, Quote> {};
184template <
class Quote>
185struct StringChar : if_then_else<
186 one<'\\'>, must<Escaped<Quote>>, Unescaped<Quote>> {};
188struct QuotedString : sor<
189 if_must<one<'"'>, until<one<'"'>, StringChar<one<'"'>>>>,
190 if_must<one<'\''>, until<one<'\''>, StringChar<one<'\''>>>>
193struct UnquotedStringChar
194 : sor<identifier_other,
195 one<'~', '!', '@', '#', '$', '%', '^', '&', '*', '-', '+', '=',
196 '|', '\\', '.', '?', '/'>> {};
198struct UnquotedString : star<UnquotedStringChar> {};
200struct PredArgString : sor<QuotedString, UnquotedString> {};
202struct PredArgVal : sor<
203 PredArgFloat, PredArgInt, PredArgBool, PredArgString> {};
205struct PredKWArgName : minus<identifier, ReservedWord> {};
207struct PredKWArgPrefix : seq<PredKWArgName, OptSpaced<one<'='>>> {};
208struct PredKWArg : if_must<PredKWArgPrefix, PredArgVal> {};
210struct PredParenPosArg : seq<not_at<PredKWArgPrefix>, PredArgVal> {};
212struct PredFuncName : minus<identifier, ReservedWord> {};
215struct PredKWArgStep : if_must<OptSpacedComma, PredKWArg> {};
216struct PredKWArgs : seq<PredKWArg, star<PredKWArgStep>> {};
223 : if_then_else<list<PredParenPosArg, OptSpacedComma>,
224 opt<if_must<OptSpacedComma, PredKWArgs>>,
229struct PredColonArgStep : if_must<one<','>, PredArgVal> {};
230struct PredColonArgs : seq<PredArgVal, star<PredColonArgStep>> {};
232struct PredColonCall : if_must<seq<PredFuncName, one<':'>>, PredColonArgs> {};
235struct PredParenClose : one<')'> {};
236struct PredParenCall : seq<
237 PredFuncName, OptSpaced<one<'('>>,
238 must<PredParenArgs, star<blank>, PredParenClose>
242struct PredBareCall : PredFuncName {};
246struct PredOpenGroup : one<'('> {};
247struct PredCloseGroup : one<')'> {};
250struct GroupedPredExpr : OptSpaced<PredExpr> {};
257 if_must<PredOpenGroup, GroupedPredExpr, PredCloseGroup>
261struct PredFactor : seq<opt<OptSpaced<list<NotKW, plus<blank>>>>, PredAtom> {};
268struct PredExplicitOp : sor<OptSpaced<AndKW>, OptSpaced<OrKW>> {};
269struct PredExprStep : if_must<PredExplicitOp, PredFactor> {};
270struct ImpliedAndStep : seq<
271 at<seq<ImpliedAnd, PredFactor>>, ImpliedAnd, PredFactor> {};
273struct PredExpr : seq<PredFactor, star<sor<PredExprStep, ImpliedAndStep>>> {};
277struct PredExprEnd : eolf {};
296struct Errors :
public normal<Rule>
298 static char const *message;
300 template <
class Input,
class... States>
301 [[noreturn]]
static void raise(Input
const &in, States &&...) {
302 throw parse_error(message, in);
307inline char const *Errors<Rule>::message =
"";
309#define PARSE_ERROR(rule, msg) \
310 template <> inline char const *Errors<rule>::message = msg
312PARSE_ERROR(PredExprEnd,
"expected end of predicate expression");
313PARSE_ERROR(Digits,
"expected digits");
314PARSE_ERROR(Escaped<one<
'\''>>,
"expected escape character after '\\'");
315PARSE_ERROR(Escaped<one<
'"'>>,
"expected escape character after '\\'");
316PARSE_ERROR(PredArgVal,
"expected argument value after '='");
317PARSE_ERROR(PredColonArgs,
"expected argument list after ':'");
318PARSE_ERROR(PredKWArg,
"expected keyword argument after ','");
319PARSE_ERROR(PredKWArgs,
"expected keyword argument after ','");
320PARSE_ERROR(PredParenClose,
"expected ')' to close function call");
321PARSE_ERROR(GroupedPredExpr,
"expected predicate expression after '('");
322PARSE_ERROR(PredCloseGroup,
"expected ')' to close predicate expression "
324PARSE_ERROR(PredFactor,
"expected predicate expression after operator");
331struct PredAction : nothing<Rule> {};
333template <SdfPredicateExpression::Op op>
336 template <
class Input>
337 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
342template <>
struct PredAction<NotKW>
343 : PredOpAction<SdfPredicateExpression::Not> {};
344template <>
struct PredAction<AndKW>
345 : PredOpAction<SdfPredicateExpression::And> {};
346template <>
struct PredAction<OrKW>
347 : PredOpAction<SdfPredicateExpression::Or> {};
348template <>
struct PredAction<ImpliedAnd>
349 : PredOpAction<SdfPredicateExpression::ImpliedAnd> {};
352struct PredAction<PredOpenGroup>
354 template <
class Input>
355 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
361struct PredAction<PredCloseGroup>
363 template <
class Input>
364 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
365 builder.CloseGroup();
370struct PredAction<PredFuncName>
372 template <
class Input>
373 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
374 builder.SetFuncName(in.string());
379struct PredAction<PredArgInt>
381 template <
class Input>
382 static bool apply(Input
const &in, SdfPredicateExprBuilder &builder) {
383 bool outOfRange =
false;
388 builder.AddFuncArg(
VtValue(ival));
394struct PredAction<PredArgBool>
396 template <
class Input>
397 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
398 builder.AddFuncArg(
VtValue(in.string()[0] ==
't'));
403struct PredAction<PredArgFloat>
405 template <
class Input>
406 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
407 std::string
const &instr = in.string();
409 if (instr ==
"inf") {
410 fval = std::numeric_limits<double>::infinity();
412 else if (instr ==
"-inf") {
413 fval = -std::numeric_limits<double>::infinity();
418 builder.AddFuncArg(
VtValue(fval));
423struct PredAction<PredArgString>
425 template <
class Input>
426 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
427 std::string
const &instr = in.string();
428 size_t trimAmount = 0;
429 if (instr.size() >= 2 &&
430 ((instr.front() ==
'"' && instr.back() ==
'"') ||
431 (instr.front() ==
'\'' && instr.back() ==
'\''))) {
436 instr.c_str(), instr.size(), trimAmount)));
441struct PredAction<PredKWArgName>
443 template <
class Input>
444 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
445 builder.SetFuncArgKWName(in.string());
449template <SdfPredicateExpression::FnCall::Kind callKind>
452 template <
class Input>
453 static void apply(Input
const &in, SdfPredicateExprBuilder &builder) {
454 builder.PushCall(callKind);
457template <>
struct PredAction<PredBareCall>
458 : PredCallAction<SdfPredicateExpression::FnCall::BareCall> {};
459template <>
struct PredAction<PredParenCall>
460 : PredCallAction<SdfPredicateExpression::FnCall::ParenCall> {};
461template <>
struct PredAction<PredColonCall>
462 : PredCallAction<SdfPredicateExpression::FnCall::ColonCall> {};
466PXR_NAMESPACE_CLOSE_SCOPE
Low-level utilities for informing users of various internal and external diagnostic conditions.
Represents a logical expression syntax tree consisting of predicate function calls joined by the logi...
Op
Enumerant describing a subexpression operation.
static SDF_API SdfPredicateExpression MakeOp(Op op, SdfPredicateExpression &&left, SdfPredicateExpression &&right)
Produce a new expression by combining left and right with the operator op.
static SDF_API SdfPredicateExpression MakeNot(SdfPredicateExpression &&right)
Produce a new expression by prepending the 'not' operator onto right.
static SDF_API SdfPredicateExpression MakeCall(FnCall &&call)
Produce a new expression containing just a the function call call.
Provides a container which may hold any type, and provides introspection and iteration over array typ...
TF_API int64_t TfStringToInt64(const std::string &txt, bool *outOfRange=NULL)
Convert a sequence of digits in txt to an int64_t value.
TF_API double TfStringToDouble(const std::string &txt)
Converts text string to double.