Приведенные грамматики Приведенные грамматики — это КС-грамматики, которые не содержат недостижимых и бесплодных символов, циклов и -правил («пустых» правил). Приведенные грамматики называют также КС-грамматиками в каноническом виде. Для того чтобы преобразовать произвольную КС-грамматику к приведенному виду, необходимо выполнить следующие действия: удалить все бесплодные символы; удалить все недостижимые символы; удалить -правила; удалить цепные правила. Следует подчеркнуть, что шаги преобразования должны выполняться именно в указанном порядке, и никак иначе. Преобразования грамматик В некоторых случаях КС-грамматика может содержать недостижимые и бесплодные символы, которые не участвуют в порождении цепочек языка и поэтому могут быть удалены из грамматики. Определение: символ A VN называется бесплодным в грамматике G = (VT, VN, P, S), если множество { | VT*, A } пусто. Алгоритм удаления бесплодных символов: Вход: КС-грамматика G = (VT, VN, P, S). Выход: КС-грамматика G’ = (VT, VN’, P’, S), не содержащая бесплодных символов, для которой L(G) = L(G’). Метод: Рекурсивно строим множества N0, N1, ... 1. N0 = , i = 1. 2. Ni = {A | (A ) P и (Ni-1 VT)*} Ni-1. 3. Если Ni Ni-1, то i = i+1 и переходим к шагу 2, иначе VN’ = Ni; P’ состоит из правил множества P, содержащих только символы из VN’ VT; G’ = (VT, VN’, P’, S). Определение: символ x (VT VN) называется недостижимым в грамматике G = (VT, VN, P, S), если он не появляется ни в одной сентенциальной форме этой грамматики. Алгоритм удаления недостижимых символов: Вход: КС-грамматика G = (VT, VN, P, S) Выход: КС-грамматика G’ = (VT’, VN’, P’, S), не содержащая недостижимых символов, для которой L(G) = L(G’). Метод: 1. V0 = {S}; i = 1. 2. Vi = {x | x (VT VN), (A x) P и A Vi-1} Vi-1. 3. Если Vi Vi-1, то i = i+1 и переходим к шагу 2, иначе VN’ = Vi VN; VT’ = Vi VT; P’ состоит из правил множества P, содержащих только символы из Vi; G’ = (VT’, VN’, P’, S). Определение: КС-грамматика G недостижимых и бесплодных символов. Алгоритм приведения грамматики: называется приведенной, если в ней нет (1) обнаруживаются и удаляются все бесплодные нетерминалы. (2) обнаруживаются и удаляются все недостижимые символы. Удаление символов сопровождается удалением правил вывода, содержащих эти символы. Замечание: если в этом алгоритме переставить шаги (1) и (2), то не всегда результатом будет приведенная грамматика. Для описания синтаксиса языков программирования однозначные приведенные КС-грамматики. стараются использовать Исключение цепных правил Определение. Правило грамматики вида A B, где A,B VN, называется цепным. Утверждение. Для КС-грамматики G, содержащей цепные правила , можно построить эквивалентную ей грамматику G', не содержащую цепных правил. Идея доказательства заключается в следующем. Если грамматика G имеет правила A B, B C, C aX, то такие правила могут быть заменены одним правилом А aX, поскольку вывод A B C aX цепочки aX в грамматике G может быть получен в грамматике G' с помощью правила A aX. В общем случае доказательство последнего утверждения можно выполнить так. Разобьем множество правил P грамматики G на два подмножества P1 и P2, включая в P1 все правила вида A B. Для каждого правила из P1 найдем множество правил S(Ai), которые строятся так: если Ai * Aj и в P2 есть правило Aj , где - цепочка словаря (VN VT)*, то в S(Ai) включим правило Ai . Построим новое множество правил P’ путем объединения правил P2 и всех построенных множеств S(Ai). Получим грамматику G' = {VN ,VT , P’, S}, которая эквивалентна заданной и не содержит правил вида A B. В качестве примера выполним исключение цепных правил из грамматики G : G = ({+,*,(,),a}, {E,T,F}, P={E E+T | T, T T*F | F, F (E) | a}, E). Вначале разобьем правила грамматики на два подмножества: P1 = {E T, T F} , P2 = {E E+T, T T*F, F (E) | a } Для каждого правила из P1 построим соответствующее подмножество. S(E) = { E T*F, E (E) | a }, S(T) = { T (E) | a} В результате получаем искомое множество правил грамматики без цепных правил в виде: P2 U S(E) U S(T) = { E T+T | T*F | (E) | a, T T*F | (E) | a, F (E) | a } Преобразование неукорачивающих грамматик Последний вид рассматриваемых преобразований связан с удалением из грамматики правил с пустой правой частью. Определение. Правило вида A называется «пустым» (аннулирующим) правилом. Определение. Грамматика называется неукорачивающей или грамматикой без «пустых» правил, если либо 1)схема грамматики не содержит аннулирующих правил, 2)либо схема грамматики содержит только одно правило вида S , где S - начальный символ грамматики, и символ S не встречается в правых частях остальных правил грамматики. Для грамматик, утверждение. содержащих аннулирующие правила, справедливо следующее Утверждение. Для каждой КС-грамматики G', содержащей аннулирующие правила, можно построить эквивалентную ей неукорачивающую грамматику G, такую что L(G')=L(G). Построение неукорачивающей грамматики приведет к увеличению числа правил заданной грамматики из-за построения дополнительных правил, получаемых в результате исключения нетерминалов аннулирующих правил. Чтобы построить дополнительные правила необходимо выполнить все возможные подстановки пустой цепочки вместо аннулирующего нетерминала во все правила грамматики. Если же в грамматике есть правило вида S , где S – начальный символ грамматики, и символ S входит в правые части других правил грамматики, то следует ввести новый начальный символ S’ и заменить правило S двумя новыми правилами: S' и S' S. В качестве иллюстрации способа построения неукорачивающих грамматик, исключим аннулирующие правила из следующей грамматики: G ({a,b}, {S}, P = { S aSbS, S bSaS, S }, S). Выполняя все возможные замены символа S в первом правиле грамматики, получаем четыре правила вида: S aSbS, S abS, S aSb, S ab . Поступая аналогично со вторым правилом, имеем: S bSaS, S baS, S bSa, S ba. Учитывая, что начальный символ, образующий аннулирующее правило, входит в правые части других правил грамматики, заменим правило S правилами вида S' и S' S. Построенная совокупность неукорачивающей грамматики. правил образует множество правил искомой S' S | S aSbS | abS | aSb | ab | bSaS |baS | bSa | ba Все приведенные выше преобразования грамматик могут быть использованы при построении как конечных, так и магазинных автоматов. КС-грамматики в нормальной форме Грамматики в нормальной форме Хомского Нормальная форма Хомского или бинарная нормальная форма (БНФ) — это одна из предопределенных форм для правил КС-грамматики. В нормальную форму Хомского можно преобразовать любую произвольную КС-грамматику. Для преобразования в нормальную форму Хомского предварительно грамматику надо преобразовать в приведенный вид. Определение нормальной формы Хомского КС-грамматика G(VT,VN,P,S) называется грамматикой в нормальной форме Хомского, если в ее множестве правил Р присутствуют только правила следующего вида: 1. А ВС, где A,B,CVN. 2. А а, где AeVN и aVT. 3. S , если L(G), причем S не должно встречаться в правых частях других правил. Никакие другие формы правил не должны встречаться среди правил грамматики в нормальной форме Хомского [6, т. 1, 26]. КС-грамматика в нормальной форме Хомского называется также грамматикой в бинарной нормальной форме (БНФ). Название «бинарная» происходит от того, что на каждом шаге вывода в такой грамматике один нетерминальный символ может быть заменен только на два других нетерминальных символа. Поэтому в дереве вывода грамматики в нормальной форме Хомского каждая вершина либо распадается на две другие вершины (в соответствии с первым видом правил), либо содержит один последующий лист с терминальным символом (в соответствии со вторым видом правил) Третий вид правил введен для того, чтобы к нормальной форме Хомского можно было преобразовывать грамматики КС-языков, содержащих пустые цепочки символов. Алгоритм преобразования грамматики в нормальную форму Хомского Алгоритм позволяет преобразовать произвольную исходную КС-грамматику в эквивалентную грамматику в нормальной форме Хомского. Условие: дана КС-грамматика G(VT,VN,P,S), необходимо построить эквивалентную ей грамматику G'(VT,VN',P',S') в нормальной форме Хомского: L(G) = L(G'). На первом шаге исходную грамматику надо преобразовать к приведенному виду. Поскольку алгоритм преобразования КС-грамматик к приведенному виду был рассмотрен выше, можно считать, что исходная грамматика уже является приведенной (не содержит бесполезных и недостижимых символов, цепных правил и -правил). В начале работы алгоритма преобразования приведенной КС-грамматики в нормальную форму Хомского множество нетерминальных символов VN' результирующей грамматики G' строится на основе множества нетерминальных символов VN исходной грамматики G: VN’ = VN. Затем алгоритм преобразования работает с множеством правил Р исходной грамматики G. Он просматривает все правила из множества Р и в зависимости от вида каждого правила строит множество правил Р' результирующей грамматики G' и дополняет множество нетерминальных символов этой грамматики VN'. 1. Если встречается правило вида Аа, где AVN и aVT, то оно переносится во множество Р' без изменений. 2. Если встречается правило вида АВС, где A,B,CVN, то оно переносится во множество Р' без изменений. 3. Если встречается правило вида S, где S — целевой символ грамматики G, то оно переносится во множество Р' без изменений. 4. Если встречается правило вида АаВ, где A,BVN и aVT, то во множество правил Р' включаются правила А<АаВ>В и <АаВ>а и новый символ <АаВ > добавляется во множество нетерминальных символов VN' грамматики G'. 5. Если встречается правило вида АВа, где A.BVN и aVT, то во множество правил Р' включаются правила АВ<АВа> и <АВа>а, и новый символ <АВа> добавляется во множество нетерминальных символов VN' грамматики G'. 6. Если встречается правило вида АаЬ, где A VN и a,bVT, то во множество правил Р' включаются правила А<Аа><АЬ>, <Аа>а и <Ab>b, новые символы <Аа> и <АЬ> добавляются во множество нетерминальных символов VN' грамматики G'. 7. Если встречается правило вида AX1...Xk, k>2, где AVN и i: XiVTVN, то во множество правил Р' включается цепочка правил: А <X1’><X2...Xk> <X2...Xk> <X2’><X3...Xk> <Xk-1Xk> <Xk-1’><Xk> новые нетерминальные символы <Х2...Хk>, <Х3...Хk);>,..., <Xk-1,Xk> включаются во множество нетерминальных символов VN' грамматики G', кроме того, i: если XiVN, то <Хi'>Хi иначе (если XiVT) <Xi'> — это новый нетерминальный символ, он добавляется во множество VN', а во множество правил Р' грамматики G' добавляется правило <Хi'> Xi . Целевым символом результирующей грамматики G' является целевой символ исходной грамматики G. Пример преобразования грамматики в нормальную форму Хомского Рассмотрим в качестве примера грамматику G({a,b.c}.{A,B,C,S},P,S) Р: S АаВ | Аа | be А АВ | а | аС В Ва | b С АВ | с Эта грамматика уже находится в приведенной форме. Построим эквивалентную ей грамматику G'(VT,VN',P',S ) в нормальной форме Хомского. Начнем построение с множества нетерминальных символов новой грамматики: VN' = {A,B,C,S}. Множество еще будет дополняться в процессе работы алгоритма. Начнем разбирать правила этой грамматики. Первое правило исходной грамматики SAaB подпадает под 7-й вариант работы алгоритма. В соответствии с требованиями алгоритма заменяем его на последовательность: S <A'><aB> <aB> <а'><В'> Поскольку А и В — нетерминальные символы, а «а» — терминальный символ, то получаем, что <А'>А и <В'>В, а новое правило <а'>->а должно быть добавлено во множество правил Р' новой грамматики. Получаем последовательность правил: S А <аВ> <аВ> <а'>В <а'> а Во множество нетерминальных символов VN' новой грамматики необходимо добавить новые символы <аВ> и <а'>. Получаем VN' = {A,B,C,S,<aB>,<a'>}. Второе правило исходной грамматики S Aa подпадает под 5-й вариант работы алгоритма. Заменяем его на два правила: S A<SAa> <SAa> а Новый символ <SAa> добавляется во множество нетерминальных символов новой грамматики. Получаем VN' = {A,B,C,S,<aB>,<a'>,<SAa>}. Третье правило исходной грамматики S bc подпадает под 6-й вариант работы алгоритма. Заменяем его на три правила: S <Sb><Sc> <Sb> b <Sc> с Новые символы <Sb> и <Sc> добавляются во множество нетерминальных символов новой грамматики. Получаем VN' = {A,B>C,S,<aB>,<a'>,<SAa>,<Sb>,<Sc>}. Четвертое правило исходной грамматики А АВ подпадает под 2-й вариант работы алгоритма. Переносим его во множество правил новой грамматики без изменений. Пятое правило исходной грамматики А а подпадает под 1-й вариант работы алгоритма. Переносим его во множество правил новой грамматики без изменений. Шестое правило исходной грамматики А аС подпадает под 4-й вариант работы алгоритма. Заменяем его на два правила: А <АаС>С <АаС> а Новый символ <АаС> добавляется во множество нетерминальных символов новой грамматики. Получаем VN' = {A,B,C,S,<aB>,<a'>,<SAa>,<Sb>,<Sc>,<AaC>}. Седьмое правило исходной грамматики В Ва подпадает под 5-й вариант работы алгоритма. Заменяем его на два правила: В В<ВВа> <ВВа> а Новый символ <ВВа> добавляется во множество нетерминальных символов новой грамматики. Получаем VN' = {A,B,C,S,<aB>,<a'>,<SAa>,<Sb>,<Sc>,<AaC>, <ВВа>}. Восьмое правило исходной грамматики B b подпадает под 1-й вариант работы алгоритма. Переносим его во множество правил новой грамматики без изменений. Девятое правило исходной грамматики С->АВ подпадает под 2-й вариант работы алгоритма. Переносим его во множество правил новой грамматики без изменений. Десятое правило исходной грамматики С-»с подпадает под 1-й вариант работы алгоритма. Переносим его во множество правил новой грамматики без изменений. Рассмотрение множества правил исходной грамматики закончено. Множество правил Р' новой грамматики G' и множество нетерминальных символов VN' этой грамматики окончательно построены. Целевым символом новой грамматики является символ S. Получаем новую грамматику в нормальной форме Хомского, эквивалентную исходной: G'({a,b,c},{A,B,C,S,<aB>,<a'>,<SAa>,<Sb>,<Sc>,<AaC>,<BBa>}, P', S): Р': S А<аВ> | A<SAa> | <Sb><Sc> <аВ> <а'>В <а'> а <SAa> a <Sb> b <Sc> с А АВ | а | <АаC>C <АаC> а В В<ВВа> | b <ВВа> а С АВ | с Видно, что при приведении грамматики к нормальной форме Хомского количество правил и нетерминальных символов в грамматике увеличивается. При этом врастет объем грамматики и несколько затрудняется ее восприятие человеком. Однако цель преобразования — не упрощение грамматики, а упрощение построения распознавателя языка на ее основе. Именно этой цели и служит нормальная форма Хомского. Далее будут рассмотрены методы построения распознавателей, в основе которых лежит именно эта форма представления грамматики КС-языка. Левая рекурсия в КС-грамматиках. Алгоритм устранения левой рекурсии из правил грамматики. Определение. Правило вида A A , где A VN , (VT VN) праворекурсивным, а правило вида A A - леворекурсивным. * , называется Утверждение. Для каждой КС-грамматики G, содержащей леворекурсивные правила, можно построить эквивалентную грамматику G', не содержащую леворекурсивных правил. Способ построения эквивалентной грамматики заключается в следующем. Допустим, что исходная грамматика G содержит правила: A A1 | A2 | ... |Am| 1 | 2 | … | n, где ни одна цепочка не начинается с A и i i (VT VN)* . Введем новый нетерминал <A'> и преобразуем правила так: A 1 | 2 |...| n | 1<A'> | 2<A'>|...| n<A'>, <A'> 1 | 2 |...| m| 1<A'> |2<A'>|...|m<A'>. Заменяя все правила с левой рекурсией в G описанным способом, получим грамматику G', причем L(G)=L(G') , поскольку каждая цепочка, выведенная в грамматике G, может быть построена в грамматике G'. Рассмотрим построение выводов в G и G'. В грамматике G вывод цепочки имеет вид: A A1 A11 A111 1111, в грамматике G' эта же цепочка выводится так: A 1<A'> 11<A'> 111<A'> 1111. Чтобы показать технику преобразования, рассмотрим преобразовать грамматику G (рассмотренную ранее), с правилами: пример. Требуется P: EE+T|T TT*F|F F (E) | a Следуя описанному способу, правила E E + T | T преобразуем в правила E T | TE' и E' +T | +TE' , а правила T T * F | F преобразуем в правила T F | FT' и T' F | * FT'. В результате получаем грамматику G' с правилами: P': ET E TE' E' + T E' + TE' TF T FT' T' * F T' * FT' F a F (E) не содержащую леворекурсивных правил. Грамматики в нормальной форме Грейбах На основании грамматики, в которой исключена левая рекурсия, можно построить грамматику в нормальной форме Грейбах. КС-грамматика G(VT,VN,P,S) называется грамматикой в нормальной форме Грейбах, если она не является леворекурсивной и в ее множестве правил Р присутствуют только правила следующего вида: А а, где aVT и VN*. 2. S , если L(G), причем S не должно встречаться в правых частях других правил. 1. Никакие другие формы правил не должны встречаться среди правил грамматики в нормальной форме Грейбах. Нормальная форма Грейбах является удобной формой представления грамматик для построения нисходящих левосторонних распознавателей (в тех случаях, когда присутствие левой рекурсии в правилах грамматики недопустимо). Подробнее с нею можно познакомиться в [6, т. 1, 26].