2011-11-19 64 views
3

我想學習的概念,以及如何創建一個詞法分析器和解析器在C從BNF符號,而不是EBNF。我想用C的語言學習它。BNF到Lex解析器在C

任何人都可以向我解釋我使用的詞彙分析器和解析器放在C語言中的哪些部分,以及在哪裏放置它們?比如也可以使用一個例子?我發現,在解析器,你把終端,非終端,標記,類型等..

很抱歉,如果多數民衆贊成在不明確或任何東西,我的頭是遍佈在這個

的地方謝謝

ps。 BNF我有

<for_statement> ::= FOR <identifier> 
IS <expression> BY <expression> TO <expression> DO <statement_list> ENDFOR 

詞法分析器代碼片段

ENDP     printf("keyword: ENDP\n"); 
DECLARATIONS   printf("keyword: DECLARATIONS\n"); 
CODE     printf("keyword: CODE\n"); 
"OF TYPE"    printf("keyword: OF TYPE\n"); 
+2

這個問題有點含糊。閱讀[gnu-lex和Bison手冊頁](http://dinosaur.compilertools.net/)開始。如果遇到問題,請隨時發佈具體問題。 –

回答

2

前提:我認爲一個更好的方法來了解你說的可能是把可用的工具工作的概念。你可以從基本的開始,比如flex/bison,或者-better-一些最近的免費工具,比如GOLD

由於底層狀態機的複雜性,今天詞法分析器和解析器不是手動實現的。但爲了學習的目的,正如Pascal的「父親」Niklaus Wirth倡導的那樣,或者爲了「引導」SW軟件工具,或者(過去)也出於效率原因,詞法分析器有時需要手工實現。詞法分析器通常需要許多大的開關(S)的形式,並先行可使用ungetc函數可以天真地實現():

#include <stdio.h> 
enum token {Num, Sym}; 

token getnum() { 
char c; 
for (; ;) 
    switch (c = getc()) { 
    case '0': 
    ... 
    case '9': 
    break; 
    default: 
    ungetc(c); 
    return Num; 
    } 
} 
token getsym() { 
char c; 
for (; ;) 
    switch (c = getc()) { 
    case '0': 
    ... 
    case '9': 
    break; 
    default: 
    ungetc(c); 
    return Sym; 
} 
} 
token lex() { 
char c; 
switch (c = getc()) { 
case '0': 
... 
case '9': 
    return getnum(); 
case 'A': 
... 
case 'Z': 
case 'a': 
... 
case 'z': 
case '_': 
    return getsym(); 
} 

最簡單的解析器它是自上而下的遞歸,要求你的語法是LL(1)。值得注意的是,Pascal解析器是這種類型的(當然,Wirth恰當地設計了這種語言)。我們需要每個非終結符的函數和一個令牌的前瞻。解析器成爲一組互相遞歸過程(在這裏完全虛構的僞代碼):

void A(token t); 
void B(token t); 

void B(token t) 
{ 
if (t == Sym) 
{ 
    t = lex(); 
    B(t); 
} 
else if (t == Num) 
{ 
    t = lex(); 
    A(t); 
} 
else 
    syntaxerr(); 
} 
void A(token t) 
{ 
if (t == Num) 
{ 
    t = lex(); 
    B(t); 
} 
else 
    syntaxerr(); 
} 

int main(int argc, char **argv) 
{ 
A(lex()); 
} 

我們總是可以重寫EBNF在BFN,引入服務非終端。