123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- From bcf3d534e38d6afaca9e898cef1af7fa3e0ecdb3 Mon Sep 17 00:00:00 2001
- From: Maxime Devos <maximedevos@telenet.be>
- Date: Sat, 21 May 2022 11:31:16 +0000
- Subject: [PATCH] Port src/parsers.rs to nom 7
- TODO:
- * [ ] run tests (the build system I use (not Cargo) hasn't
- implemented running tests yet)
- * [ ] probably not done idiomatically
- * [ ] how to resolve expr_res
- ---
- Cargo.toml | 2 +-
- src/parsers.rs | 479 ++++++++++++++++++++++---------------------------
- 2 files changed, 213 insertions(+), 268 deletions(-)
- diff --git a/Cargo.toml b/Cargo.toml
- index 3afe4c2..f02795e 100644
- --- a/Cargo.toml
- +++ b/Cargo.toml
- @@ -13,7 +13,7 @@ edition = "2018"
- heapless = "0.5.6"
-
- [dependencies.nom]
- -version = "4.2.3"
- +version = "^7."
- default-features = false
-
- [features]
- diff --git a/src/parsers.rs b/src/parsers.rs
- index b0bf613..66651db 100644
- --- a/src/parsers.rs
- +++ b/src/parsers.rs
- @@ -5,235 +5,177 @@ use crate::AnsiSequence;
-
- use core::convert::TryInto;
- use heapless::Vec;
- +use nom::branch::alt;
- +use nom::bytes::streaming::tag;
- +use nom::character::streaming::{digit0, digit1};
- +use nom::combinator::{map_res, opt};
- +use nom::error::ErrorKind;
- use nom::*;
-
- +// TODO: copied from rust-nom@4.2.3 -- what should it be changed to
- +// when using combinators instead of macros?
- +macro_rules! expr_res (
- + ($i:expr, $e:expr) => (
- + {
- + match $e {
- + Ok(output) => Ok(($i, output)),
- + // TODO: what should be the error for a failed Vec::from_slice?
- + // ErrorKind::ExprRes has been removed in rust-nom@7.0.0
- + Err(_) => Err(Err::Error(error_position!($i, ErrorKind::TooLarge)))
- + }
- + }
- + )
- +);
- +
- macro_rules! tag_parser {
- ($sig:ident, $tag:expr, $ret:expr) => {
- - named!(
- - $sig<&str, AnsiSequence>,
- - do_parse!(
- - tag!($tag) >>
- - ($ret)
- - )
- - );
- - }
- + fn $sig(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag($tag)(input)?;
- + Ok((input, $ret))
- + }
- + };
- }
-
- -named!(
- - parse_int<&str, u32>,
- - map_res!(
- - nom::digit,
- - |s: &str| s.parse::<u32>()
- - )
- -);
- +fn parse_int(input: &str) -> IResult<&str, u32> {
- + combinator::map_res(digit1, |s: &str| s.parse::<u32>())(input)
- +}
-
- // TODO kind of ugly, would prefer to pass in the default so we could use it for
- // all escapes with defaults (not just those that default to 1).
- -named!(
- - parse_def_cursor_int<&str, u32>,
- - map!(
- - nom::digit0,
- - |s: &str| s.parse::<u32>().unwrap_or(1)
- - )
- -);
- +fn parse_def_cursor_int(input: &str) -> IResult<&str, u32> {
- + combinator::map(digit0, |s: &str| s.parse::<u32>().unwrap_or(1))(input)
- +}
-
- -named!(
- - cursor_pos<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - x: parse_def_cursor_int >>
- - opt!(tag!(";")) >>
- - y: parse_def_cursor_int >>
- - alt!(
- - tag!("H") |
- - tag!("f")
- - ) >>
- - (AnsiSequence::CursorPos(x, y))
- - )
- -);
- +fn cursor_pos(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, x) = parse_def_cursor_int(input)?;
- + let (input, _) = opt(tag(";"))(input)?;
- + let (input, y) = parse_def_cursor_int(input)?;
- + let (input, _) = alt((tag("H"), tag("f")))(input)?;
- + Ok((input, AnsiSequence::CursorPos(x, y)))
- +}
-
- -named!(
- - escape<&str, AnsiSequence>,
- - do_parse!(
- - tag!("\u{1b}") >>
- - (AnsiSequence::Escape)
- - )
- -);
- +fn escape(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("\u{1b}")(input)?;
- + Ok((input, AnsiSequence::Escape))
- +}
-
- -named!(
- - cursor_up<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - am: parse_def_cursor_int >>
- - tag!("A") >>
- - (AnsiSequence::CursorUp(am))
- - )
- -);
- +fn cursor_up(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, am) = parse_def_cursor_int(input)?;
- + Ok((input, AnsiSequence::CursorUp(am)))
- +}
-
- -named!(
- - cursor_down<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - am: parse_def_cursor_int >>
- - tag!("B") >>
- - (AnsiSequence::CursorDown(am))
- - )
- -);
- +fn cursor_down(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, am) = parse_def_cursor_int(input)?;
- + let (input, _) = tag("B")(input)?;
- + Ok((input, AnsiSequence::CursorDown(am)))
- +}
-
- -named!(
- - cursor_forward<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - am: parse_def_cursor_int >>
- - tag!("C") >>
- - (AnsiSequence::CursorForward(am))
- - )
- -);
- +fn cursor_forward(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, am) = parse_def_cursor_int(input)?;
- + let (input, _) = tag("C")(input)?;
- + Ok((input, AnsiSequence::CursorForward(am)))
- +}
-
- -named!(
- - cursor_backward<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - am: parse_def_cursor_int >>
- - tag!("D") >>
- - (AnsiSequence::CursorBackward(am))
- - )
- -);
- +fn cursor_backward(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, am) = parse_def_cursor_int(input)?;
- + let (input, _) = tag("D")(input)?;
- + Ok((input, AnsiSequence::CursorBackward(am)))
- +}
-
- -named!(
- - graphics_mode1<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - val: parse_int >>
- - tag!("m") >>
- - val: expr_res!(val.try_into()) >>
- - conv: expr_res!(Vec::from_slice(&[val])) >>
- - (AnsiSequence::SetGraphicsMode(conv))
- - )
- -);
- +fn graphics_mode1(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, val) = parse_int(input)?;
- + let (input, _) = tag("m")(input)?;
- + let (input, val) = expr_res!(input, val.try_into())?;
- + let (input, conv) = expr_res!(input, Vec::from_slice(&[val]))?;
- + Ok((input, AnsiSequence::SetGraphicsMode(conv)))
- +}
-
- -named!(
- - graphics_mode2<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - val1: parse_int >>
- - tag!(";") >>
- - val2: parse_int >>
- - tag!("m") >>
- - val1: expr_res!(val1.try_into()) >>
- - val2: expr_res!(val2.try_into()) >>
- - conv: expr_res!(Vec::from_slice(&[
- - val1,
- - val2,
- - ])) >>
- - (AnsiSequence::SetGraphicsMode(conv))
- - )
- -);
- +fn graphics_mode2(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, val1) = parse_int(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val2) = parse_int(input)?;
- + let (input, _) = tag("m")(input)?;
- + let (input, val1) = expr_res!(input, val1.try_into())?;
- + let (input, val2) = expr_res!(input, val2.try_into())?;
- + let (input, conv) = expr_res!(input, Vec::from_slice(&[val1, val2,]))?;
- + Ok((input, AnsiSequence::SetGraphicsMode(conv)))
- +}
-
- -named!(
- - graphics_mode3<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - val1: parse_int >>
- - tag!(";") >>
- - val2: parse_int >>
- - tag!(";") >>
- - val3: parse_int >>
- - tag!("m") >>
- - val1: expr_res!(val1.try_into()) >>
- - val2: expr_res!(val2.try_into()) >>
- - val3: expr_res!(val3.try_into()) >>
- - conv: expr_res!(Vec::from_slice(&[
- - val1,
- - val2,
- - val3,
- - ])) >>
- - (AnsiSequence::SetGraphicsMode(conv))
- - )
- -);
- +fn graphics_mode3(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, val1) = parse_int(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val2) = parse_int(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val3) = parse_int(input)?;
- + let (input, _) = tag("m")(input)?;
- + let (input, val1) = expr_res!(input, val1.try_into())?;
- + let (input, val2) = expr_res!(input, val2.try_into())?;
- + let (input, val3) = expr_res!(input, val3.try_into())?;
- + let (input, conv) = expr_res!(input, Vec::from_slice(&[val1, val2, val3,]))?;
- + Ok((input, AnsiSequence::SetGraphicsMode(conv)))
- +}
-
- -named!(
- - graphics_mode4<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[m") >>
- - (AnsiSequence::SetGraphicsMode(Vec::new()))
- - )
- -);
- +fn graphics_mode4(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[m")(input)?;
- + Ok((input, AnsiSequence::SetGraphicsMode(Vec::new())))
- +}
-
- -named!(
- - graphics_mode5<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - val1: parse_int >>
- - tag!(";") >>
- - val2: parse_int >>
- - tag!(";") >>
- - val3: parse_int >>
- - tag!(";") >>
- - val4: parse_int >>
- - tag!(";") >>
- - val5: parse_int >>
- - tag!("m") >>
- - val1: expr_res!(val1.try_into()) >>
- - val2: expr_res!(val2.try_into()) >>
- - val3: expr_res!(val3.try_into()) >>
- - val4: expr_res!(val4.try_into()) >>
- - val5: expr_res!(val5.try_into()) >>
- - conv: expr_res!(Vec::from_slice(&[
- - val1,
- - val2,
- - val3,
- - val4,
- - val5,
- - ])) >>
- - (AnsiSequence::SetGraphicsMode(conv))
- - )
- -);
- +fn graphics_mode5(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, val1) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val2) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val3) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val4) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, val5) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag("m")(input)?;
- + let (input, conv) = expr_res!(input, Vec::from_slice(&[val1, val2, val3, val4, val5,]))?;
- + Ok((input, AnsiSequence::SetGraphicsMode(conv)))
- +}
-
- -named!(
- - graphics_mode<&str, AnsiSequence>,
- - alt!(
- - graphics_mode1
- - | graphics_mode2
- - | graphics_mode3
- - | graphics_mode4
- - | graphics_mode5
- - )
- -);
- +fn graphics_mode(input: &str) -> IResult<&str, AnsiSequence> {
- + alt((
- + graphics_mode1,
- + graphics_mode2,
- + graphics_mode3,
- + graphics_mode4,
- + graphics_mode5,
- + ))(input)
- +}
-
- -named!(
- - set_mode<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[=") >>
- - mode: parse_int >>
- - conv: expr_res!(mode.try_into()) >>
- - tag!("h") >>
- - (AnsiSequence::SetMode(conv))
- - )
- -);
- +fn set_mode(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[=")(input)?;
- + let (input, conv) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag("h")(input)?;
- + Ok((input, AnsiSequence::SetMode(conv)))
- +}
-
- -named!(
- - reset_mode<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[=") >>
- - mode: parse_int >>
- - conv: expr_res!(mode.try_into()) >>
- - tag!("l") >>
- - (AnsiSequence::ResetMode(conv))
- - )
- -);
- +fn reset_mode(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[=")(input)?;
- + let (input, conv) = map_res(parse_int, |s| s.try_into())(input)?;
- + let (input, _) = tag("l")(input)?;
- + Ok((input, AnsiSequence::ResetMode(conv)))
- +}
-
- -named!(
- - set_top_and_bottom<&str, AnsiSequence>,
- - do_parse!(
- - tag!("[") >>
- - x: parse_int >>
- - tag!(";") >>
- - y: parse_int >>
- - tag!("r") >>
- - (AnsiSequence::SetTopAndBottom(x, y))
- - )
- -);
- +fn set_top_and_bottom(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("[")(input)?;
- + let (input, x) = parse_int(input)?;
- + let (input, _) = tag(";")(input)?;
- + let (input, y) = parse_int(input)?;
- + let (input, _) = tag("r")(input)?;
- + Ok((input, AnsiSequence::SetTopAndBottom(x, y)))
- +}
-
- tag_parser!(cursor_save, "[s", AnsiSequence::CursorSave);
- tag_parser!(cursor_restore, "[u", AnsiSequence::CursorRestore);
- @@ -276,66 +218,69 @@ tag_parser!(set_g1_graph, ")2", AnsiSequence::SetG1AltAndSpecialGraph);
- tag_parser!(set_single_shift2, "N", AnsiSequence::SetSingleShift2);
- tag_parser!(set_single_shift3, "O", AnsiSequence::SetSingleShift3);
-
- -named!(
- - combined<&str, AnsiSequence>,
- - alt!(
- - escape
- - | cursor_pos
- - | cursor_up
- - | cursor_down
- - | cursor_forward
- - | cursor_backward
- - | cursor_save
- - | cursor_restore
- - | erase_display
- - | erase_line
- - | graphics_mode
- - | set_mode
- - | reset_mode
- - | hide_cursor
- - | show_cursor
- - | cursor_to_app
- - | set_new_line_mode
- - | set_col_132
- - | set_smooth_scroll
- - | set_reverse_video
- - | set_origin_rel
- - | set_auto_wrap
- - | set_auto_repeat
- - | set_interlacing
- - | set_linefeed
- - | set_cursorkey
- - | set_vt52
- - | set_col80
- - | set_jump_scroll
- - | set_normal_video
- - | set_origin_abs
- - | reset_auto_wrap
- - | reset_auto_repeat
- - | reset_interlacing
- - | set_top_and_bottom
- - | set_alternate_keypad
- - | set_numeric_keypad
- - | set_uk_g0
- - | set_uk_g1
- - | set_us_g0
- - | set_us_g1
- - | set_g0_special
- - | set_g1_special
- - | set_g0_alternate
- - | set_g1_alternate
- - | set_g0_graph
- - | set_g1_graph
- - | set_single_shift2
- - | set_single_shift3
- - )
- -);
- +fn combined(input: &str) -> IResult<&str, AnsiSequence> {
- + // alt supports only 21 cases, so avoid the limit by nesting them
- + alt((
- + alt((
- + escape,
- + cursor_pos,
- + cursor_up,
- + cursor_down,
- + cursor_forward,
- + cursor_backward,
- + cursor_save,
- + cursor_restore,
- + erase_display,
- + erase_line,
- + graphics_mode,
- + set_mode,
- + reset_mode,
- + hide_cursor,
- + show_cursor,
- + cursor_to_app,
- + )),
- + alt((
- + set_new_line_mode,
- + set_col_132,
- + set_smooth_scroll,
- + set_reverse_video,
- + set_origin_rel,
- + set_auto_wrap,
- + set_auto_repeat,
- + set_interlacing,
- + set_linefeed,
- + set_cursorkey,
- + set_vt52,
- + set_col80,
- + set_jump_scroll,
- + set_normal_video,
- + set_origin_abs,
- + )),
- + alt((
- + reset_auto_wrap,
- + reset_auto_repeat,
- + reset_interlacing,
- + set_top_and_bottom,
- + set_alternate_keypad,
- + set_numeric_keypad,
- + set_uk_g0,
- + set_uk_g1,
- + set_us_g0,
- + set_us_g1,
- + set_g0_special,
- + set_g1_special,
- + set_g0_alternate,
- + set_g1_alternate,
- + set_g0_graph,
- + set_g1_graph,
- + set_single_shift2,
- + set_single_shift3,
- + )),
- + ))(input)
- +}
-
- -named!(
- - pub parse_escape<&str, AnsiSequence>,
- - do_parse!(
- - tag!("\u{1b}") >>
- - seq: combined >>
- - (seq)
- - )
- -);
- +pub fn parse_escape(input: &str) -> IResult<&str, AnsiSequence> {
- + let (input, _) = tag("\u{1b}")(input)?;
- + let (input, seq) = combined(input)?;
- + Ok((input, seq))
- +}
- base-commit: 6ed05bfb18ce3c5382393388c259e9c0e95d4a9d
- --
- 2.30.2
|