metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2011-06-06 01:13 am

Парсерный оверкилл?

Внезапно понадобилось сделать парсер строк с грамматикой подобного вида:
ИмяКласса | ИмяКласса(Параметр0,...)

Можно было бы не вдумываясь, склепать что-нибудь типа "найти скобки, до скобок - имя класса, внутри скобок разделить по запятым".
Но мне домашний паук из розетки приказал это сделать на генераторах парсеров, в частности fslex/fsyacc, что заняло немного больше времени, но как минимум, я теперь смогу при необходимости нормально менять грамматику или писать новые парсеры, разобравшись на простом примере.

Проблема в следующем: не является ли использование вуду-знаний из драгонбука правильных методик оверкиллом? А то уже не первый раз на работе возникают споры на тему "почему нужно делать правильно и долго, если можно сделать быстро и, с некоторыми ограничениями, будет работать".

[identity profile] gabaidulin.livejournal.com 2011-06-14 06:19 pm (UTC)(link)
Пакрат не решает эту проблему разве?

[identity profile] permea-kra.livejournal.com 2011-06-14 08:57 pm (UTC)(link)
Не-а. Пусть char 'x' - завершается успешно, если встретился x, а || порождает парсер, принимающий либо лево, либо право. Тогда парсер
a = ( a || char 'x' ++ something ) свалится в бесконечную рекурсию. В тоже время нормальный парсер-генератор такую грамматику вполне отработает. От мемоизации промежуточных результатов ничего не изменится.

Данная проблема принципиально неразрешима в рамках традиционных парсер комбинаторов, нужно имитировать один из универсальных алгоритмов парсинга. Часть библиотек отслеживает такую дурную рекурсию и ругаются, но это паллиатив.

[identity profile] gabaidulin.livejournal.com 2011-06-15 05:49 am (UTC)(link)
Ну значит manual по scala видимо говорит про какую-то другую левую рекурсию ?

http://www.scala-lang.org/api/current/scala/util/parsing/combinator/PackratParsers.html

[identity profile] permea-kra.livejournal.com 2011-06-15 08:42 am (UTC)(link)
Ваще-то да, поскольку там потроха изрядно другие, чем у простых парсер-комбинаторов.

[identity profile] gabaidulin.livejournal.com 2011-06-15 09:25 am (UTC)(link)
Хмм. Ну вообще с точки зрения кода эту будет тот же парсер комбинатор(то есть мы строим грамматику состоящую из простых правил с использованием простых парсеров, комбинируя их в более сложные с помощью специальных операторов), надо будет добавить with PackratParser и использовать lazy vals. Ну-да ладно.