1

我正在使用来解析字符串,例如:

[1,2, 3]
[ 3, 4]
[3   ,4,56, 7 ]
[]

我已经实现了一些类(从我的接口继承Token)来表示令牌:

final class OpenListToken
final class CommaToken
final class CloseListToken
final class NumberToken // Has a public final property "value" that contains the int

我还为每个实现了标记器:

static final Parser<OpenListToken> openListTokenParser
static final Parser<CommaToken> commaTokenParser
static final Parser<CloseListToken> closeListTokenParser
static final Parser<NumberToken> numberTokenParser

这些都在角色级别上起作用。例如:

final NumberToken t = numberTokenParser.parse("123");
// t.value == 123

final OpenListToken u = openListToken.parse("[");
// Succeeds

现在我想将它们组合成一个 的解析器ListExpression,它是一个代表数字列表的类。我试过类似的东西:

openListTokenParser
    .next(numberTokenParser.sepBy(commaTokenParser))
    .followedBy(closeListTokenParser)

这适用于像这样的字符串,[1,2,3]但显然不适用于像[ 1, 2 ].

是否有一个运算符需要一些解析器并whitespace*在它们之间放置?

或者是否可以让我的ListExpression解析器在我的Token接口实例流而不是字符上工作?

4

1 回答 1

1

您可以使用类中的函数直接构建标记器Terminals。在您的情况下,这将如下所示:

首先定义我们的终端集合,例如操作符、关键字、词...

Terminals terminals = operators("[", "]", ",");

然后,我们的令牌要么由我们的终端或IntegerLiteral令牌生成器令牌化:

Parser<?> tokens = Parsers.or(terminals.tokenizer(), IntegerLiteral.TOKENIZER);

我们的最终结果来自整数的句法解析器(由标记为 的标记构建INTEGER),用逗号分隔,括号标记之间。我们忽略所有标记之间的任何空格(这是 的第二个参数from

Parser<?> parser = IntegerLiteral.PARSER.sepBy(terminals.token(",")).between(terminals.token("["), terminals.token("]"))
  .from(tokens, Scanners.WHITESPACES.many().cast());

等等:

System.out.println(parser.parse( "[1,2,3]"));
System.out.println(parser.parse( "[ 1, 2 , 3 ]   "));
System.out.println(parser.parse( "   [1,2,3   ]"));
System.out.println(parser.parse( "[1, 2   ,    3]"));
于 2017-02-09T20:31:31.273 回答