Ответ 1
Что делать, если вы попробуете GLL Combinators? Хотя он использует Scala, вы можете написать для него "тонкие" обертки с помощью JNI.
Комбинаторы GLL - это структура, предназначенная для реализации алгоритма синтаксического анализа GLL (Scott and Johnstone, LDTA 2009) в функциональной манере. Более конкретно, каркас использует комбинаторы атомного парсера для составления грамматик, которые затем оценивается с использованием алгоритма GLL. Структура обеспечивает синтаксис для этого задача, которая почти идентична заданной структуре комбинатора парсеров в Scala. Например, мы можем отобразить классическую грамматику круглых скобок, используя Комбинаторы GLL:
lazy val expr: Parser[Any] = ( "(" ~ expr ~ ")" | "" )Как следует из аннотации типа,
expr
будет ссылаться на экземпляр типаParser[Any]
. То есть, атомный синтаксический анализатор, который потребляет некоторый ввод и возвращает значение типаAny
. Мы можем вызвать этот синтаксический анализатор на входString
следующим образом:expr("((()))")Это вернет значение типа
Stream[Result[Any]]
.Result[A]
ADT определяемый как один из следующих (для некоторого типаA
):
Success[A]
- представляет успешный синтаксический анализ и содержит результирующее значение.Failure
- представляет неудачный синтаксический анализ и содержит соответствующее сообщение об ошибке а также остальную часть потока синтаксического анализа (символы, которые не были потребляются).Если какой-либо результат будет успешным (т.е. экземпляр
Success[A]
), то никаких сбоев будут возвращены. Таким образом, возвращенныйStream
будет полностью однородным, содержащие либоSuccess
, либоFailure
, но не оба. AStream
является вместо одного значения, чтобы допускать двусмысленность в грамматике (см. ниже).Стоит упомянуть, что GLL является формой рекурсивного спуска разбора. В нем есть все преимущества традиционного рекурсивного спуска, включая интуитивно понятный поток управления, произвольное позиционирование семантических действий и превосходная ошибка Сообщения. Фактически, это факт, что GLL - это рекурсивный спуск, который позволяет для реализации с использованием атомных комбинаторов. Другие алгоритмы, которые разделяют те же возможности, что и GLL (такие как GLR, Earley Parsing и т.д.), в основном несовместимые с моделью комбинатора из-за их крайне неинтуитивного контроля течь. При анализе GLL поток управления следует за сигналом грамматики, как это происходит в традиционных комбинаторах парсеров или в любой другой форме рекурсивного спуска.