Вот какое замечание мне хотелось сделать про лексер... В смысле - сканер.
Возможно, немного забегаю, но предположим (хотя бы в рамках только этого поста), что неоднозначность разбиения исходного текста на лексемы - факт не вызывающий сомнений
Что такое сканер, спрашивается ???Это такая "машинка", которая делает именно однозначным (и это в нем главное) разбиение исходного текста на лексемы.
Какая для такого поведения дана информация ???Список патернов (регулярных выражений) для всех токенов (по дядюшке АхО - это класс лексем, а они в свою очередь - конкретная реализация токена в виде ли текста, числа, и т.п.)
По какому принципу разрешается неоднозначность разбиения ???Во-первых - да по тому самому правилу СДЛ. Не будем наконец вспоминать про фортрановский "DOI=1,"
Во-вторых, при равенстве длин разных лексем - по порядковому номеру в вышеозначенном списке патернов.
Чего происходит после распознавания лексемы по вышеозначенным правилам ???Самый простой ответ - возврат соответствующего LexemID. Но мы же знаем, что порой ничего возвращать не надо, а надо просто пропускать какой ни то "комментарий"
Поэтому более общим ответом будет - выполнение действий предписанных разработчиком сканера. Т.е., вышеозначенный список патернов должен быть дополнен, каким-то образом, списком действий (Action) для каждого регулярного выражения. А уже у нутре этих Action разработчик явно указывает: то ли возврат соответствующего LexemID, то ли дополнительные действия по подготовке таблиц символов или рассчету аттрибута value, то ли просто - выбрать следующую лексему (без возврата в caller), начиная с
некого начального состоянияВсе это были довольно очевидные рассуждения. Кроме последних трех слов
Как у нас все работает ??? Сканер скушал некую порцию текста, и вернул некую лексему. Начинает кушать следующую...
Вопрос: по одинаковому ли алгоритму работает наш сканер при распознавании каждой лексемы ???
А вот тут есть фишка, и очень удобная - может и по разному. Т.е., вышеозначенные слова "некого начального состояния" могут иметь смысл указания на переход сканера в состояние приема лексем, отличное от некого default-а
В чем может быть польза... Ну например, по лексеме ASM он может переключиться в режим приема асм-лексем - другой язык таки... А уже в асм-состоянии, по какому-нибудь END - опять в исходное.
Можно по односимвольной лексеме "кавычка" переключиться в состояние sting, и начать хитромудро парсить какие-нибудь esc-коды.
Скажем так, я не обладаю достаточной образованностью, чтобы ответить, описывается ли эта фишка какой-нибудь "грамматикой". Но вот то, что это не усложняет сканер принципиально - точно знаю. Как был автоматом, таким и останется. И графическое представление довольно очевидно: просто "стартовых" состояний, с которых начинают разыгрываться фишки по диаграммам переходов - становится несколько. Ну и списков патернов (вместе с соответствующими Action) становится несколько - по списку на каждое состояние сканера.
Вот Вам
пример про ЧЕСТНЫЙ комментарий.
Он в LEX-синтаксисе написан (там фигурные скобки обладают совсем другим смыслом), поэтому поясню.
В состоянии сканера comment работает всего ДВЕ лексемы: двухсимвольная "*)", и односимвольная - sym, типа любой символ. По честному любой, а не по Легалову: тут играть, тут не играть, а тут рыбу заворачивали...
Какая сработает? Да по правилу СДЛ. По срабатыванию первой - вернется сканер в исходное состояние, по второй (один символ) - просто пропустит. И опять - первая или вторая?
Вот и все!!!
Все точно и ясно, и точно и быстро, и глухо как в танке. Ошибиться невозможно.
Вот я и хотел посмотреть на "честный" патерн для комментария, без такой удобной "фишки-состояний"
Я себе его примерно представляю - именно из него ведь код процедуры
comment сделан, по правилам Вирта. А код-то Вы видели, и обсуждали в отдельной теме