Синтакса (програмски језици)У рачунарству, синтакса програмског језика представља низ правила која дефинишу комбинацију симбола за које се сматра да дају исправно структуиран документ или фрагмент у траженом програмском језику. Ово се односи на програмске језике, где документ представља изворни код, али и на језике за обележавање, где документ представља податак. Синтакса програмског језика дефинише своју површинску форму.[1] Текстуално базирани програмски језици су базирани на распореду карактера, док су визуелни програмски језици базирани на просторном распореду и вези између симбола (које могу бити текстуалне или графичке природе) апстрактно. За документ који има неисправну синтаксу каже се да има синтаксну грешку. Синтакса (форма) представља супротност семантици. Код обраде програмских језика, обрада семантике генерално долази након обраде синтаксе, али у неким случајевима је неопходна прво обрада семантике за обраду синтаксе. У комапјлеру, синтаксна анализа обухвата предњи крај, док семантичка анализа обухвата задњи крај (и средњи крај, ако представља карактеристичан део). Нивои синтаксеСинтаксе програмских језика су генерално подељене у три нивоа:
Овакво разликовање доводи до модуларитета, дозвољавајући да се сваки ниво обради одвојено, и углавном независно. Прво лексер претвара линеаран распоред карактера у линеарни распоред знакова; ова процедура је позната као "лексичка анализа". Затим парсер претвара линеарни распоред знакова у хијерархијско синтаксно стабло; ова процедура је позната као "рашчлањивање" у генералном смислу. Затим контекстуална анализа открива имена и проверава типове. Овакав модуларитет је понекад могућ, али у многим програмским језицима ранији корак зависи од каснијег корака, нпр. лексер хак у C-у зато што организација знакова зависи од контекста. Чак и у оваквим ситуацијама, синтаксна анализа је често виђена као апроксимација за овакав идеални модел. Рашчлањивање се може поделити у два дела: дрво извођења или "конкретно синтаксно стабло", део који је одређен граматиком, али је генерално гледано превише комплексан за практичну употребу, и апстрактно синтаксно дрво (АСД), које упрошћава ово у употребљиву форму. АСД кораци и кораци семантичке анализе се могу сматрати формом семантичкке анализе, као што је додавање значења и интерпетације синтакси, или алтернативно као нефорамлна, мануелна имплементација синтаксних правила која би се тешко или непријатно описала тј. имплементирала. Нивои углавном одговарају нивоима у хијерархији Чомског. Речи су у регуларним језицима, наведене у лексичкој граматици, која је граматика "Типа-3", дате као регуларни изрази. Фразе су у контекстуално слободним језицима (КСЈ) , или генерално гледано у детерминистички контекстно слободним језицима (ДКСЈ), наведене у фразама структуре граматике, која је "Типа-2", дате као правила у Бакус-Науровој форми (БНФ). Фразе граматике су чешће специфиране у многим ограниченим граматика него у контекстно слободној граматици, како би се лакше анализирале; док се ЛР рашчлањивач може анализирази ДФЦЛ у линеарном времену, једноставни ЛАЛР рашчлањивач и чак једноставнији ЛЛ рашчлањивач су више ефикаснији од ЛР-а, али могу једино анализирази граматику која има ограничена правила. Контекстуална структура се може описати уз помоћ контекстно-сензитивне граматике, и аутоматски анализирати помоћу атрибута граматике (иако се овај корак генерално гледано обавља ручно, преко правила имена резолуције и проверавања типа) и имплементирати преко симболичке табеле која садржи имена и типове.
Примери грешакаКао пример, узећемо, (_ 1 1) lexical error: '_' is not valid (add 1 1 parsing error: missing closing ')' (add 1 x) name error: 'x' is not bound Приметно је да лексер не може да идентификује грешку - све што он зна је да након продуковања знака ЛЕВЕ_ЗАГРАДЕ, '(' остатак програма је неисправан, јер не постоји реч која креће са '_'. У овој фази рашчлањивања, рашчлањивач индетификује "листу" правила производње због '(' знака, и на тај начин се може добити порука која указује на грешку; генерално гледано, она може бити двосмислена. У фази садржаја, симбол 'х' постоји у синтаксном стаблу, али није дефинисан, па саимим тим анализа контекста може дати специфичну грешку. У строго типским прогргамским језицима, типске грешке су такође форме синтаксних грешака које се обично одређују у фази контекстуалне анализе, и ово представља снагу снажног куцања. На пример, следећи пример има неисправну синтаксу Пајтоновог кода (зато што је ово штампарска грешка, тј. тип који се може утврдити у фази рашчлањивања): 'a' + 1 ... јер сабира стринг са бројем. Ово се може детектовати у фази анализе ако постоје одвојена правила за "стринг + стринг" и "број + број", али ово ће чешће бити анализирано од стране генералног правила као што је "Књижевно или индетификовано + књижевно или идентификовано" и на тај начин ће грешка бити детектована у фази контекстуалне анализе, где се налази типска провера. У неким случајевима провера није могућа, и овакве синтаксне грешке се могу открити само при покретању програма
a + b је двосислен, и иако овај код има исправну синтаксу у периоду анализе, валидност синтаксе се може утврдити само при покретању кода, зато што променљиве немају тип у Пајтону, већ их само вредности имају. Дефиниција синтаксеСинтакса текстуалних програмских језика се обинчно дефинише коришћењем комбинације регуларних израза (за лексичку структуру) и Бакус-Наурове форме (за граматичку структуру) за идуктивно одређивање синтаксних категорија (нетерминали) и терминалских симбола. Синтаксне категорије су дефинисане правилима која се називају продукције, које специфирају вредност која припада синтаксној категорији.[1] Терминалски симболи су конкретни карактери или стрингови карактера (на пример кључна реч као што је дефиниши, ако, дозволи, или поништити) од којих су синтаксно исправни програми направљени. Програмски језик мора имати више различитих и једнаких граматика, као што су регуларни једнаки изрази (на лексичким нивоима), или различита правила анализирања која генеришу исти језик. Користећи ширу категорију граматика, као што је ЛР граматика, дозвољено је поређење мањих или једноставнијих граматика са више ограничених категорија, као што је ЛЛ граматика, која захтева дужу граматику са више правила. Различита али једнака фраза граматике даје различита стабла анализирања, иако је основни језик (низ исправних докумената) исти.
Пример: LispИспод је приказана једноставна граматика, дефинисана користећи нотацију регуларних израза и Бакус-Наурове форме. Она описује Lisp-ову синтаксу, која дефинише продукте синтатичких категорија израза (expression), атома (atom), броја (number), симбола (symbol), и листе (list): expression ::= atom | list
atom ::= number | symbol
number ::= [+-]?['0'-'9']+
symbol ::= ['A'-'Z''a'-'z'].*
list ::= '(' expression* ')'
Ова граматика дефинише следеће:
Децимални бројеви, карактери малих и великих слова, и заграде представљају симболе терминала. Следе примери добро формираних знакова у овој граматици : ' Комплексна граматикаГраматика мора спецификовати програмски језик који се може класификовати према својој позицији у хијерархији Чомског. Фразна граматика већине програмских језика се може спецификовати користећи "Тип-2" граматику, тј. они су контекстно слободне граматике,[2] иако је целокупни садржај синтаксе осетљив (због декларације променљивих и оквира програма), па отуда следи "Тип-1". Међутим, постоје изузеци, па је за неке програмске језике фразна граматика "Типа-0" (Тјуринг-комплетни програми). У неким језицима као што су на пример Перл и Lisp, спецификацију (или имплементацију) програмског језика омогућава конструкција која се извршава током фазе рашчлањавања. Осим тога, ови програмски језици имају конструкторе који дозвољавају програмеру да промни ток понашања рашлчањивања. Ова комбинација ефективно замагљује разлике између рашчлањивања и извршавања, и чини анализу синтаксне анализе неодлучивим проблемом у поменутим програмским језицима, мислећи на то да се фаза рашчлањавања можда није завршила. На пирмер, у Перлу је могуће извршавати код током фазе рашчлањивања користећи Синтакса у односу на семантикуСинтакса програмског језика описује форму исправности програма, али не даје никакве информације о значењу програма или разултатима извршавања програма. Значење дате комбинације симбола зависи од семантике (било да је формална и тешко кодирана у референтној имплементацији), тј. семантика управља значењем комбинације симбола. Нису сви синтатички исправни програми и семантички исправни. Многи синтатички исправни програми су ипак лоше формирани, и зависе од правила програмског језика; и могу (у зависности од спецификације програма и врсте имплементације) да дају резултат као грешку у преводу или извршавању. У посебним случајевима, такви програми могу да испоље недефинисано понашање. Чак и када је програм добро дефинисан и осмишљен у оквиру језика, ипак може имати супротно значење од оног значења које је програмер хтео да програм има. Коришћењем природног језика као један пример, можда неће бити могуће доделити значење граматички коректним реченицама или реченицама које су можда неисправне:
Следећи C код је синтатички исправан, али обавља операцију која није семантички дефинисана (зато што је "п (p)" нулти показивач, а операције "p->real" и "p->im" немају значење): complex *p = NULL;
complex abs_p = sqrt (p->real * p->real + p->im * p->im);
Још више поједностављено: int x;
printf("%d", x);
је синтатички исправан, али семантички неисправан код, јер користи неозначену променљиву. Види јошБрзо поређење синтакси у различитим програмским језицима. Можете погледати листу "Здраво, свете!". Ево неколико примера:
Референце
Спољашње везе
|