Я перехожу от отдельного лексера и синтаксического анализатора к комбинированному синтаксическому анализатору, который работает с массивом символов. Одна проблема заключается в том, как правильно обрабатывать пробелы.
Проблема
Возьмем язык, состоящий из последовательности символов «а» и «б». Во входных данных разрешены пробелы, но они не влияют на смысл программы.
Мой текущий подход к разбору такого языка:
var token = function(p) {
return attempt(next(
parse.many(whitespace),
p));
};
var a = token(char('a'));
var b = token(char('b'));
var prog = many(either(a, b));
Это работает, но требует ненужного возврата. Для такой программы, как '___ba_alb' (пробелы удалялись в сообщении, поэтому пусть _ будет пробелом), при сопоставлении 'b' пробел анализируется дважды, сначала для a
, а когда a
терпит неудачу, снова для b
. Простое удаление attempt
не работает, так как either
никогда не достигнет b
, если будут использованы какие-либо пробелы.
Попытки
Первым делом я переместил вызов token
за пределы either
:
var a = char('a');
var b = char('b');
var prog = many(token(either(a, b)));
Это работает, но теперь prog
нельзя легко использовать повторно. При создании библиотеки синтаксических анализаторов это, по-видимому, требует определения синтаксических анализаторов дважды: одна версия, которая фактически использует «a» или «b» и может использоваться в других синтаксических анализаторах, и одна версия, которая правильно обрабатывает пробелы. Это также загромождает определения парсеров, требуя от них явных знаний о том, как работает каждый парсер и как он обрабатывает пробелы.
Вопрос
Предполагаемое поведение состоит в том, что произвольное количество пробелов может быть использовано перед токеном. Если синтаксический анализ маркера завершается неудачно, выполняется возврат к началу маркера, а не к началу пробела.
Как это можно выразить без предварительной обработки ввода для создания потока токенов? Есть ли хорошие примеры кода из реального мира? Самое близкое, что я нашел, это функции высшего порядка для синтаксического анализа, но это не так. кажется, решить мою конкретную проблему.
<
является либо (частью) оператора отношения, либо открытием шаблонного выражения в языках c-стиля? Обычно вы должны иметь возможность отложить любые решения о том, что представляет собой символ, которые могут внести неоднозначность, от этапа лексера до этапа синтаксического анализа. - person 500 - Internal Server Error   schedule 15.09.2013vector<vector<int>>
, где появляется>>
. И реляционные выражения, и шаблонные выражения работают с<
токенами пунктуатора. В Javascript '/' может быть связан либо с токеном знака пунктуации div, либо, с некоторыми другими символами, с токеном регулярного выражения. Поскольку такие символы, как"
, могут появляться внутри регулярных выражений, я не думаю, что сработает лексирование для знаков препинания div и введение создания регулярных выражений с использованием знаков препинания div. - person Matt Bierner   schedule 16.09.2013/
может быть делением, началом или концом регулярного выражения или обозначаться как//
строковым комментарием. по этой причине пустое регулярное выражение не может быть записано как//
, а литералы регулярного выражения не могут начинаться с неэкранированного пробела... - person flow   schedule 17.06.2014