導航:首頁 > 源碼編譯 > 編譯原理實驗詞法分析設計與實現

編譯原理實驗詞法分析設計與實現

發布時間:2025-06-21 01:34:01

A. 編譯原理簡單嗎

編譯原理主要是講了編譯器的實現。
那什麼是編譯器呢?
編譯器就是將 源程序→編譯器 →目標機器代碼的程序
本文將用一段最簡單的代碼進行說明

1 + 2 + 3

第一步. 詞法分析
當代碼從文件中被讀入到編輯器時,將會進行詞法分析
示例中的代碼最終會轉換為(下面為偽代碼)

1 ADD 2 ADD 3

第二步. 語法分析
這一步編譯器將會把詞法分析的結果轉換成AST(abstract syntax tree, 抽象語法樹)
所有的操作數將會作為子節點,所有的操作符將會作為父節點。(不知道的同學可以看一下樹的生成)

1 + 2 + 3 對應的樹
3. 生成目標代碼
對上面的樹進行後序遍歷,將會得到下面的偽代碼

((1 2 +) 3 +)

生成的匯編偽代碼為

START:

MOV VALUE, 0//初始化結果為0

ADD VALUE, 1

ADD VALUE, 2//(1 2 +)的匯編偽代碼

ADD VALUE, 3

RET VALUE

END

最終匯編代碼會被編譯成機器代碼,在計算機上執行。
下面為一般情況下的編譯流程
1. 詞法分析(生成代碼對應的token序列,使用正則表達式)
2. 語法分析(生成AST)
3. 語義分析(對代碼的語法進行檢查)
4. 代碼生成(生成可執行的代碼)

B. 編譯原理詞法分析實驗中, 文件寫入順序的問題(fputs)

1)fopen在代碼中出現2次,沒有必要

2)你的程序不對 你搞混和S這個字元和TOKEN。

你的第一個WHILE讀入的是字元S,而TOKEN是由若干字元S構成的。而你的SWITCH(S)裡面按理應該是組成TOKEN的規則,而你直接就輸出了。這樣如果你要結果,我給你改了下,你看下:

int main()
{
char token[20] = {''};
char s;
char strings[10] = "(34,_)";
struct _iobuf* fp_cifa;
int i = 0, j;
strings[6] = ' '
strings[7] = ''
//fp_cifa = fopen(「D:\cifa.txt "a+");

while((size_t)i != strlen(file))
{
for(j = 0; j < 20; j++)
{
token[j] = ''
}
s = file[i++];
while(s == ' ' || s == ' ')
{
s = file[i++];
}
switch(s)
{
caseƇ':
token[0]=s;
token[1]=''
digitprint(token, value_num, num_list);
break;
case'=':
token[0]=s;
token[1]=''
digitprint(token, value_num, num_list);
//fputs(strings, fp_cifa);
break;
default:
cout<<"error"<<endl;
}
}
//fclose(fp_cifa);
return 0;
}

C. 編譯器有哪幾部分構成.編譯原理

1. 詞法分析

詞法分析器根據詞法規則識別出源程序
中的各個記號(token),每個記號代表一類單詞(lexeme)。源程序中常見的記號可以歸為幾大類:關鍵字、標識符、字面量和特殊符號。詞法分析器
的輸入是源程序,輸出是識別的記號流。詞法分析器的任務是把源文件的字元流轉換成記號流。本質上它查看連續的字元然後把它們識別為「單詞」。

2. 語法分析

語法分析器根據語法規則識別出記號流中的結構(短語、句子),並構造一棵能夠正確反映該結構的語法樹。

3. 語義分析

語義分析器根據語義規則對語法樹中的語法單元進行靜態語義檢查,如果類型檢查和轉換等,其目的在於保證語法正確的結構在語義上也是合法的。

4. 中間代碼生成

中間代碼生成器根據語義分析器的輸出生成中間代碼。中間代碼可以有若干種形式,它們的共同特徵是與具體機器無關。最常用的一種中間代碼是三地址碼,它的一種實現方式是四元式。三地址碼的優點是便於閱讀、便於優化。

D. 編譯原理中詞法分析和語法分析的任務分別是什麼

詞法分析的主要任務是將源代碼轉換為一系列有意義的詞彙單位,這個過程可以分解字元序列形成單片語合,我們稱之為詞法單元或記號。在詞法分析中,分析器識別關鍵字、標識符、常量和運算符等元素,形成一個詞法單元序列。

語法分析的任務是根據預設的語法規則,分析詞法單元序列的結構。這一步驟旨在判斷序列是否遵循既定的語法規則。語法分析器通過構建語法樹或語法分析樹,展示源代碼的結構。在此過程中,語法分析器還會檢測語法錯誤,並生成相應的錯誤信息。

詞法分析與語法分析是編譯原理中的兩個關鍵環節,它們共同協作完成源代碼的分析和轉換。詞法分析將源代碼轉換為詞法單元序列,為後續的語法分析提供數據輸入。而語法分析則依據語法規則對詞法單元序列進行深入分析,判斷其是否符合語法規則。經過這兩個步驟,編譯器能夠對源代碼進行更深層次的語義分析、優化,並最終生成目標代碼。

E. 急(高懸賞 幫個忙) 求編譯原理課程設計---c語言實現c-的語法分析,在線等

新建一個文本文檔在你工程目錄下,名字起為"輸入.txt",裡面的內容可以為
begin a:=1+7*(6+3);b:=1end#

輸出是在"輸出.txt"中查看,以下為輸出情況:

詞法分析結果如下:
(1, begin)
(10, a)
(18, :=)
(11, 1)
(13, +)
(11, 7)
(15, *)
(27, ()
(11, 6)
(13, +)
(11, 3)
(28, ))
(26, ;)
(10, b)
(18, :=)
(11, 1)
(6, end)
(0, #)
語法分析結果如下:(以四元式形式輸出)
( +, 6, 3, t1)

( *, 7, t1, t2)

( +, 1, t2, t3)

( =, t3, __, a)

( =, 1, __, b)

//提供一個編譯原理的語義分析程序 你可以直接拆猜森復制 用TC進行調試
#include "stdio.h"
#include "string.h"
#include <malloc.h>
#include <conio.h>
#include "stdlib.h"

char prog[100],token[8],ch;
char *rwtab[6]={"begin","if","then","while","do","end"};
int syn,p,m,n,sum,q;
int kk;
//四元式表的結構如下:
struct
{
char result1[8];
char ag11[8];
char op1[8];
char ag21[8];
}quad[20];

char *factor();
char *expression();
int yucu();
char *term();
int statement();
int lrparser();
char *newtemp();
void scaner();
void emit(char *result,char *ag1,char *op,char *ag2);

void main()
{
FILE *fp1,*fp2;

if((fp1=fopen("輸入.txt","rt"))==NULL)
{
printf("Cannot open 輸入.txt\n");
getch();
exit(1);
}
if((fp2=fopen("輸出.txt","wt+"))==NULL)
{
printf("Cannot create 輸出.txt FILE.strike any key exit");
getch();
exit(1);
}

int j;
q=p=kk=0;
p=0;
//printf("Please Input a String(end with '#'旅畝):\n");
while(ch!='#')
{
ch = fgetc(fp1);
if(ch == EOF)
{
printf("文件為空,請檢查後再嘗試!");
return ;
}

prog[p++]=ch;
}
if(prog[p]=='#')
{
printf("輸入的待分析的串不是以'#'結尾,請修改之後再嘗試!\n");
return;
}
p=0;
char buffer1[200] = {0};
sprintf(buffer1,"詞法分析結果如下:\n");
fputs(buffer1,fp2);
//printf("詞法分析結果如下:\n");
do
{
scaner();
switch(syn)
{
case 11:
//printf("(%d,%d)\n"兆旦,syn,sum);
sprintf(buffer1,"(%d, %d) \n",syn,sum);
fputs(buffer1,fp2);
break;
default:
//printf("(%d,%s)\n",syn,token);
sprintf(buffer1,"(%d, %s)\n",syn,token);
fputs(buffer1,fp2);
break;
}
}while(syn!=0);
printf("\n");

p=0;
char buffer[200]={0};
sprintf(buffer,"語法分析結果如下:(以四元式形式輸出)\n");
fputs(buffer,fp2);
//printf("語法分析結果如下:(以四元式形式輸出)\n");
scaner();//掃描函數
lrparser();
if(q>19)
printf(" to long sentense!\n");
else
{

for (j=0;j<q;j++)
{
//printf("( %s, %s, %s, %s) \n\n",quad[j].op1,quad[j].ag11,quad[j].ag21,quad[j].result1);
sprintf(buffer,"( %s, %s, %s, %s) \n\n",quad[j].op1,quad[j].ag11,quad[j].ag21,quad[j].result1);
fputs(buffer,fp2);
}
}
printf("已把相應的詞法和語法的結果保存到相應的文件中,請查閱!\n");
fclose(fp1);
fclose(fp2);
}
int lrparser()
{
int schain=0;
kk=0;
if (syn==1) //得到begin
{
scaner();//掃描下個字元
schain=yucu();
if(syn==6)//得到end
{
scaner();//掃描下個字元
if((syn==0)&&(kk==0)) //得到#
printf("Success!\n");
}
else
{
if(kk!=1)
printf("short of 'end' !\n");
kk=1;
getch();
exit(0);
}
}
else
{
printf("short of 'begin' !\n");
kk=1;
getch();
exit(0);
}
return (schain);
}
int yucu()
{
int schain=0;
schain=statement();
while(syn==26)
{
scaner();
schain=statement();
}
return (schain);
}
int statement()
{
char tt[8],eplace[8];
int schain=0;
if (syn==10)
{
strcpy(tt,token); //tt中保存的是第一個字元
scaner();
if(syn==18) //檢測到=號
{
scaner();
strcpy(eplace,expression());
emit(tt,eplace,"=","__");
schain=0;
}
else
{
printf("short of sign ':=' !\n");
kk=1;
getch();
exit(0);
}
return (schain);
}
}
char *expression()
{
char *tp,*ep2,*eplace,*tt;
tp=(char *)malloc(12);
ep2=(char *)malloc(12);
eplace=(char *)malloc(12);
tt=(char *)malloc(12);

strcpy(eplace,term());

while((syn==13)||(syn==14))
{
if (syn==13)
strcpy(tt,"+");
else
strcpy(tt,"-");

scaner();
strcpy(ep2,term());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2);
strcpy(eplace,tp);
}
return (eplace);
}
char *term()
{
char *tp,*ep2,*eplace,*tt;
tp=(char *)malloc(12);
ep2=(char *)malloc(12);
eplace=(char *)malloc(12);
tt=(char *)malloc(12);

strcpy(eplace,factor());

while((syn==15)||(syn==16))
{
if (syn==15)
strcpy(tt,"*");
else
strcpy(tt,"/");
scaner();
strcpy(ep2,factor());
strcpy(tp,newtemp());
emit(tp,eplace,tt,ep2);
strcpy(eplace,tp);
}
return (eplace);
}
char *factor()
{
char *fplace;
fplace=(char *)malloc(12);
strcpy(fplace,"");

if(syn==10) //得到字元
{
strcpy(fplace,token);
scaner();
}
else if(syn==11) //得到數字
{
itoa(sum,fplace,10);
scaner();
}
else if(syn==27) //得到)
{
scaner();
fplace=expression();
if(syn==28) //得到(
scaner();
else
{
printf("error on ')' !\n");
kk=1;
getch();
exit(0);
}
}
else
{
printf("error on '(' !\n");
kk=1;
getch();
exit(0);
}
return (fplace);
}
//該函數回送一個新的臨時變數名,臨時變數名產生的順序為T1,T2...
char *newtemp()
{
char *p;
char m[8];
p=(char *)malloc(8);

kk++;
itoa(kk,m,10);
strcpy(p+1,m);
p[0]='t';
return(p); //設置中間變數名放在一個字元數組中,字元數組的第一個字元為t第二個字元為m表示的數值
}
void scaner()
{
sum=0;
///for(m=0;m<8;m++)
//token[m++]=NULL;
memset(token,0,8);
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;
token[m++] = ch;
ch=prog[p++];
if(ch=='=')
{
syn=18;
token[m++] = ch;
}
else
{
syn=17;
p--;
}
break;

case '+': syn=13;token[0] = ch; break;
case '-': syn=14;token[0] = ch; break;
case '*': syn=15;token[0] = ch;break;
case '/': syn=16;token[0] = ch;break;
case '(': syn=27;token[0] = ch;break;
case ')': syn=28;token[0] = ch;break;
case '=': syn=25;token[0] = ch;break;
case ';': syn=26;token[0] = ch;break;
case '#': syn=0;token[0] = ch;break;
default: syn=-1;break;
}
}
//該函數是生成一個三地址語句送到四元式表中
void emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad[q].result1,result);
strcpy(quad[q].ag11,ag1);
strcpy(quad[q].op1,op);
strcpy(quad[q].ag21,ag2);
q++; //統計有多少個四元式
}

閱讀全文

與編譯原理實驗詞法分析設計與實現相關的資料

熱點內容
為什麼說光遇白鳥是安卓的神 瀏覽:763
玩客雲改裝成伺服器 瀏覽:644
數據結構與演算法分析視頻教程 瀏覽:394
伺服器維保從什麼時候開始計算 瀏覽:804
泰爾網測連不上伺服器怎麼回事 瀏覽:917
壹同app怎麼玩 瀏覽:981
手機版方舟如何自己創造伺服器 瀏覽:339
php設置永久cookie 瀏覽:497
jenkins編譯代碼git腳本報錯 瀏覽:217
linuxgui開發 瀏覽:84
相干壓縮態與壓縮相干態 瀏覽:275
如何復制加密門禁卡信號 瀏覽:210
frp伺服器token是什麼 瀏覽:760
編輯動作命令 瀏覽:32
pc原神怎麼進入世界樹伺服器 瀏覽:651
華為用方舟編譯 瀏覽:822
linux可視化界面 瀏覽:456
安卓手機發什麼可以恢復聊天記錄 瀏覽:283
騰訊雲伺服器怎麼下載輸入法 瀏覽:160
奈及利亞主要加密貨幣交易所 瀏覽:494