词法分析程序

上课没听啥,一边看书,一边做的。基本上,老师的要求是实现了,能把一个句子(也可以是一整个程序,但还不完善,由于时间急,很多情况来不及考虑了)中的单词项分析出它是保留字,还是标识符,运算符等等。
开始是在控制台下做得,代码也比较纯正:

//lex.h
#ifndef LEX_H
#define  LEX_H
#include 
< list >
#include 
< string >
#include 
< cstddef >
#define  rev 1
#define  idf 2
#define  con 3
#define  opr 4
#define  fon 5

using   namespace  std;

struct  word {
    
string content;
    
int att;
    word():att(
0){};
}
;

class  Clex {
    
string instr;            //input string
    list<string> revstr;    //reserve words
    list<string> oper;    //reserve words
    list<string> frontier;
    list
<char> ch;        
    size_t strindex;
private:
    
void SetRevstr();
    
void SetOper();
    
void SetFrontier();
    list
<word> words;        //words input string contained
private:
    
void GetBC();
    
char GetChar();
    
bool IsLetter(char&const;
    
bool IsDigit(char&const;
    size_t Retract();
    
    
bool IsReserve(string&);
    
bool IsIdentifier(string&);
    
bool IsConst(string&);
    
bool IsOper(string&);
    
bool IsFrontier(string&);
    
void SetAtt(word&);            //set words attribute
private:
    
void Predo();            //preprocessing,initiate words
    string temp(int);

public:
    Clex(
string str);
    
~Clex(){};
    
void Output();
}
;
#endif
//lex.cpp
#include "lex.h"
#include <iostream>
#include <fstream>
Clex::Clex(string str):strindex(0),instr(str)
{
 SetRevstr();
 SetOper();
 SetFrontier();
}
bool Clex::IsLetter(char& chr) const
{
 if((chr>64 && chr<91)||(chr>96 && chr<123))
  return true;
 return false;
}
bool Clex::IsDigit(char& chr) const
{
 if(chr>47 && chr<58)
  return true;
 return false;
}
size_t Clex::Retract()
{
 if(strindex>0) return --strindex;
 return 0;
}
void Clex::SetRevstr()
{
 string tempstr[]={"if","else","switch","case","default",
  "break","continue","return","while","do","for","register",
  "void","int","float","double","bool","char","long",
  "enum","union","sizeof","const","static"};
 size_t num=sizeof tempstr/sizeof tempstr[0];
 for(size_t i=0;i<num;i++)
  revstr.push_back(tempstr[i]);
 revstr.sort();
}
bool Clex::IsReserve(string& wstr)
{
 for(list<string>::iterator ite=revstr.begin();ite!=revstr.end();++ite)
  if(wstr==(*ite)) return true;
 return false;
}
bool Clex::IsIdentifier(string& wstr)   //should put behind IsReserve
{
 if(wstr!="" && IsLetter(wstr.at(0))) return true;
 return false;
}
bool Clex::IsConst(string& wstr)
{
 if(wstr!="" && wstr.at(0)=='"' && wstr.at(wstr.length()-1)=='"') return true;
 else if(IsDigit(wstr.at(0)))
 {
  for(size_t index=1;index<wstr.length();++index)
   if(!IsDigit(wstr.at(index)) && wstr.at(index)!='.') return false;
  return true;
 }
 return false;
}
void Clex::SetOper()
{
 string tempstr[]={"+","-","*","/","&&",
  "||","&","|",">",">=","<","<=",
  "=","==",">>","<<"};
 size_t num=sizeof tempstr/sizeof tempstr[0];
 for(size_t i=0;i<num;i++)
  oper.push_back(tempstr[i]);
}
bool Clex::IsOper(string& wstr)
{
 for(list<string>::iterator ite=oper.begin();ite!=oper.end();++ite)
  if(wstr==*ite) return true;
 return false;
}
void Clex::SetFrontier()
{
 string tempstr[]={"(", ")", ";", ","};
 size_t num=sizeof tempstr/sizeof tempstr[0];
 for(size_t i=0;i<num;i++)
  frontier.push_back(tempstr[i]);
}
bool Clex::IsFrontier(string& wstr)
{
 for(list<string>::iterator ite=frontier.begin();ite!=oper.end();++ite)
  if(wstr==*ite) return true;
 return false;
}
void Clex::SetAtt(word& tw)
{
 if(IsReserve(tw.content)) tw.att=rev;
 else if(IsIdentifier(tw.content)) tw.att=idf;
 else if(IsConst(tw.content)) tw.att=con;
 else if(IsOper(tw.content)) tw.att=opr;
 else if(IsFrontier(tw.content)) tw.att=fon;
}
void Clex::GetBC()
{
 size_t tempt=strindex;
 while(GetChar()==' ' && strindex<instr.length()) GetChar();
 if(tempt!=strindex) Retract();
}
char Clex::GetChar()
{
 if(strindex<instr.length()) ++strindex;
 return instr.at(strindex-1);
}
void Clex::Predo()
{
 GetBC();
 while(strindex<instr.length())
 {
  word tw;
  char tchr;
  while(strindex<instr.length() && (tchr=GetChar())!=' ')
  {
   tw.content+=tchr;
  }
  SetAtt(tw);
  words.push_back(tw);
  GetBC();
 }
 cout<<"words.size()="<<words.size()<<endl;
}
string Clex::temp(int t)
{
 switch(t)
 {
  case 1:return "保留字";break;
  case 2:return "标识符";break;
  case 3:return "常数";break;
  case 4:return "运算符";break;
  case 5:return "界符";break;
  default:return "其他东东";
 }
}
void Clex::Output()
{
 Predo();
 for(list<word>::iterator ite=words.begin();ite!=words.end();++ite)
  cout<<(*ite).content<<""<<"-----is----"<<temp((*ite).att)<<endl;
}
int main()
{
 string str;
    cout<<"Please input a string:";
 getline(cin,str);
 Clex yanlex(str);
 yanlex.Output();
}

注:getline(cin,str);读取标准输入的一行并赋值给str,单纯的cin>>str由于空格优先限定原则每次至多只能读取一个单词。如输入"if ( i = 1 )",str将为"if"而不是"if ( i = 1 )"。
 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值