用c++做pl0的编译时,对于一个注释“{。}”,我想屏蔽掉“{。}”,同时当花括号不匹配时还要报错。
目前编写这个的一个段代码如下:
case'}':ch=fgetc(fp);
while(ch!='}'){ch=fgetc(fp;i++;)}
现在出现的问题就是,当不存在“}”时,程序就会停止在“{”前一个字符(其实也就是进入了一个死循环);
现在我就是想请大神们帮忙修改。。例如:对abc{xxxx}dfg
当{}匹配的时候,就把xxxx过滤掉,对然后能继续读取dfg
当{}不匹配的时候,就把abc xxxx dfg都加以读取。(此时半边花括号)

解决方案 »

  1.   

    整个不成形的代码如下
    #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;
    }
      

  2.   

    下面是那个作为test的一些代码:
    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.
      

  3.   

    判断一下fgetc的返回值,当为EOF的时候,退出while