Использование PEG-а вместо регулярных выражений
От: VladD2 Российская Империя www.nemerle.org
Дата: 21.04.11 17:21
Оценка: 28 (4) +2
В этой
Автор: Рысцов Денис
Дата: 20.04.11
теме Денис затронул тему использования PegGrammar вместо регулярных выражений.

Там же
Автор: VladD2
Дата: 21.04.11
я высказал мысль, что в текущем виде это не вполне удобно.

Предлагаю подумать над синтаксисом и семантикой такой замены — inline PEG.

Опишу какие тут есть сложности.

1. Так как PEG поддерживает рекурсию, то подходы регекспов подходят тут плохо. Хотя конечно и не рекурсивный может быть полезен, но лучше все же чтобы inline PEG поддерживал рекурсию.

2. В отсутствии методов-орбработчиков встает вопрос именования (связывания с именами) распознанных фрагментов. Нужна какая-то иделогия именования частей грамматики, так чтобы можно было обрабатывать их результаты.

Для затравки предлагаю следующий механизм. PEG-грамматику описывать как вхождения паттернматчинга вписанные в лямбду.
Таким образом такая грамматика:
[PegGrammar(start,grammar{
  any            = ['\u0000'..'\uFFFF7'];
  d              = ['0'..'9'];
  phone : string = d{3} '-' d{4,5};
  start : string = phone !any;
})]
class PhoneParser
{
  phone(a : NToken, _ : NToken, b : NToken) : string
  { 
    $"+7(812) $(GetText(a))-$(GetText(b))"
  }
}

может быть переписана следующим образом:
peg parser(str)
{
  | <# any   = ['\u0000'..'\uFFFF7']   #> => any
  | <# d     = ['0'..'9']              #> => d
  | <# phone = b : d{3} '-' a : d{4,5} #> => $"+7(812) $a-$b"
  | <# phone : phone !any              #> => phone
}

В итоге parser будет указывать на функцию принимающую строку и возвращающую выведенный тип (в данном примере тоже строку).
Строки используются для того, чтобы можно было использовать паттерн любой сложности.

Для введения имен используется синтаксис имя : подправило.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.