Parse escape characters properly
This commit is contained in:
parent
8edf1b9595
commit
9f55bef238
56
src/basic.rs
56
src/basic.rs
@ -1,26 +1,34 @@
|
|||||||
use nom::{
|
use nom::{
|
||||||
bytes::complete::{tag, take_until, escaped},
|
branch::alt,
|
||||||
character::{complete::{u32 as ccu32, one_of}, streaming::none_of},
|
bytes::complete::{escaped_transform, tag, take_until},
|
||||||
combinator::map,
|
character::{
|
||||||
|
complete::{u32 as ccu32},
|
||||||
|
streaming::none_of,
|
||||||
|
},
|
||||||
|
combinator::{map, value},
|
||||||
sequence::{delimited, terminated, tuple},
|
sequence::{delimited, terminated, tuple},
|
||||||
IResult,
|
IResult,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type Line<'a> = (u32, Command<'a>);
|
pub type Line = (u32, Command);
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
pub enum Command<'a> {
|
pub enum Command {
|
||||||
Print(&'a str),
|
Print(String),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_string(i: &str) -> IResult<&str, &str> {
|
fn read_string(i: &str) -> IResult<&str, String> {
|
||||||
// take_until("\"")(i)
|
// take_until("\"")(i)
|
||||||
delimited(
|
delimited(
|
||||||
tag("\""),
|
tag("\""),
|
||||||
escaped(none_of("\\\""), '\\', one_of("\"\\")),
|
escaped_transform(
|
||||||
tag("\"")
|
none_of("\\\""),
|
||||||
)(i)
|
'\\',
|
||||||
|
alt((value("\\", tag("\\")), value("\"", tag("\"")))),
|
||||||
|
),
|
||||||
|
tag("\""),
|
||||||
|
)(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_command(i: &str) -> IResult<&str, Command> {
|
fn parse_command(i: &str) -> IResult<&str, Command> {
|
||||||
@ -45,25 +53,25 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn it_parses_a_print_command() {
|
fn it_parses_a_print_command() {
|
||||||
let input = "10 PRINT \"Hello, world\"";
|
let input = "10 PRINT \"Hello, world\"";
|
||||||
let expected = (10, super::Command::Print("Hello, world"));
|
let expected = (10, super::Command::Print(String::from("Hello, world")));
|
||||||
|
|
||||||
let (_, result) = super::parse_line(input).unwrap();
|
let (_, result) = super::parse_line(input).unwrap();
|
||||||
assert_eq!(expected, result);
|
assert_eq!(expected, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_reads_a_string() {
|
fn it_reads_a_string() {
|
||||||
let input = r#""Hello, \"World\"""#;
|
let input = r#""Hello, \"World\"""#;
|
||||||
let (_, output) = super::read_string(input).unwrap();
|
let (_, output) = super::read_string(input).unwrap();
|
||||||
assert_eq!(r#"Hello, \"World\""#, output);
|
assert_eq!(r#"Hello, "World""#, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_parses_a_print_command_with_escaped_quotes() {
|
fn it_parses_a_print_command_with_escaped_quotes() {
|
||||||
let input = r#"10 PRINT "Hello, \"world\"""#;
|
let input = r#"10 PRINT "Hello, \"world\"""#;
|
||||||
let expected = (10, super::Command::Print(r#"Hello, \"world\""#));
|
let expected = (10, super::Command::Print(String::from(r#"Hello, "world""#)));
|
||||||
|
|
||||||
let (_, result) = super::parse_line(input).unwrap();
|
let (_, result) = super::parse_line(input).unwrap();
|
||||||
assert_eq!(expected, result);
|
assert_eq!(expected, result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ fn main() {
|
|||||||
let (_, (_, command)) = basic::parse_line(lines).unwrap();
|
let (_, (_, command)) = basic::parse_line(lines).unwrap();
|
||||||
match command {
|
match command {
|
||||||
basic::Command::Print(input) => {
|
basic::Command::Print(input) => {
|
||||||
println!("{}", input.replace("\\", ""));
|
println!("{}", input);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("Command not recognised");
|
panic!("Command not recognised");
|
||||||
|
Loading…
Reference in New Issue
Block a user