Ver Fonte

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 há 2 anos atrás
pai
commit
4e9e594e81
2 ficheiros alterados com 77 adições e 94 exclusões
  1. 1 1
      Cargo.toml
  2. 76 93
      src/asm_parser.rs

+ 1 - 1
Cargo.toml

@@ -24,7 +24,7 @@ include = [
 
 
 [dependencies]
 [dependencies]
 
 
-combine = "2.5"
+combine = "4.6"
 libc = "0.2"
 libc = "0.2"
 time = "0.2"
 time = "0.2"
 byteorder = "1.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.
 // 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.
 //! 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::{
 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.
 /// Operand of an instruction.
@@ -34,16 +35,18 @@ pub struct Instruction {
     pub operands: Vec<Operand>,
     pub operands: Vec<Operand>,
 }
 }
 
 
-fn ident<I>(input: I) -> ParseResult<String, I>
+fn ident<I>() -> impl Parser<I, Output = String>
 where
 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
 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 {
     let sign = optional(one_of("-+".chars())).map(|x| match x {
         Some('-') => -1,
         Some('-') => -1,
@@ -53,71 +56,62 @@ where
         .with(many1(hex_digit()))
         .with(many1(hex_digit()))
         .map(|x: String| u64::from_str_radix(&x, 16).unwrap() as i64);
         .map(|x: String| u64::from_str_radix(&x, 16).unwrap() as i64);
     let dec = many1(digit()).map(|x: String| x.parse::<i64>().unwrap());
     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
 where
-    I: Stream<Item = char>,
+    I: Stream<Token = char>,
+    I::Error: ParseError<I::Token, I::Range, I::Position>,
 {
 {
     char('r')
     char('r')
         .with(many1(digit()))
         .with(many1(digit()))
         .map(|x: String| x.parse::<i64>().unwrap())
         .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
 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
 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 {
     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 {
     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!(
     format!(
         "Parse error at line {} column {}: {}",
         "Parse error at line {} column {}: {}",
         parse_error.position.line,
         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.
 /// The instructions are not validated and may have invalid names and operand types.
 pub fn parse(input: &str) -> Result<Vec<Instruction>, String> {
 pub fn parse(input: &str) -> Result<Vec<Instruction>, String> {
     match spaces()
     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),
         Ok((insts, _)) => Ok(insts),
-        Err(err) => Err(format_parse_error(&err)),
+        Err(err) => Err(format_parse_error(err)),
     }
     }
 }
 }
 
 
 #[cfg(test)]
 #[cfg(test)]
 mod tests {
 mod tests {
+
     use super::{ident, instruction, integer, operand, parse, register, Instruction, Operand};
     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.
     // Unit tests for the different kinds of parsers.
 
 
     #[test]
     #[test]
     fn test_ident() {
     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]
     #[test]
     fn test_integer() {
     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!(
         assert_eq!(
-            parser(integer).parse("0x123456789abcdef0"),
+            integer().parse("0x123456789abcdef0"),
             Ok((0x123456789abcdef0, ""))
             Ok((0x123456789abcdef0, ""))
         );
         );
-        assert_eq!(parser(integer).parse("-0x1f"), Ok((-31, "")));
+        assert_eq!(integer().parse("-0x1f"), Ok((-31, "")));
     }
     }
 
 
     #[test]
     #[test]
     fn test_register() {
     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]
     #[test]
     fn test_operand() {
     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!(
         assert_eq!(
-            parser(operand).parse("[r3+0x1f]"),
+            operand().parse("[r3+0x1f]"),
             Ok((Operand::Memory(3, 31), ""))
             Ok((Operand::Memory(3, 31), ""))
         );
         );
         assert_eq!(
         assert_eq!(
-            parser(operand).parse("[r3-0x1f]"),
+            operand().parse("[r3-0x1f]"),
             Ok((Operand::Memory(3, -31), ""))
             Ok((Operand::Memory(3, -31), ""))
         );
         );
     }
     }
@@ -211,7 +194,7 @@ mod tests {
     #[test]
     #[test]
     fn test_instruction() {
     fn test_instruction() {
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("exit"),
+            instruction().parse("exit"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "exit".to_string(),
                     name: "exit".to_string(),
@@ -222,7 +205,7 @@ mod tests {
         );
         );
 
 
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("call 2"),
+            instruction().parse("call 2"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "call".to_string(),
                     name: "call".to_string(),
@@ -233,7 +216,7 @@ mod tests {
         );
         );
 
 
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("addi r1, 2"),
+            instruction().parse("addi r1, 2"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "addi".to_string(),
                     name: "addi".to_string(),
@@ -244,7 +227,7 @@ mod tests {
         );
         );
 
 
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("ldxb r2, [r1+12]"),
+            instruction().parse("ldxb r2, [r1+12]"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "ldxb".to_string(),
                     name: "ldxb".to_string(),
@@ -255,7 +238,7 @@ mod tests {
         );
         );
 
 
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("lsh r3, 0x8"),
+            instruction().parse("lsh r3, 0x8"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "lsh".to_string(),
                     name: "lsh".to_string(),
@@ -266,7 +249,7 @@ mod tests {
         );
         );
 
 
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("jne r3, 0x8, +37"),
+            instruction().parse("jne r3, 0x8, +37"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "jne".to_string(),
                     name: "jne".to_string(),
@@ -282,7 +265,7 @@ mod tests {
 
 
         // Whitespace between operands is optional.
         // Whitespace between operands is optional.
         assert_eq!(
         assert_eq!(
-            parser(instruction).parse("jne r3,0x8,+37"),
+            instruction().parse("jne r3,0x8,+37"),
             Ok((
             Ok((
                 Instruction {
                 Instruction {
                     name: "jne".to_string(),
                     name: "jne".to_string(),
@@ -633,7 +616,7 @@ exit
         assert_eq!(
         assert_eq!(
             parse("exit\n^"),
             parse("exit\n^"),
             Err(
             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()
             )
             )
         );
         );
     }
     }