Лексичка анализа е процес во кој некој влез од низа од знаци (на пример изворниот код кај компјутерски програм) да произведе како излез низа од симболи наречени „лексички токени” или само „токени”. На пример, лексерите кај многу програмски јазици низата од знаци 123 abc ја делат на два токена: 123 и abc , празното место не се зема предвид. Целта на создавањето на токените е обично тие да се предадат на друга програма како што е расчленувачот (парсер).
За многу јазици правењето на лексичка анализа може да се направи во едно поминување - со читање на знак по знак од влезот. Но, многу комерцијални компајлери користат лексери напишани на рака (не автоматски генерирани) бидејќи во нив е возможно многу полесно да се интегрираат справувачи со грешки.
Лексерот или лексичкиот анализатор се состои од два дела: скенер и евалуатор. (Овие делови обично се интегрирани поради ефикасноста т.е. за да работат паралелно).
Во првата фаза, скенирањето, е засновано на детерминистички автомат. Тој ги енкодира информациите барајќи одредени токени. На пример токенот integer може да содржи некаква низа бројчени цифри. Во многу случаи првиот знак кој не е празно место може да се одреди за да се добие токенот кој следи, потоа влезот се обработува знак по знак сè додека не се стигне до знак кој не е прифатлив за таква секвенца.
Втората фаза, евалуацијата, кој ја ги поминува токените и им дава вредност т.е. создава стек на вредности. Токените комбинирани со нивните вредности потоа се даваат на расчленувачот.
На пример, во изворниот код на некој програм низата:
net_worth_future = (assets - liabilities);
може да биде претворена во тек на лексички токени:
NAME "net_worth_future"
EQUALS
OPEN_PARENTHESIS
NAME "assets"
MINUS
NAME "liabilities"
CLOSE_PARENTHESIS
SEMICOLON
Иако е возможно, а понекогаш и пожелно да се пишуваат лексери, тие обично се генерираат од автоматски алатки. Овие алатки генерално прифаќаат регуларни изрази коишто ги опишуваат токените кои се дозволени на влез. Секој регуларен израз е проследен со продукција на лексичката граматика на програмскиот јазик којшто ги евалуира токените спојувајќи ги со регуларните изрази. Овие алатки можат да генерираат изворен код којшто може да биде компајлиран и извршен, или можат да конструираат табела на состојби за детерминистички автомат.
Пример за лексички анализатор
Ова е пример за скенер напишан во програмскиот јазик С.
Симболите што ги препознава се:
Скенирањето започнува со повикување на init_scan, со кое се предава името на изворната податотека. Ако изворната податотека успешно се отвори, тогаш расчленувачот ја повикува getsym последователно за сукцесивно да ги врати симболите од изворната податотека.
Срцето на скенерот, getsym, ги извршува акциите одејќи само нанапред. Прво, празните места се прескокнуваат, потоа знаците се класифицираат. Ако знаците претставуваат некој повеќезнаковен симбол тогаш треба да се направи некое дополнителна обработка. Броевите се претвораат во внатрешен облик, а идентификаторите се проверуваат за да се види дали имаат значење на некој клучен збор.
int read_ch(void) {
int ch = fgetc(source);
cur_col++;
if (ch == '\n') {
cur_line++;
cur_col = 0;
}
return ch;
}
Околу 50 реда код за FLEX наспроти 100 реда на рачно напишан код.
Обично скенерите не се тешки за пишување. Ако се напишани точно, рачно напишаните скенери можат да бидат побрзи и пофлексибилни од скенерите кои се направени со помош на генератор за скенер.