用c++做pl0的编译时,对于一个注释“{。}”,我想屏蔽掉“{。}”,同时当花括号不匹配时还要报错。
目前编写这个的一个段代码如下:
case'}':ch=fgetc(fp);
while(ch!='}'){ch=fgetc(fp;i++;)}
现在出现的问题就是,当不存在“}”时,程序就会停止在“{”前一个字符(其实也就是进入了一个死循环);
现在我就是想请大神们帮忙修改。。例如:对abc{xxxx}dfg
当{}匹配的时候,就把xxxx过滤掉,对然后能继续读取dfg
当{}不匹配的时候,就把abc xxxx dfg都加以读取。(此时半边花括号)
目前编写这个的一个段代码如下:
case'}':ch=fgetc(fp);
while(ch!='}'){ch=fgetc(fp;i++;)}
现在出现的问题就是,当不存在“}”时,程序就会停止在“{”前一个字符(其实也就是进入了一个死循环);
现在我就是想请大神们帮忙修改。。例如:对abc{xxxx}dfg
当{}匹配的时候,就把xxxx过滤掉,对然后能继续读取dfg
当{}不匹配的时候,就把abc xxxx dfg都加以读取。(此时半边花括号)
#include <iostream>
#include<ctype.h>
#include<string>
#include<stdlib.h>
using namespace std;
#define ID 11
#define INT 12
#define COMMA 13
#define ENDF 14
#define COLON 15
#define SEMIC 16
#define ADD 17
#define MINUS 18
#define MULTI 19
#define EVALU 20
#define LE 21
#define NE 22
#define LT 23
#define EQ 24
#define GE 25
#define GT 26
char TOKEN[20]; //字符数组用来依次存放单词词文的各个字符extern int lookup(char *); //以TOKEN字符串查保留字表
extern void out(int,char *); //以(CLASS VALUE)的二元组形式分类输出个各个单词
extern void report_error(char); //报告程序中的词法错误
bool isalpha(char); //判断接收字符是否为字母
bool isalnum(char); //判断接收字符是否为字母或者数字
bool isdigit(char); //判断接收字符是否为数字void scanner(FILE *fp)
{//词法分析的主体程序,对输入的文本文件进行词法分析
char ch;
int i,c,n=0,len=0,k=0,d=0;
int error=0; //记录文件中词法错误的个数
ch=fgetc(fp); //从输入文件中读取一个字符
while(ch!=EOF)
{//当从输入文件接收的字符不是文件结束符时,执行循环
if(isalpha(ch))
{//如果从输入文件接收的第一个字符是字母
TOKEN[0]=ch;
ch=fgetc(fp);i=1;
while(isalnum(ch))
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
}
TOKEN[i]='\0'; //在字符数组末尾添加字符串结束符
c=lookup(TOKEN); //查保留字表
if(c==0)out(ID,TOKEN); //输出接受单词为标识符
else out(c,TOKEN); //输出接收单词为保留字
}
if(isdigit(ch)) //如果从输入文件接收的第一个字符是数字
{
TOKEN[0]=ch;
ch=fgetc(fp);i=1;
while(isdigit(ch)||ch=='.')
{//从第二个接收字符开始,当是数字时,执行循环
TOKEN[i]=ch;i++;
ch=fgetc(fp); //重复接收字符,直到接收到非数字
}
if(isalpha(ch))
{
while(isalpha(ch))
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
}
TOKEN[i]='\0';
cout<<"\'"<<TOKEN<<"\'"<<" IS ERROR!"<<endl;
}
else
{
fseek(fp,-1,1);
TOKEN[i]='\0'; //在字符数组末尾添加字符串结束符
out(INT,TOKEN); //输出接收单词为整数
}
}
else //如果从输入文件接收的第一个字符既不是字母又不是数字
switch(ch)
{//将所接收到的符号字符进行分类,采取一符一类
case':':ch=fgetc(fp);
if(ch=='=')out(EVALU,"':='"); //输出接收符号为赋值号
else
{
fseek(fp,-1,1); //文件接收字符回推一个字符
out(COLON,"':'"); //输出冒号
}
break;
case',':out(COMMA,"','");break; //输出逗号
case'.':out(ENDF,"'.'");break; //输出句号
case';':out(SEMIC,"';'");break; //输出分号
case'+':out(ADD,"'+'");break; //输出加号
case'-':out(MINUS,"'-'");break; //输出减号
case'*':out(MULTI,"'*'");break; //输出乘号
case'<':ch=fgetc(fp);
if(ch=='=')out(LE,"'<='"); //输出小于或等于号
else if(ch=='>')out(NE,"'<>'"); //输出不等于号
else
{
fseek(fp,-1,1);
out(LT,"'<'"); //输出小于号
}
break;
case'=':out(EQ,"'='");break; //输出等于号
case'>':ch=fgetc(fp);
if(ch=='=')out(GE,"'>='"); //输出大于或等于号
else
{
fseek(fp,-1,1);
out(GT,"'>'"); //输出大于号
}
break;
case' ':break; //空格不作处理
case'\n':break; //换行不作处理
case'\t':break;
case'/':ch=fgetc(fp);
if(ch=='/')
{
while(ch!='\n')
{
TOKEN[i]=ch;i++;
ch=fgetc(fp);
} }
else{
fseek(fp,-1,1);
error++;
cout<<"'/' IS ERROR!"<<'\n';
}break;
case'{':while(ch!=EOF){case'}':break;
}
default:report_error(ch); //接收非上述字符程序报告词法错误
error++;break;
}
ch=fgetc(fp); //继续从文件中读取下一个单词,直到文件结束
}//while循环结束
cout<<endl<<"共发现"<<error<<"个词法错误!"<<endl;
return;
}
int lookup(char *token)
{
string keyword[10]={"else","begin","end","var","integer","while","do","if","then","procedure",};
/* 建立保留字表如下:
1 begin
2 end
3 var
4 integer
5 while
6 do
7 if
8 then
9 procedure
0 else
*/
for(int j=1;j<=9;j++)if(token==keyword[j])return j; //以TOKEN字符串查保留字表,若查到返回保留字类别码
return 0; //TOKEN不是保留字,返回0
}
void out(int c,char *token)
{//以(CLASS VALUE)的二元组形式分类输出个各个单词
cout<<'('<<c<<','<<token<<')'<<endl;
}
void report_error(char c)
{//报告程序中的词法错误
cerr<<'\''<<c<<'\''<<" IS ERROR!"<<endl;
}
bool isalpha(char c)
{ //判断接收字符是否为字母
if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))return 1;
else return 0;
}
bool isalnum(char c)
{//判断接收字符是否为字母或者数字
if((c>='a'&&c<='z')||(c>='A'&&c<='Z')||(c>='0'&&c<='9'))return 1;
else return 0;
}
bool isdigit(char c)
{//判断接收字符是否为数字
if(c>='0'&&c<='9')return 1;
else return 0;
}int main()
{
FILE *fp; //定义文件指针
char filename[20];
printf("请输入文件名:");
scanf("%s",filename);
if((fp=fopen(filename,"r"))==NULL) //打开要读取的文本文件,用fp指向
{
printf("不能打开文件.\n");
exit(0);
}scanner(fp); //调用词法分析程序
getchar();getchar();
return 0;
}
VAR 3x,y,&z:integer;
a:integer;/procedure test // aaaa
begin
while($@) do
x:=23.5+5;
y:=z+18*3-100;
{计算
dfgdfgf 判断}if 256<>986 then <=else ;
end.