aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLi Jin <dragon-fly@qq.com>2023-01-20 16:57:58 +0800
committerLi Jin <dragon-fly@qq.com>2023-01-20 16:58:04 +0800
commit89b606df6303a44f121be8ff0f4458c97f93d9df (patch)
tree9e863026e48eb9fe35a4cde7cf3e34353f2d683d
parent2fad28df04f2c8f015ccf90e16e74c47ad174bde (diff)
downloadyuescript-89b606df6303a44f121be8ff0f4458c97f93d9df.tar.gz
yuescript-89b606df6303a44f121be8ff0f4458c97f93d9df.tar.bz2
yuescript-89b606df6303a44f121be8ff0f4458c97f93d9df.zip
try auto merging parser call stacks.
-rw-r--r--src/yuescript/parser.cpp306
-rw-r--r--src/yuescript/parser.hpp14
-rw-r--r--src/yuescript/yue_parser.cpp529
-rw-r--r--src/yuescript/yue_parser.h1
4 files changed, 491 insertions, 359 deletions
diff --git a/src/yuescript/parser.cpp b/src/yuescript/parser.cpp
index be38e83..078e23f 100644
--- a/src/yuescript/parser.cpp
+++ b/src/yuescript/parser.cpp
@@ -176,6 +176,14 @@ private:
176 bool _parse_term(rule& r); 176 bool _parse_term(rule& r);
177}; 177};
178 178
179enum class EXPR_TYPE {
180 NORMAL,
181 SEQ_TWO,
182 SEQ_LIST,
183 CHOICE_TWO,
184 CHOICE_LIST
185};
186
179// base class for expressions 187// base class for expressions
180class _expr { 188class _expr {
181public: 189public:
@@ -188,6 +196,8 @@ public:
188 196
189 // parse terminal 197 // parse terminal
190 virtual bool parse_term(_context& con) const = 0; 198 virtual bool parse_term(_context& con) const = 0;
199
200 virtual EXPR_TYPE get_type() const { return EXPR_TYPE::NORMAL; }
191}; 201};
192 202
193// single character expression. 203// single character expression.
@@ -199,12 +209,12 @@ public:
199 } 209 }
200 210
201 // parse with whitespace 211 // parse with whitespace
202 virtual bool parse_non_term(_context& con) const { 212 virtual bool parse_non_term(_context& con) const override {
203 return _parse(con); 213 return _parse(con);
204 } 214 }
205 215
206 // parse terminal 216 // parse terminal
207 virtual bool parse_term(_context& con) const { 217 virtual bool parse_term(_context& con) const override {
208 return _parse(con); 218 return _parse(con);
209 } 219 }
210 220
@@ -235,12 +245,12 @@ public:
235 } 245 }
236 246
237 // parse with whitespace 247 // parse with whitespace
238 virtual bool parse_non_term(_context& con) const { 248 virtual bool parse_non_term(_context& con) const override {
239 return _parse(con); 249 return _parse(con);
240 } 250 }
241 251
242 // parse terminal 252 // parse terminal
243 virtual bool parse_term(_context& con) const { 253 virtual bool parse_term(_context& con) const override {
244 return _parse(con); 254 return _parse(con);
245 } 255 }
246 256
@@ -250,8 +260,8 @@ private:
250 260
251 // parse the string 261 // parse the string
252 bool _parse(_context& con) const { 262 bool _parse(_context& con) const {
253 for (input::const_iterator it = m_string.begin(), 263 for (auto it = m_string.begin(),
254 end = m_string.end(); 264 end = m_string.end();
255 ;) { 265 ;) {
256 if (it == end) return true; 266 if (it == end) return true;
257 if (con.end()) break; 267 if (con.end()) break;
@@ -286,12 +296,12 @@ public:
286 } 296 }
287 297
288 // parse with whitespace 298 // parse with whitespace
289 virtual bool parse_non_term(_context& con) const { 299 virtual bool parse_non_term(_context& con) const override {
290 return _parse(con); 300 return _parse(con);
291 } 301 }
292 302
293 // parse terminal 303 // parse terminal
294 virtual bool parse_term(_context& con) const { 304 virtual bool parse_term(_context& con) const override {
295 return _parse(con); 305 return _parse(con);
296 } 306 }
297 307
@@ -358,12 +368,12 @@ public:
358 } 368 }
359 369
360 // parse with whitespace 370 // parse with whitespace
361 virtual bool parse_non_term(_context& con) const { 371 virtual bool parse_non_term(_context& con) const override {
362 return m_expr->parse_term(con); 372 return m_expr->parse_term(con);
363 } 373 }
364 374
365 // parse terminal 375 // parse terminal
366 virtual bool parse_term(_context& con) const { 376 virtual bool parse_term(_context& con) const override {
367 return m_expr->parse_term(con); 377 return m_expr->parse_term(con);
368 } 378 }
369}; 379};
@@ -378,7 +388,7 @@ public:
378 } 388 }
379 389
380 // parse with whitespace 390 // parse with whitespace
381 virtual bool parse_non_term(_context& con) const { 391 virtual bool parse_non_term(_context& con) const override {
382 pos pos = con.m_pos; 392 pos pos = con.m_pos;
383 if (m_expr->parse_non_term(con)) { 393 if (m_expr->parse_non_term(con)) {
384 item_t item = {&pos, &con.m_pos, con.m_user_data}; 394 item_t item = {&pos, &con.m_pos, con.m_user_data};
@@ -388,7 +398,7 @@ public:
388 } 398 }
389 399
390 // parse terminal 400 // parse terminal
391 virtual bool parse_term(_context& con) const { 401 virtual bool parse_term(_context& con) const override {
392 pos pos = con.m_pos; 402 pos pos = con.m_pos;
393 if (m_expr->parse_term(con)) { 403 if (m_expr->parse_term(con)) {
394 item_t item = {&pos, &con.m_pos, con.m_user_data}; 404 item_t item = {&pos, &con.m_pos, con.m_user_data};
@@ -410,7 +420,7 @@ public:
410 } 420 }
411 421
412 // parse with whitespace 422 // parse with whitespace
413 virtual bool parse_non_term(_context& con) const { 423 virtual bool parse_non_term(_context& con) const override {
414 // if parsing of the first fails, restore the context and stop 424 // if parsing of the first fails, restore the context and stop
415 _state st(con); 425 _state st(con);
416 if (!m_expr->parse_non_term(con)) { 426 if (!m_expr->parse_non_term(con)) {
@@ -431,7 +441,7 @@ public:
431 } 441 }
432 442
433 // parse terminal 443 // parse terminal
434 virtual bool parse_term(_context& con) const { 444 virtual bool parse_term(_context& con) const override {
435 // if parsing of the first fails, restore the context and stop 445 // if parsing of the first fails, restore the context and stop
436 _state st(con); 446 _state st(con);
437 if (!m_expr->parse_term(con)) { 447 if (!m_expr->parse_term(con)) {
@@ -461,7 +471,7 @@ public:
461 } 471 }
462 472
463 // parse with whitespace 473 // parse with whitespace
464 virtual bool parse_non_term(_context& con) const { 474 virtual bool parse_non_term(_context& con) const override {
465 // parse the first; if the first fails, stop 475 // parse the first; if the first fails, stop
466 if (!m_expr->parse_non_term(con)) return false; 476 if (!m_expr->parse_non_term(con)) return false;
467 477
@@ -478,7 +488,7 @@ public:
478 } 488 }
479 489
480 // parse terminal 490 // parse terminal
481 virtual bool parse_term(_context& con) const { 491 virtual bool parse_term(_context& con) const override {
482 // parse the first; if the first fails, stop 492 // parse the first; if the first fails, stop
483 if (!m_expr->parse_term(con)) return false; 493 if (!m_expr->parse_term(con)) return false;
484 494
@@ -504,14 +514,14 @@ public:
504 } 514 }
505 515
506 // parse with whitespace 516 // parse with whitespace
507 virtual bool parse_non_term(_context& con) const { 517 virtual bool parse_non_term(_context& con) const override {
508 _state st(con); 518 _state st(con);
509 if (!m_expr->parse_non_term(con)) con.restore(st); 519 if (!m_expr->parse_non_term(con)) con.restore(st);
510 return true; 520 return true;
511 } 521 }
512 522
513 // parse terminal 523 // parse terminal
514 virtual bool parse_term(_context& con) const { 524 virtual bool parse_term(_context& con) const override {
515 _state st(con); 525 _state st(con);
516 if (!m_expr->parse_term(con)) con.restore(st); 526 if (!m_expr->parse_term(con)) con.restore(st);
517 return true; 527 return true;
@@ -527,7 +537,7 @@ public:
527 } 537 }
528 538
529 // parse with whitespace 539 // parse with whitespace
530 virtual bool parse_non_term(_context& con) const { 540 virtual bool parse_non_term(_context& con) const override {
531 _state st(con); 541 _state st(con);
532 bool ok = m_expr->parse_non_term(con); 542 bool ok = m_expr->parse_non_term(con);
533 con.restore(st); 543 con.restore(st);
@@ -535,7 +545,7 @@ public:
535 } 545 }
536 546
537 // parse terminal 547 // parse terminal
538 virtual bool parse_term(_context& con) const { 548 virtual bool parse_term(_context& con) const override {
539 _state st(con); 549 _state st(con);
540 bool ok = m_expr->parse_term(con); 550 bool ok = m_expr->parse_term(con);
541 con.restore(st); 551 con.restore(st);
@@ -552,7 +562,7 @@ public:
552 } 562 }
553 563
554 // parse with whitespace 564 // parse with whitespace
555 virtual bool parse_non_term(_context& con) const { 565 virtual bool parse_non_term(_context& con) const override {
556 _state st(con); 566 _state st(con);
557 bool ok = !m_expr->parse_non_term(con); 567 bool ok = !m_expr->parse_non_term(con);
558 con.restore(st); 568 con.restore(st);
@@ -560,7 +570,7 @@ public:
560 } 570 }
561 571
562 // parse terminal 572 // parse terminal
563 virtual bool parse_term(_context& con) const { 573 virtual bool parse_term(_context& con) const override {
564 _state st(con); 574 _state st(con);
565 bool ok = !m_expr->parse_term(con); 575 bool ok = !m_expr->parse_term(con);
566 con.restore(st); 576 con.restore(st);
@@ -577,14 +587,14 @@ public:
577 } 587 }
578 588
579 // parse with whitespace 589 // parse with whitespace
580 virtual bool parse_non_term(_context& con) const { 590 virtual bool parse_non_term(_context& con) const override {
581 if (!m_expr->parse_non_term(con)) return false; 591 if (!m_expr->parse_non_term(con)) return false;
582 con.next_line(); 592 con.next_line();
583 return true; 593 return true;
584 } 594 }
585 595
586 // parse terminal 596 // parse terminal
587 virtual bool parse_term(_context& con) const { 597 virtual bool parse_term(_context& con) const override {
588 if (!m_expr->parse_term(con)) return false; 598 if (!m_expr->parse_term(con)) return false;
589 con.next_line(); 599 con.next_line();
590 return true; 600 return true;
@@ -602,14 +612,17 @@ public:
602 612
603 // destructor. 613 // destructor.
604 virtual ~_binary() { 614 virtual ~_binary() {
605 delete m_left; 615 if (m_left) delete m_left;
606 delete m_right; 616 if (m_right) delete m_right;
607 } 617 }
608 618
609protected: 619protected:
610 // left and right expressions 620 // left and right expressions
611 _expr* m_left; 621 _expr* m_left;
612 _expr* m_right; 622 _expr* m_right;
623
624 friend expr operator>>(expr&& left, expr&& right);
625 friend expr operator|(expr&& left, expr&& right);
613}; 626};
614 627
615// sequence 628// sequence
@@ -621,29 +634,35 @@ public:
621 } 634 }
622 635
623 // parse with whitespace 636 // parse with whitespace
624 virtual bool parse_non_term(_context& con) const { 637 virtual bool parse_non_term(_context& con) const override {
625 if (!m_left->parse_non_term(con)) return false; 638 if (!m_left->parse_non_term(con)) return false;
626 return m_right->parse_non_term(con); 639 return m_right->parse_non_term(con);
627 } 640 }
628 641
629 // parse terminal 642 // parse terminal
630 virtual bool parse_term(_context& con) const { 643 virtual bool parse_term(_context& con) const override {
631 if (!m_left->parse_term(con)) return false; 644 if (!m_left->parse_term(con)) return false;
632 return m_right->parse_term(con); 645 return m_right->parse_term(con);
633 } 646 }
647
648 virtual EXPR_TYPE get_type() const override {
649 return EXPR_TYPE::SEQ_TWO;
650 }
634}; 651};
635 652
636// sequence list 653// sequence list
637class _seq_list : public _expr { 654class _seq_list : public _expr {
638public: 655public:
639 // constructor. 656 // constructor.
640 _seq_list(std::initializer_list<expr> list) { 657 _seq_list(std::initializer_list<_expr*> list) {
641 m_list.reserve(list.size()); 658 m_list.reserve(list.size());
642 for (const expr& expr : list) { 659 for (_expr* expr : list) {
643 m_list.push_back(_private::get_expr(expr)); 660 m_list.push_back(expr);
644 } 661 }
645 } 662 }
646 663
664 _seq_list() { }
665
647 virtual ~_seq_list() { 666 virtual ~_seq_list() {
648 for (_expr* expr : m_list) { 667 for (_expr* expr : m_list) {
649 delete expr; 668 delete expr;
@@ -651,7 +670,7 @@ public:
651 } 670 }
652 671
653 // parse with whitespace 672 // parse with whitespace
654 virtual bool parse_non_term(_context& con) const { 673 virtual bool parse_non_term(_context& con) const override {
655 for (_expr* expr : m_list) { 674 for (_expr* expr : m_list) {
656 if (!expr->parse_non_term(con)) return false; 675 if (!expr->parse_non_term(con)) return false;
657 } 676 }
@@ -659,14 +678,20 @@ public:
659 } 678 }
660 679
661 // parse terminal 680 // parse terminal
662 virtual bool parse_term(_context& con) const { 681 virtual bool parse_term(_context& con) const override {
663 for (_expr* expr : m_list) { 682 for (_expr* expr : m_list) {
664 if (!expr->parse_term(con)) return false; 683 if (!expr->parse_term(con)) return false;
665 } 684 }
666 return true; 685 return true;
667 } 686 }
687
688 virtual EXPR_TYPE get_type() const override {
689 return EXPR_TYPE::SEQ_LIST;
690 }
691
668private: 692private:
669 std::vector<_expr*> m_list; 693 std::vector<_expr*> m_list;
694 friend expr operator>>(expr&& left, expr&& right);
670}; 695};
671 696
672// choice 697// choice
@@ -678,7 +703,7 @@ public:
678 } 703 }
679 704
680 // parse with whitespace 705 // parse with whitespace
681 virtual bool parse_non_term(_context& con) const { 706 virtual bool parse_non_term(_context& con) const override {
682 _state st(con); 707 _state st(con);
683 if (m_left->parse_non_term(con)) return true; 708 if (m_left->parse_non_term(con)) return true;
684 con.restore(st); 709 con.restore(st);
@@ -686,33 +711,39 @@ public:
686 } 711 }
687 712
688 // parse terminal 713 // parse terminal
689 virtual bool parse_term(_context& con) const { 714 virtual bool parse_term(_context& con) const override {
690 _state st(con); 715 _state st(con);
691 if (m_left->parse_term(con)) return true; 716 if (m_left->parse_term(con)) return true;
692 con.restore(st); 717 con.restore(st);
693 return m_right->parse_term(con); 718 return m_right->parse_term(con);
694 } 719 }
720
721 virtual EXPR_TYPE get_type() const override {
722 return EXPR_TYPE::CHOICE_TWO;
723 }
695}; 724};
696 725
697// select 726// choice list
698class _sel : public _expr { 727class _choice_list : public _expr {
699public: 728public:
700 // constructor. 729 // constructor.
701 _sel(std::initializer_list<expr> list) { 730 _choice_list(std::initializer_list<_expr*> list) {
702 m_list.reserve(list.size()); 731 m_list.reserve(list.size());
703 for (const expr& expr : list) { 732 for (_expr* expr : list) {
704 m_list.push_back(_private::get_expr(expr)); 733 m_list.push_back(expr);
705 } 734 }
706 } 735 }
707 736
708 virtual ~_sel() { 737 _choice_list() { }
738
739 virtual ~_choice_list() {
709 for (_expr* expr : m_list) { 740 for (_expr* expr : m_list) {
710 delete expr; 741 delete expr;
711 } 742 }
712 } 743 }
713 744
714 // parse with whitespace 745 // parse with whitespace
715 virtual bool parse_non_term(_context& con) const { 746 virtual bool parse_non_term(_context& con) const override {
716 _state st(con); 747 _state st(con);
717 for (_expr* expr : m_list) { 748 for (_expr* expr : m_list) {
718 if (expr->parse_non_term(con)) return true; 749 if (expr->parse_non_term(con)) return true;
@@ -722,7 +753,7 @@ public:
722 } 753 }
723 754
724 // parse terminal 755 // parse terminal
725 virtual bool parse_term(_context& con) const { 756 virtual bool parse_term(_context& con) const override {
726 _state st(con); 757 _state st(con);
727 for (_expr* expr : m_list) { 758 for (_expr* expr : m_list) {
728 if (expr->parse_term(con)) return true; 759 if (expr->parse_term(con)) return true;
@@ -730,8 +761,14 @@ public:
730 } 761 }
731 return false; 762 return false;
732 } 763 }
764
765 virtual EXPR_TYPE get_type() const override {
766 return EXPR_TYPE::CHOICE_LIST;
767 }
768
733private: 769private:
734 std::vector<_expr*> m_list; 770 std::vector<_expr*> m_list;
771 friend expr operator|(expr&& left, expr&& right);
735}; 772};
736 773
737// reference to rule 774// reference to rule
@@ -743,12 +780,12 @@ public:
743 } 780 }
744 781
745 // parse with whitespace 782 // parse with whitespace
746 virtual bool parse_non_term(_context& con) const { 783 virtual bool parse_non_term(_context& con) const override {
747 return con.parse_non_term(m_rule); 784 return con.parse_non_term(m_rule);
748 } 785 }
749 786
750 // parse terminal 787 // parse terminal
751 virtual bool parse_term(_context& con) const { 788 virtual bool parse_term(_context& con) const override {
752 return con.parse_term(m_rule); 789 return con.parse_term(m_rule);
753 } 790 }
754 791
@@ -761,12 +798,12 @@ private:
761class _eof : public _expr { 798class _eof : public _expr {
762public: 799public:
763 // parse with whitespace 800 // parse with whitespace
764 virtual bool parse_non_term(_context& con) const { 801 virtual bool parse_non_term(_context& con) const override {
765 return parse_term(con); 802 return parse_term(con);
766 } 803 }
767 804
768 // parse terminal 805 // parse terminal
769 virtual bool parse_term(_context& con) const { 806 virtual bool parse_term(_context& con) const override {
770 return con.end(); 807 return con.end();
771 } 808 }
772}; 809};
@@ -775,12 +812,12 @@ public:
775class _any : public _expr { 812class _any : public _expr {
776public: 813public:
777 // parse with whitespace 814 // parse with whitespace
778 virtual bool parse_non_term(_context& con) const { 815 virtual bool parse_non_term(_context& con) const override {
779 return parse_term(con); 816 return parse_term(con);
780 } 817 }
781 818
782 // parse terminal 819 // parse terminal
783 virtual bool parse_term(_context& con) const { 820 virtual bool parse_term(_context& con) const override {
784 if (!con.end()) { 821 if (!con.end()) {
785 con.next_col(); 822 con.next_col();
786 return true; 823 return true;
@@ -794,12 +831,12 @@ public:
794class _true : public _expr { 831class _true : public _expr {
795public: 832public:
796 // parse with whitespace 833 // parse with whitespace
797 virtual bool parse_non_term(_context&) const { 834 virtual bool parse_non_term(_context&) const override {
798 return true; 835 return true;
799 } 836 }
800 837
801 // parse terminal 838 // parse terminal
802 virtual bool parse_term(_context&) const { 839 virtual bool parse_term(_context&) const override {
803 return true; 840 return true;
804 } 841 }
805}; 842};
@@ -808,12 +845,12 @@ public:
808class _false : public _expr { 845class _false : public _expr {
809public: 846public:
810 // parse with whitespace 847 // parse with whitespace
811 virtual bool parse_non_term(_context&) const { 848 virtual bool parse_non_term(_context&) const override {
812 return false; 849 return false;
813 } 850 }
814 851
815 // parse terminal 852 // parse terminal
816 virtual bool parse_term(_context&) const { 853 virtual bool parse_term(_context&) const override {
817 return false; 854 return false;
818 } 855 }
819}; 856};
@@ -1263,12 +1300,82 @@ expr operator>>(const expr& left, const expr& right) {
1263 new _seq(_private::get_expr(left), _private::get_expr(right))); 1300 new _seq(_private::get_expr(left), _private::get_expr(right)));
1264} 1301}
1265 1302
1266/** creates a sequence of expressions. 1303expr operator>>(expr&& left, expr&& right) {
1267 @param list list of expressions. 1304 auto left_expr = _private::get_expr(left);
1268 @return an expression which parses a sequence. 1305 auto right_expr = _private::get_expr(right);
1269*/ 1306 switch (left_expr->get_type()) {
1270expr seq(std::initializer_list<expr> list) { 1307 case EXPR_TYPE::SEQ_TWO: {
1271 return _private::construct_expr(new _seq_list(list)); 1308 auto l_seq = static_cast<_seq*>(left_expr);
1309 switch (right_expr->get_type()) {
1310 case EXPR_TYPE::SEQ_TWO: {
1311 auto r_seq = static_cast<_seq*>(right_expr);
1312 auto list = new _seq_list{
1313 l_seq->m_left,
1314 l_seq->m_right,
1315 r_seq->m_left,
1316 r_seq->m_right};
1317 l_seq->m_left = nullptr;
1318 l_seq->m_right = nullptr;
1319 r_seq->m_left = nullptr;
1320 r_seq->m_right = nullptr;
1321 delete l_seq;
1322 delete r_seq;
1323 return _private::construct_expr(list);
1324 }
1325 case EXPR_TYPE::SEQ_LIST: {
1326 auto r_list = static_cast<_seq_list*>(right_expr);
1327 auto list = new _seq_list{};
1328 list->m_list.reserve(2 + list->m_list.size());
1329 list->m_list.push_back(l_seq->m_left);
1330 list->m_list.push_back(l_seq->m_right);
1331 list->m_list.insert(list->m_list.end(), r_list->m_list.begin(), r_list->m_list.end());
1332 l_seq->m_left = nullptr;
1333 l_seq->m_right = nullptr;
1334 r_list->m_list.clear();
1335 delete l_seq;
1336 delete r_list;
1337 return _private::construct_expr(list);
1338 }
1339 default: {
1340 auto list = new _seq_list{
1341 l_seq->m_left,
1342 l_seq->m_right,
1343 right_expr};
1344 l_seq->m_left = nullptr;
1345 l_seq->m_right = nullptr;
1346 delete l_seq;
1347 return _private::construct_expr(list);
1348 }
1349 }
1350 }
1351 case EXPR_TYPE::SEQ_LIST: {
1352 auto l_list = static_cast<_seq_list*>(left_expr);
1353 switch (right_expr->get_type()) {
1354 case EXPR_TYPE::SEQ_TWO: {
1355 auto r_seq = static_cast<_seq*>(right_expr);
1356 l_list->m_list.insert(l_list->m_list.end(), {r_seq->m_left, r_seq->m_right});
1357 r_seq->m_left = nullptr;
1358 r_seq->m_right = nullptr;
1359 delete r_seq;
1360 return _private::construct_expr(l_list);
1361 }
1362 case EXPR_TYPE::SEQ_LIST: {
1363 auto r_list = static_cast<_seq_list*>(right_expr);
1364 l_list->m_list.insert(l_list->m_list.end(), r_list->m_list.begin(), r_list->m_list.end());
1365 r_list->m_list.clear();
1366 delete r_list;
1367 return _private::construct_expr(l_list);
1368 }
1369 default: {
1370 l_list->m_list.push_back(right_expr);
1371 return _private::construct_expr(l_list);
1372 }
1373 }
1374 }
1375 default:
1376 return _private::construct_expr(
1377 new _seq(left_expr, right_expr));
1378 }
1272} 1379}
1273 1380
1274/** creates a choice of expressions. 1381/** creates a choice of expressions.
@@ -1281,12 +1388,81 @@ expr operator|(const expr& left, const expr& right) {
1281 new _choice(_private::get_expr(left), _private::get_expr(right))); 1388 new _choice(_private::get_expr(left), _private::get_expr(right)));
1282} 1389}
1283 1390
1284/** creates multiple choices of expressions. 1391expr operator|(expr&& left, expr&& right) {
1285 @param list list of expressions. 1392 auto left_expr = _private::get_expr(left);
1286 @return an expression which parses multiple choices. 1393 auto right_expr = _private::get_expr(right);
1287*/ 1394 switch (left_expr->get_type()) {
1288expr sel(std::initializer_list<expr> list) { 1395 case EXPR_TYPE::CHOICE_TWO: {
1289 return _private::construct_expr(new _sel(list)); 1396 auto l_choice = static_cast<_choice*>(left_expr);
1397 switch (right_expr->get_type()) {
1398 case EXPR_TYPE::CHOICE_TWO: {
1399 auto r_choice = static_cast<_choice*>(right_expr);
1400 auto list = new _choice_list{
1401 l_choice->m_left,
1402 l_choice->m_right,
1403 r_choice->m_left,
1404 r_choice->m_right};
1405 l_choice->m_left = nullptr;
1406 l_choice->m_right = nullptr;
1407 r_choice->m_left = nullptr;
1408 r_choice->m_right = nullptr;
1409 delete l_choice;
1410 delete r_choice;
1411 return _private::construct_expr(list);
1412 }
1413 case EXPR_TYPE::CHOICE_LIST: {
1414 auto r_list = static_cast<_choice_list*>(right_expr);
1415 auto list = new _choice_list{};
1416 list->m_list.reserve(2 + list->m_list.size());
1417 list->m_list.insert(list->m_list.end(), {l_choice->m_left, l_choice->m_right});
1418 list->m_list.insert(list->m_list.end(), r_list->m_list.begin(), r_list->m_list.end());
1419 l_choice->m_left = nullptr;
1420 l_choice->m_right = nullptr;
1421 r_list->m_list.clear();
1422 delete l_choice;
1423 delete r_list;
1424 return _private::construct_expr(list);
1425 }
1426 default: {
1427 auto list = new _choice_list{
1428 l_choice->m_left,
1429 l_choice->m_right,
1430 right_expr};
1431 l_choice->m_left = nullptr;
1432 l_choice->m_right = nullptr;
1433 delete l_choice;
1434 return _private::construct_expr(list);
1435 }
1436 }
1437 }
1438 case EXPR_TYPE::CHOICE_LIST: {
1439 auto l_list = static_cast<_choice_list*>(left_expr);
1440 switch (right_expr->get_type()) {
1441 case EXPR_TYPE::CHOICE_TWO: {
1442 auto r_choice = static_cast<_choice*>(right_expr);
1443 l_list->m_list.insert(l_list->m_list.end(), {r_choice->m_left, r_choice->m_right});
1444 r_choice->m_left = nullptr;
1445 r_choice->m_right = nullptr;
1446 delete r_choice;
1447 return _private::construct_expr(l_list);
1448 }
1449 case EXPR_TYPE::CHOICE_LIST: {
1450 auto r_list = static_cast<_choice_list*>(right_expr);
1451 l_list->m_list.insert(l_list->m_list.end(), r_list->m_list.begin(), r_list->m_list.end());
1452 r_list->m_list.clear();
1453 delete r_list;
1454 return _private::construct_expr(l_list);
1455 }
1456 default: {
1457 l_list->m_list.push_back(right_expr);
1458 return _private::construct_expr(l_list);
1459 }
1460 }
1461 }
1462 default:
1463 return _private::construct_expr(
1464 new _choice(left_expr, right_expr));
1465 }
1290} 1466}
1291 1467
1292/** converts a parser expression into a terminal. 1468/** converts a parser expression into a terminal.
diff --git a/src/yuescript/parser.hpp b/src/yuescript/parser.hpp
index b504866..1973315 100644
--- a/src/yuescript/parser.hpp
+++ b/src/yuescript/parser.hpp
@@ -302,12 +302,7 @@ private:
302 @return an expression which parses a sequence. 302 @return an expression which parses a sequence.
303*/ 303*/
304expr operator>>(const expr& left, const expr& right); 304expr operator>>(const expr& left, const expr& right);
305 305expr operator>>(expr&& left, expr&& right);
306/** creates a sequence of expressions.
307 @param list list of expressions.
308 @return an expression which parses a sequence.
309*/
310expr seq(std::initializer_list<expr> list);
311 306
312/** creates a choice of expressions. 307/** creates a choice of expressions.
313 @param left left operand. 308 @param left left operand.
@@ -315,12 +310,7 @@ expr seq(std::initializer_list<expr> list);
315 @return an expression which parses a choice. 310 @return an expression which parses a choice.
316*/ 311*/
317expr operator|(const expr& left, const expr& right); 312expr operator|(const expr& left, const expr& right);
318 313expr operator|(expr&& left, expr&& right);
319/** creates multiple choices of expressions.
320 @param list list of expressions.
321 @return an expression which parses multiple choices.
322*/
323expr sel(std::initializer_list<expr> list);
324 314
325/** converts a parser expression into a terminal. 315/** converts a parser expression into a terminal.
326 @param e expression. 316 @param e expression.
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index e62417c..4532d21 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -36,7 +36,6 @@ YueParser::YueParser() {
36 line_break = nl(-expr('\r') >> '\n'); 36 line_break = nl(-expr('\r') >> '\n');
37 any_char = line_break | any(); 37 any_char = line_break | any();
38 stop = line_break | eof(); 38 stop = line_break | eof();
39 indent = plain_space;
40 comment = "--" >> *(not_(set("\r\n")) >> any_char) >> and_(stop); 39 comment = "--" >> *(not_(set("\r\n")) >> any_char) >> and_(stop);
41 multi_line_open = "--[["; 40 multi_line_open = "--[[";
42 multi_line_close = "]]"; 41 multi_line_close = "]]";
@@ -47,34 +46,33 @@ YueParser::YueParser() {
47 space = -(and_(set(" \t-\\")) >> *space_one >> -comment); 46 space = -(and_(set(" \t-\\")) >> *space_one >> -comment);
48 space_break = space >> line_break; 47 space_break = space >> line_break;
49 white = space >> *(line_break >> space); 48 white = space >> *(line_break >> space);
50 alpha_num = sel({range('a', 'z'), range('A', 'Z'), range('0', '9'), '_'}); 49 alpha_num = range('a', 'z') | range('A', 'Z') | range('0', '9') | '_';
51 not_alpha_num = not_(alpha_num); 50 not_alpha_num = not_(alpha_num);
52 Name = sel({range('a', 'z'), range('A', 'Z'), '_'}) >> *alpha_num; 51 Name = (range('a', 'z') | range('A', 'Z') | '_') >> *alpha_num;
53 num_expo = set("eE") >> -set("+-") >> num_char; 52 num_expo = set("eE") >> -set("+-") >> num_char;
54 num_expo_hex = set("pP") >> -set("+-") >> num_char; 53 num_expo_hex = set("pP") >> -set("+-") >> num_char;
55 lj_num = -set("uU") >> set("lL") >> set("lL"); 54 lj_num = -set("uU") >> set("lL") >> set("lL");
56 num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9'))); 55 num_char = range('0', '9') >> *(range('0', '9') | '_' >> and_(range('0', '9')));
57 num_char_hex = sel({range('0', '9'), range('a', 'f'), range('A', 'F')}); 56 num_char_hex = range('0', '9') | range('a', 'f') | range('A', 'F');
58 num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex)); 57 num_lit = num_char_hex >> *(num_char_hex | '_' >> and_(num_char_hex));
59 Num = sel({ 58 Num =
60 "0x" >> ( 59 "0x" >> (
61 +num_lit >> sel({ 60 +num_lit >> (
62 seq({'.', +num_lit, -num_expo_hex}), 61 '.' >> +num_lit >> -num_expo_hex |
63 num_expo_hex, 62 num_expo_hex |
64 lj_num, 63 lj_num |
65 true_() 64 true_()
66 }) | seq({ 65 ) | (
67 '.', +num_lit, -num_expo_hex 66 '.' >> +num_lit >> -num_expo_hex
68 }) 67 )
69 ), 68 ) |
70 +num_char >> sel({ 69 +num_char >> (
71 seq({'.', +num_char, -num_expo}), 70 '.' >> +num_char >> -num_expo |
72 num_expo, 71 num_expo |
73 lj_num, 72 lj_num |
74 true_() 73 true_()
75 }), 74 ) |
76 seq({'.', +num_char, -num_expo}) 75 '.' >> +num_char >> -num_expo;
77 });
78 76
79 cut = false_(); 77 cut = false_();
80 Seperator = true_(); 78 Seperator = true_();
@@ -86,7 +84,7 @@ YueParser::YueParser() {
86 84
87 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut) 85 #define ensure(patt, finally) ((patt) >> (finally) | (finally) >> cut)
88 86
89 #define key(str) (str >> not_alpha_num) 87 #define key(str) (expr(str) >> not_alpha_num)
90 88
91 #define disable_do_rule(patt) ( \ 89 #define disable_do_rule(patt) ( \
92 disable_do >> ( \ 90 disable_do >> ( \
@@ -117,11 +115,9 @@ YueParser::YueParser() {
117 ) 115 )
118 116
119 #define body_with(str) ( \ 117 #define body_with(str) ( \
120 sel({ \ 118 key(str) >> space >> (in_block | Statement) | \
121 key(str) >> space >> (in_block | Statement), \ 119 in_block | \
122 in_block, \ 120 empty_block_error \
123 empty_block_error \
124 }) \
125 ) 121 )
126 122
127 #define opt_body_with(str) ( \ 123 #define opt_body_with(str) ( \
@@ -129,7 +125,7 @@ YueParser::YueParser() {
129 in_block \ 125 in_block \
130 ) 126 )
131 127
132 #define body (sel({in_block, Statement, empty_block_error})) 128 #define body (in_block | Statement | empty_block_error)
133 129
134 Variable = pl::user(Name, [](const item_t& item) { 130 Variable = pl::user(Name, [](const item_t& item) {
135 State* st = reinterpret_cast<State*>(item.user_data); 131 State* st = reinterpret_cast<State*>(item.user_data);
@@ -166,11 +162,11 @@ YueParser::YueParser() {
166 SelfClass = "@@"; 162 SelfClass = "@@";
167 SelfClassName = "@@" >> Name; 163 SelfClassName = "@@" >> Name;
168 164
169 SelfItem = sel({SelfClassName, SelfClass, SelfName, Self}); 165 SelfItem = SelfClassName | SelfClass | SelfName | Self;
170 KeyName = SelfItem | Name; 166 KeyName = SelfItem | Name;
171 VarArg = "..."; 167 VarArg = "...";
172 168
173 check_indent = pl::user(indent, [](const item_t& item) { 169 check_indent = pl::user(plain_space, [](const item_t& item) {
174 int indent = 0; 170 int indent = 0;
175 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 171 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
176 switch (*i) { 172 switch (*i) {
@@ -183,7 +179,7 @@ YueParser::YueParser() {
183 }); 179 });
184 check_indent_match = and_(check_indent); 180 check_indent_match = and_(check_indent);
185 181
186 advance = pl::user(indent, [](const item_t& item) { 182 advance = pl::user(plain_space, [](const item_t& item) {
187 int indent = 0; 183 int indent = 0;
188 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 184 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
189 switch (*i) { 185 switch (*i) {
@@ -201,7 +197,7 @@ YueParser::YueParser() {
201 }); 197 });
202 advance_match = and_(advance); 198 advance_match = and_(advance);
203 199
204 push_indent = pl::user(indent, [](const item_t& item) { 200 push_indent = pl::user(plain_space, [](const item_t& item) {
205 int indent = 0; 201 int indent = 0;
206 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) { 202 for (input_it i = item.begin->m_it; i != item.end->m_it; ++i) {
207 switch (*i) { 203 switch (*i) {
@@ -229,13 +225,13 @@ YueParser::YueParser() {
229 225
230 in_block = +space_break >> advance_match >> ensure(Block, pop_indent); 226 in_block = +space_break >> advance_match >> ensure(Block, pop_indent);
231 227
232 LocalFlag = sel({'*', '^'}); 228 LocalFlag = expr('*') | '^';
233 LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); 229 LocalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow));
234 Local = key("local") >> space >> (LocalFlag | LocalValues); 230 Local = key("local") >> space >> (LocalFlag | LocalValues);
235 231
236 ConstAttrib = key("const"); 232 ConstAttrib = key("const");
237 CloseAttrib = key("close"); 233 CloseAttrib = key("close");
238 local_const_item = sel({Variable, SimpleTable, TableLit}); 234 local_const_item = Variable | SimpleTable | TableLit;
239 LocalAttrib = ( 235 LocalAttrib = (
240 ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) | 236 ConstAttrib >> Seperator >> space >> local_const_item >> *(space >> ',' >> space >> local_const_item) |
241 CloseAttrib >> Seperator >> space >> Variable >> *(space >> ',' >> space >> Variable) 237 CloseAttrib >> Seperator >> space >> Variable >> *(space >> ',' >> space >> Variable)
@@ -246,42 +242,42 @@ YueParser::YueParser() {
246 import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name); 242 import_name_list = Seperator >> *space_break >> space >> import_name >> *((+space_break | space >> ',' >> *space_break) >> space >> import_name);
247 ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> Exp; 243 ImportFrom = import_name_list >> *space_break >> space >> key("from") >> space >> Exp;
248 244
249 ImportLiteralInner = sel({range('a', 'z'), range('A', 'Z'), set("_-")}) >> *(alpha_num | '-'); 245 ImportLiteralInner = (range('a', 'z') | range('A', 'Z') | set("_-")) >> *(alpha_num | '-');
250 import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner); 246 import_literal_chain = Seperator >> ImportLiteralInner >> *('.' >> ImportLiteralInner);
251 ImportLiteral = sel({ 247 ImportLiteral = (
252 '\'' >> import_literal_chain >> '\'', 248 '\'' >> import_literal_chain >> '\''
253 '"' >> import_literal_chain >> '"' 249 ) | (
254 }); 250 '"' >> import_literal_chain >> '"'
251 );
255 252
256 MacroNamePair = MacroName >> ':' >> space >> MacroName; 253 MacroNamePair = MacroName >> ':' >> space >> MacroName;
257 ImportAllMacro = '$'; 254 ImportAllMacro = '$';
258 import_tab_item = sel({ 255 import_tab_item =
259 VariablePair, 256 VariablePair |
260 NormalPair, 257 NormalPair |
261 ':' >> MacroName, 258 ':' >> MacroName |
262 MacroNamePair, 259 MacroNamePair |
263 ImportAllMacro, 260 ImportAllMacro |
264 MetaVariablePair, 261 MetaVariablePair |
265 MetaNormalPair, 262 MetaNormalPair |
266 Exp 263 Exp;
267 });
268 import_tab_list = import_tab_item >> *(space >> ',' >> space >> import_tab_item); 264 import_tab_list = import_tab_item >> *(space >> ',' >> space >> import_tab_item);
269 import_tab_line = ( 265 import_tab_line = (
270 push_indent_match >> (space >> import_tab_list >> pop_indent | pop_indent) 266 push_indent_match >> (space >> import_tab_list >> pop_indent | pop_indent)
271 ) | space; 267 ) | space;
272 import_tab_lines = space_break >> import_tab_line >> *(-(space >> ',') >> space_break >> import_tab_line) >> -(space >> ','); 268 import_tab_lines = space_break >> import_tab_line >> *(-(space >> ',') >> space_break >> import_tab_line) >> -(space >> ',');
273 ImportTabLit = seq({ 269 ImportTabLit = (
274 '{', Seperator, 270 '{' >> Seperator >>
275 -(space >> import_tab_list), 271 -(space >> import_tab_list) >>
276 -(space >> ','), 272 -(space >> ',') >>
277 -import_tab_lines, 273 -import_tab_lines >>
278 white, 274 white >>
279 '}' 275 '}'
280 }) | seq({ 276 ) | (
281 Seperator, key_value, *(space >> ',' >> space >> key_value) 277 Seperator >> key_value >> *(space >> ',' >> space >> key_value)
282 }); 278 );
283 279
284 ImportAs = ImportLiteral >> -(space >> key("as") >> space >> sel({ImportTabLit, Variable, ImportAllMacro})); 280 ImportAs = ImportLiteral >> -(space >> key("as") >> space >> (ImportTabLit | Variable | ImportAllMacro));
285 281
286 Import = key("import") >> space >> (ImportAs | ImportFrom); 282 Import = key("import") >> space >> (ImportAs | ImportFrom);
287 283
@@ -291,7 +287,7 @@ YueParser::YueParser() {
291 287
292 ShortTabAppending = "[]" >> space >> Assign; 288 ShortTabAppending = "[]" >> space >> Assign;
293 289
294 BreakLoop = sel({"break", "continue"}) >> not_alpha_num; 290 BreakLoop = (expr("break") | "continue") >> not_alpha_num;
295 291
296 Return = key("return") >> -(space >> (TableBlock | ExpListLow)); 292 Return = key("return") >> -(space >> (TableBlock | ExpListLow));
297 293
@@ -324,12 +320,12 @@ YueParser::YueParser() {
324 IfCond = disable_chain_rule(disable_arg_table_block_rule(Assignment | Exp)); 320 IfCond = disable_chain_rule(disable_arg_table_block_rule(Assignment | Exp));
325 if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then"); 321 if_else_if = -(line_break >> *space_break >> check_indent_match) >> space >> key("elseif") >> space >> IfCond >> space >> body_with("then");
326 if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body; 322 if_else = -(line_break >> *space_break >> check_indent_match) >> space >> key("else") >> space >> body;
327 IfType = sel({"if", "unless"}) >> not_alpha_num; 323 IfType = (expr("if") | "unless") >> not_alpha_num;
328 If = seq({IfType, space, IfCond, space, opt_body_with("then"), *if_else_if, -if_else}); 324 If = IfType >> space >> IfCond >> space >> opt_body_with("then") >> *if_else_if >> -if_else;
329 325
330 WhileType = sel({"while", "until"}) >> not_alpha_num; 326 WhileType = (expr("while") | "until") >> not_alpha_num;
331 While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do"); 327 While = WhileType >> space >> disable_do_chain_arg_table_block_rule(Exp) >> space >> opt_body_with("do");
332 Repeat = seq({key("repeat"), space, Body, line_break, *space_break, check_indent_match, space, key("until"), space, Exp}); 328 Repeat = key("repeat") >> space >> Body >> line_break >> *space_break >> check_indent_match >> space >> key("until") >> space >> Exp;
333 329
334 ForStepValue = ',' >> space >> Exp; 330 ForStepValue = ',' >> space >> Exp;
335 for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue; 331 for_args = Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> space >> -ForStepValue;
@@ -397,50 +393,48 @@ YueParser::YueParser() {
397 StarExp = '*' >> space >> Exp; 393 StarExp = '*' >> space >> Exp;
398 CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | Exp); 394 CompForEach = key("for") >> space >> AssignableNameList >> space >> key("in") >> space >> (StarExp | Exp);
399 CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> -ForStepValue; 395 CompFor = key("for") >> space >> Variable >> space >> '=' >> space >> Exp >> space >> ',' >> space >> Exp >> -ForStepValue;
400 comp_clause = sel({CompFor, CompForEach, key("when") >> space >> Exp}); 396 comp_clause = CompFor | CompForEach | key("when") >> space >> Exp;
401 397
402 Assign = '=' >> space >> Seperator >> sel({ 398 Assign = '=' >> space >> Seperator >> (
403 With, If, Switch, TableBlock, 399 With | If | Switch | TableBlock |
404 Exp >> *(space >> set(",;") >> space >> Exp) 400 Exp >> *(space >> set(",;") >> space >> Exp)
405 }); 401 );
406 402
407 UpdateOp = sel({ 403 UpdateOp =
408 "..", "//", "or", "and", 404 expr("..") | "//" | "or" | "and" |
409 ">>", "<<", "??", 405 ">>" | "<<" | "??" |
410 set("+-*/%&|") 406 set("+-*/%&|");
411 });
412 407
413 Update = UpdateOp >> '=' >> space >> Exp; 408 Update = UpdateOp >> '=' >> space >> Exp;
414 409
415 Assignable = sel({AssignableChain, Variable, SelfItem}); 410 Assignable = AssignableChain | Variable | SelfItem;
416 411
417 UnaryValue = +(UnaryOperator >> space) >> Value; 412 UnaryValue = +(UnaryOperator >> space) >> Value;
418 413
419 exponential_operator = '^'; 414 exponential_operator = '^';
420 expo_value = seq({exponential_operator, *space_break, space, Value}); 415 expo_value = exponential_operator >> *space_break >> space >> Value;
421 expo_exp = Value >> *(space >> expo_value); 416 expo_exp = Value >> *(space >> expo_value);
422 417
423 UnaryOperator = sel({ 418 UnaryOperator =
424 '-' >> not_(set(">=") | space_one), 419 '-' >> not_(set(">=") | space_one) |
425 '#', 420 '#' |
426 '~' >> not_('=' | space_one), 421 '~' >> not_('=' | space_one) |
427 "not" >> not_alpha_num 422 key("not");
428 });
429 UnaryExp = *(UnaryOperator >> space) >> expo_exp; 423 UnaryExp = *(UnaryOperator >> space) >> expo_exp;
430 424
431 pipe_operator = "|>"; 425 pipe_operator = "|>";
432 pipe_value = seq({pipe_operator, *space_break, space, UnaryExp}); 426 pipe_value = pipe_operator >> *space_break >> space >> UnaryExp;
433 pipe_exp = UnaryExp >> *(space >> pipe_value); 427 pipe_exp = UnaryExp >> *(space >> pipe_value);
434 428
435 BinaryOperator = sel({ 429 BinaryOperator =
436 "or" >> not_alpha_num, 430 key("or") |
437 "and" >> not_alpha_num, 431 key("and") |
438 "<=", ">=", "~=", "!=", "==", 432 "<=" | ">=" | "~=" | "!=" | "==" |
439 "..", "<<", ">>", "//", 433 ".." | "<<" | ">>" | "//" |
440 set("+-*/%><|&~") 434 set("+-*/%><|&~");
441 }); 435
442 ExpOpValue = seq({BinaryOperator, *space_break, space, pipe_exp}); 436 ExpOpValue = BinaryOperator >> *space_break >> space >> pipe_exp;
443 Exp = seq({Seperator, pipe_exp, *(space >> ExpOpValue), -(space >> "??" >> space >> Exp)}); 437 Exp = Seperator >> pipe_exp >> *(space >> ExpOpValue) >> -(space >> "??" >> space >> Exp);
444 438
445 disable_chain = pl::user(true_(), [](const item_t& item) { 439 disable_chain = pl::user(true_(), [](const item_t& item) {
446 State* st = reinterpret_cast<State*>(item.user_data); 440 State* st = reinterpret_cast<State*>(item.user_data);
@@ -454,22 +448,21 @@ YueParser::YueParser() {
454 return true; 448 return true;
455 }); 449 });
456 450
457 chain_line = seq({check_indent_match, space, chain_dot_chain | colon_chain, -InvokeArgs}); 451 chain_line = check_indent_match >> space >> (chain_dot_chain | colon_chain) >> -InvokeArgs;
458 chain_block = pl::user(true_(), [](const item_t& item) { 452 chain_block = pl::user(true_(), [](const item_t& item) {
459 State* st = reinterpret_cast<State*>(item.user_data); 453 State* st = reinterpret_cast<State*>(item.user_data);
460 return st->noChainBlockStack.empty() || !st->noChainBlockStack.top(); 454 return st->noChainBlockStack.empty() || !st->noChainBlockStack.top();
461 }) >> +space_break >> advance_match >> ensure( 455 }) >> +space_break >> advance_match >> ensure(
462 chain_line >> *(+space_break >> chain_line), pop_indent); 456 chain_line >> *(+space_break >> chain_line), pop_indent);
463 ChainValue = seq({ 457 ChainValue =
464 Seperator, 458 Seperator >>
465 chain, 459 chain >>
466 -ExistentialOp, 460 -ExistentialOp >>
467 -(InvokeArgs | chain_block), 461 -(InvokeArgs | chain_block) >>
468 -TableAppendingOp 462 -TableAppendingOp;
469 });
470 463
471 SimpleTable = seq({Seperator, key_value, *(space >> ',' >> space >> key_value)}); 464 SimpleTable = Seperator >> key_value >> *(space >> ',' >> space >> key_value);
472 Value = sel({SimpleValue, SimpleTable, ChainValue, String}); 465 Value = SimpleValue | SimpleTable | ChainValue | String;
473 466
474 single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char; 467 single_string_inner = '\\' >> set("'\\") | not_('\'') >> any_char;
475 SingleString = '\'' >> *single_string_inner >> '\''; 468 SingleString = '\'' >> *single_string_inner >> '\'';
@@ -479,7 +472,7 @@ YueParser::YueParser() {
479 DoubleStringInner = +(not_(interp) >> double_string_plain); 472 DoubleStringInner = +(not_(interp) >> double_string_plain);
480 DoubleStringContent = DoubleStringInner | interp; 473 DoubleStringContent = DoubleStringInner | interp;
481 DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"'; 474 DoubleString = '"' >> Seperator >> *DoubleStringContent >> '"';
482 String = sel({DoubleString, SingleString, LuaString}); 475 String = DoubleString | SingleString | LuaString;
483 476
484 lua_string_open = '[' >> *expr('=') >> '['; 477 lua_string_open = '[' >> *expr('=') >> '[';
485 lua_string_close = ']' >> *expr('=') >> ']'; 478 lua_string_close = ']' >> *expr('=') >> ']';
@@ -501,101 +494,90 @@ YueParser::YueParser() {
501 494
502 LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose; 495 LuaString = LuaStringOpen >> -line_break >> LuaStringContent >> LuaStringClose;
503 496
504 Parens = seq({'(', *space_break, space, Exp, *space_break, space, ')'}); 497 Parens = '(' >> *space_break >> space >> Exp >> *space_break >> space >> ')';
505 Callable = sel({Variable, SelfItem, MacroName, VarArg, Parens}); 498 Callable = Variable | SelfItem | MacroName | VarArg | Parens;
506 fn_args_exp_list = space >> Exp >> space >> *seq({line_break | ',', white, Exp}); 499 fn_args_exp_list = space >> Exp >> space >> *((line_break | ',') >> white >> Exp);
507 500
508 fn_args = sel({ 501 fn_args =
509 seq({'(', *space_break, -fn_args_exp_list, *space_break, space, ')'}), 502 '(' >> *space_break >> -fn_args_exp_list >> *space_break >> space >> ')' |
510 seq({space, '!', not_('=')}) 503 space >> '!' >> not_('=');
511 });
512 504
513 meta_index = sel({Name, index, String}); 505 meta_index = Name | index | String;
514 Metatable = '<' >> space >> '>'; 506 Metatable = '<' >> space >> '>';
515 Metamethod = '<' >> space >> meta_index >> space >> '>'; 507 Metamethod = '<' >> space >> meta_index >> space >> '>';
516 508
517 ExistentialOp = '?' >> not_('?'); 509 ExistentialOp = '?' >> not_('?');
518 TableAppendingOp = "[]"; 510 TableAppendingOp = "[]";
519 chain_call = seq({ 511 chain_call = (
520 Callable, 512 Callable >> -ExistentialOp >> -chain_items
521 -ExistentialOp, 513 ) | (
522 -chain_items 514 String >> chain_items
523 }) | seq({ 515 );
524 String, 516 chain_index_chain = index >> -ExistentialOp >> -chain_items;
525 chain_items 517 chain_dot_chain = DotChainItem >> -ExistentialOp >> -chain_items;
526 }); 518
527 chain_index_chain = seq({index, -ExistentialOp, -chain_items}); 519 chain = chain_call | chain_dot_chain | colon_chain | chain_index_chain;
528 chain_dot_chain = seq({DotChainItem, -ExistentialOp, -chain_items}); 520
529 521 chain_call_list = (
530 chain = sel({chain_call, chain_dot_chain, colon_chain, chain_index_chain}); 522 Callable >> -ExistentialOp >> chain_items
531 523 ) | (
532 chain_call_list = seq({ 524 String >> chain_items
533 Callable, 525 );
534 -ExistentialOp, 526 chain_list = chain_call_list | chain_dot_chain | colon_chain | chain_index_chain;
535 chain_items
536 }) | seq({
537 String,
538 chain_items
539 });
540 chain_list = sel({chain_call_list, chain_dot_chain, colon_chain, chain_index_chain});
541 527
542 AssignableChain = Seperator >> chain_list; 528 AssignableChain = Seperator >> chain_list;
543 529
544 chain_with_colon = +chain_item >> -colon_chain; 530 chain_with_colon = +chain_item >> -colon_chain;
545 chain_items = chain_with_colon | colon_chain; 531 chain_items = chain_with_colon | colon_chain;
546 532
547 index = seq({'[', not_('['), space, Exp, space, ']'}); 533 index = '[' >> not_('[') >> space >> Exp >> space >> ']';
548 chain_item = sel({ 534 chain_item =
549 Invoke >> -ExistentialOp, 535 Invoke >> -ExistentialOp |
550 DotChainItem >> -ExistentialOp, 536 DotChainItem >> -ExistentialOp |
551 Slice, 537 Slice |
552 index >> -ExistentialOp 538 index >> -ExistentialOp;
553 }); 539 DotChainItem = '.' >> (Name | Metatable | Metamethod);
554 DotChainItem = '.' >> sel({Name, Metatable, Metamethod}); 540 ColonChainItem = (expr('\\') | "::") >> (LuaKeyword | Name | Metamethod);
555 ColonChainItem = sel({'\\', "::"}) >> sel({LuaKeyword, Name, Metamethod});
556 invoke_chain = Invoke >> -ExistentialOp >> -chain_items; 541 invoke_chain = Invoke >> -ExistentialOp >> -chain_items;
557 colon_chain = ColonChainItem >> -ExistentialOp >> -invoke_chain; 542 colon_chain = ColonChainItem >> -ExistentialOp >> -invoke_chain;
558 543
559 DefaultValue = true_(); 544 DefaultValue = true_();
560 Slice = seq({ 545 Slice =
561 '[', not_('['), 546 '[' >> not_('[') >>
562 space, Exp | DefaultValue, 547 space >> (Exp | DefaultValue) >>
563 space, ',', 548 space >> ',' >>
564 space, Exp | DefaultValue, 549 space >> (Exp | DefaultValue) >>
565 space, ',' >> space >> Exp | DefaultValue, 550 space >> (',' >> space >> Exp | DefaultValue) >>
566 space, ']' 551 space >> ']';
567 }); 552
568 553 Invoke = Seperator >> (
569 Invoke = Seperator >> sel({ 554 fn_args |
570 fn_args, 555 SingleString |
571 SingleString, 556 DoubleString |
572 DoubleString, 557 and_('[') >> LuaString |
573 and_('[') >> LuaString,
574 and_('{') >> TableLit 558 and_('{') >> TableLit
575 }); 559 );
576 560
577 SpreadExp = "..." >> space >> Exp; 561 SpreadExp = "..." >> space >> Exp;
578 562
579 table_value = sel({ 563 table_value =
580 VariablePairDef, 564 VariablePairDef |
581 NormalPairDef, 565 NormalPairDef |
582 MetaVariablePairDef, 566 MetaVariablePairDef |
583 MetaNormalPairDef, 567 MetaNormalPairDef |
584 SpreadExp, 568 SpreadExp |
585 NormalDef 569 NormalDef;
586 });
587 570
588 table_lit_lines = space_break >> table_lit_line >> *(-(space >> ',') >> space_break >> table_lit_line) >> -(space >> ','); 571 table_lit_lines = space_break >> table_lit_line >> *(-(space >> ',') >> space_break >> table_lit_line) >> -(space >> ',');
589 572
590 TableLit = seq({ 573 TableLit =
591 space, '{', Seperator, 574 space >> '{' >> Seperator >>
592 -(space >> table_value_list), 575 -(space >> table_value_list) >>
593 -(space >> ','), 576 -(space >> ',') >>
594 -table_lit_lines, 577 -table_lit_lines >>
595 white, '}' 578 white >> '}';
596 });
597 579
598 table_value_list = table_value >> *seq({space, ',', space, table_value}); 580 table_value_list = table_value >> *(space >> ',' >> space >> table_value);
599 581
600 table_lit_line = ( 582 table_lit_line = (
601 push_indent_match >> (space >> table_value_list >> pop_indent | pop_indent) 583 push_indent_match >> (space >> table_value_list >> pop_indent | pop_indent)
@@ -611,21 +593,22 @@ YueParser::YueParser() {
611 593
612 ClassMemberList = Seperator >> key_value >> *(space >> ',' >> space >> key_value); 594 ClassMemberList = Seperator >> key_value >> *(space >> ',' >> space >> key_value);
613 class_line = check_indent_match >> space >> (ClassMemberList | Statement) >> -(space >> ','); 595 class_line = check_indent_match >> space >> (ClassMemberList | Statement) >> -(space >> ',');
614 ClassBlock = seq({+space_break, advance_match, Seperator, class_line, *(+space_break >> class_line), pop_indent}); 596 ClassBlock =
615 597 +space_break >>
616 ClassDecl = seq({ 598 advance_match >> Seperator >>
617 key("class"), not_(':'), 599 class_line >> *(+space_break >> class_line) >>
618 disable_arg_table_block_rule(seq({ 600 pop_indent;
619 -(space >> Assignable), 601
620 -seq({space, key("extends"), prevent_indent, space, ensure(Exp, pop_indent)}), 602 ClassDecl =
621 -seq({space, key("using"), prevent_indent, space, ensure(ExpList, pop_indent)}) 603 key("class") >> not_(':') >> disable_arg_table_block_rule(
622 })), 604 -(space >> Assignable) >>
623 -ClassBlock 605 -(space >> key("extends") >> prevent_indent >> space >> ensure(Exp, pop_indent)) >>
624 }); 606 -(space >> key("using") >> prevent_indent >> space >> ensure(ExpList, pop_indent))
607 ) >> -ClassBlock;
625 608
626 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow)); 609 GlobalValues = NameList >> -(space >> '=' >> space >> (TableBlock | ExpListLow));
627 GlobalOp = sel({'*', '^'}); 610 GlobalOp = expr('*') | '^';
628 Global = key("global") >> space >> sel({ClassDecl, GlobalOp, GlobalValues}); 611 Global = key("global") >> space >> (ClassDecl | GlobalOp | GlobalValues);
629 612
630 ExportDefault = key("default"); 613 ExportDefault = key("default");
631 614
@@ -659,57 +642,51 @@ YueParser::YueParser() {
659 642
660 VariablePair = ':' >> Variable; 643 VariablePair = ':' >> Variable;
661 644
662 NormalPair = seq({ 645 NormalPair =
663 sel({ 646 (
664 KeyName, 647 KeyName |
665 seq({'[', not_('['), space, Exp, space, ']'}), 648 '[' >> not_('[') >> space >> Exp >> space >> ']' |
666 String 649 String
667 }), 650 ) >> ':' >> not_(':') >> space >>
668 ':', not_(':'), space, 651 (Exp | TableBlock | +space_break >> space >> Exp);
669 sel({Exp, TableBlock, +space_break >> space >> Exp})
670 });
671 652
672 MetaVariablePair = ":<" >> space >> Variable >> space >> '>'; 653 MetaVariablePair = ":<" >> space >> Variable >> space >> '>';
673 654
674 MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >> 655 MetaNormalPair = '<' >> space >> -meta_index >> space >> ">:" >> space >>
675 sel({Exp, TableBlock, +space_break >> space >> Exp}); 656 (Exp | TableBlock | +space_break >> space >> Exp);
676 657
677 destruct_def = -seq({space, '=', space, Exp}); 658 destruct_def = -(space >> '=' >> space >> Exp);
678 VariablePairDef = VariablePair >> destruct_def; 659 VariablePairDef = VariablePair >> destruct_def;
679 NormalPairDef = NormalPair >> destruct_def; 660 NormalPairDef = NormalPair >> destruct_def;
680 MetaVariablePairDef = MetaVariablePair >> destruct_def; 661 MetaVariablePairDef = MetaVariablePair >> destruct_def;
681 MetaNormalPairDef = MetaNormalPair >> destruct_def; 662 MetaNormalPairDef = MetaNormalPair >> destruct_def;
682 NormalDef = Exp >> Seperator >> destruct_def; 663 NormalDef = Exp >> Seperator >> destruct_def;
683 664
684 key_value = sel({ 665 key_value =
685 VariablePair, 666 VariablePair |
686 NormalPair, 667 NormalPair |
687 MetaVariablePair, 668 MetaVariablePair |
688 MetaNormalPair 669 MetaNormalPair;
689 });
690 key_value_list = key_value >> *(space >> ',' >> space >> key_value); 670 key_value_list = key_value >> *(space >> ',' >> space >> key_value);
691 key_value_line = check_indent_match >> space >> sel({ 671 key_value_line = check_indent_match >> space >> (
692 key_value_list >> -(space >> ','), 672 key_value_list >> -(space >> ',') |
693 TableBlockIndent, 673 TableBlockIndent |
694 '*' >> space >> sel({SpreadExp, Exp, TableBlock}) 674 '*' >> space >> (SpreadExp | Exp | TableBlock)
695 }); 675 );
696 676
697 FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '=' >> space >> Exp); 677 FnArgDef = (Variable | SelfItem >> -ExistentialOp) >> -(space >> '=' >> space >> Exp);
698 678
699 FnArgDefList = Seperator >> ( 679 FnArgDefList = Seperator >> ((
700 seq({ 680 FnArgDef >>
701 FnArgDef, 681 *(space >> (',' | line_break) >> white >> FnArgDef) >>
702 *seq({space, ',' | line_break, white, FnArgDef}), 682 -(space >> (',' | line_break) >> white >> VarArg)
703 -seq({space, ',' | line_break, white, VarArg}) 683 ) | VarArg);
704 }) |
705 VarArg
706 );
707 684
708 OuterVarShadow = key("using") >> space >> (NameList | key("nil")); 685 OuterVarShadow = key("using") >> space >> (NameList | key("nil"));
709 686
710 FnArgsDef = seq({'(', white, -FnArgDefList, -(space >> OuterVarShadow), white, ')'}); 687 FnArgsDef = '(' >> white >> -FnArgDefList >> -(space >> OuterVarShadow) >> white >> ')';
711 FnArrow = sel({"->", "=>"}); 688 FnArrow = expr("->") | "=>";
712 FunLit = seq({-FnArgsDef, space, FnArrow, -(space >> Body)}); 689 FunLit = -FnArgsDef >> space >> FnArrow >> -(space >> Body);
713 690
714 MacroName = '$' >> Name; 691 MacroName = '$' >> Name;
715 macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')'; 692 macro_args_def = '(' >> white >> -FnArgDefList >> white >> ')';
@@ -722,15 +699,11 @@ YueParser::YueParser() {
722 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure); 699 AssignableNameList = Seperator >> NameOrDestructure >> *(space >> ',' >> space >> NameOrDestructure);
723 700
724 FnArrowBack = '<' >> set("-="); 701 FnArrowBack = '<' >> set("-=");
725 Backcall = seq({-(FnArgsDef >> space), FnArrowBack, space, ChainValue}); 702 Backcall = -(FnArgsDef >> space) >> FnArrowBack >> space >> ChainValue;
726 703
727 PipeBody = seq({ 704 PipeBody = Seperator >>
728 Seperator, 705 pipe_operator >> space >> UnaryExp >>
729 pipe_operator, 706 *(+space_break >> check_indent_match >> space >> pipe_operator >> space >> UnaryExp);
730 space,
731 UnaryExp,
732 *seq({+space_break, check_indent_match, space, pipe_operator, space, UnaryExp})
733 });
734 707
735 ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp); 708 ExpList = Seperator >> Exp >> *(space >> ',' >> space >> Exp);
736 ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp); 709 ExpListLow = Seperator >> Exp >> *(space >> set(",;") >> space >> Exp);
@@ -755,21 +728,19 @@ YueParser::YueParser() {
755 }); 728 });
756 729
757 InvokeArgs = 730 InvokeArgs =
758 not_(set("-~")) >> space >> Seperator >> 731 not_(set("-~")) >> space >> Seperator >> (
759 sel({ 732 Exp >> *(space >> ',' >> space >> Exp) >> -(space >> invoke_args_with_table) |
760 Exp >> *(space >> ',' >> space >> Exp) >> -(space >> invoke_args_with_table), 733 arg_table_block |
761 arg_table_block,
762 leading_spaces_error 734 leading_spaces_error
763 }); 735 );
764 736
765 ConstValue = sel({"nil", "true", "false"}) >> not_alpha_num; 737 ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num;
766 738
767 SimpleValue = sel({ 739 SimpleValue =
768 TableLit, ConstValue, If, Switch, Try, With, 740 TableLit | ConstValue | If | Switch | Try | With |
769 ClassDecl, ForEach, For, While, Do, 741 ClassDecl | ForEach | For | While | Do |
770 UnaryValue, TblComprehension, Comprehension, 742 UnaryValue | TblComprehension | Comprehension |
771 FunLit, Num 743 FunLit | Num;
772 });
773 744
774 ExpListAssign = ExpList >> -(space >> (Update | Assign)) >> not_(space >> '='); 745 ExpListAssign = ExpList >> -(space >> (Update | Assign)) >> not_(space >> '=');
775 746
@@ -780,70 +751,66 @@ YueParser::YueParser() {
780 yue_line_comment = "--" >> YueLineComment >> and_(stop); 751 yue_line_comment = "--" >> YueLineComment >> and_(stop);
781 YueMultilineComment = multi_line_content; 752 YueMultilineComment = multi_line_content;
782 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close; 753 yue_multiline_comment = multi_line_open >> YueMultilineComment >> multi_line_close;
783 yue_comment = check_indent >> sel({ 754 yue_comment = check_indent >> (
784 seq({ 755 (
785 yue_multiline_comment, 756 yue_multiline_comment >>
786 *(set(" \t") | yue_multiline_comment), 757 *(set(" \t") | yue_multiline_comment) >>
787 -yue_line_comment 758 -yue_line_comment
788 }), 759 ) | yue_line_comment
789 yue_line_comment 760 ) >> and_(line_break);
790 }) >> and_(line_break);
791 761
792 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign; 762 ChainAssign = Seperator >> Exp >> +(space >> '=' >> space >> Exp >> space >> and_('=')) >> space >> Assign;
793 763
794 StatementAppendix = sel({IfLine, WhileLine, CompInner}) >> space; 764 StatementAppendix = (IfLine | WhileLine | CompInner) >> space;
795 StatementSep = and_(seq({ 765 StatementSep = and_(
796 *space_break, check_indent_match, space, 766 *space_break >> check_indent_match >> space >> (
797 sel({ 767 set("($'\"") |
798 set("($'\""), 768 "[[" |
799 "[[",
800 "[=" 769 "[="
801 }) 770 )
802 })); 771 );
803 Statement = seq({ 772 Statement =
804 Seperator, 773 Seperator >>
805 -seq({ 774 -(
806 yue_comment, 775 yue_comment >>
807 *(line_break >> yue_comment), 776 *(line_break >> yue_comment) >>
808 line_break, 777 line_break >>
809 check_indent_match 778 check_indent_match
810 }), 779 ) >>
811 space, 780 space >> (
812 sel({ 781 Import | While | Repeat | For | ForEach |
813 Import, While, Repeat, For, ForEach, 782 Return | Local | Global | Export | Macro |
814 Return, Local, Global, Export, Macro, 783 MacroInPlace | BreakLoop | Label | Goto | ShortTabAppending |
815 MacroInPlace, BreakLoop, Label, Goto, ShortTabAppending, 784 LocalAttrib | Backcall | PipeBody | ExpListAssign | ChainAssign |
816 LocalAttrib, Backcall, PipeBody, ExpListAssign, ChainAssign,
817 StatementAppendix >> empty_block_error 785 StatementAppendix >> empty_block_error
818 }), 786 ) >>
819 space, 787 space >>
820 -StatementAppendix, 788 -StatementAppendix >>
821 -StatementSep 789 -StatementSep;
822 });
823 790
824 Body = in_block | Statement; 791 Body = in_block | Statement;
825 792
826 empty_line_break = sel({ 793 empty_line_break = (
827 check_indent >> (multi_line_comment >> space | comment), 794 check_indent >> (multi_line_comment >> space | comment) |
828 advance >> ensure(multi_line_comment >> space | comment, pop_indent), 795 advance >> ensure(multi_line_comment >> space | comment, pop_indent) |
829 plain_space 796 plain_space
830 }) >> and_(line_break); 797 ) >> and_(line_break);
831 798
832 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { 799 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) {
833 throw ParserError("unexpected indent", *item.begin, *item.end); 800 throw ParserError("unexpected indent", *item.begin, *item.end);
834 return false; 801 return false;
835 }); 802 });
836 803
837 line = sel({ 804 line = (
838 check_indent_match >> Statement, 805 check_indent_match >> Statement |
839 empty_line_break, 806 empty_line_break |
840 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent) 807 advance_match >> ensure(space >> (indentation_error | Statement), pop_indent)
841 }); 808 );
842 Block = seq({Seperator, line, *(+line_break >> line)}); 809 Block = Seperator >> line >> *(+line_break >> line);
843 810
844 shebang = "#!" >> *(not_(stop) >> any_char); 811 shebang = "#!" >> *(not_(stop) >> any_char);
845 BlockEnd = seq({Block, white, stop}); 812 BlockEnd = Block >> white >> stop;
846 File = seq({-shebang, -Block, white, stop}); 813 File = -shebang >> -Block >> white >> stop;
847} 814}
848// clang-format on 815// clang-format on
849 816
diff --git a/src/yuescript/yue_parser.h b/src/yuescript/yue_parser.h
index f3b3f4f..da25d3d 100644
--- a/src/yuescript/yue_parser.h
+++ b/src/yuescript/yue_parser.h
@@ -135,7 +135,6 @@ private:
135 rule multi_line_close; 135 rule multi_line_close;
136 rule multi_line_content; 136 rule multi_line_content;
137 rule multi_line_comment; 137 rule multi_line_comment;
138 rule indent;
139 rule escape_new_line; 138 rule escape_new_line;
140 rule space_one; 139 rule space_one;
141 rule space; 140 rule space;