Octal escape codes supported #211

This commit is contained in:
Jason Turner
2015-10-02 11:45:28 -06:00
parent 8d9dc2b0a3
commit 41e9027d9a
3 changed files with 128 additions and 83 deletions

View File

@@ -174,7 +174,7 @@ else()
add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG}) add_definitions(-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wcast-qual -Wunused -Woverloaded-virtual -pedantic ${CPP11_FLAG})
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_definitions(-Weverything -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors) add_definitions(-Weverything -Wno-c++98-compat-pedantic -Wno-c++98-compat -Wno-documentation -Wno-switch-enum -Wno-weak-vtables -Wno-sign-conversion -Wno-missing-prototypes -Wno-padded -Wno-missing-noreturn -Wno-exit-time-destructors)
else() else()
add_definitions(-Wnoexcept) add_definitions(-Wnoexcept)
endif() endif()

View File

@@ -951,49 +951,88 @@ namespace chaiscript
struct Char_Parser struct Char_Parser
{ {
std::string &match;
bool is_escaped; bool is_escaped;
bool is_interpolated; bool is_interpolated;
bool saw_interpolation_marker; bool saw_interpolation_marker;
bool is_octal;
const bool interpolation_allowed; const bool interpolation_allowed;
Char_Parser(const bool t_interpolation_allowed) std::string octal_matches;
: is_escaped(false),
Char_Parser(std::string &t_match, const bool t_interpolation_allowed)
: match(t_match),
is_escaped(false),
is_interpolated(false), is_interpolated(false),
saw_interpolation_marker(false), saw_interpolation_marker(false),
is_octal(false),
interpolation_allowed(t_interpolation_allowed) interpolation_allowed(t_interpolation_allowed)
{ {
} }
void parse(std::string &t_match, const char t_char, const int line, const int col, const std::string &filename) { ~Char_Parser(){
if (is_octal) {
process_octal();
}
}
void process_octal()
{
int val = stoi(octal_matches, 0, 8);
match.push_back(char(val));
octal_matches.clear();
is_escaped = false;
is_octal = false;
}
void parse(const char t_char, const int line, const int col, const std::string &filename) {
if (t_char == '\\') { if (t_char == '\\') {
if (is_escaped) { if (is_escaped) {
t_match.push_back('\\'); match.push_back('\\');
is_escaped = false; is_escaped = false;
} else { } else {
is_escaped = true; is_escaped = true;
} }
} else { } else {
if (is_escaped) { if (is_escaped) {
bool is_octal_char = t_char >= '0' && t_char <= '7';
if (is_octal) {
if (is_octal_char) {
octal_matches.push_back(t_char);
if (octal_matches.size() == 3) {
process_octal();
}
} else {
process_octal();
match.push_back(t_char);
}
} else if (is_octal_char) {
is_octal = true;
octal_matches.push_back(t_char);
} else {
switch (t_char) { switch (t_char) {
case ('\'') : t_match.push_back('\''); break; case ('\'') : match.push_back('\''); break;
case ('\"') : t_match.push_back('\"'); break; case ('\"') : match.push_back('\"'); break;
case ('?') : t_match.push_back('?'); break; case ('?') : match.push_back('?'); break;
case ('a') : t_match.push_back('\a'); break; case ('a') : match.push_back('\a'); break;
case ('b') : t_match.push_back('\b'); break; case ('b') : match.push_back('\b'); break;
case ('f') : t_match.push_back('\f'); break; case ('f') : match.push_back('\f'); break;
case ('n') : t_match.push_back('\n'); break; case ('n') : match.push_back('\n'); break;
case ('r') : t_match.push_back('\r'); break; case ('r') : match.push_back('\r'); break;
case ('t') : t_match.push_back('\t'); break; case ('t') : match.push_back('\t'); break;
case ('v') : t_match.push_back('\v'); break; case ('v') : match.push_back('\v'); break;
case ('$') : t_match.push_back('$'); break; case ('$') : match.push_back('$'); break;
default: throw exception::eval_error("Unknown escaped sequence in string", File_Position(line, col), filename); default: throw exception::eval_error("Unknown escaped sequence in string", File_Position(line, col), filename);
} }
is_escaped = false;
}
} else if (interpolation_allowed && t_char == '$') { } else if (interpolation_allowed && t_char == '$') {
saw_interpolation_marker = true; saw_interpolation_marker = true;
} else { } else {
t_match.push_back(t_char); match.push_back(t_char);
} }
is_escaped = false;
} }
} }
@@ -1011,11 +1050,12 @@ namespace chaiscript
if (Quoted_String_()) { if (Quoted_String_()) {
std::string match; std::string match;
Char_Parser cparser(true);
const auto prev_stack_top = m_match_stack.size(); const auto prev_stack_top = m_match_stack.size();
bool is_interpolated = [&]() {
Char_Parser cparser(match, true);
auto s = start + 1, end = m_position - 1; auto s = start + 1, end = m_position - 1;
while (s != end) { while (s != end) {
@@ -1072,12 +1112,15 @@ namespace chaiscript
} }
cparser.saw_interpolation_marker = false; cparser.saw_interpolation_marker = false;
} else { } else {
cparser.parse(match, *s, start.line, start.col, *m_filename); cparser.parse(*s, start.line, start.col, *m_filename);
++s; ++s;
} }
} }
if (cparser.is_interpolated) { return cparser.is_interpolated;
}();
if (is_interpolated) {
m_match_stack.push_back(make_node<eval::Quoted_String_AST_Node>(match, start.line, start.col)); m_match_stack.push_back(make_node<eval::Quoted_String_AST_Node>(match, start.line, start.col));
build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+"); build_match<eval::Binary_Operator_AST_Node>(prev_stack_top, "+");
@@ -1129,10 +1172,14 @@ namespace chaiscript
const auto start = m_position; const auto start = m_position;
if (Single_Quoted_String_()) { if (Single_Quoted_String_()) {
std::string match; std::string match;
Char_Parser cparser(false);
{
// scope for cparser destrutor
Char_Parser cparser(match, false);
for (auto s = start + 1, end = m_position - 1; s != end; ++s) { for (auto s = start + 1, end = m_position - 1; s != end; ++s) {
cparser.parse(match, *s, start.line, start.col, *m_filename); cparser.parse(*s, start.line, start.col, *m_filename);
}
} }
m_match_stack.push_back(make_node<eval::Single_Quoted_String_AST_Node>(match, start.line, start.col)); m_match_stack.push_back(make_node<eval::Single_Quoted_String_AST_Node>(match, start.line, start.col));

View File

@@ -384,8 +384,6 @@ class JSON
return std::to_string( Internal.Int ); return std::to_string( Internal.Int );
case Class::Boolean: case Class::Boolean:
return Internal.Bool ? "true" : "false"; return Internal.Bool ? "true" : "false";
default:
return "";
} }
} }
@@ -548,7 +546,7 @@ namespace {
JSON parse_number( const string &str, size_t &offset ) { JSON parse_number( const string &str, size_t &offset ) {
JSON Number; JSON Number;
string val, exp_str; string val, exp_str;
char c; char c = '\0';
bool isDouble = false; bool isDouble = false;
long exp = 0; long exp = 0;
for (; offset < str.size() ;) { for (; offset < str.size() ;) {