Описание ядра лексических анализаторов
Об авторе
Сергей Шатунов, 1980 г.р.
Специалист в области лексического анализа, разработке УП для станков с ЧПУ и XML технологий.
Лицензия
LGPL
Где взять
На данный момент эта библиотека лежит здесь.
Попробовать повозиться с ней можно здесь.
Для кого эта инструкция
Инструкция расчитана на людей, знакомых не только с JavaScript, но и с lex(flex) и yacc(bison).
Общее
Библиотека представляет собой функцию lexer, принимающую на вход 2 аргумента:
function lexer(конфигурация,опции)
Структура конфигурации лексера
конфигурация имеет следующую структуру:
{
состояние:[
[выражение,функция],
...
[выражение,функция]
],
...
состояние:[
[выражение,функция],
...
[выражение,функция]
]
}
состояние - строковое выражение, аналогично уникальным индентификаторам в lex, которые записываются в угловых скобках.
выражение - регулярное выражение или строка его описывющая. Используются нативные регулярные выражения.
Никакого осообого контроля за ними нет, так что стреляйте себе в ноги на здоровъе.
функция - может быть как функцией JavaScript так и её текстовым представлением,
принимает единственный аргумент с объектом для управления лексером.
Опции лексера
Опции представляют собой объект со следующими полями:
start - начальный режим, по умолчанию пустая строка
before - функция или код, которая запускается перед началом работы лексического анализатора
after - функция или код, которая вызывается по окончанию, лексический анализатор возвращает её результат
error - функция или код, которая вызывается при возникновении ошибок разбора, лексический анализатор возвращает её результат
forparser - если истина, то возвращать функцию при вызове которой, собственно и будет происходить обработка, иначе обрабатывать текст сразу.
Это удобно в случае совместного использования с парсером.
Структура аргумента функций обработчиков
В обработчик передаётся статический объект.
Ядром лексера изменяется только поле text.
Это позволяет использовать его для хранения временных значений.
Изначально он содержит следующие поля:
text - найденный текст.
push - аналог yy_push_state.
pop - аналог yy_pop_state.
top - аналог yy_top_state.
begin - аналог BEGIN с той лишь разницей, что это всего лишь операция с вершиной стека.
read - читает указаное количество символов.
unput - возвращает на дообработку указаную строку.
reject - переход к следующему регулярному выражению.
ret - лексер возвращает заданное значение.
Замечания
Обработчики переданые в лексер могут использовать this.
Это объект к которому применяется результирующий лексер через call/apply или в качестве поля.
С объектом передающемся функциям обработчикам можно проводить различные полезные операции, как хранение данных в его полях, так и подмену стандартных функций.
Например, вывод в лог возвращаемых значений:
function start_callback(state){
state.ret = (function(ret){
return function(val){
console.log(val);
ret.call(this, val);
}
})(ret);
}
Полезные ссылки
JS/CC - Основной проект. Эта библиотека появилась в процессе работы над ним.
FLEX - Основная реализация LEX.
BISON - Основная реализация YACC.