Я рассматриваю возможность использования библиотеки разбора Haskell Parsec для анализа подмножества Java как рекурсивного парсера спуска в качестве альтернативы более традиционным решениям парсера-генератора, таким как Happy. Parsec кажется очень простым в использовании, и скорость разбора определенно не является для меня фактором. Мне интересно, однако, если возможно реализовать "резервное копирование" с Parsec, метод, который находит правильное производство для использования, пытаясь каждый из них по очереди. Для простого примера рассмотрим начало Java-грамматики JLS:
Literal:
IntegerLiteral
FloatingPointLiteral
Я бы хотел, чтобы не нужно было выяснить, как я должен заказать эти два правила, чтобы заставить синтаксический анализ добиться успеха. Как бы то ни было, наивная реализация такая:
literal = do {
x <- try (do { v <- integer; return (IntLiteral v)}) <|>
(do { v <- float; return (FPLiteral v)});
return(Literal x)
}
Не будет работать... Входы, такие как "15.2", заставят целочисленный синтаксический анализатор быть успешным первым, а затем все это задохнется на ".". символ. В этом случае, конечно, очевидно, что вы можете решить эту проблему, переупорядочив две постановки. В общем случае, однако, поиск подобных вещей будет кошмаром, и очень вероятно, что я пропущу некоторые случаи. В идеале, я бы хотел, чтобы Parsec выяснял такие вещи, как это для меня. Возможно ли это, или я просто пытаюсь сделать слишком много с библиотекой? Документация Parsec утверждает, что она может "анализировать контекстно-зависимые, бесконечные грамматические символы с перспективой", поэтому мне кажется, что я должен что-то сделать здесь.