【问题标题】:Parsing a Number in nom以 nom 解析一个数字
【发布时间】:2020-06-18 10:39:30
【问题描述】:

我正在尝试使用 nom5 传递一些锌格式 https://www.project-haystack.org/doc/Zinc

数字格式可以是以下任意一种格式

1、-34、10_000、5.4e-45、-5.4e-45、9.23kg、74.2°F、4 分钟、INF、-INF、NaN

如果指定,我相信单位可以是任何单位。

我有一些简单数字传递的例子,比如 Parsing number with nom 5.0

fn number<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
    map(
        tuple((
            opt(char('-')),
            many1(digit1),
            opt(preceded(char('.'), many1(digit1)))
        )),
        |s| Token::Number(s)
    )(i)
}

但我不确定如何处理 值也可能是 INF 或 -INF、NaN 并可能添加单位。

我该如何处理这个案子?

谢谢

【问题讨论】:

  • 单位只是另一个尾随opt,选择使用alt建模。

标签: rust nom


【解决方案1】:

最后我把它建成了

fn simple_number<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {

    map(
        recognize(tuple( (opt(alt((char('-'), char('+')))), many1(digit1), opt(preceded(char('.'), many1(digit1)))) ) ),
        |s: &str| Token::Number(s.parse::<f64>().unwrap(), "".into())
        //|s: &str| Token::Var(s.into())
    )(i)
}

fn exponent<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
    map(
        recognize(tuple(  ( alt((char('e'), char('E'))), simple_number  )) ),
        |s: &str| Token::Var(s.into())
    )(i)
}

fn number<'a>(i: &'a str) -> IResult<&'a str, f64, (&'a str, ErrorKind)> {
    map(
        recognize(tuple((simple_number, opt(exponent))) ),
        |s: &str| s.parse::<f64>().unwrap()
    )(i)
}

fn units<'a>(i: &'a str) -> IResult<&'a str, &'a str, (&'a str, ErrorKind)> {
    alphanumeric1(i)
}

fn number_with_unit<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {
    map(
        tuple((number, opt(units))),
        |t: (f64, Option<&str>)| Token::Number(t.0, t.1.unwrap_or(&"".to_string()).into())
    )(i)
}

// Number: 1, -34, 5.4, -5.4, 9.23, 74.2, 4, 5.4e-45, -5.4e-45, 67.3E7 INF -INF +INF NAN
fn zinc_number<'a>(i: &'a str) -> IResult<&'a str, Token, (&'a str, ErrorKind)> {

    alt( (number_with_unit, inf, nan) ) (i)
}

【讨论】:

  • 这似乎没有按照问题中的问题陈述的要求解析单位。
  • 你是对的。我一定是累了,不关心单位了。我现在已经更新了我的答案。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 2017-08-05
  • 2021-05-04
  • 1970-01-01
  • 1970-01-01
  • 2019-03-14
  • 1970-01-01
相关资源
最近更新 更多