Parcourir la source

update combine to 4.6.6

The older version of combine uses the ascii crate. However, the latest
version of combine version 4.6 no longer has this dependency. Since the
major version changed from 2 -> 4, there are breaking changes. We
address these breaking changes in this commit.

Signed-off-by: yihuaf <yihuaf@unkies.org>
yihuaf il y a 2 ans
Parent
commit
4e9e594e81
2 fichiers modifiés avec 77 ajouts et 94 suppressions
  1. 1 1
      Cargo.toml
  2. 76 93
      src/asm_parser.rs

+ 1 - 1
Cargo.toml

@@ -24,7 +24,7 @@ include = [
 
 [dependencies]
 
-combine = "2.5"
+combine = "4.6"
 libc = "0.2"
 time = "0.2"
 byteorder = "1.2"

+ 76 - 93
src/asm_parser.rs

@@ -5,11 +5,12 @@
 // file of the crate. Do not expect to find those comments in the documentation of the crate.
 
 //! This module parses eBPF assembly language source code.
-use combine::char::{alpha_num, char, digit, hex_digit, spaces, string};
-use combine::primitives::{Error, Info};
+
+use combine::parser::char::{alpha_num, char, digit, hex_digit, spaces, string};
+use combine::stream::position::{self, SourcePosition};
 use combine::{
-    between, eof, many, many1, one_of, optional, parser, sep_by, try, ParseError, ParseResult,
-    Parser, State, Stream,
+    attempt, between, easy, eof, many, many1, one_of, optional, sep_by, EasyParser, ParseError,
+    Parser, Stream,
 };
 
 /// Operand of an instruction.
@@ -34,16 +35,18 @@ pub struct Instruction {
     pub operands: Vec<Operand>,
 }
 
-fn ident<I>(input: I) -> ParseResult<String, I>
+fn ident<I>() -> impl Parser<I, Output = String>
 where
-    I: Stream<Item = char>,
+    I: Stream<Token = char>,
+    I::Error: ParseError<I::Token, I::Range, I::Position>,
 {
-    many1(alpha_num()).parse_stream(input)
+    many1(alpha_num())
 }
 
-fn integer<I>(input: I) -> ParseResult<i64, I>
+fn integer<I>() -> impl Parser<I, Output = i64>
 where
-    I: Stream<Item = char>,
+    I: Stream<Token = char>,
+    I::Error: ParseError<I::Token, I::Range, I::Position>,
 {
     let sign = optional(one_of("-+".chars())).map(|x| match x {
         Some('-') => -1,
@@ -53,71 +56,62 @@ where
         .with(many1(hex_digit()))
         .map(|x: String| u64::from_str_radix(&x, 16).unwrap() as i64);
     let dec = many1(digit()).map(|x: String| x.parse::<i64>().unwrap());
-    (sign, try(hex).or(dec))
-        .map(|(s, x)| s * x)
-        .parse_stream(input)
+    (sign, attempt(hex).or(dec)).map(|(s, x)| s * x)
 }
 
-fn register<I>(input: I) -> ParseResult<i64, I>
+fn register<I>() -> impl Parser<I, Output = i64>
 where
-    I: Stream<Item = char>,
+    I: Stream<Token = char>,
+    I::Error: ParseError<I::Token, I::Range, I::Position>,
 {
     char('r')
         .with(many1(digit()))
         .map(|x: String| x.parse::<i64>().unwrap())
-        .parse_stream(input)
 }
 
-fn operand<I>(input: I) -> ParseResult<Operand, I>
+fn operand<I>() -> impl Parser<I, Output = Operand>
 where
-    I: Stream<Item = char>,
+    I: Stream<Token = char>,
+    I::Error: ParseError<I::Token, I::Range, I::Position>,
 {
-    let register_operand = parser(register).map(Operand::Register);
-    let immediate = parser(integer).map(Operand::Integer);
-    let memory = between(
-        char('['),
-        char(']'),
-        (parser(register), optional(parser(integer))),
-    )
-    .map(|t| Operand::Memory(t.0, t.1.unwrap_or(0)));
-    register_operand
-        .or(immediate)
-        .or(memory)
-        .parse_stream(input)
+    let register_operand = register().map(Operand::Register);
+    let immediate = integer().map(Operand::Integer);
+    let memory = between(char('['), char(']'), (register(), optional(integer())))
+        .map(|t| Operand::Memory(t.0, t.1.unwrap_or(0)));
+    register_operand.or(immediate).or(memory)
 }
 
-fn instruction<I>(input: I) -> ParseResult<Instruction, I>
+fn instruction<I>() -> impl Parser<I, Output = Instruction>
 where
-    I: Stream<Item = char>,
+    I: Stream<Token = char>,
+    I::Error: ParseError<I::Token, I::Range, I::Position>,
 {
-    let operands = sep_by(parser(operand), char(',').skip(spaces()));
-    (parser(ident).skip(spaces()), operands, spaces())
-        .map(|t| Instruction {
-            name: t.0,
-            operands: t.1,
-        })
-        .parse_stream(input)
+    let operands = sep_by(operand(), char(',').skip(spaces()));
+    (ident().skip(spaces()), operands, spaces()).map(|t| Instruction {
+        name: t.0,
+        operands: t.1,
+    })
 }
 
-fn format_info(info: &Info<char, &str>) -> String {
+fn format_info(info: &easy::Info<char, &str>) -> String {
     match *info {
-        Info::Token(x) => format!("{x:?}"),
-        Info::Range(x) => format!("{x:?}"),
-        Info::Owned(ref x) => x.clone(),
-        Info::Borrowed(x) => x.to_string(),
+        easy::Info::Token(x) => format!("{x:?}"),
+        easy::Info::Range(x) => format!("{x:?}"),
+        easy::Info::Owned(ref x) => x.clone(),
+        easy::Info::Static(x) => x.to_string(),
     }
 }
 
-fn format_error(error: &Error<char, &str>) -> String {
+fn format_error(error: &easy::Error<char, &str>) -> String {
     match *error {
-        Error::Unexpected(ref x) => format!("unexpected {}", format_info(x)),
-        Error::Expected(ref x) => format!("expected {}", format_info(x)),
-        Error::Message(ref x) => format_info(x),
-        Error::Other(ref x) => format!("{x:?}"),
+        easy::Error::Unexpected(ref x) => format!("unexpected {}", format_info(x)),
+        easy::Error::Expected(ref x) => format!("expected {}", format_info(x)),
+        easy::Error::Message(ref x) => format_info(x),
+        easy::Error::Other(ref x) => format!("{x:?}"),
     }
 }
 
-fn format_parse_error(parse_error: &ParseError<State<&str>>) -> String {
+fn format_parse_error(parse_error: easy::Errors<char, &str, SourcePosition>) -> String {
     format!(
         "Parse error at line {} column {}: {}",
         parse_error.position.line,
@@ -136,74 +130,63 @@ fn format_parse_error(parse_error: &ParseError<State<&str>>) -> String {
 /// The instructions are not validated and may have invalid names and operand types.
 pub fn parse(input: &str) -> Result<Vec<Instruction>, String> {
     match spaces()
-        .with(many(parser(instruction)).skip(eof()))
-        .parse(State::new(input))
+        .with(many(instruction()).skip(eof()))
+        .easy_parse(position::Stream::new(input))
     {
         Ok((insts, _)) => Ok(insts),
-        Err(err) => Err(format_parse_error(&err)),
+        Err(err) => Err(format_parse_error(err)),
     }
 }
 
 #[cfg(test)]
 mod tests {
+
     use super::{ident, instruction, integer, operand, parse, register, Instruction, Operand};
-    use combine::{parser, Parser};
+    use combine::Parser;
 
     // Unit tests for the different kinds of parsers.
 
     #[test]
     fn test_ident() {
-        assert_eq!(parser(ident).parse("nop"), Ok(("nop".to_string(), "")));
-        assert_eq!(parser(ident).parse("add32"), Ok(("add32".to_string(), "")));
-        assert_eq!(
-            parser(ident).parse("add32*"),
-            Ok(("add32".to_string(), "*"))
-        );
+        assert_eq!(ident().parse("nop"), Ok(("nop".to_string(), "")));
+        assert_eq!(ident().parse("add32"), Ok(("add32".to_string(), "")));
+        assert_eq!(ident().parse("add32*"), Ok(("add32".to_string(), "*")));
     }
 
     #[test]
     fn test_integer() {
-        assert_eq!(parser(integer).parse("0"), Ok((0, "")));
-        assert_eq!(parser(integer).parse("42"), Ok((42, "")));
-        assert_eq!(parser(integer).parse("+42"), Ok((42, "")));
-        assert_eq!(parser(integer).parse("-42"), Ok((-42, "")));
-        assert_eq!(parser(integer).parse("0x0"), Ok((0, "")));
+        assert_eq!(integer().parse("0"), Ok((0, "")));
+        assert_eq!(integer().parse("42"), Ok((42, "")));
+        assert_eq!(integer().parse("+42"), Ok((42, "")));
+        assert_eq!(integer().parse("-42"), Ok((-42, "")));
+        assert_eq!(integer().parse("0x0"), Ok((0, "")));
         assert_eq!(
-            parser(integer).parse("0x123456789abcdef0"),
+            integer().parse("0x123456789abcdef0"),
             Ok((0x123456789abcdef0, ""))
         );
-        assert_eq!(parser(integer).parse("-0x1f"), Ok((-31, "")));
+        assert_eq!(integer().parse("-0x1f"), Ok((-31, "")));
     }
 
     #[test]
     fn test_register() {
-        assert_eq!(parser(register).parse("r0"), Ok((0, "")));
-        assert_eq!(parser(register).parse("r15"), Ok((15, "")));
+        assert_eq!(register().parse("r0"), Ok((0, "")));
+        assert_eq!(register().parse("r15"), Ok((15, "")));
     }
 
     #[test]
     fn test_operand() {
-        assert_eq!(parser(operand).parse("r0"), Ok((Operand::Register(0), "")));
-        assert_eq!(
-            parser(operand).parse("r15"),
-            Ok((Operand::Register(15), ""))
-        );
-        assert_eq!(parser(operand).parse("0"), Ok((Operand::Integer(0), "")));
-        assert_eq!(parser(operand).parse("42"), Ok((Operand::Integer(42), "")));
-        assert_eq!(
-            parser(operand).parse("[r1]"),
-            Ok((Operand::Memory(1, 0), ""))
-        );
-        assert_eq!(
-            parser(operand).parse("[r3+5]"),
-            Ok((Operand::Memory(3, 5), ""))
-        );
+        assert_eq!(operand().parse("r0"), Ok((Operand::Register(0), "")));
+        assert_eq!(operand().parse("r15"), Ok((Operand::Register(15), "")));
+        assert_eq!(operand().parse("0"), Ok((Operand::Integer(0), "")));
+        assert_eq!(operand().parse("42"), Ok((Operand::Integer(42), "")));
+        assert_eq!(operand().parse("[r1]"), Ok((Operand::Memory(1, 0), "")));
+        assert_eq!(operand().parse("[r3+5]"), Ok((Operand::Memory(3, 5), "")));
         assert_eq!(
-            parser(operand).parse("[r3+0x1f]"),
+            operand().parse("[r3+0x1f]"),
             Ok((Operand::Memory(3, 31), ""))
         );
         assert_eq!(
-            parser(operand).parse("[r3-0x1f]"),
+            operand().parse("[r3-0x1f]"),
             Ok((Operand::Memory(3, -31), ""))
         );
     }
@@ -211,7 +194,7 @@ mod tests {
     #[test]
     fn test_instruction() {
         assert_eq!(
-            parser(instruction).parse("exit"),
+            instruction().parse("exit"),
             Ok((
                 Instruction {
                     name: "exit".to_string(),
@@ -222,7 +205,7 @@ mod tests {
         );
 
         assert_eq!(
-            parser(instruction).parse("call 2"),
+            instruction().parse("call 2"),
             Ok((
                 Instruction {
                     name: "call".to_string(),
@@ -233,7 +216,7 @@ mod tests {
         );
 
         assert_eq!(
-            parser(instruction).parse("addi r1, 2"),
+            instruction().parse("addi r1, 2"),
             Ok((
                 Instruction {
                     name: "addi".to_string(),
@@ -244,7 +227,7 @@ mod tests {
         );
 
         assert_eq!(
-            parser(instruction).parse("ldxb r2, [r1+12]"),
+            instruction().parse("ldxb r2, [r1+12]"),
             Ok((
                 Instruction {
                     name: "ldxb".to_string(),
@@ -255,7 +238,7 @@ mod tests {
         );
 
         assert_eq!(
-            parser(instruction).parse("lsh r3, 0x8"),
+            instruction().parse("lsh r3, 0x8"),
             Ok((
                 Instruction {
                     name: "lsh".to_string(),
@@ -266,7 +249,7 @@ mod tests {
         );
 
         assert_eq!(
-            parser(instruction).parse("jne r3, 0x8, +37"),
+            instruction().parse("jne r3, 0x8, +37"),
             Ok((
                 Instruction {
                     name: "jne".to_string(),
@@ -282,7 +265,7 @@ mod tests {
 
         // Whitespace between operands is optional.
         assert_eq!(
-            parser(instruction).parse("jne r3,0x8,+37"),
+            instruction().parse("jne r3,0x8,+37"),
             Ok((
                 Instruction {
                     name: "jne".to_string(),
@@ -633,7 +616,7 @@ exit
         assert_eq!(
             parse("exit\n^"),
             Err(
-                "Parse error at line 2 column 1: unexpected '^', expected end of input".to_string()
+                "Parse error at line 2 column 1: unexpected '^', expected letter or digit, expected whitespaces, expected 'r', expected '-', expected '+', expected '[', expected end of input".to_string()
             )
         );
     }