Описание ядра лексических анализаторов

Об авторе

Сергей Шатунов, 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.