词法分析(C++)

来源:互联网 发布:海岛奇兵塔克升级数据 编辑:程序博客网 时间:2024/04/29 14:04

题目:输入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;}



0 0
原创粉丝点击