1. 预处理的任务
预处理作为实现词法分析器的前提。
(1)合并空白符:把原始程序中相邻的空格、制表符、回车等空白符合并成一个空格,便于后续处理
(2)消除注释:消除原始程序中的注释内容
单行注释:“//”引导内容,与C++语言中单行注释一致
多行注释:“(*”和“*)”之间内容
2. PL/0示例程序
3. 思路
将预处理分为两个部分来完成:消除注释和合并空白符
(1)首先是消除注释:先将注释所在的行置为空行,再将空行去除。
注释有单行注释和多行注释:多行注释比较简单,只需要找到位置即可;单行注释分为整行都是注释,或者一行当中前一部分是代码,后一部分是注释。
(2)合并空白符
借鉴了其它博主的思想,将合并空白符转化为提取字符串,即将连续的字符串提取出来,再用空格做间隔。
4. 其它
在代码实现中使用了读文件和写文件操作。这个是参考其他博主的。下面附上链接。
首先读入文件pl0.txt,将文件内容存入一个字符串数组buffer[];将处理之后的结果存入字符串数组buffer1[],再写入文件pl0_txt
5.代码实现
代码中的一些注释掉的输出语句,是用来调试程序的。
其中要注意在进行字符串提取时,要在每一行的末尾加上一个空格。
具体实现见代码和注释,如下。
#include<iostream>
#include<fstream>
#include<string.h>
using namespace std;
/**
预处理程序的主要功能包括两部分:
(1)合并空白符:把原始程序中相邻的空格、制表符、回车等空白符合并成一个空格,便于后续处理
(2)消除注释:消除原始程序中的注释内容。
单行注释:“//”引导内容
多行注释:“(*”和“*)”之间的内容
**/
int main()
{
ifstream ifs;
ifs.open("pl0.txt");
//读取:将文件读取到字符串数组buffer中
string buf;
string buffer[20]; //存储文件
int n=0;
while(getline(ifs,buf))
{
int length=buf.length();
if(length!=0) //将非空行存储到buffer中
{
buffer[n]=buf;
n++;
}
}//共存入n行
ifs.close();
//消除单行注释:有两种情况
//1.整行都是注释:将该行置为空行
//2.代码+注释:删除注释部分
for(int i=0;i<n;i++)
{
int position=buffer[i].find("//");
if(position!=-1) //有注释的行
{
buffer[i]=buffer[i].substr(0,position);//截取前一部分(这个时候可能产生空行)
}
}
//消除多行注释:将多行注释置为空行
int begin=-1; //"(*"所在的行
int end=-1; //"*)"所在的行
for(int i=0;i<n;i++)
{
if(buffer[i].find("(*")!=-1) begin=i;
if(buffer[i].find("*)")!=-1) end=i;
if(begin!=-1 && end!=-1)
{
for(int j=begin;j<=end;j++)
buffer[j]="";
begin=-1;
end=-1;
}
}
//将生成的空行删除,并合并空白符,结果另存于buffer1
string buffer1[20];
int m=0;
for(int i=1;i<n;i++)
{
int length=buffer[i].length();
if(length!=0) //对非空行进行保存
{
// cout<<"第"<<i<<"行,长度为:"<<length<<endl;
buffer[i]+=" "; //最后加一个空格便于截取子串
// cout<<"第"<<i<<"行,长度为:"<<buffer[i].length()<<endl;
//对每一行当中的子串进行提取,通过空格间隔,存放入s中,最后将s存放入buffer1中
string s="";
int beg=-1; //每个子串的开始
int en=-1; //每个子串的结束
for(int j=0;j<buffer[i].length();j++) //对每一个非空行进行遍历
{
if(buffer[i][j]!=' ' && beg==-1)
{
beg=j;
// cout<<"字串开始于"<<beg<<endl;
}
if(buffer[i][j]==' ' && beg!=-1)
{
en=j;
// cout<<"子串结束于"<<en<<endl;
//截取子串
string s1=buffer[i].substr(beg,en-beg);
s=s+s1+" ";
beg=-1;
en=-1;
}
}
// cout<<s<<endl;
buffer1[m]=s;
m++;
}
}//此时,buffer1中存放的是预处理后的程序,共有m行,每一行最后一个字符都是空格
//将预处理后的程序写入文件pl0_.txt
ofstream ofs;
ofs.open("pl0_.txt");
for(int i=0;i<m;i++)
{
ofs<<buffer1[i]<<endl;
}
// ofs<<"zww"<<endl;
cout<<"预处理完毕!";
ofs.close();
return 0;
}