日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言语法分析源程序,深入浅出编译原理-5-一个简单语法分析器的C语言实现

發(fā)布時間:2024/4/13 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言语法分析源程序,深入浅出编译原理-5-一个简单语法分析器的C语言实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引言

前面已經(jīng)介紹了編譯器的預(yù)處理,詞法分析,詞法分析器的實現(xiàn),也在其中說到了語法分析的任務(wù)和過程。

語法分析的輸入是詞法單元序列,然后根據(jù)語言的文法表示(展開式),利用有限狀態(tài)機理論,生成抽象語法樹,然后遍歷得到中間代碼,即,三地址碼。本節(jié)就以一個實驗的方式,來看一下,語法分析器的內(nèi)在實現(xiàn)機制。

5.1實驗描述

編制一個遞歸下降分析程序,實現(xiàn)對詞法分析程序所提供的單詞序列的語法檢查和結(jié)構(gòu)分析。

利用C語言編制遞歸下降分析程序,并對簡單語言進行語法分析。

5.1.1待分析的簡單語言的語法

用擴充的BNF表示如下:

⑴::=beginend

⑵::={;}

⑶::=

⑷::=ID:=

⑸::={+ | -}

⑹::={* | /

⑺::=ID | NUM |()

5.1..2實驗要求說明

輸入單詞串,以“#”結(jié)束,如果是文法正確的句子,則輸出成功信息,打印“success”,否則輸出“error”。

例如:

輸入begin a:=9; x:=2*3; b:=a+x end #

輸出success!

輸入x:=a+b*c end #

輸出error

5.2 C語言代碼實現(xiàn)

核心思想就是,從開始狀態(tài)開始,按照文法展開式,逐級進行狀態(tài)分析,直到分析完畢,如果在此期間出現(xiàn)狀態(tài)不匹配,即語法錯誤,停止分析。當(dāng)然在實際的語法分析器要有錯誤恢復(fù)機制,以發(fā)現(xiàn)其他的語法錯誤。即,一次報告多個語法錯誤。這里需要說明的是,要想實現(xiàn)語法分析,必須先有詞法分析,所以,這段代碼包含了上一節(jié)的內(nèi)容,詞法分析部分。

#include "stdio.h"

#include "string.h"

char prog[100],token[8],ch;

char *rwtab[6]={"begin","if","then","while","do","end"};

int syn,p,m,n,sum;

int kk;

void factor(void);

void expression(void);

void yucu(void);

void term(void);

void statement(void);

void lrparser(void);

void scaner(void);

int main(void)

{

p=kk=0;

printf("\nplease input a string (end with '#'): \n");

do

{

scanf("%c",&ch);

prog[p++]=ch;

}while(ch!='#');

p=0;

scaner();

lrparser();

//getch();

}

void lrparser(void)

{

if(syn==1)

{

scaner(); /*讀下一個單詞符號*/

yucu(); /*調(diào)用yucu()函數(shù);*/

if(syn==6)

{

scaner();

if((syn==0)&&(kk==0))

printf("success!\n");

}

else

{

if(kk!=1) printf("the string haven't got a 'end'!\n");

kk=1;

}

}

else

{

printf("haven't got a 'begin'!\n");

kk=1;

}

return;

}

void yucu(void)

{

statement(); /*調(diào)用函數(shù)statement();*/

while(syn==26)

{

scaner(); /*讀下一個單詞符號*/

if(syn!=6)

statement(); /*調(diào)用函數(shù)statement();*/

}

return;

}

void statement(void)

{

if(syn==10)

{

scaner(); /*讀下一個單詞符號*/

if(syn==18)

{

scaner(); /*讀下一個單詞符號*/

expression(); /*調(diào)用函數(shù)statement();*/

}

else

{

printf("the sing ':=' is wrong!\n");

kk=1;

}

}

else

{

printf("wrong sentence!\n");

kk=1;

}

return;

}

void expression(void)

{

term();

while((syn==13)||(syn==14))

{

scaner(); /*讀下一個單詞符號*/

term(); /*調(diào)用函數(shù)term();*/

}

return;

}

void term(void)

{

factor();

while((syn==15)||(syn==16))

{

scaner(); /*讀下一個單詞符號*/

factor(); /*調(diào)用函數(shù)factor(); */

}

return;

}

void factor(void)

{

if((syn==10)||(syn==11))

{

scaner();

}

else if(syn==27)

{

scaner(); /*讀下一個單詞符號*/

expression(); /*調(diào)用函數(shù)statement();*/

if(syn==28)

{

scaner(); /*讀下一個單詞符號*/

}

else

{

printf("the error on '('\n");

kk=1;

}

}

else

{

printf("the expression error!\n");

kk=1;

}

return;

}

void scaner(void)

{

sum=0;

for(m=0;m<8;m++)

token[m++]=NULL;

m=0;

ch=prog[p++];

while(ch==' ')

ch=prog[p++];

if(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A')))

{

while(((ch<='z')&&(ch>='a'))||((ch<='Z')&&(ch>='A'))||((ch>='0')&&(ch<='9')))

{

token[m++]=ch;

ch=prog[p++];

}

p--;

syn=10;

token[m++]='\0';

for(n=0;n<6;n++)

if(strcmp(token,rwtab[n])==0)

{

syn=n+1;

break;

}

}

else if((ch>='0')&&(ch<='9'))

{

while((ch>='0')&&(ch<='9'))

{

sum=sum*10+ch-'0';

ch=prog[p++];

}

p--;

syn=11;

}

else

switch(ch)

{

case '

m=0;

ch=prog[p++];

if(ch=='>')

{

syn=21;

}

else if(ch=='=')

{

syn=22;

}

else

{

syn=20;

p--;

}

break;

case '>':

m=0;

ch=prog[p++];

if(ch=='=')

{

syn=24;

}

else

{

syn=23;

p--;

}

break;

case ':':

m=0;

ch=prog[p++];

if(ch=='=')

{

syn=18;

}

else

{

syn=17;

p--;

}

break;

case '+':

syn=13;

break;

case '-':

syn=14;

break;

case '*':

syn=15;

break;

case '/':

syn=16;

break;

case '(':

syn=27;

break;

case ')':

syn=28;

break;

case '=':

syn=25;

break;

case ';':

syn=26;

break;

case '#':

syn=0;

break;

default:

syn=-1;

break;

}

}

5.3小結(jié)

語法分析的核心工作就是:從開始狀態(tài)開始,利用有限狀態(tài)機理論,根據(jù)語言的文法展開式,進行狀態(tài)分析,得到語法樹。然后進而生成中間代碼(三地址碼),為后面的匯編做好準(zhǔn)備。本小節(jié)的內(nèi)容只是進行狀態(tài)分析。但對理解語法分析器有很大幫助。代碼的具體流程圖,讀者可自己畫一下,其中味道,可意不可言......

總結(jié)

以上是生活随笔為你收集整理的c语言语法分析源程序,深入浅出编译原理-5-一个简单语法分析器的C语言实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。