3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-03 21:01:22 +00:00

Fix for escape sequences in SMT2 scanner

This commit is contained in:
Christoph M. Wintersteiger 2016-01-16 13:53:29 +00:00
parent 88362a1c3a
commit 01cb20e098

View file

@ -46,7 +46,7 @@ namespace smt2 {
} }
m_spos++; m_spos++;
} }
void scanner::read_comment() { void scanner::read_comment() {
SASSERT(curr() == ';'); SASSERT(curr() == ';');
next(); next();
@ -62,7 +62,7 @@ namespace smt2 {
next(); next();
} }
} }
scanner::token scanner::read_quoted_symbol() { scanner::token scanner::read_quoted_symbol() {
SASSERT(curr() == '|'); SASSERT(curr() == '|');
bool escape = false; bool escape = false;
@ -105,7 +105,7 @@ namespace smt2 {
} }
} }
} }
scanner::token scanner::read_symbol() { scanner::token scanner::read_symbol() {
SASSERT(m_normalized[static_cast<unsigned>(curr())] == 'a' || curr() == ':' || curr() == '-'); SASSERT(m_normalized[static_cast<unsigned>(curr())] == 'a' || curr() == ':' || curr() == '-');
m_string.reset(); m_string.reset();
@ -113,14 +113,14 @@ namespace smt2 {
next(); next();
return read_symbol_core(); return read_symbol_core();
} }
scanner::token scanner::read_number() { scanner::token scanner::read_number() {
SASSERT('0' <= curr() && curr() <= '9'); SASSERT('0' <= curr() && curr() <= '9');
rational q(1); rational q(1);
m_number = rational(curr() - '0'); m_number = rational(curr() - '0');
next(); next();
bool is_float = false; bool is_float = false;
while (true) { while (true) {
char c = curr(); char c = curr();
if ('0' <= c && c <= '9') { if ('0' <= c && c <= '9') {
@ -139,7 +139,7 @@ namespace smt2 {
break; break;
} }
} }
if (is_float) if (is_float)
m_number /= q; m_number /= q;
TRACE("scanner", tout << "new number: " << m_number << "\n";); TRACE("scanner", tout << "new number: " << m_number << "\n";);
return is_float ? FLOAT_TOKEN : INT_TOKEN; return is_float ? FLOAT_TOKEN : INT_TOKEN;
@ -160,14 +160,14 @@ namespace smt2 {
return read_symbol_core(); return read_symbol_core();
} }
} }
scanner::token scanner::read_string() { scanner::token scanner::read_string() {
SASSERT(curr() == '\"'); SASSERT(curr() == '\"');
next(); next();
m_string.reset(); m_string.reset();
while (true) { while (true) {
char c = curr(); char c = curr();
if (c == EOF) if (c == EOF)
throw scanner_exception("unexpected end of string", m_line, m_spos); throw scanner_exception("unexpected end of string", m_line, m_spos);
if (c == '\n') { if (c == '\n') {
new_line(); new_line();
@ -179,11 +179,19 @@ namespace smt2 {
return STRING_TOKEN; return STRING_TOKEN;
} }
} }
else if (c == '\\') {
next();
c = curr();
if (c == EOF)
throw scanner_exception("unexpected end of string", m_line, m_spos);
if (c != '\\' && c != '\"')
throw scanner_exception("invalid escape sequence", m_line, m_spos);
}
m_string.push_back(c); m_string.push_back(c);
next(); next();
} }
} }
scanner::token scanner::read_bv_literal() { scanner::token scanner::read_bv_literal() {
SASSERT(curr() == '#'); SASSERT(curr() == '#');
next(); next();
@ -200,7 +208,7 @@ namespace smt2 {
} }
else if ('a' <= c && c <= 'f') { else if ('a' <= c && c <= 'f') {
m_number *= rational(16); m_number *= rational(16);
m_number += rational(10 + (c - 'a')); m_number += rational(10 + (c - 'a'));
} }
else if ('A' <= c && c <= 'F') { else if ('A' <= c && c <= 'F') {
m_number *= rational(16); m_number *= rational(16);
@ -236,9 +244,9 @@ namespace smt2 {
throw scanner_exception("invalid bit-vector literal, expecting 'x' or 'b'", m_line, m_spos); throw scanner_exception("invalid bit-vector literal, expecting 'x' or 'b'", m_line, m_spos);
} }
} }
scanner::scanner(cmd_context & ctx, std::istream& stream, bool interactive): scanner::scanner(cmd_context & ctx, std::istream& stream, bool interactive):
m_interactive(interactive), m_interactive(interactive),
m_spos(0), m_spos(0),
m_curr(0), // avoid Valgrind warning m_curr(0), // avoid Valgrind warning
m_line(1), m_line(1),
@ -248,7 +256,7 @@ namespace smt2 {
m_bend(0), m_bend(0),
m_stream(stream), m_stream(stream),
m_cache_input(false) { m_cache_input(false) {
m_smtlib2_compliant = ctx.params().m_smtlib2_compliant; m_smtlib2_compliant = ctx.params().m_smtlib2_compliant;
for (int i = 0; i < 256; ++i) { for (int i = 0; i < 256; ++i) {
@ -287,7 +295,7 @@ namespace smt2 {
m_normalized[static_cast<int>('/')] = 'a'; m_normalized[static_cast<int>('/')] = 'a';
next(); next();
} }
scanner::token scanner::scan() { scanner::token scanner::scan() {
while (true) { while (true) {
signed char c = curr(); signed char c = curr();