my $token = $rdr->next();
given ($token) {
when(/^-?[0-9]+$/) { return Integer->new($token) }
- when(/^".*"$/) {
+ when(/^"(?:\\.|[^\\"])*"$/) {
my %escaped_chars = ( "\\\\" => "\\", "\\\"" => "\"", "\\n" => "\n" );
my $str = substr $token, 1, -1;
$str =~ s/\\./$escaped_chars{$&}/ge;
return String->new($str)
}
- when(/^".*/) {
+ when(/^"/) {
die "expected '\"', got EOF";
}
when(/^:/) { return _keyword(substr($token,1)) }
def read_atom(reader):
int_re = re.compile(r"-?[0-9]+$")
float_re = re.compile(r"-?[0-9][0-9.]*$")
+ string_re = re.compile(r'"(?:[\\].|[^\\"])*"')
token = reader.next()
if re.match(int_re, token): return int(token)
elif re.match(float_re, token): return int(token)
- elif token[0] == '"':
- if token[-1] == '"': return _s2u(_unescape(token[1:-1]))
- else: raise Exception("expected '\"', got EOF")
+ elif re.match(string_re, token):return _s2u(_unescape(token[1:-1]))
+ elif token[0] == '"': raise Exception("expected '\"', got EOF")
elif token[0] == ':': return _keyword(token[1:])
elif token == "nil": return None
elif token == "true": return True
^true$ { return $::mal_true }
^false$ { return $::mal_false }
^: { return [keyword_new [parse_keyword $token]] }
- ^\".*\"$ { return [string_new [parse_string $token]] }
- ^\".*$ { error "expected '\"', got EOF" }
+ ^\"(\\\\.|[^\\\\\"])*\"$
+ { return [string_new [parse_string $token]] }
+ ^\" { error "expected '\"', got EOF" }
default { return [symbol_new $token] }
}
}