0

使用 jparsec,我正在尝试解析可能为负数或非负数的数字:

@Test
public void canParseIntegerValues() {
    assertEquals(0, ValueParser.PARSER.parse("0"));
    assertEquals(276, ValueParser.PARSER.parse("276"));
    assertEquals(-3874, ValueParser.PARSER.parse("-3874"));
}

我一直无法弄清楚如何声明PARSER. 我试过了:

private static final Parser<Integer> INTEGER_VALUE_PARSER = Terminals.IntegerLiteral.TOKENIZER
        .map(new Map<Fragment, Integer>() {
            @Override
            public Integer map(Fragment from) {
                return Integer.valueOf(from.text());
            }
        });

这不起作用,因为Terminals.IntegerLiteral.TOKENIZER不包含减号。接下来,我尝试了:

private static final Parser<Integer> INTEGER_VALUE_PARSER = Parsers.sequence(
        Scanners.string("-").optional().token(),
        Terminals.IntegerLiteral.TOKENIZER
            .map(new Map<Fragment, Integer>() {
                @Override
                public Integer map(Fragment from) {
                    return Integer.valueOf(from.text());
                }
            }));

这也不起作用,因为负号被丢弃并且我的地图函数永远不会看到它。

谁能告诉我如何使用 jparsec 正确解析可能为正数或非正数的整数?

编辑:我找到了一种方法,但我很难相信这是最好的方法:

private static final Parser<Integer> INTEGER_VALUE_PARSER = Parsers.sequence(
        Scanners.string("-").many(),
        Terminals.IntegerLiteral.TOKENIZER,
        new Map2<List<Void>, Fragment, Integer>() {
            @Override
            public Integer map(List<Void> from1, Fragment from2) {
                boolean isNegative = (from1.size() % 2) == 1;

                if (isNegative) {
                    return -1 * Integer.valueOf(from2.text());
                } else {
                    return Integer.valueOf(from2.text());
                }
            }
        });
4

1 回答 1

2

您可以查看Calculatorjparsec 示例中的类:https://github.com/abailly/jparsec/blob/master/jparsec-examples/src/main/java/org/codehaus/jparsec/examples/calculator/Calculator。 java这里负整数被处理为应用了前缀 -运算符的整数。

或者,您可以简单地声明一个包含减号的模式:

public void test() {
  Pattern regex = Patterns.regex("-?\\d+");
  Parser<Integer> integer = Scanners.pattern(regex, "Integer").source().map(new    Map<String, Integer>() {
      @Override
      public Integer map(String s) {
        return Integer.parseInt(s);
      }
    });

  assertEquals(-42, (int) integer.parse("-42"));
 }

高温高压

阿尔诺

于 2014-06-23T12:49:19.793 回答