diff options
author | Li Jin <dragon-fly@qq.com> | 2023-01-20 16:57:58 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2023-01-20 16:58:04 +0800 |
commit | 89b606df6303a44f121be8ff0f4458c97f93d9df (patch) | |
tree | 9e863026e48eb9fe35a4cde7cf3e34353f2d683d | |
parent | 2fad28df04f2c8f015ccf90e16e74c47ad174bde (diff) | |
download | yuescript-89b606df6303a44f121be8ff0f4458c97f93d9df.tar.gz yuescript-89b606df6303a44f121be8ff0f4458c97f93d9df.tar.bz2 yuescript-89b606df6303a44f121be8ff0f4458c97f93d9df.zip |
try auto merging parser call stacks.
-rw-r--r-- | src/yuescript/parser.cpp | 306 | ||||
-rw-r--r-- | src/yuescript/parser.hpp | 14 | ||||
-rw-r--r-- | src/yuescript/yue_parser.cpp | 529 | ||||
-rw-r--r-- | src/yuescript/yue_parser.h | 1 |
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 | ||
179 | enum 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 |
180 | class _expr { | 188 | class _expr { |
181 | public: | 189 | public: |
@@ -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 | ||
609 | protected: | 619 | protected: |
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 |
637 | class _seq_list : public _expr { | 654 | class _seq_list : public _expr { |
638 | public: | 655 | public: |
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 | |||
668 | private: | 692 | private: |
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 |
698 | class _sel : public _expr { | 727 | class _choice_list : public _expr { |
699 | public: | 728 | public: |
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 | |||
733 | private: | 769 | private: |
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: | |||
761 | class _eof : public _expr { | 798 | class _eof : public _expr { |
762 | public: | 799 | public: |
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: | |||
775 | class _any : public _expr { | 812 | class _any : public _expr { |
776 | public: | 813 | public: |
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: | |||
794 | class _true : public _expr { | 831 | class _true : public _expr { |
795 | public: | 832 | public: |
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: | |||
808 | class _false : public _expr { | 845 | class _false : public _expr { |
809 | public: | 846 | public: |
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. | 1303 | expr 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()) { |
1270 | expr 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. | 1391 | expr 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()) { |
1288 | expr 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 | */ |
304 | expr operator>>(const expr& left, const expr& right); | 304 | expr operator>>(const expr& left, const expr& right); |
305 | 305 | expr 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 | */ | ||
310 | expr 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 | */ |
317 | expr operator|(const expr& left, const expr& right); | 312 | expr operator|(const expr& left, const expr& right); |
318 | 313 | expr 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 | */ | ||
323 | expr 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; |