Искусство программирования на Си (984073), страница 63
Текст из файла (страница 63)
за и тельные темами чеекие разделы С'инзлпкеичеекий аназиз иннин<ление «ыразкеннй Часть!П рйупгахА1С = РБупгахйеаб->уугяСЫСегпаге[ яггсру(КооС1пейавеТаЫе[3).яйавеВобу,"депб1исбе"); йооЫпенавеТаЫе(3].ВобуКоогкпе = депб1ч]без зА1С = 0; мЫ1е ((РЯупгахй]С[=НОВЫ ЬЬ ( ЫС<10]) яггсру(йоогспейавеТаЫе[4).яйавеВобу,"депвобо1пя"); ( йопгзпейаиеТаЫе[4].Вобуйопгзпе = депвобо1пяз яггсру(йопС1пейавеТаЫе[5).яйавеВобу, депво11 ]; 1А1Сез; ргзпС(( Бгагг о1 а11егпаге зсрз",ряупгахА1С); КооЫпейавеТаЫе[5).вобукопЫпе = деп1С; яггсру(йоогзпейавеТаЫе[б).яйаиеВобу,"деп1е"); рг1пСЕ(" А1Сегпаге соопгег зСбз1п", йопгзпейавеТаЫе[б).ВобуйопЫпе = деп1е; РБупгахА1С->зй1СегпагеНовЬег); яггсру(йооСзпейавеТаЫе[7).яйавеВобу, депдС )7 рг1пСГ(" ЯупСах Соппгег гп А1Сегпаге зсбз1п", йопС1пейаиеТаЫе(7].Вобуйопгзпе = депдС; ряупгахА11->1ЯупСахйшяЬег); яггсру (КооЫпейавеТаЫе [ 8] .
яйавеВобу, "Бенде ) [ Ргспгу( Вобу рокпгег зп А1Сегпаге зсрзсп" йопЫпейавеТаЫе(8).ВобуНопгспе = депде; ряупгахЫС->ТЫяВобу); яггсру(йопггпейаиеТаЫе[9].яйавеВобу,"делец ); /* Провервть в цакпе все альтераатнвм данного головного элемента сннтаксвса */ КооСкпейаветаЫе[9).Вобуйооггпе = делец[ /* провервть в цвкле ясе осноаеме эпементм для данной альтернатнвм */ яСгсру(йопгспейаветаЫе[10].яйавеВобу,"деппе"); РЯУпгахВ<н[у = РЯупгахА1С->ТЫяВобу; йоосзпенаветаые(10).Вобукопсзпе = деппе; кВобу = 0; яггсру(йопгспейаветаЬ1е( 11).яйавейобу,"депАНО"); мЫ1е ((РБупсахВобу(=НОВО) ьь (зВобу<20)) КопСзпейаветаЫе[11).ВобуКопЫпе = депАНО; ( яггсру(йолгспейаиетаЫе[ 12).яйаиевобу,"допой ); ргзпСУ(" Бгагг ос Ьобу зсрз ,РБупгахВобу); КоогзпейавеТаЫе(12].Вобуйопгзпе = депой; яггсру(КооСзпейавеТаЫе(13).яйаиеВобу, депХОК")1 рагепС а1С зьрз)п',РБупгахйобу->рагелСА1С); КопС1пейавеТаЫе[ 13].Вобуйоогспе = депХОК; Ланалнитслтыс та натинсп иг раз дслы С шт~акс и кс кии ан а на и сын ислс кис нырахксиии Часть 1и Глава 10 Полная версия Бегирйонг(пейявея ( ) 91оЬЬаЬе1 = 01 Теперь, когда известно, каким образом люжет быть выполнен синтаксический ацазиз выражения, осталось рассмотреть еше два следующих вопроса: как сделать синтаксический анализ эффективным и что можно Ьвоодвупса» = йеаевупгах ( ярйооГБупгах ) 11приГР(1е = горев(я1приеу(1еваве,"г")1 хЕ (11пригг(1е==МОЬЫ ( СС[ЕПГ([)ЕГ:(Лт 1Е!СЕГ [С[ЕППГ)ССГ-гаС[ 0 СС[ЕП1(([ЕГ-гаС[ ((ЕХ[С[гаС1) Зт [ЕПЕГ СС(СПП[)ЕГ-1а(1 [ С[1011 сформировать в качестве выходного результата сепг((1 ег-1а11 [ Сс[еппрсег-[а[1 [ етрсу Ф хееаЬпя = ЕХЕТ РАЕЬООЕ Эффектность синтаксического аназиза в данном слуааа[гсге-схргезгсоп зт ти пр слог[не-гхрсезггап а [ггие- А11егпаеетаЫе[0).рй11егпатеро(пеег = МОЬЬЕ А1гегпаееуаЫе[0[.(БупгахйнвЬег = 0; А11егпяеетяЫе[0[.ЕБГяггяи1ГЬ 0; А1хегпяеетаЫе[0[.(ииягсопеаьп = 0; рйоогвупьях = МОЬЬ; Рйоогвагее = МОЬЬ; Ееупеахухье = МОЬ(Ы яггсру(явупеахРЕ(емяве,"Бупгах.гхг")1 11пригг(1е = МОЬЬ; яегсру(я1приЕР11енаве, "Тея11прие.ахе ); ЕпигригР11е = МОЬЬ; яегсру(яоигриеу(1ейаве,"Оепегяееаеоде.гхе') В листинге 19.2 приведен основной код синтаксического анализатора.
Бшссс подробные комментарии к нему даны в файлах СЫ9Рагя.с и СЫ9Рагя.Ь, находяшихся на нгеЬ-сайте "ДиаСофт". Этому коду может потребоваться много времени для обнаружения ошибки во входных данных, а также для поиска правильного пути синтаксического анализа правильных входных данных. В нем нс используются таблицы "Должно содержать" и "С чего начинается".
Добавить соответств> юший код вам будет нетрудно. Возможно, полезным окажется также введение лругих сокращенных процедур, вызываемых во время синтаксического анализа. Они могут быть указаны в круглых скобках (например, (ланге)), однако такой способ злесь не демонстрируется. Подобные процелуры могут быть использованы в обход обычного синтаксического аназнза в особых местах синтаксиса, тле не грсбуется применять в полную силу обычные возможности Гюлее медлительного синтаксического анализатора.
Такую возможность следует рассматривать толька в том случае, если время выполнения кола синтаксического анняизатора играет первостепенную роль. Таким образом, можно было бы получить слслуюшин синтаксис Лопокиипигниие темпмичл к не(кги)ти С иитпксическии антики кичитение пиромкнио Часть и! Глава 19 Й Йдр(/раей(Я((/лб(м '0" ! "«" ! '2"! '3"! '4"! '5" ! 'б" ! '7" едиа(йу-ехргетап х= ге(алана(-ехргеьяап ! едиаЯ(у- элсмента /(аа((п№-саг(ьгап( (т.е. (телег-рал (лепик чисть/) рованис соответствуюшсго кода.
При этом осушсстачя- ! '8" ! '9" № ехргеьяал "==" ге(алана(-ехргетап /яепед/ ! едиаЯ(у- может быть подобна элементу lте№ег-салман(, поиск ется просмотр дерева синтаксического анализа и приюта — (ЯК /рагас(а): .:= ' (ч(' / ( (/:Я(м '0" ! '1" ! 2" ! '3" ! '4" ! '5" ! ехргся(ап "!="ге(аяана(-ехргея|ап /лег(пе/ № этой цары лексических элементов должен выполняют- менение оверац«зй генерирования кода в порядке слс'б " ! '7 " ! 'В " ! '9" № ,«д(Р - ..
(. ~(дР .. ся в следующем порядке:/(аа((пе-салыап(, а затем т(ееег- дования обратной польской нотации. Действия А/(Р-ехргеььюп хм едии(пу-ехрггяюп ! А/чР-екргетап сапяат. Этот синтаксис был изменен таким образом, различных цроцелур описаны в табл. «9.4. ариола(-и<!а(-ЙЯ(( хм акга(-г(1№1( ! етр(г № ск едиа(№>'-ехргеьь(ои /№епАЛ'Р/ № чтобы отразить наличие двух разных видов элемента Привеленный в табл.
«9.4 код не столь эффективен Ьех-ЙЯК х= йр( ! иррег.йех-г((ХЯ ! (аиег-№ех-Йрр( ! ехс(иьпе-ОЯ-ех итал к=А(чР-ех гетин екс(иыое-ОЯ- (п(ееег-саг(ыаис того, что используется в лексическом по сравнению с тем кодом, который может быть сгснсиррегйек-г((е(( хм "А" ! 'В" ! 'С" ! 'В" ! 'Е" ! 'Е" № скргея(ап " "А)ч'Р-ех геяюп 1 епХОЯ/ № р "" —.р ' /я ( анализе, и того, что лежит в основе лругого опрелеле- рирован. Например, в окончательной последовательно-№ -№ = ъ"! ь ! - -! й-! "! т" № тс(илье-ОК-екргеьяап с:= ехсlияие-ОЯ-екргеьяап ! ния «(пгеяег-сапыап(/ч(), для которого лексический ана- сти может неоднократно встретиться слслуюшая цара тсlиьте- ОЯ-ехргеяюп "! ехс(илье-ОК-ехргея(ап /№епОК/ лиз не требуется.
команл. еьсирейг№агасгег /(екеьггЬаг/ пбс= !" еьеаре-ьедиепге № еяареьедиепсе х= "л" ! ч "! 9" ! б" ! '«'" ! '««" ! "а" ! 'чч" ! (а№(са(А(чРехргеьыап ' =- тг(иь(пе-Ояекргеьыал Строгие правила языка С '. "! ""! с(а -дя(ариола( ас(а(-№1№1(ар(а (-ос(а(-Йяа (а№(са(-А/чР-екргеьыап "кд&" тс(иь(ие-Оя-ехргеьыал Различные процедуры, имена которых теперь обозначе! 'х" №ех-ЙЯ(( Лек-Й«р( № которая всегда может быть оптимизирована. Этого мож/Яеп/А/и'Р/ № иы в синтаксисе, должны быль известны си(паксичсс- но добиться бла(одаря ор«аннзации простого взаимолей(п(е№ег-сапа(апг /(ехт(сал) иб(м с((Я(( т(е№ег-са(ц(аг№ ! ЙЯ(( № (а№(са(-ОК-ехргеьыал -= (а (га(-Аяр-ех гея!ап ! ( (ги(- ком> анализатору.
По мере загрузки синтаксического ствия между цроцсд>рами генерирования кода либо Раапп№-сапяап( /(ех/(рспп):(..= т(е№еграг(/юг(юп-рал ОК-екргеьяап ''!!" (а№гса(-АМР-екргетап/лег(/ОЯ/ № второго прохода сгенерированного кода, при котором Е- а(т ех апеп( г- аг( № известным списком, а затем в синтаксичсском лерсве екргеяlап с= (а№(са(-ОЯ-екргеьь(оп № удаляются лишнис кодовые пары.
В настояших комвиппе№ег-<аляап(/чЕ х= ЙГР( (п(е№ег-сапяап( ! Йбд( № размешаются указатели на реазьные процедуры. Если ляторах выполняется нс только это, но и оптимизация Приведенные выше онрелеления классов (слег /буку- нроцсдура неизвестна, тогда может быть выдано сооб- Доош~штетиые тоиотичесииерок)елы Часть И! Таблица 19.Я. Процедуры генерирования кода. ) еаве Процедура генерирования кода Действие Описание ( *рррагвеВобу = ('ррРагвевобу)->Нехарагве! Х[депк)] А! = х;в1аси[!пбех++] = Я1; Загрузит~ содержимое идентификатора в регистр ) А1 и поместить его в стек 11(( рруагвевобу)1=аойй) Х[двпсоп51] А! = х;в!ась[!пбехч- ь] =. А1; Загрузить константу в регистр А) и поместить ее в ( *РРРагвеВеаб = (*рррагвевобу)->Рагепсрагве! [депр!изрыв] А1 = в1аск[!лбах-Н-];А2 = 1;А1 = Прибавить 1 к верхнему элементу стека ) = А! + А2;в1аск[!пбех+ ь] =.
Я1; ( [деппкпивгпкюв] А! = ваагн[~пбех-];А2 = 1;А1 = Вычесть 1 из верхнего элемента стека РРРагвеэеаб = Ээйй! = А1 — А2;в(ась[!пбехч ь] = А1; ) [цепгпигар1у] А! =- в1асарпбех-);А2 = Умножить два верхних элемента стека. Этот код = в1аси[юбех-];А! = А! ' А2, весьма похож на код других арифметических ) операций. Так, для выполнения операций [цепабб], [цепвисв1пзст] и [деппюби1ив] над одним символом гпт депсоврагзвоп ( сваг* рвхооврагааог ) достаточно заменить команду в(асх[!пбех-и-] = А! ( упс (заасив = РВОВ! [цеп)1] Ат = в!зги[~паек-];А2 = Определить, является ли один элемент стека = в1асх[!пбех — ];б(А! < А2) цо1о меньше другого.
Следует заметить, что другие М2;А1 = 0;цо1о с2;М2:А! =. 1;с2: огерации сравнения — [цепц(], [цеп(е], [цепец] и [делив] — выполняются аналогичным образом для гргупсг(гоцгроау(1е, "гзе (А1 ав А2) восо В14. 4б;ал, Сино окситской оно сиз и вычисление торо осеоий Глава 19 Дыеамите нные меиаминеемееяаздееы Щ~— Часть П! Резюме В ЭТОЙ ГЛАВЕ В этой главе была рассмотрена альтернативная (и более старая) форма БНФ, а также были показаны некоторые се расширения, способствуюшис созданию более эффек- тивных синтаксических выражений. Ричард Хэзфилд ° Характеристики хоро|них программных средств ° Библиотеки кодов ° Фильтры и инструменты обшего применения ° Автомагическос генерирование тестовых данных ° Генераторы кола Более подробные сведения об обработке ошибок привалены в реколзснловапной выше кншс "Принципы проекепидоваеаея компишепоров "Альфрсла В Ахо и Джеффри Д.
Улльмана. Итак, внимательно пишите код и пользуйтесь синтаксическим анаяизом! Был привелен пример транслятора, который читает синтаксис языка, а затем анализир)ст сто, выдавая выходной семантический результат или с~о интерпретацию. Это один из наиболее распространенных примеров транслятора. И наконец, здесь было показано, что лаже пример кода, приведенный в этой книг, способен анализировать отнюдь не все. Поэтому дальнейшее изучение синтаксического анализа вы, при нсобхолимости, будете осушсствлять самостоятельно. Создание программных инструментальных средств Сутцсствусз три Вида ПрОграММннх иНСтруыентЮП.НЫл ененн деланы ео, что ыаы надо, ыо оы делал лишь то, дпя допатнитольниеыеиатинагкигракусти ь издан г го нрогяоминик ни 1 Масть 1П Я никогла не встречал кого-нибудь, кто бы входил которого рода аргумента командной строки с заданным значение неверно.
Это позволит сэкономить множно ва- ЯИ$дИОтЕКИ КОДО)( в команду программистов конкретно с целью написания по умолчанию значением (например, агйсы=1), при ко- шего врсмени. инструментов для остальной части команды. Но смысл тором бы выводился короткий список инструкций по Повторное нспольювание колов — это обнзаглельное угясен: никто вместо нас не создаст нужные нам инстру- работе с программой. Гибкость ловие 11родуктивного программирования. В простейшслз менты. Насколько это возможно, ориснтируйте программу случае мы снова используем коды каждый раз, когда Чем болсс гибкими ятшяются инструл1снты.