一,文法定義
1)文法:對語言結構的定義與描述。即從形式上用於描述和規定語言結構的稱為“文法”(或稱為“文法”),而未
涉及語義問題。
例:有一句子:“我是大學生” 。這是一個在文法、語義上都正確的句子,該句子的結構(稱為文法結構)是由它的文法決定的。在本例中它為“主謂結構”
2)文法定義
文法G=(Vn,Vt,P,Z)
Vn:非終結符號集,文法變數
Vt:終結符號集,詞法單元
P:產生式或規則的集合
Z:開始符號(識別符號) Z∈Vn
例:if(expression) statement else statement;
關鍵字if 和括弧:為 終結符號(詞法單元)
expression、statement:非終結符號
3)推導
從一個要識別的符號開始推導,即用相應規則的右部來替代規則的左部,每次僅用一條規則去進行推導。從開始符號出發,不斷將某個非終結符號替換為該非終結符號的某個產生式的體。
<句子>::=<主語><謂語>
<主語>::=<代詞>|<名詞>
<代詞> ::=你|我|他
<名詞>::= 王民|大學生|工人|英語
<謂語>::=<動詞><直接賓語>
<動詞>::=是|學習
<直接賓語>::=<代詞>|<名詞>
4)文法分析
接受一個終結符號串作為輸入,找出從文法的開始符號推匯出這個串的方法。如果不能從文法符號推到得到該終結符號串,則報錯。
5)文法分析樹
文法分析樹被定義為具有下述性質的一棵樹:
1) 根由開始符號所標記;
2) 每個葉子由一個終結符、非終結符、或ε標記;
3) 每個內部結點由一個非終結符標記;
4) 若A是某內部節點的標記,且X1,X2,...,Xn是該節點從左至右所有孩子的標記,則A→X1X2...Xn是一個產生式。若A→ε,則標記為A的結點可以僅有一個標記為ε的孩子。
例子:9-5+2
文法的產生式:list -> list + digit ;
list -> list - digit ;
list -> digit
digit -> 0 | 1| 2| 3| 4| 5| 6| 7| 8| 9
非終結符:list digit list是文法開始符號
終結符:零個或多個終結符號組成的序列,零個終結符組成的串稱為空白串
文法分析樹:
list
/ | \
list | digit
/ | \ | |
list | digit | |
| | | | |
9 - 5 + 2
6)二義性
一個文法可能有多顆文法分析樹,產生同一個給定的終結符號。
例子:句子id+id*id可能的分析樹
(id+id)*id id+id*id
消除二義性:
① 改寫二義文法為非二義文法;
② 規定二義文法中符號的優先順序和結合性,使僅產生一棵分析樹。
二義文法的優點:
① 比非二義文法容易理解;
② 分析效率高(分析樹低,直接推導步驟少)。
三,文法制導翻譯
1)屬性:與某個程式構造相關的任意的量,屬性可以使多種多樣的,比如運算式的資料類型、產生的程式碼中的指令數目或為某個產生的程式碼中第一條指令的位置。
2)翻譯方案:將程式片段附加到一個文法的各個產生式上的標記法。當在文法分析過程中使用一個產生式時,相應的程式片段就會執行。
3)文法制導定義:把①每個文法符號和一個屬性集合相關聯,並且把 ② 每個產生式和一組語義規則相關聯,這些規則用於計算與該產生式中符號相關聯的屬性值
四,文法分析
1)文法分析:決定如何使用一個文法產生一個終結符號串的過程。原則上文法分析器必須能夠構造出文法分析樹,否則將無法保證翻譯的正確性
2)文法分析分為:自頂向下分析方法和自底向上分析方法
3)自頂向下分析方法:構造方法從根節點開始,逐步向葉子節點方向進行。
4)預測性分析法(遞迴下降分析法):自頂向下的文法分析方法,使用一組遞迴過程來處理輸入。
五,簡單運算式的翻譯器
1)抽象文法樹:每個內部節點代表一個運算子(而不像文法分析樹 為非終結符號)
2)將中綴運算式翻譯成尾碼運算式:
package demo_parser;import java.io.*;public class Demo_Parser { static int lookahead;//位元組流以整數形式(ascii碼中對應十進位數)表示 public Demo_Parser() throws IOException { lookahead=System.in.read();//read方法以位元組流的方式來讀取命令列的輸入的資料 } void term() throws IOException //如果是數字則輸出(不識別字母) { if(Character.isDigit((char)lookahead)) { System.out.write((char)lookahead); match(lookahead); } else throw new Error("syntax error"); } void match(int t)throws IOException { if(lookahead == t) lookahead= System.in.read(); else throw new Error("syntax error"); } void expr() throws IOException { term(); while(true) { if(lookahead =='+') { match('+'); term(); System.out.write('+'); } else if(lookahead == '-') { match('-'); term(); System.out.write('-'); } else return; } } public static void main(String[] args) throws IOException{ Demo_Parser parser = new Demo_Parser(); parser.expr(); System.out.write('\n'); }}
六,詞法分析
1)從輸入中讀取字元,並將它們組成”詞法單元對象“。構成一個詞法單元的輸入字元序列成為詞素。
2)剔除空白和注釋:實現這個遠非易事
3)預讀:比如讀到 then 還要往下讀,如果是空格或其他非標識符則判斷為關鍵字。否則為標識符(thenOther)
<= >= == <>
4)識別關鍵字和標識符:詞法分析採用一個表來儲存字串
七,符號表
1)符號表:一種供編譯器用於儲存有關來源程式構造的各種資訊的資料結構。這些資訊在編譯器的分析階段被逐步手機並放入符號表。
2)符號表條目:在分析階段由,詞法分析器、文法分析器和語義分析器建立並使用。文法分析器建立。
3)每個範圍設定一個符號表,其作用是將資訊從聲明的地方傳遞到實際使用的地方。
八,產生中間代碼
1)兩種中間表示形式:樹形結構,線性表示形式(特別是"三地址代碼")