aboutsummaryrefslogtreecommitdiff
path: root/src/yuescript/yue_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuescript/yue_parser.cpp')
-rw-r--r--src/yuescript/yue_parser.cpp63
1 files changed, 35 insertions, 28 deletions
diff --git a/src/yuescript/yue_parser.cpp b/src/yuescript/yue_parser.cpp
index d8fdc28..f215ee4 100644
--- a/src/yuescript/yue_parser.cpp
+++ b/src/yuescript/yue_parser.cpp
@@ -30,6 +30,17 @@ std::unordered_set<std::string> Keywords = {
30 "try"s, "unless"s, "using"s, "when"s, "with"s // Yue keywords 30 "try"s, "unless"s, "using"s, "when"s, "with"s // Yue keywords
31}; 31};
32 32
33class ParserError : public std::logic_error {
34public:
35 explicit ParserError(std::string_view msg, const pos* begin)
36 : std::logic_error(std::string(msg))
37 , line(begin->m_line)
38 , col(begin->m_col) { }
39
40 int line;
41 int col;
42};
43
33// clang-format off 44// clang-format off
34YueParser::YueParser() { 45YueParser::YueParser() {
35 plain_space = *set(" \t"); 46 plain_space = *set(" \t");
@@ -78,7 +89,7 @@ YueParser::YueParser() {
78 Seperator = true_(); 89 Seperator = true_();
79 90
80 empty_block_error = pl::user(true_(), [](const item_t& item) { 91 empty_block_error = pl::user(true_(), [](const item_t& item) {
81 throw ParserError("must be followed by a statement or an indented block", *item.begin, *item.end); 92 throw ParserError("must be followed by a statement or an indented block"sv, item.begin);
82 return false; 93 return false;
83 }); 94 });
84 95
@@ -489,7 +500,7 @@ YueParser::YueParser() {
489 st->expLevel++; 500 st->expLevel++;
490 const int max_exp_level = 100; 501 const int max_exp_level = 100;
491 if (st->expLevel > max_exp_level) { 502 if (st->expLevel > max_exp_level) {
492 throw ParserError("nesting expressions exceeds 100 levels", *item.begin, *item.end); 503 throw ParserError("nesting expressions exceeds 100 levels"sv, item.begin);
493 } 504 }
494 return true; 505 return true;
495 }); 506 });
@@ -658,10 +669,10 @@ YueParser::YueParser() {
658 }) >> (pl::user(space >> ExportDefault >> space >> Exp, [](const item_t& item) { 669 }) >> (pl::user(space >> ExportDefault >> space >> Exp, [](const item_t& item) {
659 State* st = reinterpret_cast<State*>(item.user_data); 670 State* st = reinterpret_cast<State*>(item.user_data);
660 if (st->exportDefault) { 671 if (st->exportDefault) {
661 throw ParserError("export default has already been declared", *item.begin, *item.end); 672 throw ParserError("export default has already been declared"sv, item.begin);
662 } 673 }
663 if (st->exportCount > 1) { 674 if (st->exportCount > 1) {
664 throw ParserError("there are items already being exported", *item.begin, *item.end); 675 throw ParserError("there are items already being exported"sv, item.begin);
665 } 676 }
666 st->exportDefault = true; 677 st->exportDefault = true;
667 return true; 678 return true;
@@ -669,7 +680,7 @@ YueParser::YueParser() {
669 | (not_(space >> ExportDefault) >> pl::user(true_(), [](const item_t& item) { 680 | (not_(space >> ExportDefault) >> pl::user(true_(), [](const item_t& item) {
670 State* st = reinterpret_cast<State*>(item.user_data); 681 State* st = reinterpret_cast<State*>(item.user_data);
671 if (st->exportDefault && st->exportCount > 1) { 682 if (st->exportDefault && st->exportCount > 1) {
672 throw ParserError("can not export any more items when 'export default' is declared", *item.begin, *item.end); 683 throw ParserError("can not export any more items when 'export default' is declared"sv, item.begin);
673 } 684 }
674 return true; 685 return true;
675 }) >> space >> ExpList >> -(space >> Assign)) 686 }) >> space >> ExpList >> -(space >> Assign))
@@ -762,7 +773,7 @@ YueParser::YueParser() {
762 ) | arg_table_block; 773 ) | arg_table_block;
763 774
764 leading_spaces_error = pl::user(+space_one >> '(' >> space >> Exp >> +(space >> ',' >> space >> Exp) >> space >> ')', [](const item_t& item) { 775 leading_spaces_error = pl::user(+space_one >> '(' >> space >> Exp >> +(space >> ',' >> space >> Exp) >> space >> ')', [](const item_t& item) {
765 throw ParserError("write invoke arguments in parentheses without leading spaces or just leading spaces without parentheses", *item.begin, *item.end); 776 throw ParserError("write invoke arguments in parentheses without leading spaces or just leading spaces without parentheses"sv, item.begin);
766 return false; 777 return false;
767 }); 778 });
768 779
@@ -776,12 +787,12 @@ YueParser::YueParser() {
776 ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num; 787 ConstValue = (expr("nil") | "true" | "false") >> not_alpha_num;
777 788
778 braces_expression_error = pl::user(true_(), [](const item_t& item) { 789 braces_expression_error = pl::user(true_(), [](const item_t& item) {
779 throw ParserError("syntax error in brace expression", *item.begin, *item.end); 790 throw ParserError("syntax error in brace expression"sv, item.begin);
780 return false; 791 return false;
781 }); 792 });
782 793
783 brackets_expression_error = pl::user(true_(), [](const item_t& item) { 794 brackets_expression_error = pl::user(true_(), [](const item_t& item) {
784 throw ParserError("syntax error in bracket expression", *item.begin, *item.end); 795 throw ParserError("syntax error in bracket expression"sv, item.begin);
785 return false; 796 return false;
786 }); 797 });
787 798
@@ -846,7 +857,7 @@ YueParser::YueParser() {
846 ) >> and_(line_break); 857 ) >> and_(line_break);
847 858
848 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) { 859 indentation_error = pl::user(not_(pipe_operator | eof()), [](const item_t& item) {
849 throw ParserError("unexpected indent", *item.begin, *item.end); 860 throw ParserError("unexpected indent"sv, item.begin);
850 return false; 861 return false;
851 }); 862 });
852 863
@@ -875,7 +886,7 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) {
875 res.codes = std::make_unique<input>(); 886 res.codes = std::make_unique<input>();
876 } 887 }
877 } catch (const std::range_error&) { 888 } catch (const std::range_error&) {
878 res.error = "invalid text encoding"sv; 889 res.error = {"invalid text encoding"s, 1, 1};
879 return res; 890 return res;
880 } 891 }
881 error_list errors; 892 error_list errors;
@@ -888,26 +899,22 @@ ParseInfo YueParser::parse(std::string_view codes, rule& r) {
888 res.exportMacro = state.exportMacro; 899 res.exportMacro = state.exportMacro;
889 } 900 }
890 } catch (const ParserError& err) { 901 } catch (const ParserError& err) {
891 res.error = res.errorMessage(err.what(), &err.loc); 902 res.error = {err.what(), err.line, err.col};
892 return res; 903 return res;
893 } catch (const std::logic_error& err) { 904 } catch (const std::logic_error& err) {
894 res.error = err.what(); 905 res.error = {err.what(), 1, 1};
895 return res; 906 return res;
896 } 907 }
897 if (!errors.empty()) { 908 if (!errors.empty()) {
898 std::ostringstream buf; 909 const error& err = errors.front();
899 for (error_list::iterator it = errors.begin(); it != errors.end(); ++it) { 910 switch (err.m_type) {
900 const error& err = *it; 911 case ERROR_TYPE::ERROR_SYNTAX_ERROR:
901 switch (err.m_type) { 912 res.error = {"syntax error"s, err.m_begin.m_line, err.m_begin.m_col};
902 case ERROR_TYPE::ERROR_SYNTAX_ERROR: 913 break;
903 buf << res.errorMessage("syntax error"sv, &err); 914 case ERROR_TYPE::ERROR_INVALID_EOF:
904 break; 915 res.error = {"invalid EOF"s, err.m_begin.m_line, err.m_begin.m_col};
905 case ERROR_TYPE::ERROR_INVALID_EOF: 916 break;
906 buf << res.errorMessage("invalid EOF"sv, &err);
907 break;
908 }
909 } 917 }
910 res.error = buf.str();
911 } 918 }
912 return res; 919 return res;
913} 920}
@@ -944,9 +951,9 @@ void trim(std::string& str) {
944} 951}
945} // namespace Utils 952} // namespace Utils
946 953
947std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc) const { 954std::string ParseInfo::errorMessage(std::string_view msg, int errLine, int errCol) const {
948 const int ASCII = 255; 955 const int ASCII = 255;
949 int length = loc->m_begin.m_line; 956 int length = errLine;
950 auto begin = codes->begin(); 957 auto begin = codes->begin();
951 auto end = codes->end(); 958 auto end = codes->end();
952 int count = 0; 959 int count = 0;
@@ -961,7 +968,7 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc
961 count++; 968 count++;
962 } 969 }
963 } 970 }
964 int oldCol = loc->m_begin.m_col; 971 int oldCol = errCol;
965 int col = std::max(0, oldCol - 1); 972 int col = std::max(0, oldCol - 1);
966 auto it = begin; 973 auto it = begin;
967 for (int i = 0; i < oldCol && it != end; ++i) { 974 for (int i = 0; i < oldCol && it != end; ++i) {
@@ -977,7 +984,7 @@ std::string ParseInfo::errorMessage(std::string_view msg, const input_range* loc
977 } 984 }
978 Utils::replace(line, "\t"sv, " "sv); 985 Utils::replace(line, "\t"sv, " "sv);
979 std::ostringstream buf; 986 std::ostringstream buf;
980 buf << loc->m_begin.m_line << ": "sv << msg << '\n' 987 buf << errLine << ": "sv << msg << '\n'
981 << line << '\n' 988 << line << '\n'
982 << std::string(col, ' ') << "^"sv; 989 << std::string(col, ' ') << "^"sv;
983 return buf.str(); 990 return buf.str();