Простой синтаксический анализ. Или выражение со скобками

Предметом нашего изучения будет структурированный текст. Например - программа на ЯП. В этом мы схожи с обычной, гуманитарной лингвистикой.

Как и в человеческом языке, в машинном мы выделяем лексику, синтаксис и семантику.
Лексика определяет слова, минимальные “осмысленные” (в кавычках, так как это не термин, а просто иллюстративное определение) единица языка - слова. В человеческом языке лексема это слово в любой грамотной форме. В машинном языке - схоже. Но мы относим к лексемам еще и служебные конструкции, не только числа, литералы и имена переменных, но и разделители и знаки операций и скобки и их аналоги (begin - end).

Разделение входного задания на последовательность лексем - называется Лексический анализ. Программа это выполняющая - Лексический анализатор или Лексер.

Синтаксис определяет уже конструкции языка, как и в человеческом. Есть словосочетания, обороты, предложения. Так и в машинном есть выражения, операторы, условия, блоки. И даже вся программа целиком - тоже синтаксический элемент. Правила объединения лексем в допустимые конструкции называются грамматика.
Разделение входного задания на синтаксические единицы, причем рекурсивное, иерархическое разделение, называется Синтаксический анализ и программа выполняющее это “Синтаксический анализатор”. Почему рекурсивное? Потому, что синтаксические единицы рекурсивно вложены одна в другую. Программа состоит из модулей, модуль состоит из объявлений и определений. Определение состоит из заголовка и тела, тело из блоков, блоки из операторов. Оператор “если” (к примеру) из условия и другого оператора. … и так далее матрёшкой.

В этом, кстати, важное отличие лексической единицы (лексемы) от синтаксической. Лексема при анализе не делится на другие лексемы. Мы не делим число на знак, целую и дробную части. Для лексера есть число целиком, или мы можем написать грамматику иначе и лексер нам отдаст последовательность: (знак, число, “.”, число, “Е”, знак, число) и мы их объединим уже на уровне СИНТАКСИСА. Это наш выбор, можем писать программу так или иначе, как хотим. Но Лексер не соединяет лексемы вместе. Лексема не делима.

бо намших. к регулярним выражениям.

Я пока не планирую углубляться в теорию формальных грамматик.
Остановимся на том, что регулярное выражение РВ это то, что помогает нам определить устройство простых конструкций из букв.

Формально, без лишних “украшений” в грамматике РВ от GNU, РВ это

  • или буква или последовательность букв.
  • альтернатива из двух РВ (например: или “фыв” или “йцу”)
  • повтор (0 и более) некоторого РВ.
    Всё.
    Грамматика ГНУ еще дает нам всякие удобства типа привязать совпадение к концу/началу строки/слова. Повтор в любом интервале раз - (например от 12 до 23 раз :wink: ) и даже ноль или 1 раз. И еще немного разных “фич”, которые можно и не использовать, но они помогут написать код короче и понятнее.

Вот пример РВ:
\+?\d{1,3}[-.\s]?\(?\d{2,3}\)?[-.\s]?\d{3}[-.\s]?\d{2,4}
Это РВ для поиска телефонного номера.
Разберем:
+ - знак “+”
+? - знака “+” повторен о или 1 раз
\d - цифра
\d{1,3} цифра повторена 1, 2 или 3 раза.
[-.\s]? - не обязательный разделитель дефис или точка или пробел

И так далее. Прошу проанализировать самостоятельно и задать вопросы если не понятно.
Вот еще регулярки для самостоятельного анализа:
https?:\/\/[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
УРЛ с https
\d{2}/\d{2}/\d{4}
дата типа 12/11/2025

Завтра о том, как РВ связаны с Лексическим анализом и собственно с пакетом Lex.
Обязательно разобраться с синтаксисом РВ. Это вообще очень важно любому программисту, на мой взгляд. Если что-то по синтаксису РВ непонятно - обязательно задайте вопрос.

И чтобы идти дальше нужно попробовать понять что такое БНФ.

Спасибо, Влад.
Ближайшее время постараюсь найти время и подробно разобрать все написанное.

Влад, это не так. Я, например, читаю и Вас, и ЕП, и других участников форума. Если мне сходу удается понять все что написано, то я просто использую это и не задаю вопросов. Если мне текст не понятен, то и вопросы задавать стоит, лишь погрузившись в тему. Что не всегда получается быстро в силу возраста.
А тут тему Вы тут подняли сложную. Вот мне, например, регулярные выражения тяжелы для понимания. Но это не значит, что я не вернусь к регуляркам спустя месяц или квартал.
Так, например, было с шаблонами. С помощью которых ЕП в другой теме показал реализацию функции подсчета символов строки в формате UTF-8. Тогда я сходу в шаблонах не разобрался, а спустя некоторое время все же понимание пришло.

К чему я все это написал. Образовательная информация, выкладываемая на форуме крайне полезна. Потому прошу при наличии желания все же делиться с нами Вашими знаниями.

О, коллега.

Преподайте человеку, который чот там слышал про lex//yacc, но в руках не держал, урок-воркшоп.

Задача: нужно написать программу, которая будет читать файлик, и обрабатывать его.

А файлик, короче говоря, HTML.

И вот, нужно пройтись по всем тегам, добавить в них атрибуты (или поменять существующие), посчитать статистику по тегам, вырезать все комментарии, закоментировать весь JavaScript, то-сё.

Например.

Или куркулятор. С погремушками, пусть будет поддерживать переменные в выражениях.

Или, интерпретатор си-подобного языка (поглазеть можно в Quake1 source, там есть крохотный компилятор и исполнятор)

Я с этого начал в контексте Метода Рекурсивного Спуска. Это ты хотел ответвление про lex и yacc.
А я как раз хотел показать, что можно написать простой интерпретатор строк на 400 без генераторов.

А это что за фантазия? Если ты про учебный пример, то это дурацкий пример. Понятный только тем, кто глубоко в теме веб-разработки. В таком примере теряется учебный материал и вместо него вылезает никчемная конкретика самого примера.
Или я не понял и это тебе надо? :wink: :wink: Неее… только за твердую валюту! :wink:
Если серьёзно, то я посмотрю, куда пойдёт. Какие-то примеры буду показывать конечно. Но не столь специальные, как веб разработка. Целиком интерпретатор на Бизоне тоже не хороший пример, так как в нем придется много, больше половины внимания уделить структуре хранения кода, обработке типов и прочему. Это смежные вопросы, которые “расфокусируют” внимание с вопросов синтаксического анализа.

Ладно. Потом продолжу.

Не, мне не надо, это я просто вспомнил, с чего начинал сам :))).