我使用jparsec来解析字符串,如:
[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
接口实例流而不是字符上工作?
答案 0 :(得分: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());
Etvoilà:
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]"));