最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++實(shí)現(xiàn)詞法分析程序的示例代碼

 更新時(shí)間:2023年05月24日 09:36:19   作者:Aricl.  
這篇文章主要為大家詳細(xì)介紹了如何基于C/C++實(shí)現(xiàn)一個(gè)簡單的詞法分析程序,并通過完成詞法分析程序,了解詞法分析的過程,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)

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

通過完成詞法分析程序,了解詞法分析的過程。編制一個(gè)讀單詞程序,對(duì)PL/0語言進(jìn)行詞法分析,把輸入的字符串形式的源程序分割成一個(gè)個(gè)單詞符號(hào),即基本保留字、標(biāo)識(shí)符、常數(shù)、運(yùn)算符、分界符五大類。

對(duì)PL/0語言進(jìn)行詞法分析,把輸入的字符串形式的源程序分割成一個(gè)個(gè)單詞符號(hào),其詞法描述如下:

(1)關(guān)鍵字:

begin,call,const,do,end,if,odd,procedure,read,then,var,while,write

(2) 標(biāo)識(shí)符:用來表示各種名字,必須以字母開頭小于10位字符組成

(3) 數(shù)字:以0-9組成小于14位的數(shù)字

(4) 運(yùn)算符:+,-,*,/,:=,<,<=,>,>=,#

(5) 分界符:, ,. ,; ,( ,)

二、實(shí)驗(yàn)代碼

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<iomanip>
using namespace std;
//創(chuàng)建四個(gè)表,儲(chǔ)存符號(hào) 
const char *k[13]={"begin","call","const","do","end","if","odd","procedure","read","then","var","while","write"};//關(guān)鍵字表
const char *s1[5]={",",".",";","(",")"};//界符表
const char *s2[6]={"+","-","*","/","++","--",};//運(yùn)算符號(hào)表 
const char *s3[9]={"<=",">",">=","=",">",">=","<>",":=","#"}; //關(guān)系運(yùn)算符號(hào)表 
//定義全局變量
int row=1,line=1; 
int t,p=0;//單詞類別碼以及記錄移動(dòng)指針
char instring[100];//保存輸入的程序代碼緩存數(shù)組
char outtoken[10];//輸出
char ci[8],id[10];//暫時(shí)保存數(shù)字和字符
//函數(shù)的聲明
void analysis();//分析函數(shù),決定調(diào)用哪個(gè)函數(shù)進(jìn)行分析
void symbol();//分析以非字母數(shù)字開頭的字符
void constant();//分析常數(shù)
void alphabet();//分析標(biāo)識(shí)符和關(guān)鍵字
void show();//打印輸出函數(shù)
bool isnumber(char x);//判斷是否是數(shù)字 
bool isalpha(char x);//判斷是否是字母 
int main(){
	cout<<"請(qǐng)輸入一段程序代碼并以@結(jié)束:"<<endl;
	//輸出程序代碼 
	do{
		instring[p++]=getchar();
	} while(instring[p-1]!='@'); 
	getchar();//吸收回車鍵 
	instring[p-1]='\0';//抵消掉@
	p=0;//移動(dòng)指針歸零
	cout<<left;
	cout<<"------------------------------------------------------------------------------"<<endl; 
	cout<<setw(6)<<"單詞"<<"			"<<setw(6)<<"二元序列"<<"			"<<setw(6)<<"類型"<<"			"<<endl;
	//掃描輸入的字符 
	while(p<strlen(instring)){
		analysis();
		show();
	} 
	cout<<"------------------------------------------------------------------------------"<<endl; 
	cout<<"[注]:"<<endl;
	cout<<"t=1:關(guān)鍵字,"<<"t=2:分界符,"<<"t=3:算術(shù)運(yùn)算符,"<<"t=4:關(guān)系運(yùn)算符,"<<"t=5:常數(shù),"<<"t=6:標(biāo)識(shí)符,"<<"t==7:詞法出錯(cuò)"<<endl; 
	cout<<"@為結(jié)束符,不參與到詞法分析中"<<endl; 
	cout<<endl;
	return 0;
} 
//判斷是否是數(shù)字
bool isnumber(char x){
	return x>='0'&&x<='9';
}
//判斷是否是字母
bool isalpha(char x){
	return (x>='a'&&x<='z'||x>='A'&&x<='Z');
}
//分析函數(shù),決定調(diào)用哪個(gè)函數(shù)進(jìn)行分析
void analysis(){
	strcpy(outtoken,"");//清空outtoken數(shù)組
	while(instring[p]==' '||instring[p]=='\n'){
		if(instring[p]=='\n'){
			row++;
			line=1;
		}
		p++;
	} 
	//執(zhí)行完之后指向第一個(gè)不為空格的字符
	char ch=instring[p];
	//按照字符的類別調(diào)用不同的分析處理函數(shù) 
	if(isalpha(ch))
	   alphabet();
	else if(isnumber(ch))
		constant();
	else 
		symbol();
}
//常數(shù)處理函數(shù)
void constant(){
	strcpy(ci,"");//清空ci
	t=5;//類別碼
	int i=0;
	while(isnumber(instring[p])){
		ci[i++]=instring[p++]; 
	} 
	while(isalpha(instring[p])||isnumber(instring[p])){
		ci[i++]=instring[p++];
		t=7;//出錯(cuò) 
	}
	ci[i]='\0';//結(jié)束符
	//strcpy_s(outtoken,strlen(ci)+1,ci);
	strcpy(outtoken,ci);
	line++;
	return; 
} 
//標(biāo)識(shí)符和關(guān)鍵字的分析函數(shù)
void  alphabet(){
	strcpy(id,"");//清空id
	int i=0;
	//讀取連續(xù)的字母數(shù)字序列 
	while(isalpha(instring[p])||isnumber(instring[p])){
		id[i++]=instring[p++];//p指向連續(xù)序列之后的第一個(gè)字符 
	} 
	id[i]='\0';
	//查關(guān)鍵字表 
	for(i=0;i<8;i++){
		if(strcmp(id,k[i])==0){
			t=1;//表示關(guān)鍵字
			line++;
			strcpy(outtoken,id);
			return; //是關(guān)鍵字的話,直接退出 
		}
	}
	//查看是否是標(biāo)識(shí)符
	for(i=0;i<strlen(id);i++){
		if(!(isalpha(id[i])||isnumber(id[i]))){
			t=7;
			strcpy(outtoken,id);
			line++;
			return;
		}
	} 
	line++;
	t=6;//不是關(guān)鍵字且沒有出錯(cuò)即為標(biāo)識(shí)符
	strcpy(outtoken,id);
}
//其它運(yùn)算符的分析函數(shù)
void symbol(){
	char ch=instring[p++];
	char ch2=instring[p];
	t=7;
	switch(ch){
		case '+':
			if(ch2=='+')
			  t=3;
			break;
		case '-':
			if(ch2=='-')
			  t=3;
			break;
		case '>':
			if(ch2=='=')
			  t=4;
			break;
		case '<':
			if(ch2=='='||ch2=='>')
			  t=4;
			break;
		case ':':
			if(ch2=='=')
			  t=3;
			break;
	}
	//判斷是否具有兩個(gè)符號(hào)的運(yùn)算符
	if(ch=='>'&&ch2=='='||ch=='<'&&ch2=='='||ch=='<'&&ch2=='>'||ch=='+'&&ch2=='+'||ch=='-'&&ch2=='-'||ch==':'&&ch2=='='){
		p++;
		outtoken[0]=ch;
		outtoken[1]=ch2;
		outtoken[2]='\0';
		line++;
		return;
	} else{
		char chq[2];
		chq[0]=ch;
		chq[1]='\0';
		//分界符比較 
		for(int i=0;i<6;i++){
			if(strcmp(chq,s1[i])==0){
				t=2;
				break;
			}
		}	
		//算術(shù)運(yùn)算符比較 
		for(int i=0;i<6;i++){
			if(strcmp(chq,s2[i])==0){
				t=3;
				break;
			}
		}	
		//關(guān)系運(yùn)算符比較 
		for(int i=0;i<9;i++){
			if(strcmp(chq,s3[i])==0){
				t=4;
				break;
			}
		}
	}
	line++;
	outtoken[0]=ch;
	outtoken[1]='\0';
	return;
} 
//輸出函數(shù),根據(jù)以上分析函數(shù)進(jìn)行打印輸出分析的結(jié)果
void show(){
	cout<<left;
	//setw(6)表示占位寬度為6個(gè)字符 
	if(t==7){
		cout<<setw(6)<<outtoken<<"			"<<setw(6)<<"ERROR!"<<setw(11)<<" "<<setw(10)<<"ERROR!";
	}else{
		cout<<left;
		cout<<setw(6)<<outtoken<<"			"<<"<"<<t<<","<<outtoken;
		cout<<setw(6-strlen(outtoken))<<">"<<"			";
		switch(t){
			case 1:cout<<left<<setw(10)<<"關(guān)鍵字";break;
			case 2:cout<<left<<setw(10)<<"分界符";break;
			case 3:cout<<left<<setw(10)<<"算術(shù)運(yùn)算符";break;
			case 4:cout<<left<<setw(10)<<"關(guān)系運(yùn)算符";break;
			case 5:cout<<left<<setw(10)<<"常數(shù)";break;
			case 6:cout<<left<<setw(10)<<"標(biāo)識(shí)符";break;
		}
	} 
	cout<<endl;
} 
/*變量說明: 
k數(shù)組:關(guān)鍵字表; s數(shù)組:分界符表,其中分界符,算術(shù)運(yùn)算符,關(guān)系運(yùn)算符分別存放在s1,s2,s3數(shù)組中 
id:標(biāo)識(shí)符; ci:常數(shù) ;row:行 line:列,單詞的位置 
instring數(shù)組:為輸入源程序代碼的單詞緩存; outtoken數(shù)組:記錄為輸出內(nèi)部表示緩存
 symbol:分析//后的注釋;constant:常數(shù)分析;alphabet:標(biāo)識(shí)符和關(guān)鍵字分析
analysis:分析函數(shù),根據(jù)輸入字符判斷調(diào)用哪一個(gè)函數(shù) ;show:輸出打印函數(shù)
t:單詞的種類 t=1:關(guān)鍵字 t=2:分界符 t=3:算術(shù)運(yùn)算符 t=4:關(guān)系運(yùn)算符 t=5:常數(shù) t=6:標(biāo)識(shí)符 t=7:出錯(cuò)*/

三、實(shí)驗(yàn)結(jié)果

測(cè)試一

測(cè)試二

四、實(shí)驗(yàn)總結(jié)

整體的代碼思路是創(chuàng)建四個(gè)數(shù)組分別存放關(guān)鍵字表、界符表、運(yùn)算符號(hào)表、關(guān)系運(yùn)算符號(hào)表,這樣若想新增符號(hào)只需要在數(shù)組中修改即可,實(shí)現(xiàn)動(dòng)態(tài)變化而非寫死的。

下面進(jìn)行模塊化設(shè)計(jì),總共分為analysis()、symbol()、constant()、alphabet()、show()、isnumber()、isalpha()七個(gè)函數(shù),analysis函數(shù)作為總的分析函數(shù),通過分析當(dāng)前字符是否是字母還是數(shù)字或者其它符號(hào),分別調(diào)用不同的函數(shù)進(jìn)行具體的分析,然后將結(jié)果存儲(chǔ)在全局變量outtoken和t中,前者代表輸出的二元組,后者代表該單詞的類型,難點(diǎn)在于兩個(gè)符號(hào)的運(yùn)算符的判斷。

本題還有一個(gè)細(xì)節(jié)之處,在輸入完代碼后敲的那個(gè)回車鍵會(huì)多余需要使用一個(gè)getchar()函數(shù)來吸收掉,并且結(jié)束符@為自定義的,不參與到詞法分析中,所以在輸入完程序代碼后使用instring[p-1]='\0';//抵消掉@,這樣就使得instring數(shù)組里存放的是完整的有效的程序代碼,不含結(jié)束符。

到此這篇關(guān)于C/C++實(shí)現(xiàn)詞法分析程序的示例代碼的文章就介紹到這了,更多相關(guān)C++詞法分析內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c++定義全局變量詳解

    c++定義全局變量詳解

    這篇文章主要給大家介紹了C++語言中定義全局變量,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2021-10-10
  • 深入c語言continue和break的區(qū)別詳解

    深入c語言continue和break的區(qū)別詳解

    本篇文章是對(duì)c語言中continue和break的區(qū)別進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Dev C++ 安裝及使用方法(圖文教程)

    Dev C++ 安裝及使用方法(圖文教程)

    Dev C++ 是一款非常好用,簡約的C/C++開發(fā)工具,本文主要介紹了Dev C++ 安裝及使用方法(圖文教程),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 利用C++和QT實(shí)現(xiàn)Log自定義日志系統(tǒng)

    利用C++和QT實(shí)現(xiàn)Log自定義日志系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了如何利用C++和QT實(shí)現(xiàn)Log自定義日志系統(tǒng),文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考下
    2023-12-12
  • 關(guān)于C++一些特性的探究

    關(guān)于C++一些特性的探究

    下面小編就為大家?guī)硪黄P(guān)于C++一些特性的探究。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • C++與Qt的內(nèi)存管理機(jī)制詳解

    C++與Qt的內(nèi)存管理機(jī)制詳解

    這篇文章主要介紹了C++與Qt的內(nèi)存管理機(jī)制使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • C++?LeetCode542矩陣示例詳解

    C++?LeetCode542矩陣示例詳解

    這篇文章主要為大家介紹了C++?LeetCode542矩陣示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • c++中struct使用注意事項(xiàng)

    c++中struct使用注意事項(xiàng)

    本文通過2個(gè)小示例給大家展示了一下c++中struct使用的注意事項(xiàng),希望對(duì)大家學(xué)習(xí)C++能夠有所幫助。
    2016-01-01
  • C++類和對(duì)象之初始化列表的使用方式

    C++類和對(duì)象之初始化列表的使用方式

    這篇文章主要介紹了C++類和對(duì)象之初始化列表的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • C++模板超詳細(xì)介紹

    C++模板超詳細(xì)介紹

    C++語言的模板技術(shù)包括函數(shù)模板和類模板,模板技術(shù)是一種代碼重用技術(shù),函數(shù)和類是C++語言中兩種主要的重用代碼形式,這篇文章主要介紹了C++函數(shù)模板和類模板,需要的朋友可以參考下
    2022-09-09

最新評(píng)論

济宁市| 永昌县| 吴旗县| 兴国县| 元朗区| 定边县| 锦屏县| 桓台县| 泰兴市| 蕲春县| 巴楚县| 东辽县| 西乌珠穆沁旗| 大厂| 封丘县| 胶南市| 鄢陵县| 石狮市| 天门市| 江阴市| 阿拉善右旗| 会宁县| 宁安市| 甘德县| 准格尔旗| 疏勒县| 叙永县| 桂林市| 确山县| 崇阳县| 垣曲县| 镇巴县| 深圳市| 会昌县| 施秉县| 南康市| 城固县| 柏乡县| 丰都县| 玛多县| 马公市|