词法分析(C++)

题目:输入PL/0语言源程序的文本文件,输出源程序中所有单词种类,并以文本文件保存


思路:这次是在上次识别标识符的基础上增加了查找功能,确定单词种类。在分词函数部分做了一些修改,设errflag参数,用以确定单词是否非法,以达到忽略非法标识符的目的。


部分代码-分类查找

for(i=0;i<words.size();i++){
if(isalpha(words[i][0])){ 
	for(k=0;k<reserved_word.size();k++){
	    if( words[i] == reserved_word[k] ) {//是保留字
		out << "(" << word_sym[k]<< " , " <<words[i] <<" )"<<endl;
		break;
	    }
	}
	if(k==reserved_word.size()){ //是标志符
	   out << "(ident , " <<words[i] <<" )"<<endl;
	}
}
else if(isdigit(words[i][0])){ //是数字
	out << "(number , " <<words[i] <<" )"<<endl;
    }
    else{
	for(k=0;k<operators.size();k++){
		if(words[i] == operators[k]) { //是运算符
		out << "(" << oprsym[k]<< " , " <<words[i] <<" )"<<endl;
			break;
		}
	}
	if(k==operators.size()){ 
		for(j=0;j<delimiters.size();j++){//是界符
			if(words[i] == delimiters[j]){
			out << "(" << delsym[j]<< " , " <<words[i] <<" )"<<endl;
				break;
			}
		}
	}
    }
}


完整代码如下:

#include "stdafx.h"
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <cctype>

using namespace std;

void splitword(vector<string>  &words,string &s)
{
	string temp;
	int i=0;
	int flag=0,errflag=0;  //flag表示之前一个字符的种类;errflag表示该单词是否非法
	while(s[i] != 0){
		if(isalpha(s[i])){  //如果是字母
			if(s[i] >= 'A' && s[i] <= 'Z' )  s[i] -= -32; //转成小写
			if(flag != 1 && flag != 2 ) 	{	 //如果前面一个字符不是字母或者数字,则断开该字符
				if(errflag==0)
					words.push_back(temp);
				errflag=0;
				temp = "";
			}
			if(temp!="" && !isalpha(temp[0])) errflag=1;
			temp += s[i];
			flag = 1;
		}
		else if(isdigit(s[i])){//如果是数字
			if(flag != 1 && flag != 2){	
				if(errflag==0)
					words.push_back(temp);
				errflag=0;
				temp = "";
			}
			temp += s[i];
			flag = 2;
		}
		else if(s[i] == ' ' || s[i] == '\t'){
			flag = 0;
		}
		else if(s[i] == '_' && isalpha(temp[0])) //只允许在单词后加下划线,否则忽略
			temp += s[i];
		else {
			if(flag != 3 || s[i] != '='){	
				if(errflag==0)
					words.push_back(temp);
				errflag=0;
				temp = "";
			}
			temp += s[i];
			flag = 3;
		}
		i++;
		if(s[i]==0){
			if(errflag==0)  
				words.push_back(temp);
			errflag=0;
			temp="";
		}
	}
}

void init(vector<string> &reserved_word,vector<string> &word_sym,
		  vector<string> &operators,vector<string> &oprsym,
		  vector<string> &delimiters,vector<string> &delsym){
	reserved_word.push_back("begin");
	reserved_word.push_back("call");
	reserved_word.push_back("const");
	reserved_word.push_back("do");
	reserved_word.push_back("end");
	reserved_word.push_back("if");
	reserved_word.push_back("odd");
	reserved_word.push_back("procedure");
	reserved_word.push_back("read");
	reserved_word.push_back("then");
	reserved_word.push_back("var");
	reserved_word.push_back("while");
	reserved_word.push_back("write");

	word_sym.push_back("beginsym");
	word_sym.push_back("callsym");
	word_sym.push_back("constsym");
	word_sym.push_back("dosym");
	word_sym.push_back("endsym");
	word_sym.push_back("ifsym");
	word_sym.push_back("oddsym");
	word_sym.push_back("procsym");
	word_sym.push_back("readsym");
	word_sym.push_back("thensym");
	word_sym.push_back("varsym");
	word_sym.push_back("whilesym");
	word_sym.push_back("writesym");

	operators.push_back("+");
	operators.push_back("-");
	operators.push_back("*");
	operators.push_back("/");
	operators.push_back("=");
	operators.push_back("#");
	operators.push_back("<");
	operators.push_back(">");
	operators.push_back("<=");
	operators.push_back(">=");
	operators.push_back(":=");

	oprsym.push_back("plus");
	oprsym.push_back("minus");
	oprsym.push_back("times");
	oprsym.push_back("slash");
	oprsym.push_back("eql");
	oprsym.push_back("neq");
	oprsym.push_back("lss");
	oprsym.push_back("leq");
	oprsym.push_back("gtr");
	oprsym.push_back("geq");
	oprsym.push_back("becomes");

	delimiters.push_back("(");
	delimiters.push_back(")");
	delimiters.push_back(",");
	delimiters.push_back(";");
	delimiters.push_back(".");

	delsym.push_back("lparen");
	delsym.push_back("rparen");
	delsym.push_back("comma");
	delsym.push_back("semicolon");
	delsym.push_back("period");
}

int _tmain(int argc, _TCHAR* argv[])
{
	vector<string> reserved_word;
	vector<string> word_sym;
	vector<string> operators;
	vector<string> oprsym;
	vector<string> delimiters;
	vector<string> delsym;
	init(reserved_word,word_sym,operators,oprsym,delimiters,delsym);
	vector<string> words;
	ifstream in;
	string filename;
	int endflag=0;
	while(endflag==0){
		cout << "请输入源程序文件名(输入end则退出该程序,以.txt结尾):";
		cin >> filename;
		if(filename =="end") endflag=1;
		else{
			in.open(filename); 
			if(!in){
				cout << "文件打开错误" <<endl;
			}
			else{
				string s;
				while(getline(in,s)) {
					splitword(words,s);
				}
				in.close();
		
				string outfilename;
				ofstream out;
				cout << "请输入输出文件名(请以.txt结尾):";
				cin >> outfilename;
				out.open(outfilename);
				//判断
				unsigned int i,k,j;
				for(i=0;i<words.size();i++){
					if(isalpha(words[i][0])){ 
						for(k=0;k<reserved_word.size();k++){
							if( words[i] == reserved_word[k] ) {//是保留字
								out << "(" << word_sym[k]<< " , " <<words[i] <<" )"<<endl;
								break;
							}
						}
						if(k==reserved_word.size()){ //是标志符
								out << "(ident , " <<words[i] <<" )"<<endl;
						}
					}
					else if(isdigit(words[i][0])){ //是数字
						out << "(number , " <<words[i] <<" )"<<endl;
					}
					else{
						for(k=0;k<operators.size();k++){
							if(words[i] == operators[k]) { //是运算符
								out << "(" << oprsym[k]<< " , " <<words[i] <<" )"<<endl;
								break;
							}
						}
						if(k==operators.size()){ 
							for(j=0;j<delimiters.size();j++){//是界符
								if(words[i] == delimiters[j]){
									out << "(" << delsym[j]<< " , " <<words[i] <<" )"<<endl;
									break;
								}
							}
						}
					}
				}
				out.close();
				cout << "结果为:"<<endl;
				in.open(outfilename);
				while(getline(in,s)) cout << s <<endl;
				cout << "结果已存入"<<outfilename<<endl;
			}
		}
	}
	system("pause");
	return 0;
}



  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值