Автоматный язык с символом-ограничителем Дана автоматная грамматика. Все цепочки порождаемого ею языка дополним символом-ограничителем, для чего все правила вида A → a заменим на правила A → aZ, где Z – новый нетерминал, и добавим правило: Z → ┴ . Если в грамматике есть недетерминированность, то ее устраняем. После этого строим матрицу переходов. Пример: {S → aA, A → aA, A → aB, A → b, B → bB, B → b}. После преобразования: {S → aA, A → aA, A → bZ, Z → bZ, Z → ┴}. Входной символ_ Состояние a S A A A Z b ┴ Z Z допуск Автоматный язык с несколькими видами цепочек и с символом-ограничителем Дана автоматная грамматика, порождающая цепочки нескольких видов, в конце которых имеется символ-ограничитель. В грамматике для каждого вида цепочек должен быть предусмотрен отдельный заключительный нетерминал. Пример 1: Грамматика, порождающая цепочки: • имена (идентификаторы языков программирования); • целые числа без знака; • числа с десятичной точкой без знака. Для сокращения записи вместо отдельных цифр 0,1,. . .,9 будем писать <ц>, а вместо отдельных букв A,B,. . .,Z будем писать <б>. Символ «точка» запишем в кавычках: «.». Правила грамматики: {S → <б>I, S → <ц>C, I → <б>I, I → <ц>I, I → ┴, C → <ц>C, C → «.»D, C → ┴ , D → <ц>E, E → <ц>E, E → ┴}. Заключительные нетерминалы: I, C, E. Конечный автомат с семантическими программами Кроме перехода в новое состояние в конечном автомате на каждом шаге можно предусмотреть дополнительные действия (семантические программы). Номера программ указываются в клетках матрицы переходов. Пример 1. Входной символ_ Состояние <б> <ц> S I/1 C/2 I I/3 I/3 C C/4 D E/6 E E/6 «.» ┴ имя D/5 цел.число вещ.число Семантические программы Пример 1. C[i] – текущий входной символ; name – символьная строка; n – целочисленная переменная; x, d – вещественные переменные. 1. name := C[i]; 2. n := ord(C[i]) – ord(’0’) ; 3. name := name + C[i]; 4. n := n * 10 + ord(C[i]) – ord(’0’); 5. d := 1; x := n; 6. d := d * 0.1; x := x + (ord(C[i]) – ord(’0’)) * d; Автоматный язык с последовательностью цепочек нескольких видов Дана автоматная грамматика, порождающая последовательность цепочек нескольких видов, разделенных одним или несколькими разделителями, в конце имеется символ-ограничитель. Пример 2. Грамматика, порождающая цепочку, в которую входят имена, целые числа без знака, числа с десятичной точкой без знака и пробелы, как символы-разделители . Обозначения: <ц> – цифра, <б> – буква, «.» – точка, « » – пробел, ┴ – концевой ограничитель. Правила грамматики: {S → <б>I, S → <ц>C, S → « »S, S → ┴ , I → <б>I, I → <ц>I, I → « »S, I → ┴, C → <ц>C, C → «.»D, C → « »S, C → ┴ , D → <ц>E, E → <ц>E, E → « »S, E → ┴}. Пример 2: Конечный автомат с семантическими программами Семантические программы в автомате формируют имена, целые и вещественные числа и запоминают их в соответствующих массивах. Входной символ_ Состояние <б> <ц> S I «.» «» ┴ I/1 C/2 S выход I/3 I/3 S/7 выход / 7 C C/4 D/5 S/8 выход / 8 D E/6 E E/6 S/9 выход / 9 Семантические программы Пример 2. C[i] – текущий входной символ; name – символьная строка; n – целочисленная переменная; x, d – вещественные переменные. Массивы для запоминания и их размеры: ID – для символьных строк, nid – их количество; IN – для целых чисел, nin – их количество; RN – для вещественных чисел, nrn – их количество; 0. nid := 0; nin := 0; nrn := 0; {программа выполняется перед работой конечного автомата} 1. name := C[i]; 2. n := ord(C[i]) – ord(’0’) ; 3. name := name + C[i]; 4. n := n * 10 + ord(C[i]) – ord(’0’); 5. d := 1; x := n; 6. d := d * 0.1; x := x + (ord(C[i]) – ord(’0’)) * d; 7. nid := nid + 1; ID[nid]:= name; 8. nin := nin + 1; IN [nin]:= n; 9. nrn := nrn + 1; RN [nrn]:= x; Лексический анализатор для языка программирования Лексемы, выделяемые лексическим анализатором: • имена (идентификаторы), • ключевые (служебные) слова, • целые числа, • вещественные числа (с десятичной точкой и/или с показателем степени), • символьные строки, • составные символы (:= и др.). Лексемы, пропускаемые лексическим анализатором: • пробелы и символы конца строки, • комментарии. Принципы функционирования лексического анализатора Лексический анализатор реализуется как процедура, вызываемая всякий раз, как требуется из входной строки символов выделить очередную лексему. Пример входа: C – входная строка символов. i – номер текущего входного символа в строке C, с него начинается анализ; после окончания анализа. Начиная с i–го символа могут размещаться пропускаемые лексемы (пробелы и др.), после них начинается распознаваемая лексема. Пример выхода: i – номер символа в строке C, следующего за распознанной лексемой. a – номер распознанной лексемы. name – символьная строка, содержащая имя, если лексема – имя или строка символов. n – значение целого числа, если лексема – целое число. x – значение вещественного числа, если лексема – вещественное число. Пример 3. Анализируемая входная строка символов содержит лексемы: • имена (в том числе те, которые являются служебными словами), • целые числа без знака, • числа с десятичной точкой без знака, • символьные строки в одиночных кавычках, • отдельные символы языка (такие, как +, *, скобки и др.), • составной символ (:=), • пробелы, • комментарии, начинаются символами (/*), заканчиваются символами (*/), • концевой ограничитель, • все другие символы, которые могут встречаться внутри комментария (не символы языка). Обозначения входных символов: <ц> – цифра, <б> – буква, «.» – точка, « » – пробел, <с> – отдельные символы, ┴ – концевой ограничитель, <д> – другие символы (не символы языка). Входной символ_ Состояние <б> <ц> «.» « » : = / * <с> <д> ┴ S I C Z+ S A Z+ K Z+ Z+ Z I I I Z Z Z Z Z Z Z Z C C D Z Z Z Z Z Z Z D E E E Z Z Z Z Z Z Z A Z Z Z Z Z Z+ Z Z Z Z K Z Z Z Z Z Z Z L Z Z L L L L L L L L M L L M L L L L L L S M L L