PEG-парсинг на JS и Python

предыдущая серия

Использование версии OMeta для веба (точнее, в JavaScript) ещё проще, нежели в случае C#. Достаточно скачать дистрибутив с github.com/alexwarth/ometa-js/ , задеплоить его в свой проект, и настроить пути к скриптам.

Вот базовый шаблон для использования OMeta/JS:

<html>
<head>
<script src="prototype.js"></script>
<script src="lib.js"></script>
<script src="ometa-base.js"></script>
<script src="parser.js"></script>
<script src="bs-js-compiler.js"></script>
<script src="bs-ometa-compiler.js"></script>
<script src="bs-ometa-optimizer.js"></script>
<script src="bs-ometa-js-compiler.js"></script>
<script src="ometa-script-tag.js"></script>

<script type=»text/x-ometa-js»>

Сюда вставляем код OMeta

</script>

<body>

</body>
</html>

В качестве кода можно взять например такой уже знакомый нам пример:

ometa Calc {
digit    = ^digit:d                 -> d.digitValue(),
number   = number:n digit:d         -> (n * 10 + d)
| digit,
addExpr  = addExpr:x '+' mulExpr:y  -> (x + y)
| addExpr:x '-' mulExpr:y  -> (x - y)
| mulExpr,
mulExpr  = mulExpr:x '*' primExpr:y -> (x * y)
| mulExpr:x '/' primExpr:y -> (x / y)
| primExpr,
primExpr = '(' expr:x ')'           -> x
| number,
expr     = addExpr
}

Визуально протестировать его в браузере можно, добавив в хвост данному коду вызов

alert( Calc.matchAll('6*(4+3)', 'expr') )

На экране покажется сообщение «42».

Ещё более интересна версия OMeta для Python, удобная для использования в Linux. Существует несколько реализаций, порекомендую PyOMeta/OMeta2 (github.com/espinielli/pyometa). Устанавливается она с гитхаба стандартным образом, в наборе тестов доступны самые разные примеры.

Благодаря своей динамичности, Питон позволяет использовать очень наглядный синтаксис. Простейший пример интерпретатора арифметической грамматики:

g = self.compile("""
interp = ([interp:x '+' interp:y] -> x + y
| [interp:x '*' interp:y] -> x * y
| :x ?(isinstance(x, basestring) and x.isdigit()) -> int(x))
""")

Вызвать его можно, даже не описывая анализируемое выражение в виде строки, а непосредственно в виде питоновского списка:

result = g.interp([['3', '+', ['5', '*', '2']]])

В result занесётся значение 13. Таким образом, появляется удобная возможность обходиться без промежуточной фазы формирования интерпретируемого кода в виде текста с собственным синтаксисом.

Поделиться статьей ...Share on Facebook0Share on Google+0Tweet about this on TwitterShare on LinkedIn0Share on VKPrint this page

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *