2017-02-08 8 views
2

Я пытаюсь написать простой анализатор для номера версии с использованием JParsec 3. Номер версии выглядит следующим образом:JParsec для номера версии

123 
1.2.3 
123.4 

правило:

до трех не- отрицательные целые числа, разделенные .

у меня есть Versionclass с тремя фабричные методы:

Version.of(int major) 
Version.of(int major, int minor) 
Version.of(int major, int minor, int patch) 

Я хотел бы написать парсер для версий любого из трех типов.

Вот то, что я до сих пор:

static final Parser<Integer> integerParser = Scanners.INTEGER 
     .map(x -> Integer.parseUnsignedInt(x)); 

static final Parser<Version> versionParser1 = 
     integerParser.map(x -> Version.of(x)); 

static final Parser<Version> versionParser2 = 
     Parsers.sequence(
       integerParser.followedBy(Scanners.isChar('.')), 
       integerParser) 
       .map(x -> Version.of(x.get(0), x.get(1))); 

static final Parser<Version> versionParser3 = 
     Parsers.sequence(
       integerParser.followedBy(Scanners.isChar('.')), 
       integerParser.followedBy(Scanners.isChar('.')), 
       integerParser) 
       .map(x -> Version.of(x.get(0), x.get(1), x.get(2))); 

public static final Parser<Version> versionParser = 
    versionParser1.or(versionParser2).or(versionParser3); 

Это не компилировать, потому что, когда у меня есть x.get(0), x является Integer.

Как я могу использовать JParsec здесь?

ответ

2

Вместо этого вы можете использовать функции Parsers.sequence(p1,p2,...,map). Поведение Parsers.sequence(p1...).map(f) состоит в том, чтобы отбросить вывод всех парсеров, кроме последнего. Затем объедините все синтаксические анализаторы, используя другой комбинатор, чем or(), потому что он будет терпеть неудачу, если парсеры будут потреблять входные данные, но не удастся. Возможное решение

public static final Parser<Version> versionParser = Parsers.longest(versionParser1, versionParser2, versionParser3);

+0

Спасибо, 'longest' было именно то, что я искал. – sdgfsdh