11#ifndef CHAISCRIPT_PARSER_HPP_
12#define CHAISCRIPT_PARSER_HPP_
33#if defined(CHAISCRIPT_UTF16_UTF32)
38#if defined(CHAISCRIPT_MSVC) && defined(max) && defined(min)
39#define CHAISCRIPT_PUSHED_MIN_MAX
40#pragma push_macro("max")
42#pragma push_macro("min")
73 template<
typename string_type>
79 typedef std::string::value_type char_type;
82 c[1] = char_type(val);
83 c[0] = char_type(val >> 8);
87 return std::string(1, c[1]);
90 return std::string(c, 2);
95 typedef typename string_type::value_type target_char_type;
96#if defined (CHAISCRIPT_UTF16_UTF32)
98 std::wstring_convert<std::codecvt_utf8<target_char_type>, target_char_type> converter;
103 return string_type(1, target_char_type(val));
121 template<
typename Tracer,
typename Optimizer, std::
size_t Parse_Depth=512>
127 std::size_t m_current_parse_depth = 0;
131 static const auto max_depth = Parse_Depth;
134 ++
parser->m_current_parse_depth;
135 if (
parser->m_current_parse_depth > max_depth) {
141 ~Depth_Counter()
noexcept
143 --
parser->m_current_parse_depth;
149 static std::array<std::array<bool, detail::lengthof_alphabet>,
detail::max_alphabet> build_alphabet()
153 for (
auto &alpha : alphabet) {
210 static const std::array<std::array<bool, detail::lengthof_alphabet>,
detail::max_alphabet> &create_alphabet()
212 static const auto alpha = build_alphabet();
217 static const std::vector<std::vector<utility::Static_String>> &create_operator_matches() {
218 static const std::vector<std::vector<utility::Static_String>> operator_matches {
226 {
"<",
"<=",
">",
">="},
231 {
"++",
"--",
"-",
"+",
"!",
"~"}
234 return operator_matches;
238 static const std::array<Operator_Precidence, 12> &create_operators() {
239 static const std::array<Operator_Precidence, 12> operators = { {
286 const std::array<std::array<bool, detail::lengthof_alphabet>,
detail::max_alphabet> &m_alphabet = create_alphabet();
287 const std::vector<std::vector<utility::Static_String>> &m_operator_matches = create_operator_matches();
288 const std::array<Operator_Precidence, 12> &m_operators = create_operators();
290 std::shared_ptr<std::string> m_filename;
291 std::vector<eval::AST_Node_Impl_Ptr<Tracer>> m_match_stack;
296 Position() =
default;
298 Position(std::string::const_iterator t_pos, std::string::const_iterator t_end)
299 : line(1), col(1), m_pos(t_pos), m_end(t_end), m_last_col(1)
303 static std::string
str(
const Position &t_begin,
const Position &t_end) {
304 return std::string(t_begin.m_pos, t_end.m_pos);
307 Position &operator++() {
308 if (m_pos != m_end) {
309 if (*m_pos ==
'\n') {
311 m_last_col = std::exchange(col, 1);
321 Position &operator--() {
323 if (*m_pos ==
'\n') {
332 Position &operator+=(
size_t t_distance) {
333 *
this = (*this) + t_distance;
337 Position
operator+(
size_t t_distance)
const {
339 for (
size_t i = 0; i < t_distance; ++i) {
345 Position &operator-=(
size_t t_distance) {
346 *
this = (*this) - t_distance;
350 Position
operator-(
size_t t_distance)
const {
352 for (
size_t i = 0; i < t_distance; ++i) {
358 bool operator==(
const Position &t_rhs)
const {
359 return m_pos == t_rhs.m_pos;
362 bool operator!=(
const Position &t_rhs)
const {
363 return m_pos != t_rhs.m_pos;
366 bool has_more()
const {
367 return m_pos != m_end;
370 size_t remaining()
const {
371 return static_cast<size_t>(std::distance(m_pos, m_end));
375 if (m_pos == m_end) {
376 static const char ktmp =
'\0';
387 std::string::const_iterator m_pos;
388 std::string::const_iterator m_end;
395 Optimizer m_optimizer;
397 void validate_object_name(
const std::string &
name)
const
406 : m_tracer(
std::move(tracer)),
409 m_match_stack.reserve(2);
440 template<
typename NodeType>
442 bool is_deep =
false;
446 if (t_match_start != m_match_stack.size()) {
450 m_match_stack[t_match_start]->location.start.line,
451 m_match_stack[t_match_start]->location.start.column,
466 std::vector<eval::AST_Node_Impl_Ptr<Tracer>> new_children;
469 new_children.assign(std::make_move_iterator(m_match_stack.begin() +
static_cast<int>(t_match_start)),
470 std::make_move_iterator(m_match_stack.end()));
471 m_match_stack.erase(m_match_stack.begin() +
static_cast<int>(t_match_start), m_match_stack.end());
475 m_match_stack.push_back(
476 m_optimizer.optimize(
480 std::move(new_children)))
488 const auto len = sym.
size();
489 if (m_position.remaining() >= len) {
490 const char *file_pos = &(*m_position);
491 for (
size_t pos = 0; pos < len; ++pos)
493 if (sym.
c_str()[pos] != file_pos[pos]) {
return false; }
503 if (
Symbol_(multiline_comment_begin())) {
504 while (m_position.has_more()) {
505 if (
Symbol_(multiline_comment_end())) {
507 }
else if (!
Eol_()) {
512 }
else if (
Symbol_(singleline_comment())) {
513 while (m_position.has_more()) {
517 }
else if (
Char_(
'\n')) {
525 }
else if (
Symbol_(annotation())) {
526 while (m_position.has_more()) {
530 }
else if (
Char_(
'\n')) {
549 while (m_position.has_more()) {
550 if(
static_cast<unsigned char>(*m_position) > 0x7e) {
553 auto end_line = (*m_position != 0) && ((*m_position ==
'\n') || (*m_position ==
'\r' && *(m_position+1) ==
'\n'));
558 if(*m_position ==
'\r') {
580 if (m_position.has_more() && (std::tolower(*m_position) ==
'e')) {
582 if (m_position.has_more() && ((*m_position ==
'-') || (*m_position ==
'+'))) {
585 auto exponent_pos = m_position;
589 if (m_position == exponent_pos) {
612 if (m_position.has_more() && (std::tolower(*m_position) ==
'e')) {
616 else if (m_position.has_more() && (*m_position ==
'.')) {
635 if (m_position.has_more() && (*m_position ==
'0')) {
673 if (m_position.has_more() && (*m_position ==
'0')) {
700 auto i = t_val.size();
704 char val = t_val[i-1];
706 if (val ==
'f' || val ==
'F')
709 }
else if (val ==
'l' || val ==
'L') {
730 bool unsigned_ =
false;
732 bool longlong_ =
false;
734 auto i = t_val.size();
738 const char val = t_val[i-1];
740 if (val ==
'u' || val ==
'U')
743 }
else if (val ==
'l' || val ==
'L') {
755 const auto val = prefixed?std::string(t_val.begin()+2,t_val.end()):t_val;
758#pragma GCC diagnostic push
759#pragma GCC diagnostic ignored "-Wsign-compare"
761#ifdef CHAISCRIPT_CLANG
762#pragma GCC diagnostic ignored "-Wtautological-compare"
763#pragma GCC diagnostic ignored "-Wsign-conversion"
769 auto u = std::stoll(val,
nullptr,base);
772 if (!unsigned_ && !long_ && u >= std::numeric_limits<int>::min() && u <= std::numeric_limits<int>::max()) {
774 }
else if ((unsigned_ || base != 10) && !long_ && u >= std::numeric_limits<unsigned int>::min() && u <= std::numeric_limits<unsigned int>::max()) {
775 return const_var(
static_cast<unsigned int>(u));
776 }
else if (!unsigned_ && !longlong_ && u >= std::numeric_limits<long>::min() && u <= std::numeric_limits<long>::max()) {
778 }
else if ((unsigned_ || base != 10) && !longlong_
780 && u >= std::numeric_limits<unsigned long>::min()
781 && u <= std::numeric_limits<unsigned long>::max()) {
782 return const_var(
static_cast<unsigned long>(u));
783 }
else if (!unsigned_ && u >= std::numeric_limits<long long>::min() && u <= std::numeric_limits<long long>::max()) {
784 return const_var(
static_cast<long long>(u));
786 return const_var(
static_cast<unsigned long long>(u));
789 }
catch (
const std::out_of_range &) {
792 auto u = std::stoull(val,
nullptr,base);
794 if (!longlong_ && u >= std::numeric_limits<unsigned long>::min() && u <= std::numeric_limits<unsigned long>::max()) {
795 return const_var(
static_cast<unsigned long>(u));
797 return const_var(
static_cast<unsigned long long>(u));
799 }
catch (
const std::out_of_range &) {
801 return const_var(std::numeric_limits<long long>::max());
806#pragma GCC diagnostic pop
811 template<
typename T,
typename ... Param>
812 std::unique_ptr<eval::AST_Node_Impl<Tracer>>
make_node(std::string t_match,
const int t_prev_line,
const int t_prev_col, Param && ...param)
821 const auto start = m_position;
825 auto match = Position::str(start, m_position);
826 auto bv =
buildInt(16, match,
true);
832 auto match = Position::str(start, m_position);
838 auto match = Position::str(start, m_position);
845 auto match = Position::str(start, m_position);
846 if (!match.empty() && (match[0] ==
'0')) {
847 auto bv =
buildInt(8, match,
false);
850 else if (!match.empty()) {
851 auto bv =
buildInt(10, match,
false);
858 }
catch (
const std::invalid_argument &) {
876 }
else if (m_position.has_more() && (*m_position ==
'`')) {
878 const auto start = m_position;
880 while (m_position.has_more() && (*m_position !=
'`')) {
889 if (start == m_position) {
892 else if (!m_position.has_more()) {
904 bool Id(
const bool validate) {
907 const auto start = m_position;
910 auto text = Position::str(start, m_position);
911 const auto text_hash = utility::fnv1a_32(text.c_str());
914 validate_object_name(text);
917#ifdef CHAISCRIPT_MSVC
919#pragma warning(disable : 4307)
923 case utility::fnv1a_32(
"true"): {
926 case utility::fnv1a_32(
"false"): {
929 case utility::fnv1a_32(
"Infinity"): {
931 const_var(std::numeric_limits<double>::infinity())));
933 case utility::fnv1a_32(
"NaN"): {
935 const_var(std::numeric_limits<double>::quiet_NaN())));
937 case utility::fnv1a_32(
"__LINE__"): {
941 case utility::fnv1a_32(
"__FILE__"): {
945 case utility::fnv1a_32(
"__FUNC__"): {
946 std::string fun_name =
"NOT_IN_FUNCTION";
947 for (
size_t idx = m_match_stack.empty() ? 0 : m_match_stack.size() - 1; idx > 0; --idx)
951 fun_name = m_match_stack[idx-1]->text;
958 case utility::fnv1a_32(
"__CLASS__"): {
959 std::string fun_name =
"NOT_IN_CLASS";
960 for (
size_t idx = m_match_stack.empty() ? 0 : m_match_stack.size() - 1; idx > 1; --idx)
965 fun_name = m_match_stack[idx-2]->text;
972 case utility::fnv1a_32(
"_"): {
974 Boxed_Value(std::make_shared<dispatch::Placeholder_Object>())));
977 std::string val = std::move(text);
980 val = Position::str(start+1, m_position-1);
986#ifdef CHAISCRIPT_MSVC
998 bool Arg(
const bool t_type_allowed =
true) {
999 const auto prev_stack_top = m_match_stack.size();
1008 if (t_type_allowed) {
1021 if (m_position.has_more() && (*m_position ==
'\"')) {
1022 char prev_char = *m_position;
1025 int in_interpolation = 0;
1026 bool in_quote =
false;
1028 while (m_position.has_more() && ((*m_position !=
'\"') || (in_interpolation > 0) || (prev_char ==
'\\'))) {
1031 if (prev_char ==
'$' && *m_position ==
'{') {
1033 }
else if (prev_char !=
'\\' && *m_position ==
'"') {
1034 in_quote = !in_quote;
1035 }
else if (*m_position ==
'}' && !in_quote) {
1039 if (prev_char ==
'\\') {
1042 prev_char = *m_position;
1048 if (m_position.has_more()) {
1059 template<
typename string_type>
1096 }
catch (
const std::invalid_argument &) {
1128 const auto ch =
static_cast<uint32_t
>(std::stoi(
hex_matches,
nullptr, 16));
1136 if (u_size != match_size) {
1139 if (u_size == 4 && ch >= 0xD800 && ch <= 0xDFFF) {
1145 match +=
static_cast<char>(ch);
1146 }
else if (ch < 0x800) {
1147 buf[0] =
static_cast<char>(0xC0 | (ch >> 6));
1148 buf[1] =
static_cast<char>(0x80 | (ch & 0x3F));
1149 match.append(buf, 2);
1150 }
else if (ch < 0x10000) {
1151 buf[0] =
static_cast<char>(0xE0 | (ch >> 12));
1152 buf[1] =
static_cast<char>(0x80 | ((ch >> 6) & 0x3F));
1153 buf[2] =
static_cast<char>(0x80 | (ch & 0x3F));
1154 match.append(buf, 3);
1155 }
else if (ch < 0x200000) {
1156 buf[0] =
static_cast<char>(0xF0 | (ch >> 18));
1157 buf[1] =
static_cast<char>(0x80 | ((ch >> 12) & 0x3F));
1158 buf[2] =
static_cast<char>(0x80 | ((ch >> 6) & 0x3F));
1159 buf[3] =
static_cast<char>(0x80 | (ch & 0x3F));
1160 match.append(buf, 4);
1167 void parse(
const char_type t_char,
const int line,
const int col,
const std::string &filename) {
1168 const bool is_octal_char = t_char >=
'0' && t_char <=
'7';
1170 const bool is_hex_char = (t_char >=
'0' && t_char <=
'9')
1171 || (t_char >=
'a' && t_char <=
'f')
1172 || (t_char >=
'A' && t_char <=
'F');
1175 if (is_octal_char) {
1217 if (t_char ==
'\\') {
1219 match.push_back(
'\\');
1226 if (is_octal_char) {
1229 }
else if (t_char ==
'x') {
1231 }
else if (t_char ==
'u') {
1233 }
else if (t_char ==
'U') {
1237 case (
'\'') :
match.push_back(
'\'');
break;
1238 case (
'\"') :
match.push_back(
'\"');
break;
1239 case (
'?') :
match.push_back(
'?');
break;
1240 case (
'a') :
match.push_back(
'\a');
break;
1241 case (
'b') :
match.push_back(
'\b');
break;
1242 case (
'f') :
match.push_back(
'\f');
break;
1243 case (
'n') :
match.push_back(
'\n');
break;
1244 case (
'r') :
match.push_back(
'\r');
break;
1245 case (
't') :
match.push_back(
'\t');
break;
1246 case (
'v') :
match.push_back(
'\v');
break;
1247 case (
'$') :
match.push_back(
'$');
break;
1255 match.push_back(t_char);
1265 Depth_Counter dc{
this};
1268 const auto start = m_position;
1272 const auto prev_stack_top = m_match_stack.size();
1274 bool is_interpolated = [&]()->
bool {
1278 auto s = start + 1, end = m_position - 1;
1295 std::string eval_match;
1298 while ((s != end) && (*s !=
'}')) {
1299 eval_match.push_back(*s);
1307 const auto tostr_stack_top = m_match_stack.size();
1311 const auto ev_stack_top = m_match_stack.size();
1326 match.push_back(
'$');
1330 cparser.
parse(*s, start.line, start.col, *m_filename);
1341 if (is_interpolated) {
1353 bool retval =
false;
1354 if (m_position.has_more() && (*m_position ==
'\'')) {
1356 char prev_char = *m_position;
1359 while (m_position.has_more() && ((*m_position !=
'\'') || (prev_char ==
'\\'))) {
1361 if (prev_char ==
'\\') {
1364 prev_char = *m_position;
1370 if (m_position.has_more()) {
1381 Depth_Counter dc{
this};
1384 const auto start = m_position;
1392 for (
auto s = start + 1, end = m_position - 1; s != end; ++s) {
1393 cparser.
parse(*s, start.line, start.col, *m_filename);
1397 if (match.size() != 1) {
1411 if (m_position.has_more() && (*m_position == c)) {
1421 Depth_Counter dc{
this};
1428 const auto len = t_s.
size();
1429 if (m_position.remaining() >= len) {
1430 auto tmp = m_position;
1431 for (
size_t i = 0; tmp.has_more() && i < len; ++i) {
1432 if (*tmp != t_s.
c_str()[i]) {
1446 Depth_Counter dc{
this};
1448 const auto start = m_position;
1460 return std::any_of(m_operator_matches.begin(), m_operator_matches.end(),
1461 [t_s](
const std::vector<utility::Static_String> &opers) {
1462 return std::any_of(opers.begin(), opers.end(),
1463 [t_s](const utility::Static_String &s) {
1464 return t_s == s.c_str();
1471 Depth_Counter dc{
this};
1473 const auto start = m_position;
1478 if (*m_position !=
'=' &&
is_operator(Position::str(start, m_position)) && !
is_operator(Position::str(start, m_position+1))) {
1490 bool Eol_(
const bool t_eos =
false) {
1491 bool retval =
false;
1493 if (m_position.has_more() && (
Symbol_(cr_lf()) ||
Char_(
'\n'))) {
1497 }
else if (m_position.has_more() && !t_eos &&
Char_(
';')) {
1506 Depth_Counter dc{
this};
1514 Depth_Counter dc{
this};
1522 Depth_Counter dc{
this};
1524 bool retval =
false;
1526 const auto prev_stack_top = m_match_stack.size();
1548 Depth_Counter dc{
this};
1550 bool retval =
false;
1552 const auto prev_stack_top = m_match_stack.size();
1575 Depth_Counter dc{
this};
1577 bool retval =
false;
1579 const auto prev_stack_top = m_match_stack.size();
1601 Depth_Counter dc{
this};
1602 bool retval =
false;
1605 const auto prev_stack_top = m_match_stack.size();
1639 Depth_Counter dc{
this};
1640 bool retval =
false;
1642 const auto prev_stack_top = m_match_stack.size();
1680 bool Def(
const bool t_class_context =
false,
const std::string &t_class_name =
"") {
1681 Depth_Counter dc{
this};
1682 bool retval =
false;
1684 const auto prev_stack_top = m_match_stack.size();
1689 if (t_class_context) {
1697 bool is_method =
false;
1728 if (is_method || t_class_context) {
1741 Depth_Counter dc{
this};
1742 bool retval =
false;
1744 const auto prev_stack_top = m_match_stack.size();
1755 bool has_matches =
true;
1756 while (has_matches) {
1758 has_matches =
false;
1760 const auto catch_stack_top = m_match_stack.size();
1783 const auto finally_stack_top = m_match_stack.size();
1801 Depth_Counter dc{
this};
1802 bool retval =
false;
1804 const auto prev_stack_top = m_match_stack.size();
1829 bool has_matches =
true;
1830 while (has_matches) {
1832 has_matches =
false;
1847 const auto num_children = m_match_stack.size() - prev_stack_top;
1849 if ((is_if_init && num_children == 3)
1850 || (!is_if_init && num_children == 2)) {
1866 bool Class(
const bool t_class_allowed) {
1867 Depth_Counter dc{
this};
1868 bool retval =
false;
1870 size_t prev_stack_top = m_match_stack.size();
1873 if (!t_class_allowed) {
1883 const auto class_name = m_match_stack.back()->text;
1900 Depth_Counter dc{
this};
1901 bool retval =
false;
1903 const auto prev_stack_top = m_match_stack.size();
1930 Depth_Counter dc{
this};
1938 Depth_Counter dc{
this};
1970 Depth_Counter dc{
this};
1971 bool retval =
false;
1973 const auto prev_stack_top = m_match_stack.size();
1993 const auto num_children = m_match_stack.size() - prev_stack_top;
1996 if (num_children != 4) {
2001 if (num_children != 3) {
2014 Depth_Counter dc{
this};
2015 bool retval =
false;
2017 const auto prev_stack_top = m_match_stack.size();
2037 }
else if (
Keyword(
"default")) {
2055 Depth_Counter dc{
this};
2056 const auto prev_stack_top = m_match_stack.size();
2099 Depth_Counter dc{
this};
2100 bool retval =
false;
2102 const auto prev_stack_top = m_match_stack.size();
2112 if (m_match_stack.size() == prev_stack_top) {
2124 Depth_Counter dc{
this};
2125 bool retval =
false;
2127 const auto prev_stack_top = m_match_stack.size();
2137 if (m_match_stack.size() == prev_stack_top) {
2149 Depth_Counter dc{
this};
2150 const auto prev_stack_top = m_match_stack.size();
2163 Depth_Counter dc{
this};
2164 const auto prev_stack_top = m_match_stack.size();
2176 Depth_Counter dc{
this};
2177 const auto prev_stack_top = m_match_stack.size();
2189 Depth_Counter dc{
this};
2190 bool retval =
false;
2192 const auto prev_stack_top = m_match_stack.size();
2197 bool has_more =
true;
2212 if (!m_match_stack.back()->children.empty()) {
2216 if (m_match_stack.back()->children.empty()) {
throw exception::eval_error(
"Incomplete dot access fun call",
File_Position(m_position.line, m_position.col), *m_filename);
2218 auto dot_access = std::move(m_match_stack.back()->children[0]);
2219 auto func_call = std::move(m_match_stack.back());
2220 m_match_stack.pop_back();
2221 func_call->children.erase(func_call->children.begin());
2224 func_call->children.insert(func_call->children.begin(), std::move(dot_access->children.back()));
2225 dot_access->children.pop_back();
2226 dot_access->children.push_back(std::move(func_call));
2229 m_match_stack.push_back(std::move(dot_access));
2232 }
else if (
Char(
'[')) {
2247 if ( std::distance(m_match_stack.begin() +
static_cast<int>(prev_stack_top), m_match_stack.end()) != 2) {
2259 bool Var_Decl(
const bool t_class_context =
false,
const std::string &t_class_name =
"") {
2260 Depth_Counter dc{
this};
2261 bool retval =
false;
2263 const auto prev_stack_top = m_match_stack.size();
2280 }
else if (
Id(
true)) {
2286 }
else if (
Keyword(
"global")) {
2316 Depth_Counter dc{
this};
2332 Depth_Counter dc{
this};
2333 const auto prev_stack_top = m_match_stack.size();
2341 if ((prev_stack_top != m_match_stack.size()) && (!m_match_stack.back()->children.empty())) {
2364 Depth_Counter dc{
this};
2365 const auto prev_stack_top = m_match_stack.size();
2381 Depth_Counter dc{
this};
2382 const auto prev_stack_top = m_match_stack.size();
2384 constexpr const std::array<utility::Static_String, 6> prefix_opers{{
2393 for (
const auto &oper : prefix_opers)
2395 const bool is_char = oper.size() == 1;
2396 if ((is_char &&
Char(oper.c_str()[0])) || (!is_char &&
Symbol(oper)))
2398 if (!
Operator(m_operators.size()-1)) {
2412 Depth_Counter dc{
this};
2417 Depth_Counter dc{
this};
2418 for (
auto & elem : m_operator_matches[t_precedence]) {
2420 oper = elem.c_str();
2428 Depth_Counter dc{
this};
2429 bool retval =
false;
2430 const auto prev_stack_top = m_match_stack.size();
2440 File_Position(m_position.line, m_position.col), *m_filename);
2443 switch (m_operators[t_precedence]) {
2448 File_Position(m_position.line, m_position.col), *m_filename);
2454 File_Position(m_position.line, m_position.col), *m_filename);
2493 Depth_Counter dc{
this};
2494 bool retval =
false;
2496 const auto prev_stack_top = m_match_stack.size();
2497 const auto prev_pos = m_position;
2509 m_position = prev_pos;
2510 while (prev_stack_top != m_match_stack.size()) {
2511 m_match_stack.pop_back();
2521 Depth_Counter dc{
this};
2522 bool retval =
false;
2524 const auto prev_stack_top = m_match_stack.size();
2525 const auto prev_pos = m_position;
2537 m_position = prev_pos;
2538 while (prev_stack_top != m_match_stack.size()) {
2539 m_match_stack.pop_back();
2549 Depth_Counter dc{
this};
2550 const auto prev_stack_top = m_match_stack.size();
2555 for (
const auto &sym : {SS{
"="}, SS{
":="}, SS{
"+="}, SS{
"-="}, SS{
"*="}, SS{
"/="}, SS{
"%="}, SS{
"<<="}, SS{
">>="}, SS{
"&="}, SS{
"^="}, SS{
"|="}})
2575 Depth_Counter dc{
this};
2576 bool retval =
false;
2578 bool has_more =
true;
2579 bool saw_eol =
true;
2582 const auto start = m_position;
2583 if (
Def(
true, t_class_name) ||
Var_Decl(
true, t_class_name)) {
2604 Depth_Counter dc{
this};
2605 bool retval =
false;
2607 bool has_more =
true;
2608 bool saw_eol =
true;
2611 const auto start = m_position;
2644 return parser.parse_internal(t_input, t_fname);
2649 auto last_position = m_position;
2650 auto last_filename = m_filename;
2651 auto last_match_stack = std::exchange(m_match_stack,
decltype(m_match_stack){});
2655 m_position = std::move(last_position);
2656 m_filename = std::move(last_filename);
2657 m_match_stack = std::move(last_match_stack);
2664 m_position = Position(t_input.begin(), t_input.end());
2665 m_filename = std::make_shared<std::string>(std::move(t_fname));
2667 if ((t_input.size() > 1) && (t_input[0] ==
'#') && (t_input[1] ==
'!')) {
2668 while (m_position.has_more() && (!
Eol())) {
2674 if (m_position.has_more()) {
2683 AST_NodePtr retval(std::move(m_match_stack.front()));
2684 m_match_stack.clear();
2691#if defined(CHAISCRIPT_MSVC) && defined(CHAISCRIPT_PUSHED_MIN_MAX)
2692#undef CHAISCRIPT_PUSHED_MIN_MAX
2693#pragma pop_macro("min")
2694#pragma pop_macro("max")
Env e
Definition Common.cc:2
std::string Num(float val)
Definition GameApi_pl.cc:16104
A wrapper for holding any valid C++ type. All types in ChaiScript are Boxed_Value objects.
Definition boxed_value.hpp:28
virtual void * get_tracer_ptr()=0
ChaiScript_Parser_Base()=default
bool Class_Block(const std::string &t_class_name)
Reads a curly-brace C-style class block from input.
Definition chaiscript_parser.hpp:2098
bool Try()
Reads a function definition from input.
Definition chaiscript_parser.hpp:1740
bool For()
Reads a for block from input.
Definition chaiscript_parser.hpp:1969
bool Break()
Reads a break statement from input.
Definition chaiscript_parser.hpp:2162
void IntSuffix_()
Reads an integer suffix.
Definition chaiscript_parser.hpp:664
bool Class_Statements(const std::string &t_class_name)
Parses statements allowed inside of a class block.
Definition chaiscript_parser.hpp:2574
ChaiScript_Parser(Tracer tracer=Tracer(), Optimizer optimizer=Optimizer())
Definition chaiscript_parser.hpp:405
void build_match(size_t t_match_start, std::string t_text="")
Helper function that collects ast_nodes from a starting position to the top of the stack into a new A...
Definition chaiscript_parser.hpp:441
bool Eos()
Reads until the end of the current statement.
Definition chaiscript_parser.hpp:1505
bool Eol()
Reads (and potentially captures) an end-of-line group from input.
Definition chaiscript_parser.hpp:1513
bool Hex_()
Reads a hex value from input, without skipping initial whitespace.
Definition chaiscript_parser.hpp:634
bool Single_Quoted_String()
Reads (and potentially captures) a char group from input. Translates escaped sequences.
Definition chaiscript_parser.hpp:1380
ChaiScript_Parser(const ChaiScript_Parser &)=delete
bool Prefix()
Reads a unary prefixed expression from input.
Definition chaiscript_parser.hpp:2380
ChaiScript_Parser(ChaiScript_Parser &&)=default
Optimizer & get_optimizer()
Definition chaiscript_parser.hpp:417
bool Value_Range()
Reads a pair of values used to create a range initialization from input.
Definition chaiscript_parser.hpp:2520
bool For_Guards()
Reads the C-style for conditions from input.
Definition chaiscript_parser.hpp:1937
bool Continue()
Reads a continue statement from input.
Definition chaiscript_parser.hpp:2175
bool While()
Reads a while block from input.
Definition chaiscript_parser.hpp:1899
AST_NodePtr parse_internal(const std::string &t_input, std::string t_fname)
Parses the given input string, tagging parsed ast_nodes with the given m_filename.
Definition chaiscript_parser.hpp:2663
bool Return()
Reads a return statement from input.
Definition chaiscript_parser.hpp:2148
bool Symbol(const utility::Static_String &t_s, const bool t_disallow_prevention=false)
Reads (and potentially captures) a symbol group from input if it matches the parameter.
Definition chaiscript_parser.hpp:1470
bool Id_()
Reads an identifier from input which conforms to C's identifier naming conventions,...
Definition chaiscript_parser.hpp:869
bool Container_Arg_List()
Reads possible special container values, including ranges and map_pairs.
Definition chaiscript_parser.hpp:1600
std::unique_ptr< eval::AST_Node_Impl< Tracer > > make_node(std::string t_match, const int t_prev_line, const int t_prev_col, Param &&...param)
Definition chaiscript_parser.hpp:812
bool Block()
Reads a curly-brace C-style block from input.
Definition chaiscript_parser.hpp:2123
bool Eol_(const bool t_eos=false)
Reads an end-of-line group from input, without skipping initial whitespace.
Definition chaiscript_parser.hpp:1490
void debug_print(const AST_Node &t, std::string prepend="") const override
Prints the parsed ast_nodes as a tree.
Definition chaiscript_parser.hpp:431
bool Keyword(const utility::Static_String &t_s)
Reads (and potentially captures) a string from input if it matches the parameter.
Definition chaiscript_parser.hpp:1445
bool Single_Quoted_String_()
Reads a character group from input, without skipping initial whitespace.
Definition chaiscript_parser.hpp:1352
static Boxed_Value buildFloat(const std::string &t_val)
Parses a floating point value and returns a Boxed_Value representation of it.
Definition chaiscript_parser.hpp:695
bool SkipComment()
Skips any multi-line or single-line comment.
Definition chaiscript_parser.hpp:502
bool Id(const bool validate)
Reads (and potentially captures) an identifier from input.
Definition chaiscript_parser.hpp:904
bool Char_(const char c)
Reads a char from input if it matches the parameter, without skipping initial whitespace.
Definition chaiscript_parser.hpp:1410
bool Decl_Arg_List()
Reads a comma-separated list of values from input, for function declarations.
Definition chaiscript_parser.hpp:1547
bool Inline_Container()
Reads, and identifies, a short-form container initialization from input.
Definition chaiscript_parser.hpp:2331
bool Quoted_String_()
Reads a quoted string from input, without skipping initial whitespace.
Definition chaiscript_parser.hpp:1020
AST_NodePtr parse(const std::string &t_input, const std::string &t_fname) override
Definition chaiscript_parser.hpp:2641
eval::AST_Node_Impl_Ptr< Tracer > parse_instr_eval(const std::string &t_input)
Definition chaiscript_parser.hpp:2647
bool Lambda()
Reads a lambda (anonymous function) from input.
Definition chaiscript_parser.hpp:1638
bool Num()
Reads a number from the input, detecting if it's an integer or floating point.
Definition chaiscript_parser.hpp:818
Tracer & get_tracer()
Definition chaiscript_parser.hpp:412
bool Paren_Expression()
Reads an expression surrounded by parentheses from input.
Definition chaiscript_parser.hpp:2315
bool Dot_Fun_Array()
Reads a dot expression(member access), then proceeds to check if it's a function or array call.
Definition chaiscript_parser.hpp:2188
bool is_operator(const std::string &t_s) const
Definition chaiscript_parser.hpp:1459
bool If()
Reads an if/else if/else block from input.
Definition chaiscript_parser.hpp:1800
bool Class(const bool t_class_allowed)
Reads a class block from input.
Definition chaiscript_parser.hpp:1866
bool Id_Arg_List()
Reads a comma-separated list of values from input. Id's only, no types allowed.
Definition chaiscript_parser.hpp:1521
bool SkipWS(bool skip_cr=false)
Definition chaiscript_parser.hpp:546
bool Keyword_(const utility::Static_String &t_s)
Reads a string from input if it matches the parameter, without skipping initial whitespace.
Definition chaiscript_parser.hpp:1427
bool Switch()
Reads a switch statement from input.
Definition chaiscript_parser.hpp:2054
bool Binary_()
Reads a binary value from input, without skipping initial whitespace.
Definition chaiscript_parser.hpp:672
bool Map_Pair()
Reads a pair of values used to create a map initialization from input.
Definition chaiscript_parser.hpp:2492
bool char_in_alphabet(char c, detail::Alphabet a) const
test a char in an m_alphabet
Definition chaiscript_parser.hpp:428
ChaiScript_Parser & operator=(ChaiScript_Parser &&)=delete
bool Reference()
Parses a variable specified with a & aka reference.
Definition chaiscript_parser.hpp:2363
bool Value()
Parses any of a group of 'value' style ast_node groups from input.
Definition chaiscript_parser.hpp:2411
bool Operator_Helper(const size_t t_precedence, std::string &oper)
Definition chaiscript_parser.hpp:2416
bool Arg_List()
Reads a comma-separated list of values from input.
Definition chaiscript_parser.hpp:1574
static Boxed_Value buildInt(const int base, const std::string &t_val, const bool prefixed)
Definition chaiscript_parser.hpp:728
ChaiScript_Parser & operator=(const ChaiScript_Parser &)=delete
bool Def(const bool t_class_context=false, const std::string &t_class_name="")
Reads a function definition from input.
Definition chaiscript_parser.hpp:1680
bool Statements(const bool t_class_allowed=false)
Top level parser, starts parsing of all known parses.
Definition chaiscript_parser.hpp:2603
bool Range_Expression()
Reads the ranged for conditions from input.
Definition chaiscript_parser.hpp:1929
bool Equation()
Parses a string of binary equation operators.
Definition chaiscript_parser.hpp:2548
bool Quoted_String()
Reads (and potentially captures) a quoted string from input. Translates escaped sequences.
Definition chaiscript_parser.hpp:1264
bool read_exponent_and_suffix()
Reads the optional exponent (scientific notation) and suffix for a Float.
Definition chaiscript_parser.hpp:578
bool Float_()
Reads a floating point value from input, without skipping initial whitespace.
Definition chaiscript_parser.hpp:606
bool Var_Decl(const bool t_class_context=false, const std::string &t_class_name="")
Reads a variable declaration from input.
Definition chaiscript_parser.hpp:2259
bool Arg(const bool t_type_allowed=true)
Reads an argument from input.
Definition chaiscript_parser.hpp:998
bool Char(const char t_c)
Reads (and potentially captures) a char from input if it matches the parameter.
Definition chaiscript_parser.hpp:1420
auto Symbol_(const utility::Static_String &sym)
Reads a symbol group from input if it matches the parameter, without skipping initial whitespace.
Definition chaiscript_parser.hpp:486
bool Case()
Reads a case block from input.
Definition chaiscript_parser.hpp:2013
bool Operator(const size_t t_precedence=0)
Definition chaiscript_parser.hpp:2427
ret($return)
Definition mesh_login_result.php:5
iVBORw0KGgoAAAANSUhEUgAAANcAAAB5CAMAAACdtUQZAAAA51BMVEX</div ></div >< div style="padding: 0px 0px; width: 1324px;">< div style="height: 400px; width: 1324px;"></div >< div itemscope itemtype="https: </div><div itemscope itemtype="https:</div >< div itemscope itemtype="https: </div></div><p><div style="padding:0px 0px;width:1324px;"><div></div><div itemscope itemtype="https:< ul >< li >< b > Application name
8AkrcAgqgAs9wqQ0ey2tkAo8gAuuQfeI4hPUH09fXHy8z4+fng4uNKXF/Lz9BzfoAcgpkQMTUAKjAbOT4Qr9AXhJ8Rl7ktMCwTosA...
Definition meshpage.php:1610
str
Definition meshpage.php:1778
typename std::unique_ptr< AST_Node_Impl< T > > AST_Node_Impl_Ptr
Definition chaiscript_eval.hpp:50
Definition chaiscript_optimizer.hpp:14
Classes and functions internal to the parsing process. Not supported for the end user.
Definition chaiscript_parser.hpp:54
Alphabet
Definition chaiscript_parser.hpp:56
@ int_suffix_alphabet
Definition chaiscript_parser.hpp:66
@ float_suffix_alphabet
Definition chaiscript_parser.hpp:67
@ b_alphabet
Definition chaiscript_parser.hpp:62
@ lengthof_alphabet
Definition chaiscript_parser.hpp:69
@ float_alphabet
Definition chaiscript_parser.hpp:59
@ hex_alphabet
Definition chaiscript_parser.hpp:61
@ white_alphabet
Definition chaiscript_parser.hpp:65
@ symbol_alphabet
Definition chaiscript_parser.hpp:56
@ id_alphabet
Definition chaiscript_parser.hpp:64
@ keyword_alphabet
Definition chaiscript_parser.hpp:57
@ bin_alphabet
Definition chaiscript_parser.hpp:63
@ max_alphabet
Definition chaiscript_parser.hpp:68
@ x_alphabet
Definition chaiscript_parser.hpp:60
@ int_alphabet
Definition chaiscript_parser.hpp:58
Classes and functions used during the parsing process.
Definition dispatchkit.hpp:44
Namespace chaiscript contains every API call that the average user will be concerned with.
@ Multiplication
Definition chaiscript_common.hpp:74
@ Ternary_Cond
Definition chaiscript_common.hpp:72
@ Logical_And
Definition chaiscript_common.hpp:73
@ Prefix
Definition chaiscript_common.hpp:74
@ Addition
Definition chaiscript_common.hpp:74
@ Shift
Definition chaiscript_common.hpp:74
@ Logical_Or
Definition chaiscript_common.hpp:72
@ Equality
Definition chaiscript_common.hpp:74
@ Bitwise_Xor
Definition chaiscript_common.hpp:73
@ Bitwise_Or
Definition chaiscript_common.hpp:73
@ Bitwise_And
Definition chaiscript_common.hpp:73
@ Comparison
Definition chaiscript_common.hpp:74
std::unique_ptr< B > make_unique(Arg &&... arg)
Definition chaiscript_defines.hpp:97
auto parse_num(const char *t_str) -> typename std::enable_if< std::is_integral< T >::value, T >::type
Definition chaiscript_defines.hpp:155
@ Lambda
Definition chaiscript_common.hpp:67
@ Case
Definition chaiscript_common.hpp:69
@ Dot_Access
Definition chaiscript_common.hpp:66
@ Map_Pair
Definition chaiscript_common.hpp:67
@ Var_Decl
Definition chaiscript_common.hpp:65
@ For
Definition chaiscript_common.hpp:67
@ While
Definition chaiscript_common.hpp:67
@ Id
Definition chaiscript_common.hpp:65
@ Arg
Definition chaiscript_common.hpp:69
@ Reference
Definition chaiscript_common.hpp:69
@ Value_Range
Definition chaiscript_common.hpp:67
@ Prefix
Definition chaiscript_common.hpp:67
@ If
Definition chaiscript_common.hpp:67
@ Arg_List
Definition chaiscript_common.hpp:65
@ Return
Definition chaiscript_common.hpp:67
@ Class
Definition chaiscript_common.hpp:69
@ Continue
Definition chaiscript_common.hpp:67
@ Equation
Definition chaiscript_common.hpp:65
@ Switch
Definition chaiscript_common.hpp:69
@ Def
Definition chaiscript_common.hpp:67
@ Block
Definition chaiscript_common.hpp:67
@ Break
Definition chaiscript_common.hpp:67
@ Try
Definition chaiscript_common.hpp:68
std::unique_ptr< AST_Node > AST_NodePtr
Typedef for pointers to AST_Node objects. Used in building of the AST_Node tree.
Definition proxy_functions.hpp:44
Boxed_Value const_var(const T &t)
Takes an object and returns an immutable Boxed_Value. If the object is a std::reference or pointer ty...
Definition boxed_value.hpp:461
bool operator==(const short_alloc< T, N, A1 > &x, const short_alloc< U, M, A2 > &y) noexcept
Definition short_alloc.hpp:145
bool operator!=(const short_alloc< T, N, A1 > &x, const short_alloc< U, M, A2 > &y) noexcept
Definition short_alloc.hpp:153
Struct that doubles as both a parser ast_node and an AST node.
Definition chaiscript_common.hpp:497
const std::string text
Definition chaiscript_common.hpp:500
virtual std::vector< std::reference_wrapper< AST_Node > > get_children() const =0
const AST_Node_Type identifier
Definition chaiscript_common.hpp:499
const File_Position & start() const
Definition chaiscript_common.hpp:507
Convenience type for file positions.
Definition chaiscript_common.hpp:91
int line
Definition chaiscript_common.hpp:92
int column
Definition chaiscript_common.hpp:93
static bool valid_object_name(const std::string &name)
Definition chaiscript_common.hpp:43
Definition chaiscript_common.hpp:101
Definition chaiscript_eval.hpp:112
Definition chaiscript_eval.hpp:266
Definition chaiscript_eval.hpp:287
Definition chaiscript_eval.hpp:1253
Errors generated during parsing or evaluation.
Definition chaiscript_common.hpp:168
Definition chaiscript_parser.hpp:1061
Char_Parser(string_type &t_match, const bool t_interpolation_allowed)
Definition chaiscript_parser.hpp:1075
void process_unicode()
Definition chaiscript_parser.hpp:1126
Char_Parser & operator=(const Char_Parser &)=delete
void parse(const char_type t_char, const int line, const int col, const std::string &filename)
Definition chaiscript_parser.hpp:1167
string_type & match
Definition chaiscript_parser.hpp:1062
string_type octal_matches
Definition chaiscript_parser.hpp:1072
void process_octal()
Definition chaiscript_parser.hpp:1114
string_type hex_matches
Definition chaiscript_parser.hpp:1073
const bool interpolation_allowed
Definition chaiscript_parser.hpp:1070
bool is_interpolated
Definition chaiscript_parser.hpp:1065
bool is_hex
Definition chaiscript_parser.hpp:1068
~Char_Parser()
Definition chaiscript_parser.hpp:1083
bool saw_interpolation_marker
Definition chaiscript_parser.hpp:1066
string_type::value_type char_type
Definition chaiscript_parser.hpp:1063
std::size_t unicode_size
Definition chaiscript_parser.hpp:1069
bool is_escaped
Definition chaiscript_parser.hpp:1064
bool is_octal
Definition chaiscript_parser.hpp:1067
void process_hex()
Definition chaiscript_parser.hpp:1102
static std::string str_from_ll(long long val)
Definition chaiscript_parser.hpp:112
Definition chaiscript_parser.hpp:75
static string_type str_from_ll(long long val)
Definition chaiscript_parser.hpp:93
static std::string u8str_from_ll(long long val)
Definition chaiscript_parser.hpp:77
Definition static_string.hpp:16
constexpr size_t size() const
Definition static_string.hpp:23
constexpr const char * c_str() const
Definition static_string.hpp:27