编译原理词法分析程序设计(C++)

编译原理词法分析程序设计

实验内容

1.对源程序进行理解,从PL0文档中抽取出词法部分的代码,单独作为一个程序,变成一个词法程序,用visual6.0或者Dev c++进行编译,编译成为可执行文件;
词法分析部分的代码如下:

#include<fstream>
#include<cstring>
#include<string>
#include<fstream>
#include<sstream>
#include<iostream>
#include<map>
#include<bits/stdc++.h>
#include <iostream>  
#include <fstream>  
#include <stdlib.h>
using namespace std;
map<string,string> word;//应用map数据结构形成一个string->string的对应
std::map<string,string>::iterator it;//用来遍历整个对应关系的迭代器
void map_init(){//对应关系进行初始化
    word["begin"]="beginsym";
    word["call"]="callsym";
    word["const"]="constsym";
    word["do"]="dosym";
    word["end"]="endsym";
    word["if"]="ifsym";
    word["odd"]="oddsym";
    word["procedure"]="proceduresym";
    word["read"]="readsym";
    word["then"]="thensym";
    word["var"]="varsym";
    word["while"]="whilesym";
    word["write"]="writesym";
    word["+"]="plus";
    word["-"]="minus";
    word["*"]="times";
    word["/"]="slash";
    word["="]="eql";
    word["<>"]="neq";
    word["<"]="lss";
    word["<="]="leq";
    word[">"]="gtr";
    word[">="]="geq";
    word[":="]="becomes";
    word[":"]="colon";
    word["("]="lparen";
    word[")"]="rparen";
    word["["]="lmiddlebracket";
    word["]"]="rmiddlebracket";
    word[","]="comma";
    word[";"]="semicolon";
    word["."]="period";
    word["!"]="exclamationmark";
    word["\""]="doublequotation";
    word["\'"]="singlequotes";
    word["?"]="questionmark";
    word["^"]="power";
    word["#"]="poundsign";
}
struct node{
	string id;
	string s;
}aa[10000];
int main(){
    map_init();//初始化
    char ch;
    char a;
    int len = 0;
    string word1;//string变量识别单词
    string str;//string变量进行字符识别
    ifstream infile("D:\\源文件.txt");//文件输入流,文件路径
    ofstream outfile("D:\\二元组结果.txt");//文件输出流
    ostringstream buf;
    while(buf&&infile.get(ch)) buf.put(ch);//将文件中的字符读出来
    str= buf.str();//将得到的字符储存到string类型变量中
    int csize=str.length();
    for(int i=0;i<csize;i++){//对整个字符串进行遍历
        while(str[i]==' '||str[i]=='\n') i++;//若最开始为空格或换行符,则将指针的位置往后移
        if(isalpha(str[i])){//对标识符和基本字进行识别,调用库函数isalpha()
            word1=str[i++];
            while(isalpha(str[i])||isdigit(str[i])){
                word1+=str[i++];
            }
            it=word.find(word1);
            if(it!=word.end()){//判断是不是基本字,若为基本字则进行输出
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id =word[word1];
                aa[len++ ].s = word1;
            }
            else{//否则直接输出
                cout<<"(ident"<<","<<word1<<")"<<endl;
                 aa[len].id  =  "ident";
                aa[len++].s = word1;
            }
            i--;
        }
        else if(isdigit(str[i])){//判断是不是常数,调用库函数isdigit()
            word1=str[i++];
            while(isdigit(str[i])){
                word1+=str[i++];
            }
            if(isalpha(str[i])){
                cout<<"error!"<<endl;
                break;
            }
            else{
                cout<<"(number"<<","<<word1<<")"<<endl;
                 aa[len].id  = "number";
                aa[len++].s = word1;
            }
            i--;
        }else if(str[i]=='<'){//对<,<=分别进行判断
            word1=str[i++];
            if(str[i]=='>'){
                word1+=str[i];
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else if(str[i]=='='){
                word1+=str[i];
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
               aa[len].id  = word[word1];
               aa[len++].s = word1;
            }else if(str[i]!=' '||!isdigit(str[i])||!isalpha(str[i])){
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else{
                cout<<"error!"<<endl;
                break;
            }
            i--;          
        }else if(str[i]=='>'){//对>,>=分别进行判断
            word1=str[i++];
            if(str[i]=='='){
                word1+=str[i];
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else if(str[i]!=' '||!isdigit(str[i])||!isalpha(str[i])){
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else{
                cout<<"error!"<<endl;
                break;
            }
            i--;
        }else if(str[i]==':'){//对:=进行判断
            word1=str[i++];
            if(str[i]=='='){
                word1+=str[i];
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else if(str[i]!=' '||!isdigit(str[i])||!isalpha(str[i])){
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else{
                cout<<"error!"<<endl;
                break;
            }
            i--;
        }else{//对其他的基本字依次进行判断
            word1=str[i];
            it=word.find(word1);
            if(it!=word.end()){
                cout<<"("<<word[word1]<<","<<word1<<")"<<endl;
                aa[len].id  = word[word1];
                aa[len++].s = word1;
            }else{
                cout<<"error!"<<endl;
                break;
            }
        }
    }
    //输出流,输出到对应的结果文件中
      if (outfile.is_open())   
    {  
        for(int i = 0 ;i < len ;i ++){
        	 outfile <<"("<<aa[i].id<<","<<aa[i].s<<")"<<'\n';  
		} 
		 outfile.close(); 
    }  
    infile.close();
    return 0;
}

2.对输出的文件进行检验,用PL0验证源程序作为词法验证输入源程序,对其进行读入;
我这里读取的是一个很长的pl0的程序代码,里面包含各种标识符、关键字、界符、运算符,常数等,比较有验证性。
只截取了部分
3.单词序列二元组结果的显示并保存成结构文件;
以二元组的格式保存在结果文件中。
只截取了部分
我最开始做这个实验的时候一头雾水,这是给我指路的文章,非常感谢,里面对词法分析的设计思想、算法流程等都有详细的说明。https://blog.csdn.net/Flamewaker/article/details/82902906?utm_source=app
但是经过实践发现了两个小问题:
1.我的被识别文件里面的字符种类太多,所以在链接中这篇文章里的代码基础上添加了一些自负的对应关系;
2.链接中这篇文章里的代码中只有输入流操作代码,缺少输出流的操作代码,导致程序可以运行,但结果文件中没有输出内容。添加对输出流的操作后,运行结果和结果文件中都有了正确的输出内容。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值
>