Parse escape characters properly

This commit is contained in:
Lewis Dale 2023-01-02 18:41:39 +00:00
parent 0536daefa3
commit 8edf1b9595
4 changed files with 28 additions and 7 deletions

View File

@ -6,4 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nom = "7.1.2"
nom = { version = "7.1.2", features = ["alloc"] }

View File

@ -1 +1 @@
10 PRINT "Hello, world."
10 PRINT "Hello, \"world\"."

View File

@ -1,6 +1,6 @@
use nom::{
bytes::complete::{tag, take_until},
character::complete::u32 as ccu32,
bytes::complete::{tag, take_until, escaped},
character::{complete::{u32 as ccu32, one_of}, streaming::none_of},
combinator::map,
sequence::{delimited, terminated, tuple},
IResult,
@ -15,14 +15,19 @@ pub enum Command<'a> {
}
fn read_string(i: &str) -> IResult<&str, &str> {
take_until("\"")(i)
// take_until("\"")(i)
delimited(
tag("\""),
escaped(none_of("\\\""), '\\', one_of("\"\\")),
tag("\"")
)(i)
}
fn parse_command(i: &str) -> IResult<&str, Command> {
let (i, (command, _)) = tuple((take_until(" "), tag(" ")))(i)?;
let (i, cmd) = match command {
"PRINT" => map(delimited(tag("\""), read_string, tag("\"")), Command::Print)(i)?,
"PRINT" => map(read_string, Command::Print)(i)?,
_ => (i, Command::None),
};
@ -45,4 +50,20 @@ mod tests {
let (_, result) = super::parse_line(input).unwrap();
assert_eq!(expected, result);
}
#[test]
fn it_reads_a_string() {
let input = r#""Hello, \"World\"""#;
let (_, output) = super::read_string(input).unwrap();
assert_eq!(r#"Hello, \"World\""#, output);
}
#[test]
fn it_parses_a_print_command_with_escaped_quotes() {
let input = r#"10 PRINT "Hello, \"world\"""#;
let expected = (10, super::Command::Print(r#"Hello, \"world\""#));
let (_, result) = super::parse_line(input).unwrap();
assert_eq!(expected, result);
}
}

View File

@ -8,7 +8,7 @@ fn main() {
let (_, (_, command)) = basic::parse_line(lines).unwrap();
match command {
basic::Command::Print(input) => {
println!("{}", input);
println!("{}", input.replace("\\", ""));
}
_ => {
panic!("Command not recognised");