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