【文章內(nèi)容簡介】
分量按某種形式聯(lián)系起來;形式參數(shù)標(biāo)志;若在COMMON或EQUVALENCE語句中(FORTRAN語言),把它和有關(guān)名字連接在一起;它是否已處理過(即標(biāo)志位“定義否”);是否對這個變量進行過賦值(包括出現(xiàn)在輸人名表中)的標(biāo)志位;過程是否為程序的外部過程;若為函數(shù),類型是什么;其說明是否處理過;是否遞歸;形式參數(shù)是些什么;為了與實參進行比較,必須把它們的種屬、類型信息間過程名聯(lián)系在一起。對于那些只使圖單一符號表的簡單語言,對符號表填入新項的工作可由詞法分析程序 來完成。也就是,當(dāng)掃描器碰到一個標(biāo)識符時就對它查填符號表,然后回送它在符號表中的位置作為單詞值。但在某些語言中,甚至在同一過程段里允許不同一標(biāo)識符標(biāo)識各種不同對象。例如,XYZ既是一個實變量名又是一個標(biāo)號名,或者又是某個結(jié)構(gòu)型數(shù)據(jù)的一個分量名。在這種情況下,使用單一符號表或由詞法分析程序負責(zé)查填符號表都是非常不方便的。因此,釆用多種符號表并讓語法——語義分析程序負責(zé)查填工作是比較妥當(dāng)?shù)摹?對于詞法分析程序來說,只要求它凡碰到標(biāo)識符就直接送出此標(biāo)識符自身即可。符號表中信息欄的具體組織和安排取決于所翻譯的具體語言與目標(biāo)機器(的字長和指令系統(tǒng)〕。為了進行類型檢査,編譯器需要給源程序的每一個組成成分賦予一個類型表達式。然后,編譯器需要確定這些類型表達式是否滿足一組邏輯規(guī)則。這些規(guī)則被稱為源語言的類型系統(tǒng)。類型檢查具有發(fā)現(xiàn)程序中的錯誤的功能。原則上,如果目標(biāo)代碼在保存元素值的同時保存了元素類型的信息,任何檢查都可以動態(tài)地進行。一個健全的類型系統(tǒng)可以消除對動態(tài)類型檢查的需要,因為它可以幫助我們靜態(tài)地確定這些錯誤不會在程序運行的時候發(fā)生。 如果編譯器可以保證它接受的程序在運行時刻不會發(fā)生類型錯誤,那么該語言的這個實現(xiàn)就被稱為強類型的。3 系統(tǒng)詳細設(shè)計 基于C語言源程序分析器的開發(fā)在可行性分析的基礎(chǔ)上進一步全面、深入的分析,弄清C語言的編譯原理及運行狀況,在編譯程序工作的五個階段中,每個階段都必須遵從功能等價的原則。詞法規(guī)則與語法分析階段依據(jù)的語法規(guī)則一同構(gòu)成了一個語言的語法,而語法 則是從形”的角度衡量一個程序是否合法。所以在詞法分析階段,詞法規(guī)則成為重要的研究對象。詞法分析器所處理的對象即詞法分析程序的輸入數(shù)據(jù),實際上是源程序經(jīng)過編譯預(yù)處理,去掉多余的符號后而形成的代碼,這樣給詞法分析帶來方便。詞法分析的過程是線性的從頭至尾掃描一遍,復(fù)雜度較低,易實現(xiàn)。最后概括出要實現(xiàn)的幾個功能流程圖如下: 圖1 功能流程圖詞法分析程序需要完成的任務(wù)如下:1識別出源程序的各個語法單位;2剔除無用的空白字符、制表符、回車字符以及其他與輸入介質(zhì)相關(guān)的非實質(zhì)性字符;3過濾掉源程序中的注釋;4進行詞法檢查,如果出現(xiàn)錯誤,記錄出錯信總并報告。我們將編譯程序的重點放在中間代碼生成階段。詞法分析器的功能是輸入源程序,輸出單詞符號。這部分程序主要包括兩個類: Class CTlkenizer從一個字符串中(這個把一個文件看作是一個字符串,MFC中CfileCString)分離出 一個一個token,配上簡單的類型通過NextToken( )返回:define TT_EOL 39。\n39。define TT_EOF 1define TT_INTEGER 2define TT_REAL 3define TT_WORD 4define TT_STRING ’’’’define TT_CHAR ’ \’’得到具體的token類型,定義TokenType如下:enum TokenType { // reserved Keyword _AUTO, _DOUBLE, _INT, _STRUCT, _BREAK, _ELSE, _LONG, _SWITCH, _CASE, _ENUM, _REGISTER, _TYPEDEF, _CHAR, _EXTERN, _RETURN, _UNION, _CONST, _FLOAT, _SHORT, _UNSIGNED, _CONTINUE, _FOR, _SIGNED, _VOID, _DEFAULT, _GOTO, _SIZEOF, _VOLATILE, _DO, _IF, _STATIC, _WHILE, _READ, _WRITE, _PRINTF, // operations ASSIGN, PLUS, MINUS, TIMES, DIV, MOD, BITWISE_AND, BITWISE_OR, BITWISE_NOT, LOGICAL_NOT, LT, GT, // interpunctions LPARAN, RPARAN, LBRACE, RBRACE, LSQUARE, RSQUARE, COMMA, DOT, SEMI, // operations ASSIGN, PLUS, MINUS, TIMES, DIV, MOD, BITWISE_AND, BITWISE_OR, BITWISE_NOT, LOGICAL_NOT, LT, GT, // interpunctions LPARAN, RPARAN, LBRACE, RBRACE, LSQUARE, RSQUARE, COMMA, DOT, SEMI, COLON, // plex operations 11 EQ/* == */, NEQ/* != */, PLUS_PLUS/* ++ */, MINUS_MINUS/* */, PLUS_ASSIGN/* += */, MINUS_ASSIGN/* = */, TIMES_ASSIGN/* *= */, DIV_ASSIGN/* /= */, NGT/* = */, NLT/* = */, LOGICAL_AND/* amp。amp。 */, LOGICAL_OR/* || */, // others _EOF, _ID, _NUM, _STRING, _CHARACTER, _LABEL, _ERROR, _NONE }。CScaner通過一個CMapCString, LPCSTR, enum TokenType, enum TokenType m_KeyIndex 把CString的關(guān)鍵字和TokenType對應(yīng),便于查找和反向查找。表1 C關(guān)鍵字表標(biāo)識符詞法:identifier :nondigitidentifier nondigitidentifier digitnondigit : one of_ a b c d e f g h i j k l m n o p q r s t u v w x y zA B C D E F G H I J K L M N O P Q R S T U V W X Y Zdigit : one of0 1 2 3 4 5 6 7 8 9escape:\n, \r, \b, \07 在上一節(jié)中,實現(xiàn)了詞法分析程序的功能。一個字符串形式的源程序經(jīng)過詞法分析,即被轉(zhuǎn)換為一串單詞符號。編譯程序在完成了詞法分析之后,就進入語法分析階段。語法分析程序以單詞形式的源程序作為輸入或分析的對象。其基本任務(wù)是根據(jù)語言的語法規(guī)則(即描述該語言的上下文無關(guān)文法),分析源程序的語法結(jié)構(gòu)〔即分析如何將這些單 詞組成各種語法成分,如各種表達式、語句、函數(shù)或過程等〉,并在分析過程中,對源程序進行語法正確性檢查。其分析結(jié)果是識別出無語法錯誤的語法成分。其輸出形式也有多種。 語法分析模塊的核心部分設(shè)計如下:Class Cparser:定義CTreeNode,和Tiny例程類似: define MAX_CHILDREN 3 class CTreeNode { public: CTreeNode* child[ MAX_CHILDREN ]。 // point to child node CTreeNode* father。 // point to father node CTreeNode* sibling。 // point to sibling node int lineno。 NodeKind nodekind。 union { StmtKind stmt。 ExpKind exp。 } kind。 enum TokenType type。 CString szName。 CString szScope。 // node function scope BOOL bArray。 // is this an array declaration int iArraySize。 // array size }。