最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

語法分析程序的設(shè)計(jì)與實(shí)現(xiàn)-編譯原理

2022-08-04 09:20 作者:老師-忘記密碼  | 我要投稿

項(xiàng)目4 使用遞歸下降法手動(dòng)構(gòu)建語法分析器

一、目的與要求 ?

??1)目的 ?

???通過設(shè)計(jì)、編制、調(diào)試一個(gè)確定的自頂向下語法分析程序,實(shí)現(xiàn)對(duì)詞法分析程序所提供的單詞序列進(jìn)行語法檢查和結(jié)構(gòu)分析,并建立相應(yīng)的語法樹,進(jìn)一步掌握常用的語法分析方法。?

??2)要求 ?

用遞歸下降法分析、設(shè)計(jì)和實(shí)現(xiàn)TINY語言源程序的語法分析程序。

輸入:?jiǎn)卧~序列

輸出:語法樹(語法正確),有語法錯(cuò)誤,則報(bào)錯(cuò)

二、語法分析說明 ?

TINY語言的文法:


中文描述:


文法的定義可以看出,TINNY語言有以下特點(diǎn):

1)?程序共有5種語句:if語句,repeat語句,read語句,write語句和assign語句。

2)?if語句以end作為結(jié)束符號(hào),if語句和repeat語句允許語句序列作為主體。

3)?輸入/輸出由保留字read和write開始。read語句一次只讀出一個(gè)變量,而write語句一次只寫出一個(gè)表達(dá)式。

三、語法樹的設(shè)計(jì)

1)?TINY有兩種基本的結(jié)構(gòu)類型:語句和表達(dá)式。語句共有5類:(if語句、repeat語句、assign語句、read語句和write語句),表達(dá)式共有3類(算符表達(dá)式、常量表達(dá)式和標(biāo)識(shí)符表達(dá)式)。因此,語法樹節(jié)點(diǎn)首先安裝它是語句還是表達(dá)式來進(jìn)行分類,接著根據(jù)語句或表達(dá)式的種類進(jìn)行再次分類。

2)?樹節(jié)點(diǎn)最大可有3個(gè)孩子的結(jié)構(gòu)(僅在帶有else部分的if 語句才用到)。同一級(jí)的語句通過同屬域而不是子域來排序,孩子則在一個(gè)標(biāo)準(zhǔn)連接表中自左向右連接到一起,這種連接稱作同屬連接,用于區(qū)別父子連接。?

(1)if 語句(帶有3個(gè)可能的孩子)如下所示:


(2)repeat 語句有兩個(gè)孩子。第1個(gè)是表示循環(huán)體的語句序列,第2個(gè)是一個(gè)測(cè)試表達(dá)式:


(3) assign 語句有一個(gè)表示其值是被賦予的表達(dá)式的孩子(被賦予的變量名保存在語句節(jié)點(diǎn)中):

??


(4) write 語句也有一個(gè)孩子,它表示要寫出值的表達(dá)式:

?? ?


(5)Read語句,沒有孩子

?


(6)表達(dá)式有兩個(gè)孩子,它們表示左操作數(shù)表達(dá)式和右操作數(shù)表達(dá)式:

?


3)?一個(gè)Tiny語法樹節(jié)點(diǎn)的C聲明如下:

?

typedef enum {StmtK,ExpK} NodeKind;

typedef enum {IfK,RepeatK,AssignK,ReadK,WriteK} StmtKind;

?

/* ExpType is used for type checking */

typedef enum {Void,Integer,Boolean} ExpType;

?

#define MAXCHILDREN 3

?

typedef struct treeNode{

?struct treeNode * child[MAXCHILDREN];

?????struct treeNode * sibling;

?????int lineno;

?????NodeKind nodekind;

?????union { StmtKind stmt; ExpKind exp;} kind;

?????union {

TokenType op;

??????????????int val;

??????????????char * name; } attr;

???} TreeNode;


4)?下面畫出語法樹的結(jié)構(gòu),用矩形框表示語句節(jié)點(diǎn),用圓形框或橢圓形框表示表達(dá)式節(jié)點(diǎn)。仍然以Tiny語言的階乘為例,給出Tiny程序的語法樹。

?

程序清單1是該語言的一個(gè)求階乘的編程示例。

程序清單1?

?

{ Sample program

??in TINY language -

??computes factorial

}

read x; { input an integer }

if 0 < x then { don't compute if x <= 0 }

??fact := 1;

??repeat

????fact := fact * x;

????x := x - 1

??until x = 0;

??write fact ?{ output factorial of x }

end

四、?用遞歸下降法進(jìn)行語法分析程序的設(shè)計(jì)實(shí)現(xiàn)

遞歸下降法的實(shí)現(xiàn)思想就是對(duì)應(yīng)文法中的每個(gè)非終結(jié)符,編寫一個(gè)遞歸過程,每個(gè)過程的功能是識(shí)別該非終結(jié)符推出的串。當(dāng)某個(gè)非終結(jié)符的產(chǎn)生式有多個(gè)候選時(shí)能夠按照LL(1)的形式唯一地確定選擇某個(gè)候選進(jìn)行推導(dǎo)。

構(gòu)造遞歸下降分析程序時(shí),每個(gè)函數(shù)名是相應(yīng)的非終結(jié)符,函數(shù)體根據(jù)產(chǎn)生式規(guī)則右部符號(hào)串的結(jié)構(gòu)編寫,基本思路如下:

(1)?當(dāng)遇到終結(jié)符a時(shí),則編寫語句:

If (當(dāng)前讀來的輸入符號(hào)==‘a(chǎn)’)讀入下一個(gè)輸入符號(hào)

(2)?當(dāng)遇到非終結(jié)符A時(shí),則編寫語句調(diào)用A()

(3)?當(dāng)遇到A?e產(chǎn)生式規(guī)則時(shí),則編寫語句:

If(當(dāng)讀來的輸入符號(hào)不屬于Follow(A)error()

(4)?當(dāng)某個(gè)非終結(jié)符有多個(gè)候選產(chǎn)生式規(guī)則時(shí),則:

if(當(dāng)前讀來的輸入符號(hào)屬于Select(ai))則按規(guī)則A?ai進(jìn)行推導(dǎo)


?

1)對(duì)于產(chǎn)生式

< STMT-SEQUENCE > ?::= ??<STMT-SEQUENCE> ??;? ?<STATEMENT>

? ????| <STATEMENT>

?

產(chǎn)生的句型應(yīng)該是:??< STATEMENT >?;?<STATEMENT> ;?<STATEMENT> …..

產(chǎn)生的樹結(jié)點(diǎn): ?

?


我們可以構(gòu)造出對(duì)應(yīng)的程序:

TreeNode* stmt_sequence(void)

{

TreeNode* t = statement();

TreeNode* p=t;

while(token==SEMI)

{

match(SEMI);

TreeNode* t1=statement();

p->sibling = t1;

p=t1;

}

return t;

}? ?


(2)???STATEMENT? ?:= ?<IF-STMT> ?| ?<REPEAT-STMT> ?

| <ASSIGN-STMT> | <READ-STMT>

| ?<WRITE-STMT>

?

?

static TreeNode* statement()

{

TreeNode * t = NULL;

switch (token)

{

case IF: t = if_stmt(); break;

case REPEAT: t = repeat_stmt(); break;

case ID: t = assign_stmt(); break;

case READ: t = read_stmt(); break;

case WRITE: t = write_stmt(); break;

default:

{

???char t[100];

???sprintf(t, "unexpected token: %s", tokenString);

???syntaxError(t);

}

}

return t;

}


< REPEAT-STMT > ::= repeat???<STMT-SEQUENCE> ?until ??<EXP>

?

?

< SIMPLE-EXP> ?::= ?<SIMPLE-EXP> ?+ - ??<TERM>

?| ?<TERM>

產(chǎn)生的句型:<TERM> + | - <TERM> + | -<TERM>

?


表達(dá)式:a+b-c+30

?

五、出錯(cuò)處理

錯(cuò)誤處理的任務(wù):(1)報(bào)錯(cuò),發(fā)現(xiàn)錯(cuò)誤時(shí)應(yīng)盡可能準(zhǔn)確指出錯(cuò)誤位置和錯(cuò)誤屬性(2)錯(cuò)誤恢復(fù),盡可能進(jìn)行校正,使編譯工作可以繼續(xù)下去,提高程序調(diào)試的效率。為了簡(jiǎn)單,本語法分析程序的出錯(cuò)處理為報(bào)告出錯(cuò)的行數(shù),程序退出。

本實(shí)驗(yàn)采用的出錯(cuò)處理簡(jiǎn)單的處理為:一旦發(fā)生錯(cuò)誤,就報(bào)錯(cuò)后編譯停止


四、實(shí)驗(yàn)內(nèi)容

(1)讀懂源代碼,添加注釋,補(bǔ)充空白處的代碼

(2)測(cè)試求階乘的編程示例s.tiny ,輸出語法樹

?

{ Sample program

??in TINY language -

??computes factorial

}

read x; { input an integer }

if 0 < x then { don't compute if x <= 0 }

??fact := 1;

??repeat

????fact := fact * x;

????x := x - 1

??until x = 0;

??write fact ?{ output factorial of x }

end


(3)測(cè)試編譯gcd.tiny ,如果有語法錯(cuò)誤,請(qǐng)修改語法后,輸出語法樹

?

{

????求最大公約數(shù)

}

read m; { input an integer }

read n;

?

if m<n then { 將大數(shù)放入m中,小數(shù)放入n中}

t:=m;

m:=n;

n:=t;

end

?

repeat

q:=m/n;

r=m-q*n;

m:=n;

n:=r;


填充代碼1:

TreeNode* if_stmt() ?

{

? ? // ?【代碼1】 ?填充此代碼

????TreeNode?*t?=?newStmtNode(IfK);

????match(IF);

????t->child[0]?=?exp_stmt();

????match(THEN);

????t->child[1]?=?stmt_sequence();

????if(token==END)

????{

????????match(END);

????????return?t;

????}

????if(token==ELSE)

????{

????????match(ELSE);

????????t->child[2]?=?stmt_sequence();

????????match(END);

????????return?t;

????}

????return?NULL;

?}

TreeNode* read_stmt()

{

? ? // ?【代碼2】 ?填充此代碼

????TreeNode?*t?=?newStmtNode(?ReadK);

????match(READ);

????char*?idname=?copyString(tokenString);

????match(ID);

????t->attr.name=idname;

????return?t;

}

?

static TreeNode* term()

{

? ? // ?【代碼3】 ?填充此代碼

????TreeNode?*t?=?factor();

????while(token==TIMES||token==OVER)

????{

???????TreeNode?*p?=?newExpNode(OpK);

???????p->child[0]?=?t;

???????p->attr.op?=?token;

???????match(token);

???????TreeNode?*q?=?factor();

???????p->child[1]?=?q;

???????t=p;

????}

????return?t;

}

?

運(yùn)行結(jié)果

Test1

?


Test2:


語法分析程序的設(shè)計(jì)與實(shí)現(xiàn)-編譯原理的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
江孜县| 合江县| 罗甸县| 天祝| 轮台县| 镇原县| 汪清县| 二连浩特市| 枣阳市| 大丰市| 望都县| 牟定县| 禹城市| 任丘市| 封丘县| 右玉县| 临潭县| 五指山市| 新建县| 平山县| 贵阳市| 漳州市| 乌鲁木齐市| 秦安县| 仙居县| 蒲城县| 缙云县| 绍兴市| 合山市| 车致| 长葛市| 台东市| 阳谷县| 周口市| 同仁县| 日土县| 新乐市| 镇坪县| 东丰县| 济南市| 封开县|