YSTest: NPLA.cpp 源文件

YSTest PreAlpha_b800_20170810 The YSLib Test Project

- 首页
- 相关页面
- 模块
- 命名空间
- 类
- 文件

- 文件列表
- 文件成员

NPLA.cpp
浏览该文件的文档.
1 /*
2 © 2014-2017 FrankHB.
3
4 This file is part of the YSLib project, and may only be used,
5 modified, and distributed under the terms of the YSLib project
6 license, LICENSE.TXT. By continuing to use, modify, or distribute
7 this file you indicate that you have read the license and
8 understand and accept it fully.
9 */
10
28 #include "NPL/YModules.h"
29 #include YFM_NPL_NPLA
30 #include YFM_NPL_SContext
31
32 using namespace YSLib;
33
34 namespace NPL
35 {
36
37 ValueNode
38 MapNPLALeafNode(const TermNode& term)
39 {
40 return AsNode(string(),
41 string(Deliteralize(ParseNPLANodeString(MapToValueNode(term)))));
42 }
43
44 ValueNode
45 TransformToSyntaxNode(const ValueNode& node, const string& name)
46 {
47 ValueNode::Container con{AsIndexNode(size_t(), node.GetName())};
48 const auto nested_call([&](const ValueNode& nd){
49 con.emplace(TransformToSyntaxNode(nd, MakeIndex(con)));
50 });
51
52 if(node.empty())
53 {
54 if(const auto p = AccessPtr<NodeSequence>(node))
55 for(auto& nd : *p)
56 nested_call(nd);
57 else
58 con.emplace(NoContainer, MakeIndex(1),
59 Literalize(ParseNPLANodeString(node)));
60 }
61 else
62 for(auto& nd : node)
63 nested_call(nd);
64 return {std::move(con), name};
65 }
66
67 string
68 EscapeNodeLiteral(const ValueNode& node)
69 {
70 return EscapeLiteral(Access<string>(node));
71 }
72
73 string
74 LiteralizeEscapeNodeLiteral(const ValueNode& node)
75 {
76 return Literalize(EscapeNodeLiteral(node));
77 }
78
79 string
80 ParseNPLANodeString(const ValueNode& node)
81 {
82 return ystdex::value_or(AccessPtr<string>(node));
83 }
84
85
86 string
87 DefaultGenerateIndent(size_t n)
88 {
89 return string(n, '\t');
90 }
91
92 void
93 PrintIndent(std::ostream& os, IndentGenerator igen, size_t n)
94 {
95 if(YB_LIKELY(n != 0))
96 ystdex::write(os, igen(n));
97 }
98
99 void
100 PrintNode(std::ostream& os, const ValueNode& node, NodeToString node_to_str,
101 IndentGenerator igen, size_t depth)
102 {
103 PrintIndent(os, igen, depth);
104 os << EscapeLiteral(node.GetName()) << ' ';
105 if(PrintNodeString(os, node, node_to_str))
106 return;
107 os << '\n';
108 if(node)
109 {
110 const auto nested_call(std::bind(PrintNodeChild, std::ref(os),
111 std::placeholders::_1, node_to_str, igen, depth));
112
113 // TODO: Null coalescing or variant value?
114 if(const auto p = AccessPtr<NodeSequence>(node))
115 for(const auto& nd : *p)
116 nested_call(nd);
117 else
118 for(const auto& nd : node)
119 nested_call(nd);
120 }
121 }
122
123 void
124 PrintNodeChild(std::ostream& os, const ValueNode& node,
125 NodeToString node_to_str, IndentGenerator igen, size_t depth)
126 {
127 PrintIndent(os, igen, depth);
128 if(IsPrefixedIndex(node.GetName()))
129 PrintNodeString(os, node, node_to_str);
130 else
131 {
132 os << '(' << '\n';
133 TryExpr(PrintNode(os, node, node_to_str, igen, depth + 1))
134 CatchIgnore(std::out_of_range&)
135 PrintIndent(os, igen, depth);
136 os << ')' << '\n';
137 }
138 }
139
140 bool
141 PrintNodeString(std::ostream& os, const ValueNode& node,
142 NodeToString node_to_str)
143 {
144 TryRet(os << node_to_str(node) << '\n', true)
145 CatchIgnore(ystdex::bad_any_cast&)
146 return {};
147 }
148
149
150 namespace SXML
151 {
152
153 string
154 ConvertAttributeNodeString(const TermNode& term)
155 {
156 switch(term.size())
157 {
158 default:
159 YTraceDe(Warning, "Invalid term with more than 2 children found.");
160 YB_ATTR_fallthrough;
161 case 2:
162 {
163 auto i(term.begin());
164 const auto& n(Access<string>(Deref(i)));
165
166 return n + '=' + Access<string>(Deref(++i));
167 }
168 YB_ATTR_fallthrough;
169 case 1:
170 return Access<string>(Deref(term.begin()));
171 case 0:
172 break;
173 }
174 throw LoggedEvent("Invalid term with less than 1 children found.", Warning);
175 }
176
177 string
178 ConvertDocumentNode(const TermNode& term, IndentGenerator igen, size_t depth,
179 ParseOption opt)
180 {
181 if(term)
182 {
183 string res(ConvertStringNode(term));
184
185 if(res.empty())
186 {
187 if(opt == ParseOption::String)
188 throw LoggedEvent("Invalid non-string term found.");
189
190 const auto& con(term.GetContainer());
191
192 if(!con.empty())
193 try
194 {
195 auto i(con.cbegin());
196 const auto& str(Access<string>(Deref(i)));
197
198 ++i;
199 if(str == "@")
200 {
201 for(; i != con.cend(); ++i)
202 res += ' ' + ConvertAttributeNodeString(Deref(i));
203 return res;
204 }
205 if(opt == ParseOption::Attribute)
206 throw LoggedEvent("Invalid non-attribute term found.");
207 if(str == "*PI*")
208 {
209 res = "<?";
210 for(; i != con.cend(); ++i)
211 res += string(Deliteralize(ConvertDocumentNode(
212 Deref(i), igen, depth, ParseOption::String)))
213 + ' ';
214 if(!res.empty())
215 res.pop_back();
216 return res + "?>";
217 }
218 if(str == "*ENTITY*" || str == "*NAMESPACES*")
219 {
220 if(opt == ParseOption::Strict)
221 throw ystdex::unimplemented();
222 }
223 else if(str == "*COMMENT*")
224 ;
225 else if(!str.empty())
226 {
227 const bool is_content(str != "*TOP*");
228 string head('<' + str);
229 bool nl{};
230
231 if(YB_UNLIKELY(!is_content && depth > 0))
232 YTraceDe(Warning, "Invalid *TOP* found.");
233 if(i != con.end())
234 {
235 if(!Deref(i).empty()
236 && (i->begin())->Value == string("@"))
237 {
238 head += string(
239 Deliteralize(ConvertDocumentNode(*i, igen,
240 depth, ParseOption::Attribute)));
241 if(++i == con.cend())
242 return head + " />";
243 }
244 head += '>';
245 }
246 else
247 return head + " />";
248 for(; i != con.cend(); ++i)
249 {
250 nl = Deref(i).Value.type()
251 != ystdex::type_id<string>();
252 if(nl)
253 res += '\n' + igen(depth + size_t(is_content));
254 else
255 res += ' ';
256 res += string(Deliteralize(ConvertDocumentNode(*i,
257 igen, depth + size_t(is_content))));
258 }
259 if(res.size() > 1 && res.front() == ' ')
260 res.erase(0, 1);
261 if(!res.empty() && res.back() == ' ')
262 res.pop_back();
263 if(is_content)
264 {
265 if(nl)
266 res += '\n' + igen(depth);
267 return head + res + ystdex::quote(str, "</", '>');
268 }
269 }
270 else
271 throw LoggedEvent("Empty item found.", Warning);
272 }
273 CatchExpr(ystdex::bad_any_cast& e, YTraceDe(Warning,
274 "Conversion failed: <%s> to <%s>.", e.from(), e.to()))
275 }
276 return res;
277 }
278 throw LoggedEvent("Empty term found.", Warning);
279 }
280
281 string
282 ConvertStringNode(const TermNode& term)
283 {
284 return ystdex::call_value_or(EscapeXML, AccessPtr<string>(term));
285 }
286
287 void
288 PrintSyntaxNode(std::ostream& os, const TermNode& term, IndentGenerator igen,
289 size_t depth)
290 {
291 if(IsBranch(term))
292 ystdex::write(os,
293 ConvertDocumentNode(Deref(term.begin()), igen, depth), 1);
294 os << std::flush;
295 }
296
297
298 ValueNode
299 MakeXMLDecl(const string& name, const string& ver, const string& enc,
300 const string& sd)
301 {
302 auto decl("version=\"" + ver + '"');
303
304 if(!enc.empty())
305 decl += " encoding=\"" + enc + '"';
306 if(!sd.empty())
307 decl += " standalone=\"" + sd + '"';
308 return AsNodeLiteral(name, {{MakeIndex(0), "*PI*"}, {MakeIndex(1), "xml"},
309 {MakeIndex(2), decl + ' '}});
310 }
311
312 ValueNode
313 MakeXMLDoc(const string& name, const string& ver, const string& enc,
314 const string& sd)
315 {
316 auto doc(MakeTop(name));
317
318 doc.Add(MakeXMLDecl(MakeIndex(1), ver, enc, sd));
319 return doc;
320 }
321
322 } // namespace SXML;
323
324
326 namespace
327 {
328
330 string
331 InitBadIdentifierExceptionString(string&& id, size_t n)
332 {
333 return (n != 0 ? (n == 1 ? "Bad identifier: '" : "Duplicate identifier: '")
334 : "Unknown identifier: '") + std::move(id) + "'.";
335 }
336
337 } // unnamed namespace;
338
339
340 ImplDeDtor(NPLException)
341
342
343 ImplDeDtor(ListReductionFailure)
344
345
346 ImplDeDtor(InvalidSyntax)
347
348
349 ImplDeDtor(ParameterMismatch)
350
351
352 ArityMismatch::ArityMismatch(size_t e, size_t r, RecordLevel lv)
353 : ParameterMismatch(
354 ystdex::sfmt("Arity mismatch: expected %zu, received %zu.", e, r), lv),
355 expected(e), received(r)
356 {}
357 ImplDeDtor(ArityMismatch)
358
359
360 BadIdentifier::BadIdentifier(const char* id, size_t n, RecordLevel lv)
361 : NPLException(InitBadIdentifierExceptionString(id, n), lv),
362 p_identifier(make_shared<string>(id))
363 {}
364 BadIdentifier::BadIdentifier(string_view id, size_t n, RecordLevel lv)
365 : NPLException(InitBadIdentifierExceptionString(string(id), n), lv),
366 p_identifier(make_shared<string>(id))
367 {}
368 ImplDeDtor(BadIdentifier)
369
370
371 LexemeCategory
372 CategorizeBasicLexeme(string_view id) ynothrowv
373 {
374 YAssertNonnull(id.data() && !id.empty());
375
376 const auto c(CheckLiteral(id));
377
378 if(c == '\'')
379 return LexemeCategory::Code;
380 if(c != char())
381 return LexemeCategory::Data;
382 return LexemeCategory::Symbol;
383 }
384
385 LexemeCategory
386 CategorizeLexeme(string_view id) ynothrowv
387 {
388 const auto res(CategorizeBasicLexeme(id));
389
390 return res == LexemeCategory::Symbol && IsNPLAExtendedLiteral(id)
391 ? LexemeCategory::Extended : res;
392 }
393
394 bool
395 IsNPLAExtendedLiteral(string_view id) ynothrowv
396 {
397 YAssertNonnull(id.data() && !id.empty());
398
399 const char f(id.front());
400
401 return (id.size() > 1 && IsNPLAExtendedLiteralNonDigitPrefix(f)
402 && id.find_first_not_of("+-") != string_view::npos)
403 || std::isdigit(f);
404 }
405
406
407 observer_ptr<const TokenValue>
408 TermToNamePtr(const TermNode& term)
409 {
410 return AccessPtr<TokenValue>(term);
411 }
412
413 void
414 TokenizeTerm(TermNode& term)
415 {
416 for(auto& child : term)
417 TokenizeTerm(child);
418 if(const auto p = AccessPtr<string>(term))
419 term.Value.emplace<TokenValue>(std::move(*p));
420 }
421
422
423 TermNode&
424 ReferenceTerm(TermNode& term)
425 {
426 return ystdex::call_value_or(
427 [&](const TermReference& term_ref) ynothrow -> TermNode&{
428 return term_ref.get();
429 }, AccessPtr<TermReference>(term), term);
430 }
431 const TermNode&
432 ReferenceTerm(const TermNode& term)
433 {
434 return ystdex::call_value_or(
435 [&](const TermReference& term_ref) ynothrow -> const TermNode&{
436 return term_ref.get();
437 }, AccessPtr<TermReference>(term), term);
438 }
439
440
441 bool
442 CheckReducible(ReductionStatus status)
443 {
444 if(status == ReductionStatus::Clean
445 || status == ReductionStatus::Retained)
446 return {};
447 if(YB_UNLIKELY(status != ReductionStatus::Retrying))
448 YTraceDe(Warning, "Unexpected status found.");
449 return true;
450 }
451
452
453 void
454 LiftTerm(TermNode& term, TermNode& tm)
455 {
456 // NOTE: This is required to avoid cyclic reference when the object
457 // referenced by the 2nd parameter is owned by the object referenced by the
458 // 1st parameter.
459 auto t(std::move(tm.GetContainerRef()));
460
461 term.SetContent(std::move(t), std::move(tm.Value));
462 }
463
464 ValueObject
465 LiftTermObject(const ValueObject& vo)
466 {
467 if(vo.type() == ystdex::type_id<TokenValue>())
468 return vo;
469 return vo.MakeIndirect();
470 }
471
472 void
473 LiftTermOrRef(TermNode& term, TermNode& tm)
474 {
475 if(const auto p = AccessPtr<TermReference>(tm))
476 LiftTermRef(term, p->get());
477 else
478 LiftTerm(term, tm);
479 }
480
481 void
482 LiftToReference(TermNode& term, TermNode& tm)
483 {
484 if(tm)
485 {
486 if(const auto p = AccessPtr<TermReference>(tm))
487 LiftTermRef(term, p->get());
488 else if(!tm.Value.OwnsUnique())
489 LiftTerm(term, tm);
490 else
491 throw NPLException(
492 "Value of a temporary shall not be referenced.");
493 }
494 else
495 ystdex::throw_invalid_construction();
496 }
497
498 void
499 LiftToSelf(TermNode& term)
500 {
501 for(auto& child : term)
502 LiftToSelf(child);
503 LiftTermOrRef(term, term);
504 }
505
506 void
507 LiftToOther(TermNode& term, TermNode& tm)
508 {
509 LiftToSelf(tm);
510 LiftTerm(term, tm);
511 }
512
513
514 ReductionStatus
515 ReduceHeadEmptyList(TermNode& term) ynothrow
516 {
517 if(term.size() > 1 && IsEmpty(Deref(term.begin())))
518 RemoveHead(term);
519 return ReductionStatus::Clean;
520 }
521
522 ReductionStatus
523 ReduceToList(TermNode& term) ynothrow
524 {
525 return IsBranch(term) ? (void(RemoveHead(term)), ReductionStatus::Retained)
526 : ReductionStatus::Clean;
527 }
528
529
531 namespace
532 {
533
534 yconstfn_relaxed bool
535 IsReserved(string_view id) ynothrowv
536 {
537 YAssertNonnull(id.data());
538 return ystdex::begins_with(id, "__");
539 }
540
541 observer_ptr<Environment>
542 RedirectToShared(string_view id, const shared_ptr<Environment>& p_shared)
543 {
544 if(p_shared)
545 return make_observer(get_raw(p_shared));
546 // TODO: Use concrete semantic failure exception.
547 throw NPLException(ystdex::sfmt("Invalid reference found for%s name '%s',"
548 " probably due to invalid context access by dangling reference.",
549 IsReserved(id) ? " reserved" : "", id.data()));
550 }
551
552 observer_ptr<const Environment>
553 RedirectParent(const ValueObject& parent, string_view id)
554 {
555 const auto& tp(parent.type());
556
557 if(tp == ystdex::type_id<EnvironmentList>())
558 for(const auto& vo : parent.GetObject<EnvironmentList>())
559 {
560 auto p(RedirectParent(vo, id));
561
562 if(p)
563 return p;
564 }
565 if(tp == ystdex::type_id<observer_ptr<const Environment>>())
566 return parent.GetObject<observer_ptr<const Environment>>();
567 if(tp == ystdex::type_id<weak_ptr<Environment>>())
568 return RedirectToShared(id,
569 parent.GetObject<weak_ptr<Environment>>().lock());
570 if(tp == ystdex::type_id<shared_ptr<Environment>>())
571 return RedirectToShared(id,
572 parent.GetObject<shared_ptr<Environment>>());
573 return {};
574 }
575
576 } // unnamed namespace;
577
578 void
579 Environment::CheckParent(const ValueObject& vo)
580 {
581 const auto& tp(vo.type());
582
583 if(tp == ystdex::type_id<EnvironmentList>())
584 {
585 for(const auto& env : vo.GetObject<EnvironmentList>())
586 CheckParent(env);
587 }
588 else if(YB_UNLIKELY(tp != ystdex::type_id<observer_ptr<const Environment>>()
589 && tp != ystdex::type_id<weak_ptr<Environment>>()
590 && tp != ystdex::type_id<shared_ptr<Environment>>()))
591 ThrowForInvalidType(tp);
592 }
593
594 observer_ptr<const Environment>
595 Environment::DefaultRedirect(const Environment& env, string_view id)
596 {
597 return RedirectParent(env.Parent, id);
598 }
599
600 observer_ptr<ValueNode>
601 Environment::DefaultResolve(const Environment& e, string_view id)
602 {
603 YAssertNonnull(id.data());
604
605 observer_ptr<ValueNode> p;
606 auto env_ref(ystdex::ref<const Environment>(e));
607
608 ystdex::retry_on_cond(
609 [&](observer_ptr<const Environment> p_env) ynothrow -> bool{
610 if(p_env)
611 {
612 env_ref = ystdex::ref(Deref(p_env));
613 return true;
614 }
615 return {};
616 }, [&, id]() -> observer_ptr<const Environment>{
617 auto& env(env_ref.get());
618
619 p = env.LookupName(id);
620 return p ? observer_ptr<const Environment>() : env.Redirect(id);
621 });
622 return p;
623 }
624
625 void
626 Environment::Define(string_view id, ValueObject&& vo, bool forced)
627 {
628 YAssertNonnull(id.data());
629 if(forced)
630 // XXX: Self overwriting is possible.
631 swap(Bindings[id].Value, vo);
632 else if(!Bindings.AddValue(id, std::move(vo)))
633 throw BadIdentifier(id, 2);
634 }
635
636 observer_ptr<ValueNode>
637 Environment::LookupName(string_view id) const
638 {
639 YAssertNonnull(id.data());
640 return AccessNodePtr(Bindings, id);
641 }
642
643 void
644 Environment::Redefine(string_view id, ValueObject&& vo, bool forced)
645 {
646 if(const auto p = LookupName(id))
647 swap(p->Value, vo);
648 else if(!forced)
649 throw BadIdentifier(id, 0);
650 }
651
652 bool
653 Environment::Remove(string_view id, bool forced)
654 {
655 YAssertNonnull(id.data());
656 if(Bindings.Remove(id))
657 return true;
658 if(forced)
659 return {};
660 throw BadIdentifier(id, 0);
661 }
662
663 void
664 Environment::ThrowForInvalidType(const ystdex::type_info& tp)
665 {
666 throw NPLException(ystdex::sfmt("Invalid environment type '%s' found.",
667 tp.name()));
668 }
669
670
671 ContextNode::ContextNode(const ContextNode& ctx,
672 shared_ptr<Environment>&& p_rec)
673 : p_record([&]{
674 if(p_rec)
675 return std::move(p_rec);
676 throw std::invalid_argument(
677 "Invalid environment record pointer found.");
678 }()),
679 EvaluateLeaf(ctx.EvaluateLeaf), EvaluateList(ctx.EvaluateList),
680 EvaluateLiteral(ctx.EvaluateLiteral)
681 {}
682 ContextNode::ContextNode(ContextNode&& ctx)
683 : ContextNode()
684 {
685 swap(*this, ctx);
686 }
687
688 } // namespace NPL;
689
YTraceDe
#define YTraceDe(...)
YCLib 默认调试跟踪。
Definition: Debug.h:313
NPL::SXML::ConvertDocumentNode
YF_API string ConvertDocumentNode(const TermNode &, IndentGenerator=DefaultGenerateIndent, size_t=0, ParseOption=ParseOption::Normal)
转换 SXML 文档节点为 XML 字符串。
Definition: NPLA.cpp:178
NPL::Environment::DefaultResolve
static observer_ptr< ValueNode > DefaultResolve(const Environment &, string_view)
解析名称：处理保留名称并查找名称。 访问共享重定向环境失败。
Definition: NPLA.cpp:601
NPL::CategorizeBasicLexeme
YF_API LexemeCategory CategorizeBasicLexeme(string_view) ynothrowv
对排除扩展字面量的词素分类。
NPL::ReferenceTerm
YF_API TermNode & ReferenceTerm(TermNode &)
访问项并取解析 TermReference 间接值后的引用。
Definition: NPLA.cpp:424
NPL::SXML::ConvertAttributeNodeString
YF_API string ConvertAttributeNodeString(const TermNode &)
转换 SXML 节点为 XML 属性字符串。
Definition: NPLA.cpp:154
NPL::SXML::ConvertStringNode
YF_API string ConvertStringNode(const TermNode &)
转换 SXML 节点为被转义的 XML 字符串。
Definition: NPLA.cpp:282
ystdex::bad_any_cast
动态泛型转换失败异常。
Definition: any.h:628
NPL::Environment::Redefine
void Redefine(string_view, ValueObject &&, bool)
以字符串为标识符在指定上下文中覆盖定义值。
Definition: NPLA.cpp:644
NPL::SXML::ParseOption
ParseOption
限定解析选项。
Definition: NPL.h:60
ystdex::isdigit
bool isdigit(char c)
区域无关的 std::isdigit 实现。
Definition: cctype.h:122
ystdex::begins_with
bool begins_with(const _tRange1 &input, const _tRange2 &test, _fPred comp)
判断第一个参数指定的串是否以第二个参数起始。
Definition: string.hpp:398
YSLib
YSLib 命名空间。
Definition: AndroidHost.h:45
NPL::Environment::Parent
ValueObject Parent
父环境：被解释的重定向目标。
Definition: NPLA.h:1032
NPL::LiftToReference
void LiftToReference(TermNode &term, TermNode &tm)
Definition: NPLA.cpp:482
NPL::ContextNode
上下文节点。
Definition: NPLA.h:1174
ystdex::make_observer
observer_ptr< _type > make_observer(_type *p)
Definition: pointer.hpp:326
YSLib::ValueObject::type
friend type
Definition: YObject.h:914
YSLib::MakeIndex
MakeIndex
Definition: ValueNode.h:1202
YSLib::ImplDeDtor
ImplDeDtor(LoggedEvent) FatalError
Definition: YException.cpp:47
platform::Deref
yconstfn auto Deref(_type &&p) -> decltype(*p)
断言并解引用非空指针。
Definition: Debug.h:451
NPL::ReductionStatus::Retrying
需要重规约。
NPL::LexemeCategory::Extended
扩展字面量：由 NPLA 定义的其它字面量类别。
NPL::NodeToString
std::function< string(const ValueNode &)> NodeToString
Definition: NPLA.h:114
YSLib::Drawing::r
The boundary is out of the const Graphics const Rect const Point const Point Color c const Rect const Rect & r
Definition: YDraw.h:174
NPL::LiftToSelf
PDefH(void, LiftTermRef, TermNode &term, const TermNode &tm) ImplExpr(YSLib YF_API void LiftToSelf(TermNode &)
提升项引用：使用第二个参数指定的项的内容引用替换第一个项的内容。
Definition: NPLA.h:840
YSLib::ValueObject::GetObject
_type & GetObject() ynothrowv
取指定类型的对象。
Definition: YObject.h:734
YModules.h
CHRLib::f
f(d, s)
ystdex::call_value_or
auto call_value_or(_func f, _type &&p) -> decay_t< decltype(f(*std::forward< decltype(p)>(p)))>
调用非空值或取默认值。
Definition: deref_op.hpp:140
NPL::CategorizeLexeme
YF_API LexemeCategory CategorizeLexeme(string_view) ynothrowv
对词素分类。
Definition: NPLA.cpp:386
NPL::LexemeCategory
LexemeCategory
字面量类别。
Definition: NPLA.h:534
YAssertNonnull
#define YAssertNonnull(_expr)
Definition: cassert.h:120
yconstfn_relaxed
#define yconstfn_relaxed
指定编译时没有 C++11 限制和隐式成员 const 的常量函数。
Definition: ydef.h:692
NPL::ListReductionFailure
列表规约失败。
Definition: NPLA.h:431
YB_UNLIKELY
#define YB_UNLIKELY(_expr)
分支预测提示。
Definition: ydef.h:464
NPL::ReductionStatus
ReductionStatus
规约状态：一遍规约可能的中间结果。
Definition: NPLA.h:633
YSLib::LoggedEvent
记录日志的异常事件类。
Definition: YException.h:50
TryRet
#define TryRet(...)
指定表达式在 try 块中求值并返回。
Definition: YBaseMacro.h:124
ystdex::make_shared
std::shared_ptr< _type > make_shared(std::initializer_list< _tValue > il)
使用指定类型的初始化列表构造指定类型的 std::shared_ptr 对象。
Definition: memory.hpp:945
platform::containers::string
basic_string< char > string
Definition: Container.h:101
NPL::PrintNodeString
YF_API bool PrintNodeString(std::ostream &, const ValueNode &, NodeToString=EscapeNodeLiteral)
打印节点字符串。
Definition: NPLA.cpp:141
CatchIgnore
#define CatchIgnore(_ex)
指定异常处理器忽略指定异常。
Definition: YBaseMacro.h:133
ystdex::data
auto data(_tRange &c) -> decltype(c.data())
Definition: range.hpp:280
YSLib::NoContainer
yconstexpr const struct YSLib::NoContainerTag NoContainer
YSLib::ValueNode::AddValue
bool AddValue(_tKey &&k, _tParams &&...args)
添加参数指定值的子节点。
Definition: ValueNode.h:387
NPL::PrintNodeChild
YF_API void PrintNodeChild(std::ostream &, const ValueNode &, NodeToString=EscapeNodeLiteral, IndentGenerator=DefaultGenerateIndent, size_t=0)
打印作为子节点的 NPLA 节点。
Definition: NPLA.cpp:124
YSLib::RecordLevel
YF_API RecordLevel
Definition: YException.h:142
NPL::ImplDeDtor
ImplDeDtor(NPLException) ImplDeDtor(ListReductionFailure) ImplDeDtor(InvalidSyntax) ImplDeDtor(ParameterMismatch) ArityMismatch
Definition: NPLA.cpp:340
platform::Descriptions::RecordLevel
RecordLevel
记录等级。
Definition: YCommon.h:161
TryExpr
#define TryExpr(...)
指定表达式在 try 块中求值。
Definition: YBaseMacro.h:120
NPL::ArityMismatch
元数不匹配错误。
Definition: NPLA.h:474
NPL::LexemeCategory::Symbol
符号：非字面量。
YSLib::AsNode
typename _tParams ValueNode AsNode(_tString &&str, _tParams &&...args)
Definition: ValueNode.h:1065
ystdex::quote
_tString quote(const _tString &str, typename string_traits< _tString >::value_type c=typename string_traits< _tString >::value_type('"'))
取添加前缀和后缀的字符串。
Definition: string.hpp:801
NPL::SXML::PrintSyntaxNode
YF_API void PrintSyntaxNode(std::ostream &os, const TermNode &, IndentGenerator=DefaultGenerateIndent, size_t=0)
打印 SContext::Analyze 分析取得的 SXML 语法树节点并刷新流。
Definition: NPLA.cpp:288
NPL::ReduceToList
YF_API ReductionStatus ReduceToList(TermNode &) ynothrow
规约为列表：对枝节点移除第一个子项，保留余下的子项作为列表。
Definition: NPLA.cpp:523
NPL::EscapeNodeLiteral
YF_API string EscapeNodeLiteral(const ValueNode &)
转义 NPLA 节点字面量。
Definition: NPLA.cpp:68
CatchExpr
#define CatchExpr(_ex,...)
指定表达式作为异常处理器。
Definition: YBaseMacro.h:129
YSLib::ValueObject
值类型对象类。
Definition: YObject.h:539
ynothrow
#define ynothrow
YSLib 无异常抛出保证：若支持 noexcept 关键字， 指定特定的 noexcept 异常规范。
Definition: ydef.h:766
YSLib::AsIndexNode
const ValueNode &node ImplRet(MakeIndex(node.GetContainer())) YF_API size_t GetLastIndexOf(const ValueNode typename _tParams ValueNode AsIndexNode(_tParam &&arg, _tParams &&...args)
Definition: ValueNode.h:1227
NPL::LexemeCategory::Data
数据字面量。
ystdex::sfmt
auto sfmt(const _tChar *fmt,...) -> decltype(vsfmt(fmt, std::declval< std::va_list >()))
以 C 标准输出格式的输出 std::basic_string 实例的对象。
Definition: string.hpp:1200
ystdex
特性测试宏。
Definition: ydef.h:822
NPL::Environment
环境。
Definition: NPLA.h:982
NPL::ParseNPLANodeString
YF_API string ParseNPLANodeString(const ValueNode &)
解析 NPLA 节点字符串。
Definition: NPLA.cpp:80
YSLib::AccessNodePtr
YF_API observer_ptr< ValueNode > AccessNodePtr(ValueNode::Container &, const string &) ynothrow
访问节点指针。
Definition: ValueNode.cpp:113
NPL::TermNode
yimpl(ValueNode) TermNode
项节点：存储语法分析结果的值类型节点。
Definition: SContext.h:51
YSLib::i
return i
Definition: YCoreUtilities.h:176
NPL::EscapeLiteral
YF_API string EscapeLiteral(string_view)
编码转义字符串字面量。
Definition: Lexical.cpp:329
NPL::IndentGenerator
std::function< string(size_t)> IndentGenerator
生成前缀缩进的函数类型。
Definition: NPLA.h:209
NPL::BadIdentifier
标识符错误。
Definition: NPLA.h:500
NPL::TermToNamePtr
YF_API observer_ptr< const TokenValue > TermToNamePtr(const TermNode &)
访问项的值作为记号。
Definition: NPLA.cpp:408
NPL::Environment::Define
void Define(string_view, ValueObject &&, bool)
以字符串为标识符在指定上下文中定义值。
Definition: NPLA.cpp:626
NPL::Environment::ThrowForInvalidType
static YB_NORETURN void ThrowForInvalidType(const ystdex::type_info &)
对不符合环境要求的类型抛出异常。
Definition: NPLA.cpp:664
NPL::LexemeCategory::Code
代码字面量。
CHRLib::enc
enc
Definition: CharacterProcessing.h:81
NPL::Environment::LookupName
observer_ptr< ValueNode > LookupName(string_view) const
查找名称。
Definition: NPLA.cpp:637
ystdex::fseq::front
identity< _type > front(empty_base< _type, _types... >)
Definition: variadic.hpp:74
NPL::PrintIndent
YF_API void PrintIndent(std::ostream &, IndentGenerator=DefaultGenerateIndent, size_t=1)
异常中立：参数指定的处理器为空。
Definition: NPLA.cpp:93
NPL::Environment::Bindings
BindingMap Bindings
Definition: NPLA.h:990
ynothrowv
#define ynothrowv
YSLib 无异常抛出保证验证：有条件地使用无异常抛出规范。
Definition: ydef.h:786
YSLib::RemoveHead
YF_API void RemoveHead(ValueNode::Container &) ynothrowv
移除首个子节点。
Definition: ValueNode.cpp:164
ystdex::bad_any_cast::from
const char * from() const
Definition: any.cpp:44
platform::FAT::Attribute
Attribute
文件属性。
Definition: YCLib/FileSystem.h:808
CHRLib::e
const char const char * e
Definition: CharacterProcessing.h:109
NPL::LiftTermObject
ValueObject LiftTermObject(const ValueObject &vo)
Definition: NPLA.cpp:465
YSLib::ValueNode::Remove
Remove
Definition: ValueNode.h:539
ystdex::swap
void swap(container_adaptor< _tSeqCon > &x, container_adaptor< _tSeqCon > &y)
Definition: container.hpp:179
YSLib::ValueNode
值类型节点。
Definition: ValueNode.h:58
NPL::ReduceHeadEmptyList
ReductionStatus ReduceHeadEmptyList(TermNode &term) ynothrow
Definition: NPLA.cpp:515
NPL::InvalidSyntax
语法错误。
Definition: NPLA.h:444
NPL::MapNPLALeafNode
YF_API ValueNode MapNPLALeafNode(const TermNode &)
映射 NPLA 叶节点。
Definition: NPLA.cpp:38
ystdex::type_id
const type_info & type_id()
Definition: typeinfo.h:149
ystdex::value_or
auto value_or(_type &&p) -> decay_t< decltype(*std::forward< decltype(p)>(p))>
取非空值或默认值。
Definition: deref_op.hpp:116
NPL
Definition: NPL/Configuration.h:34
NPL::ReductionStatus::Clean
规约成功终止且不需要保留子项。
ystdex::mapped_set
允许指定不同于值类型的键的集合。
Definition: set.hpp:160
NPL::DefaultGenerateIndent
YF_API string DefaultGenerateIndent(size_t)
生成水平制表符为单位的缩进。
Definition: NPLA.cpp:87
ystdex::unimplemented
异常：未实现的操作。
Definition: ystdex/exception.h:135
platform::Descriptions::Warning
Definition: YCommon.h:167
NPL::SXML::MakeTop
ValueNode MakeTop(const string &name, _tParams &&...args)
构造 SXML 文档顶级节点。
Definition: NPLA.h:325
NPL::CheckReducible
bool CheckReducible(ReductionStatus status)
Definition: NPLA.cpp:442
ystdex::throw_invalid_construction
void throw_invalid_construction()
Definition: ystdex/exception.cpp:49
YSLib::UI::name
yconstfn const string & name
Definition: Loader.h:130
NPL::Deliteralize
YF_API string_view Deliteralize(string_view) ynothrowv
去除字面量边界分隔符。
Definition: Lexical.cpp:249
YSLib::Text::str
const char const char * str
Definition: TextFile.h:81
ystdex::get_raw
_type * get_raw(_type *const &p)
Definition: memory.hpp:544
CHRLib::c
c
Definition: CharacterProcessing.h:81
NPL::TransformToSyntaxNode
YF_API ValueNode TransformToSyntaxNode(const ValueNode &, const string &={})
变换节点为语法分析树叶节点。
Definition: NPLA.cpp:45
NPL::CheckLiteral
YF_API char CheckLiteral(string_view) ynothrowv
检查指定字符串是否为字面量。
Definition: Lexical.cpp:236
ystdex::retry_on_cond
result_of_t< _fCallable &&(_tParams &&...)> retry_on_cond(_fCond cond, _fCallable &&f, _tParams &&...args)
循环重复调用：代替直接使用 do-while 语句以避免过多引入作用域外的变量。
Definition: functional.hpp:1152
YSLib::ValueNode::empty
const container container empty
Definition: ValueNode.h:631
NPL::SXML::MakeXMLDoc
YF_API ValueNode MakeXMLDoc(const string &={}, const string &="1.0", const string &="UTF-8", const string &={})
构造包含 XML 声明的 SXML 文档节点。
Definition: NPLA.cpp:313
NPL::TokenizeTerm
YF_API void TokenizeTerm(TermNode &term)
标记记号节点：递归变换节点，转换其中的词素为记号值。
Definition: NPLA.cpp:414
NPL::SXML::MakeXMLDecl
YF_API ValueNode MakeXMLDecl(const string &={}, const string &="1.0", const string &="UTF-8", const string &={})
构造 SXML 文档 XML 声明节点。
Definition: NPLA.cpp:299
NPL::NPLException
NPL 异常基类。
Definition: NPLA.h:409
NPL::MapToValueNode
const TermNode &term ynothrow const TermNode &term ynothrow const TermNode &term ynothrow TermNode &term const TermNode &term MapToValueNode
Definition: SContext.h:80
NPL::ParameterMismatch
参数匹配失败。
Definition: NPLA.h:459
ystdex::size
auto size(const _tRange &c) -> decltype(c.size())
类容器访问。
Definition: range.hpp:233
NPL::Literalize
YF_API string Literalize(string_view, char= '"')
修饰字符串为字面量。
Definition: Lexical.cpp:371
YSLib::vo
vo
Definition: YApplication.h:231
YB_LIKELY
#define YB_LIKELY(_expr)
Definition: ydef.h:463
NPL::Environment::DefaultRedirect
static observer_ptr< const Environment > DefaultRedirect(const Environment &, string_view)
重定向解析环境：返回父环境。
Definition: NPLA.cpp:595
ystdex::bad_any_cast::to
const char * to() const
Definition: any.cpp:51
YB_ATTR_fallthrough
#define YB_ATTR_fallthrough
用于 switch 语句的 fallthrough 属性。
Definition: ydef.h:383
NPL::LiftTermOrRef
YF_API void LiftTermOrRef(TermNode &, TermNode &)
提升项或创建引用项。
Definition: NPLA.cpp:473
NPL::TermReference
项引用。
Definition: NPLA.h:667
ystdex::ref
lref< _type > ref(_type &t)
构造引用包装。
Definition: ref.hpp:132
NPL::IsEmpty
IsEmpty
Definition: SContext.h:64
ystdex::write
std::basic_ostream< _tChar, typename _tString::traits_type > & write(std::basic_ostream< _tChar, typename _tString::traits_type > &os, const _tString &str, typename _tString::size_type pos=0, typename _tString::size_type n=_tString::npos)
非格式输出。
Definition: string.hpp:981
NPL::IsNPLAExtendedLiteral
YF_API bool IsNPLAExtendedLiteral(string_view) ynothrowv
判断不是非扩展字面量的词素是否为 NPLA 扩展字面量。
Definition: NPLA.cpp:395
NPL::LiteralizeEscapeNodeLiteral
YF_API string LiteralizeEscapeNodeLiteral(const ValueNode &)
转义 NPLA 节点字面量。
Definition: NPLA.cpp:74
NPL::PrintNode
YF_API void PrintNode(std::ostream &, const ValueNode &, NodeToString=EscapeNodeLiteral, IndentGenerator=DefaultGenerateIndent, size_t=0)
打印 NPLA 节点。
Definition: NPLA.cpp:100
NPL::ReductionStatus::Retained
规约成功但需要保留子项。
ystdex::string_view
basic_string_view< char > string_view
Definition: string_view.hpp:415
NPL::EscapeXML
YF_API string EscapeXML(string_view)
编码 XML 字符串。
Definition: Lexical.cpp:341
NPL::LiftToOther
YF_API void LiftToOther(TermNode &, TermNode &)
递归提升项及其子项或递归创建项和子项对应的包含间接值的引用项到其它项。
Definition: NPLA.cpp:507
CHRLib::p
const auto p(d)
YSLib::lv
RecordLevel lv
Definition: YException.cpp:58
YSLib::IsPrefixedIndex
YF_API bool IsPrefixedIndex(string_view, char= '$')
判断字符串是否是前缀索引：一个指定字符和非负整数的组合。
Definition: ValueNode.cpp:172
NPL::EnvironmentList
vector< ValueObject > EnvironmentList
环境列表。
Definition: NPLA.h:974
NPL::LiftTerm
YF_API void LiftTerm(TermNode &, TermNode &)
提升项：使用第二个参数指定的项的内容替换第一个项的内容。
Definition: NPLA.cpp:454
NPL::Environment::Remove
bool Remove(string_view, bool)
Definition: NPLA.cpp:653