词法与语法分析 (VC实现)

这两个星期按下面语法图封装了一个词法与语法的类,因为水平有限现在传上来,希望各位高手指正^_^

以下是语法图:

 头文件:

struct CIFA            //存储分析出的词
{
 CString work;  //分析出的单词
 int type;  //1 关键字,2 标识符,3 数字,4或7 错误,5 操作符,6 statement number
 int loca;  //该词在缓冲的位置
// int value;  //该词的值
 CIFA * next;    //连接下一单词
};

class CFenXi 
{
public:
 BOOL GetErrFlag();
 void PrintYuFaMsg(CString &str);
 void YuFaFenXi();
 void PrintCiFaErrMsg(CString& str);
 void CifaFenxi();
 CFenXi();
 virtual ~CFenXi();

 CIFA *m_head;  //词法分析结果
 CString m_code;  //源程序缓冲

protected:
 BOOL IsRepeat();
 BOOL Expression();
 BOOL KW_VARIABLE();
 BOOL NextWord();
 void NextYuJu();
 int WhichKW(CString str);
 BOOL Condition();
 BOOL Statement();
 BOOL Program();
 BOOL IsRem(CString str);
 BOOL IsKeyWord(CString str);
 BOOL IsString(CString str);
 BOOL KW_FOR();
 BOOL KW_END();
 BOOL KW_NEXT();
 BOOL KW_UNLOOP();
 BOOL KW_IF();
 BOOL KW_REM();
 BOOL KW_GOTO();
 BOOL KW_GOSUB();
 BOOL KW_RETURN();
 BOOL KW_INPUT(int num);
 BOOL KW_PRINT(int num);

 CIFA* cur; //指向当前分析的词
 char m_keyWord[15][10]; //关键字表
 int m_keyWordNum;  //分析的单词个数
 char m_operor[15][5];  //操作符表
 char m_errMes[35][100];  //错误信息表
 int m_errors[50]; //记录语法错误
 int m_errNum;  //记录语法错误个数
 int m_errFlag;  //词法错误标志(词法有错为非零)
 int m_staNum[50];  //记录statement number
 int m_stanum; //statement Number  个数
};

 

CPP文件:

CFenXi::CFenXi()
{
 m_errFlag = 0;
 m_head = NULL;

 strcpy(m_keyWord[0],"FOR");
 strcpy(m_keyWord[1],"END");
 strcpy(m_keyWord[2],"NEXT");
 strcpy(m_keyWord[3],"UNLOOP");
 strcpy(m_keyWord[4],"IF");
 strcpy(m_keyWord[5],"REM");
 strcpy(m_keyWord[6],"GOTO");
 strcpy(m_keyWord[7], "GOSUB");
 strcpy(m_keyWord[8],"RETURN");
 strcpy(m_keyWord[9],"INPUT");
 strcpy(m_keyWord[10],"PRINT");
 strcpy(m_keyWord[11],"TO");
 strcpy(m_keyWord[12],"THEN");
 strcpy(m_keyWord[13],"program");
// strcpy(m_keyWord[13],"CR");
 m_keyWordNum = 14;

 strcpy(m_operor[0],"=");
 strcpy(m_operor[1],"-");
 strcpy(m_operor[2],"+");
 strcpy(m_operor[3],"*");
 strcpy(m_operor[4],"/");
 strcpy(m_operor[5],"(");
 strcpy(m_operor[6],")");
 strcpy(m_operor[7],"<");
 strcpy(m_operor[8],">");
 strcpy(m_operor[9],",");
 char temp[2];
 temp[0] = (char)13;
 strcpy(m_operor[10],temp); //m_operor[10]存储回车

 strcpy(m_errMes[0],"标识符定义错误或存在非法字符;标识符定义只能有一个字母打头,后面跟数字串");
 strcpy(m_errMes[1],"漏了一边括号");
 strcpy(m_errMes[2],"缺少CR或该语句后存在多余语句");
 strcpy(m_errMes[3],"缺少statement number");
 strcpy(m_errMes[4],"注释行有错");
 strcpy(m_errMes[5],"缺少关键字“ program ”");
 strcpy(m_errMes[6],"program与statement间有多余信息");
 strcpy(m_errMes[7],"缺少statement number");
 strcpy(m_errMes[8],"FOR的结构应为FOR 标识符 = 标识符或常量 TO 标识符或常量");
 strcpy(m_errMes[9],"END后除了‘CR’外没有其它字符");
 strcpy(m_errMes[10],"NEXT后只跟一个标识符");
 strcpy(m_errMes[11],"UNLOOP后只跟一个标识符");
 strcpy(m_errMes[12],"IF结构错误 正确为(标识符或常数 <或=或〉标识符或常数)");
 strcpy(m_errMes[13],"REM语句出错");
 strcpy(m_errMes[14],"GOTO后应跟statement number");
 strcpy(m_errMes[15],"GOSUB后应跟statement number");
 strcpy(m_errMes[16],"statement Number 与另一重复");
 strcpy(m_errMes[17],"INPUT后跟标识符,若有多个(不超过三个)标识符用逗号分开");
 strcpy(m_errMes[18],"PRINT后跟标识符,若有多个(不超过三个)标识符用逗号分开");
 strcpy(m_errMes[19],"variable后应为 = 表达式 CR");
 strcpy(m_errMes[20],"statement后不能直接换行");
 strcpy(m_errMes[21],"一次语句只能输入三个数");
 strcpy(m_errMes[22],"PRINT后跟标识符,若有多个(不超过三个)标识符用逗号分开");
 strcpy(m_errMes[23],"statement后只能跟关键字或变量");

}

CFenXi::~CFenXi()
{

}
void CFenXi::CifaFenxi()
{//词法分析
 m_stanum = 0;
 m_errFlag = 0; //出错标志初始为0
 if(m_head)
 {
  CIFA* p;
  CIFA* q;
  p = m_head->next;
  while(p) //当再次运行函数,将上次所占资源释放
  {
   q = p;
   p = p->next;
   delete q;
  }
  m_head = NULL;  //表头清空
 }

 m_head = new CIFA; //带头节点的链表存储词法分析结果
 CString room; //当前分析的词
 room.Empty();
 CIFA* last = m_head; //记录表尾
 BOOL m_isKG = TRUE; //判断是否读到一个词
 int m_n;  //记录词在缓冲的位置
 int flag = 1;  //0表示字符串,1表示操作符或空格
 for(int i = 0;i<=m_code.GetLength();i++)//分析源代码
 {
  if(m_isKG) //遇到空格或操作符时的处理
  {
   m_n = i;
   room.Empty();
   m_isKG = FALSE;
  }

  if(i < m_code.GetLength())//当前字符不是m_code的最后一位,则操作
  {
   int tt = m_code.GetAt(i);
   if(tt != ' ' && !(tt>=40&&tt<=45) && tt!=47 && !(tt>=60&&tt<=62) && tt!=13 && tt!=10) 
    //如果不是空格或不是操作符,继续读字符
   {
    room += m_code.GetAt(i);
    flag = 0;//将标志转成字符串
    continue;
   }
  }
//  CIFA* cur; //存放当前分析的词
  if(flag == 0)
  {//一个词读完,进行处理
   cur = new CIFA;
   cur->work = room;

   int n = 0; //room标识符的类型,1为非法,2为数字与字符混合
      //3为数字,4为字符,0为没定义
   int m; //循环控制标志
   for(m = 0;m<room.GetLength();m++)//分析当前词
   {
    if(!((room.GetAt(m)>=65 && room.GetAt(m)<=90) ||
     (room.GetAt(m)>=97 && room.GetAt(m)<=122) ||
     (room.GetAt(m)>=48 && room.GetAt(m)<58)))
    {//遇到非法字符,出错
     m_errFlag = 1;
     cur->type = 4;
     cur->loca = m_n;
     cur->next = NULL;
     last->next = cur;
     last = cur;
     n=1;
     break; //检测到非法字符,确定单词为非法串,退出循环
    }

    if(room.GetAt(m)>=48 && room.GetAt(m)<58)
    {//判断是否纯数字
     if(n!=1 && (n==0||n==3))
      n = 3;
     if(n!=1 && (n==4||n==2))
      n = 2;//确定该词为数字与字符混合
    }
    if((room.GetAt(m)>=65 && room.GetAt(m)<=90) ||
     (room.GetAt(m)>=97 && room.GetAt(m)<=122))
    {///判断是否纯字符
     if(n!=1 && (n==0||n==4))
      n=4;    
     if(n!=1 && (n==3||n==2))
      n = 2;//确定该词为数字与字符混合
    }
   }
   if(n == 3)
   {//该词类型为数字
    if(last->work == "CR")
    {
     if(IsRepeat())
      cur->type = 7;
     else
      cur->type = 6;
    }
    else
     cur->type = 3;
    cur->loca = m_n;
    cur->next = NULL;
    last->next = cur;
    last = cur;
   }
   if(n == 4)
   {
    if(m==1)//当只有一个字母时为标识符
    {
     cur->type = 2;
     cur->loca = m_n;
     cur->next = NULL;
     last->next = cur;
     last = cur;
    }
    else//当大于一个字母时为标识符
    {
     if(IsKeyWord(room))//是否为关键字
     {
      if(IsRem(room))//如果为 注释
      {
       BOOL m_yinHao = FALSE;
       CString strRem;
       for(int h = i;;h++)//过滤注释
       {
        if(m_code[h] == 13)
         break;
        if(m_code[h] == ' ')
         continue;
        else
         strRem += m_code.GetAt(h);
 //       if((m_code[h] == 34&&m_yinHao==FALSE)
 //        m_yinHao = TRUE;
       }
       if(IsString(strRem)) //分析注释
        cur->type = 1;
       else
       {
        cur->type = 4;
        m_errFlag = 1;
       }
       i = h;
      }
      else
       cur->type = 1;
      cur->loca = m_n;
      cur->next = NULL;
      last->next = cur;
      last = cur;
     }
     else
     {//大于两个字符的纯字母组成的串为非法串
      cur->type = 4;
      m_errFlag = 1;
      cur->loca = m_n;
      cur->next = NULL;
      last->next = cur;
      last = cur;
     }
    }
   }
   if(n == 2)
   {
    if(room.GetAt(0)>=48 && room.GetAt(0)<58)
    {//不符合标识符定义规则
     m_errFlag = 1;
     cur->type = 4;
     cur->loca = m_n;
     cur->next = NULL;
     last->next = cur;
     last = cur;
    }

    if((room.GetAt(0)>=65 && room.GetAt(0)<=90) ||
     (room.GetAt(0)>=97 && room.GetAt(0)<=122))
    {
     for(m = 1;m<room.GetLength();m++)
     {//标识符定义为一字符打头,后面跟数字.不能跟数字以外的符号
      if(room.GetAt(m)<48 || room.GetAt(m)>=58)
       break;  
     }
     if(m<room.GetLength())
     {//不符合标识符定义规则
      m_errFlag = 1;
      cur->type = 4;
      cur->loca = m_n;
      cur->next = NULL;
      last->next = cur;
      last = cur;
     }
     else
     {//标识符
      cur->type = 2;
      cur->loca = m_n;
      cur->next = NULL;
      last->next = cur;
      last = cur;
     }//if
    }//if
   }//for
  }//if

  if(i < m_code.GetLength())//当前字符不是m_code的最后一位,则操作
  {
   flag = 1;  //将标志转成操作符
   int t = m_code.GetAt(i);
   if((t>=40&&t<=45) || t==47 || (t>=60&&t<=62) || t==13) 
   {//当当前字符为操作符时
    cur = new CIFA;
    if(t == 13) //如果当前是回车,且上个单词不是回车,则
     if(last->work != "CR")
     {
      cur->work = "CR";
      cur->type = 1;  //回车为关键字
      i++;
     }
     else
     {//如果连续两个回车,则过滤
      m_isKG = TRUE;
      continue;
     }

    else
    {
     cur->work = m_code.GetAt(i);
     cur->type = 5; //其他为操作符
    }
    cur->loca = i;
    cur->next = NULL;
    last->next = cur;
    last = cur;
   }
  }
  m_isKG = TRUE;
 }
}

BOOL CFenXi::IsKeyWord(CString str)
{//判断是否为关键字
 char *temp; 
// for(int i = 0;i<str.GetLength();i++)
//  temp[i] = str.GetAt(i);
 temp = str.GetBuffer(str.GetLength());
 for(int m = 0;m<m_keyWordNum;m++)
  if(strcmp(temp,m_keyWord[m]) == 0)//两字符串相等
   return TRUE;
 return FALSE;
}

void CFenXi::PrintCiFaErrMsg(CString &str)
{//打印词法分析的错误信息

 CIFA * p;
 p = m_head->next;
 int num = 0; //错误单词个数
 CString temp;
 str.Empty();
 str.Format("词法分析");
 str += 13; //回车
 str += 10; //换行
 str += "属性中1 关键字,2 标识符,3 数字,4或7 错误,5 操作符,6 statement number";
 str += 13; //回车
 str += 10; //换行
 str += 13; //回车
 str += 10; //换行
 str += "属性        单词        ";
 str += 13; //回车
 str += 10; //换行
 while(p)
 {
  temp.Empty();
  switch(p->type)
  {
  case 1:
   temp += '1';//关键字
   break;
  case 2:
   temp += '2';//标识符
   break;
  case 3:
   temp += '3';//数字
   break;
  case 4:
   temp += '4';//出错
   break;
  case 5:
   temp += '5';//操作符
   break;
  case 6:
   temp += '6';//statement number
   break;
  case 7:
   temp += '7';//statement number出现重复
   break;
  }
  temp += "           ";
  temp += p->work;
  if(p->type == 4)
  {
   temp += "     ";
   if(p->work == "REM")
    temp += m_errMes[4];//显示出错信息
   else
    temp += m_errMes[0];//显示出错信息
   num++;
  }
  if(p->type == 7)
  {
   temp += "     ";
   temp += m_errMes[16];//显示出错信息
   num++;
  }
  temp += 13;
  temp += 10;
  str += temp;
  p = p->next;
 }
 str += 13; //回车
 str += 10; //换行
 char a[5];
 itoa(num,a,10); //错误个数
 str += "错误个数    ";
 str += a;
}

BOOL CFenXi::IsRem(CString str)
{//判断是否为注释行
 if(str.GetLength()>3)
  return FALSE;//不与关键字REM匹配放回FALSE
 for(int i = 0;i<str.GetLength();i++)
 {
  if(str.GetAt(i) != m_keyWord[5][i])
   break;
 }
 if(i<str.GetLength())
  return FALSE;//不与关键字REM匹配放回FALSE
 return TRUE;//与关键字REM匹配放回TRUE
}

BOOL CFenXi::IsString(CString str)
{//分析string
 if(str.GetAt(0) != 34) //判断第一个字符是否为 "
  return FALSE;
 else
  if(str.GetAt(str.GetLength()-1) != 34)
   return  FALSE;
 //注释在两双引号内则返回TRUE
 return TRUE;
}

void CFenXi::YuFaFenXi()
{
 Program();
}

BOOL CFenXi::Program()
{//程序分析开始
 cur = m_head->next; //cur获得的一个分析的单词
 m_errNum = 0;  //错误信息初始为0
 if(cur->work != "program")
  m_errors[m_errNum++] = 5; //缺少关键字“ program ”

 NextWord(); //分析下一单词

 while(1)
 {
  if(cur->work != "CR")
  {
   NextWord();
   if(m_errNum == 1)
    m_errors[m_errNum++] = 6; //program与statement间有多余信息
  }
  else
   break;  //遇到statement number时退出
 }

 NextWord();

 while(1)
 {
  if(cur)
  {
   if(Statement()) //分析statement
    return TRUE;  //遇到END返回TRUE
  }
  else
   break;
 }

 return FALSE;
}

BOOL CFenXi::Statement()
{//分析statement
 if(cur->type != 6)
 {
  NextYuJu();
  m_errors[m_errNum++] = 7; //缺少statement number
  NextWord();
  NextWord();
  return FALSE;
 }

 NextWord();

 int flag = 1;
 switch(WhichKW(cur->work))//各个语句分析
 {
 case 0: //"FOR"
  if(!KW_FOR())
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 8; //FOR的结构应为FOR 标识符 = 标识符或常量 TO 标识符或常量
    return FALSE;
   }
   else
    NextYuJu();
   m_errors[m_errNum++] = 8; //FOR的结构应为FOR 标识符 = 标识符或常量 TO 标识符或常量
  }
  break;
 case 1: //"END"
  if(!KW_END())
  {
   m_errors[m_errNum++] = 9; //END后除了‘CR’外没有其它字符
  }
  return TRUE; //END后没有字符返回真

  break;
 case 2: //"NEXT"
  if(!KW_NEXT())
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 10; //NEXT后只跟一个标识符
    return FALSE;
   }
   else
    NextYuJu();
    m_errors[m_errNum++] = 10; //NEXT后只跟一个标识符
  }
  break;
 case 3: //"UNLOOP"
  if(!KW_UNLOOP())
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 11; //UNLOOP后只跟一个标识符
    return FALSE;
   }
   else
    NextYuJu();
    m_errors[m_errNum++] = 11; //UNLOOP后只跟一个标识符
  }
  break;
 case 4: //"IF"
  if(!KW_IF())
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 12; //IF结构错误
    return FALSE;
   }
   else
    NextYuJu();
    m_errors[m_errNum++] = 12; //IF结构错误
  }
  break;
 case 5: //"REM"
  if(!KW_REM())
  {
   NextYuJu();
   m_errors[m_errNum++] = 13; //REM出错
  }
  break;
 case 6: //"GOTO"
  if(!KW_GOTO())
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 14; //GOTO后跟statement number
    return FALSE;
   }
   else
    NextYuJu();
   m_errors[m_errNum++] = 14; //GOTO后跟statement number
  }
  break;
 case 7: //"GOSUB"
  if(!KW_GOSUB())
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 15; //GOSUB后跟statement number
    return FALSE;
   }
   else
    NextYuJu();
   m_errors[m_errNum++] = 15; //GOSUB后跟statement number
  }
  break;
 case 8: //"RETURN"
  if(!KW_RETURN())
   m_errors[m_errNum++] = 16;
  break;
 case 9: //"INPUT"
  if(!KW_INPUT(0))
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 17; //INPUT后跟标识符,若有多个(不超过三个)标识符用逗号分开
    return FALSE;
   }
   else
    NextYuJu();
   m_errors[m_errNum++] = 17; //INPUT后跟标识符,若有多个(不超过三个)标识符用逗号分开
  }
  break;
 case 10: //"PRINT"
  if(!KW_PRINT(0))
  {
   if(cur->work == "CR")
   {
    NextWord();
    m_errors[m_errNum++] = 18; //PRINT后跟标识符,若有多个(不超过三个)标识符用逗号分开
    return FALSE;
   }
   else
    NextYuJu();
   m_errors[m_errNum++] = 18; //PRINT后跟标识符,若有多个(不超过三个)标识符用逗号分开
  }
  break;
 default:
  if(cur->type == 2)
  {
   if(!KW_VARIABLE())
   {
    if(cur->work == "CR")
    {
     NextWord();
     m_errors[m_errNum++] = 19; //variable后应为 = 表达式 CR
     return FALSE;
    }
    else
     NextYuJu();
    m_errors[m_errNum++] = 19; //variable后应为 = 表达式 CR
   }
  }
  else
  {
   if(cur->work != "CR")
    NextYuJu();
   else
   {
    NextWord();
    m_errors[m_errNum++] = 20; //statement后不能直接换行
    return FALSE;
   }
   m_errors[m_errNum++] = 23; //statement后只能跟关键字或变量
  }
 }

 NextWord();
 if(cur->work != "CR")
 {
  NextYuJu();
  m_errors[m_errNum++] = 2; //缺少CR或该语句后存在多余语句
  NextWord();
  NextWord();
 }
 else
  NextWord();

 return FALSE;
}

BOOL CFenXi::Condition()
{//IF的判断条件 
 if(cur->work.GetAt(0) != '(')
  return FALSE;
 NextWord();

 if(!(cur->type == 2 || cur->type == 3))
  return FALSE;
 NextWord();

 if(!(cur->work.GetAt(0) == '<' || cur->work.GetAt(0) == '=' || cur->work.GetAt(0) == '>'))
  return FALSE;
 NextWord();

 if(!(cur->type == 2 || cur->type == 3))
  return FALSE;
 NextWord();

 if(cur->work.GetAt(0) != ')')
  return FALSE;
 return TRUE;
}

int CFenXi::WhichKW(CString str)
{//判断关键字所对应的序号
 for(int i = 0;i<11;i++)
 {
  for(int j = 0;j<str.GetLength();j++)
   if(str.GetAt(j) != m_keyWord[i][j])
    break;
  if(j==str.GetLength())
   return i; //表示相应的关键字
 }
 return -1;  //表示是标示符
}

BOOL CFenXi::KW_FOR()//FOR的结构应为FOR 标识符 = 标识符或常量 TO 标识符或常量 CR
{
 NextWord();
 if(cur->type != 2)//FOR后缺标识符
  return FALSE;
 NextWord();
 if(cur->work.GetAt(0) != '=')//FOR中的 =  有误
  return FALSE;
 NextWord();
 if(!(cur->type == 2||cur->type == 3)) //标识符出错
  return FALSE;
 NextWord();
 if(cur->work != "TO")//TO 出错
  return FALSE;
 NextWord();
 if(!(cur->type == 2||cur->type == 3)) //标识符出错
  return FALSE;

 return TRUE;
}

BOOL CFenXi::KW_END()//END后除了‘CR’外没有其它字符
{
 NextWord();
 if(!cur) //为空则结束
  return TRUE;
 if(cur->work != "CR") //不空又不与CR相符,出错
  return FALSE;
 if(cur->next) //空又与CR相符,但后面还有字符,出错
  return FALSE;
 return TRUE;
}

BOOL CFenXi::KW_NEXT()//NEXT后只跟一个标识符
{
 NextWord();
 if(cur->type != 2)
  return FALSE;
 return TRUE;
}

BOOL CFenXi::KW_UNLOOP()//UNLOOP后只跟一个标识符
{
 NextWord();
 if(cur->type != 2)
  return FALSE;
 return TRUE;
}

BOOL CFenXi::KW_IF()//结构 (标识符或常数 <或=或〉标识符或常数)
{
 NextWord();
 if(!Condition())
  return FALSE;
 NextWord();
 if(cur->work != "THEN")
  return FALSE;
 NextWord();
 if(cur->type != 3)
  return FALSE;
 return TRUE;
}

BOOL CFenXi::KW_REM()
{
 return TRUE;
}

BOOL CFenXi::KW_GOTO()//GOTO后跟statement number
{
 NextWord();
 if(cur->type != 3)
  return FALSE;
 return TRUE;
}

BOOL CFenXi::KW_GOSUB()//GOSUB后跟statement number
{
 NextWord();
 if(cur->type != 3)
  return FALSE;
 return TRUE;
}

BOOL CFenXi::KW_INPUT(int num)
{//INPUT后跟标识符,若有多个(不超过三个)标识符用逗号分开
 NextWord();
 if(cur->type != 2) //不是标识符返回FALSE
  return FALSE;
// NextWord();
 if(cur->next->work != "CR")
 {
  NextWord();
  if(cur->work.GetAt(0) != ',')//若有多个逗号分开
   return FALSE;
  else
  {
   if(num < 2)
   {
    if(!KW_INPUT(++num))
     return FALSE;
   }
   else
   {
    NextYuJu();
//    m_errors[m_errNum++] = 21;//一次语句只能输入三个数 
    return FALSE;
   }
  }
 }
 return TRUE;
}

BOOL CFenXi::KW_RETURN()
{
 return TRUE;
}

BOOL CFenXi::KW_PRINT(int num)
{//PRINT后跟标识符,若有多个(不超过三个)标识符用逗号分开
 NextWord();
 if(cur->type != 2) //不是标识符返回FALSE
  return FALSE;
 if(cur->next->work != "CR")
 {
  NextWord();
  if(cur->work.GetAt(0) != ',')//若有多个逗号分开
   return FALSE;
  else
  {
   if(num < 2)
   {
    if(!KW_PRINT(++num))
     return FALSE;
   }
   else
   {
    NextYuJu();
//    m_errors[m_errNum++] = 21;//一次语句只能输入三个数 
    return FALSE;
   }
  }
 }
 return TRUE;
}

void CFenXi::PrintYuFaMsg(CString &str)
{
 str.Empty();
 char a[5];
 if(m_errNum == 0)
 {
  str += 13; //回车
  str += 10; //换行
  str += "     源程序语法正确";
  return ;
 }
 str += "语法分析结果:";
 str += 13; //回车
 str += 10; //换行
 for(int i = 1;i<=m_errNum;i++)
 {
  itoa(i,a,10); //错误排列
  str += "错误";
  str += a;
  str += "   ";
  str += m_errMes[m_errors[i-1]];
  str += 13; //回车
  str += 10; //换行
 }
 str += 13; //回车
 str += 10; //换行
 itoa(m_errNum,a,10); //错误个数
 str += "错误个数    ";
 str += a;
 
}

void CFenXi::NextYuJu()
{//将指针移到下一语句
 while(1)
 {
  if(!cur->next)
   break;
  if(cur->next->work == "CR")
   break;
  NextWord();
 }
}

BOOL CFenXi::NextWord()
{//指向下一单词
 if(cur)
 {
  cur = cur->next;
  return TRUE;
 }
 else //当没有单词时返回FALSE
  return FALSE;
}

BOOL CFenXi::KW_VARIABLE()
{
 NextWord();
 if(cur->work.GetAt(0) != '=')
  return FALSE;
 NextWord();
 if(!Expression())
  return FALSE;
 return TRUE;
}

BOOL CFenXi::Expression()
{//表达式     

 if(!(cur->type == 2 || cur->type == 3 || cur->work.GetAt(0) == '('))
  return FALSE;//不是变量或数字或因子,返回FALSE
 else
 {
  if(cur->work.GetAt(0) == '(')
  {
   NextWord();
   if(!Expression())//如果因子则判断里面是否表达式
    return FALSE;
   if(cur->work.GetAt(0) != ')')
    return FALSE;
   else
   {
    if(cur->next->work == "CR")//语句结束则返回TRUE
     return TRUE;
   }
  }
 }

 if(cur->next->work != "CR")
  NextWord();
 else
  return TRUE;//语句结束则返回TRUE

 if(!(cur->work.GetAt(0) == '+' || cur->work.GetAt(0) == '-'
  || cur->work.GetAt(0) == '*' || cur->work.GetAt(0) == '/'))
  if(cur->work.GetAt(0) != ')')
   return FALSE;//不是以上操作符返回FALSE
  else
   return TRUE;
 NextWord();

 if(!Expression())//递归
  return FALSE;

 return TRUE;
}

BOOL CFenXi::GetErrFlag()//得到此法分析时的错误标志
{
 return m_errFlag;
}

BOOL CFenXi::IsRepeat()//statement Number 是否重复出现
{
 char a[10];
 for(int i = 0;i<cur->work.GetLength();i++)
  a[i] = cur->work.GetAt(i);
 a[i] = '/0';

 int t = atoi(a);
 for(int j = 0;j<m_stanum;j++)//查找有没有重复statement number
 {
  if(t == m_staNum[j])
   break;
 }
 m_staNum[m_stanum++] = t;
 if(j<m_stanum-1)
  return TRUE;
 return FALSE;
}

类留了词法分析,语法分析,词法分析报告输出和语法分析报告输出几个接口
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值