CSDN博客

img PercyLee

大学书信选1(关于编译器)

发表于2003/10/15 23:10:00  966人阅读

简序

    大学中,有很多梦想,写一个教学用的小编译器就是一个。也曾就此与我最喜欢的年轻老师之一薛老师进行讨论,后来更是联系了另外两个非常厉害的同学,准备大四一起做这个,运用有关模式,重新设计语言,把它做出来。

    可是现在,学校中只我一人,他们都去北京实习去了。而自己要忙的事情也太多,想实践演化证明的思路,想通过内核代码把“进程”理解好,想整理自己数据结构的笔记,想把数学分析看完……这个梦想,或许也就永远留在心中了。

    忽然看到原来的一封email,写给薛老师的,就原封不动的,转贴在这里,纪念这段岁月时光!

    不去评论过去的东西了;只是要记得,新的梦想,新的征程!

 

    也愿所有的大学生朋友珍惜光阴,梦想成真。

                                                  percylee

                                               2003-10-15于武汉

 

--------------------------------------------------------------------------------------

薛老师:

首先祝您节日快乐!

我是111001班的学生,前些日子和您说要写个小编译器,那时语言与词法分析器已写好了,可惜现在要忙于考试,但争取寒假前多写点。

语言很小,是基于代数结构<Z/rou;+,*>的,rou=mod8),呵呵,目标语言是c++吧。希望能和您常联系。

 

下面是语言的小例子:

 

item a, b={3}, c;

a ={5};

c=b*(a +b)+a ;

 

out<<"c="<<c;

 

c=a+a*b;

out<<"now c="<<c;

 

if(c==a*b)

then

out<<"c is the mutlip of a and b";

else

out<<"c isnot mutlip of a and b";

end;

 

 

您看看部分程序吧,我用c++写的,感觉不少困难;但总是想,如果有一天写完了,一定会很有收获---这都是您课堂上讲的呀;到时候我会到bbs上写系列的帖子,把所有的设计过程和原代码都展示给同学看。对了,我是那个kindman:),离散版块上问问题,真希望能得到您的回答---或者,我找您吧,去找蔡老师,怕他太忙了。

 

//一个文件

#pragma once

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

 

#define SIZE 50000 //默认最大文件字符数

#define WORDNUM 20000 //最大单词数

#define CONSTNUM 100 //最大常量数

#define IDNUM 200 //最大标志符数

#define ELENUM 500 //常量运算单元数

#define ERRORSIZE 1000 //

class Sources

{

public:

 Sources(void);

 ~Sources(void);

private:

 const char * keyWords[7]; //关键字

 char * constTable[CONSTNUM]; //常量(字符串)

 char * idTable[IDNUM]; //自定义标志符

 char * elementTable[ELENUM]; //运算单元

 char idFollow[10]; //标志符follow

 int idNum;

 int eleNum;

 int constNum;

//......

public:

 bool IsKeyword(const char *& keyWord,int &numOfkey);

 bool IsIdfollow(const char ch);

 int InsertID(const char *& strToken);

 int InsertELE(const char *& strToken);

 int InsertConst(const char *& strToken);

 

//......

};

//错误记录

class ERROR

{

 public:

  int row;

  static char * strError;

};

class Error

{

 static int errorNum;

//int waringNum;

 ERROR error[ERRORSIZE];

public:

 Error(void);

 ~Error(void);

 

 int GetErrornum()const;

void SetError(const char *&strError,int row);

 

 void PrintError();

//......

};

//词法分析

class Lexer

{

 enum Token_value{

KW,ID,ELEMENT,CONST,

  EQUAL,INPUT,OUTPUT,

  ASSIGN='=',PLUS='+',MUL='*',PRINT=';',

  LP='(',RP=')',COMMA=',',SEMI='"',ROWEND='/n'

 };

 char ch; //reading file

 char memary[SIZE];//file managed a lettle

 char *word;

 

 int realSize; // of memary

 int rowCount; //of row in file

 int wordCount; //of token

 int charCount; //of reading ch in memary

 int tokenChCount;//of every tokenWord

 

std::fstream file;

 char *& strToken;//complete word in your code

 

 struct Token{

  Token_value tokval;

int codeNum;

  int rowNum;

 }token[WORDNUM];//result of lexical analysis

public:

 Lexer(void);

 ~Lexer(void);

 

 void Openfile(const char filename[30]);

 

 

 // 读一个字符至ch

 void Readchar(void);

 void ReCheckch();

 

//字符放入单词

 void Concat();

 //

 bool IsLetter();

 bool IsDigit();

 bool IsKeyword(const char* strWord,int &numOfkey,Sources source);

 //词法分析

 void DoAnalysis(Sources source,Error error);

 //编程需要:检查中间结果

 void Test();

};

//编译处理

class Compiler

{

public:

 Compiler(void);

 virtual ~Compiler(void);

private:

 //

 Error error;

 // 所用到的资源

 Sources source;

 // 词法分析器

 Lexer lexer;

 

public:

 // 读入待编译文件

 void Readfile(void);

 void Test(void);

 

//.....

};

 

//另一个文件,实现词法分析

#include "compiler.h"

#using <mscorlib.dll>

 

Lexer::Lexer(void):strToken(word)

{

 rowCount=0;

charCount=0;

wordCount=0;

tokenChCount=0;

word=new char[200];

}

 

Lexer::~Lexer(void)

{

 file.close();

 delete word;

}

 

void Lexer::Openfile(const char filename[30])

{

char nextCh=' ';

int num=0;

// __try{

file.open(filename,ios_base::in|ios_base::out);

/* }

catch(System::NullReferenceException *e)

{

  std::cerr<<"Error: Can't open file "<<filename

<<",please make sure !"<<endl;

  exit(-1);

}

 */

 while(!file.eof()){

  file.get(ch);

  memary[num++]=ch;

  if(ch==' '){

   file.get(nextCh);

   while(!file.eof()&&nextCh==' ')

    file.get(nextCh);

   memary[num++]=nextCh;

  }

 }

 

 realSize=num;

}

 

void Lexer::Readchar()

{

if(charCount<realSize)

ch=memary[charCount++];

 

 if(ch=='/n'&&ch!=' ') rowCount++;

}

 

void Lexer::ReCheckch()

{

while(ch==' ')

  Readchar();

}

 

//

void Lexer::Concat()

{

 word[tokenChCount++]=ch;

 word[tokenChCount]='/0';

}

bool Lexer::IsLetter()

{

 if(ch>='A'&&ch<='Z')

  return true;

if(ch>='a'&&ch<='z')

  return true;

return false;

}

bool Lexer::IsDigit()

{

 switch(ch){

  case '0':case '1':case '2':case '3':case '4':

  case '5':case '6':case '7':case '8':case '9':

   return true;

  default:

return false;

 }

}

 

bool Lexer::IsKeyword(const char* strWord,int &numOfkey,Sources source)

{

if(source.IsKeyword(strWord,numOfkey))

   return true;

  return false;

}

 

void Lexer::DoAnalysis(Sources source,Error error)

{

int code=-1,value=-1;

while(charCount<realSize)

{

tokenChCount=0;

 

Readchar();

 ReCheckch();

 

 if(IsLetter())

 {

  while(IsLetter() ||IsDigit())

  {

   Concat();

   Readchar();

  }

  charCount--;

  if(IsKeyword(strToken,code,source))

  {

   token[wordCount].codeNum=code;

   token[wordCount++].rowNum=rowCount;

  }

  else

   if(source.IsIdfollow(ch))

   {

    token[wordCount].rowNum=rowCount;

    token[wordCount].tokval=ID;

    value=source.InsertID(strToken);

    token[wordCount++].codeNum=value;

   }

   else {

    // error

    while(ch!='/n')

     Readchar();

    error.SetError(strToken,rowCount-1);

   

   }

 

 }//if

 else {

  switch(ch)

  {

  case '{': Readchar();

    while(IsDigit())

     Readchar();

    if(ch=='}')

    {

    token[wordCount].rowNum=rowCount;

    token[wordCount].tokval=ELEMENT;

    value=source.InsertELE(strToken);

    token[wordCount++].codeNum=value;

    }

    else

    {

     //error

     while(ch!='/n')

     Readchar();

    error.SetError(strToken,rowCount-1);

 

    }

 

   break;

  case '=':Readchar();

    if(ch!='=')

    {

token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=ASSIGN;

charCount--;

    }

    else if(ch=='=')

    {

token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=EQUAL;

    }

    break;

  case '+':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=PLUS;

    break;

  case '*':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=MUL;

    break;

  case '<':

    Readchar();

    if(ch=='<')

    {

    token[wordCount].rowNum=rowCount;

     token[wordCount++].tokval=OUTPUT;

    }

    else

    {

     //error

     while(ch!='/n')

     Readchar();

     error.SetError(strToken,rowCount-1);

    }

break;

  case '>':

    Readchar();

    if(ch=='>')

    {

    token[wordCount].rowNum=rowCount;

     token[wordCount++].tokval=INPUT;

    }

    else

    {

     //error

     while(ch!='/n')

     Readchar();

     error.SetError(strToken,rowCount-1);

    }

break;

  case '"':Readchar();

    while(ch!='/n'&&ch!='"')

     Readchar();

    if(ch=='"')

    {

    token[wordCount].rowNum=rowCount;

     token[wordCount].tokval=CONST;

value=source.InsertConst(strToken);

   token[wordCount++].codeNum=value;

    }

    else

    {

     //error

     while(ch!='/n')

     Readchar();

     error.SetError(strToken,rowCount-1);

    }

    break;

   

  case ',':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=COMMA;

    break;

  case ';':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=PRINT;

    break;

  case '(':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=LP;

    break;

  case ')':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=RP;

    break;

   case ' ':

    // Readchar();

    break;

   case '/n':

    token[wordCount].rowNum=rowCount;

    token[wordCount++].tokval=ROWEND;

    break;

  default:

    {

    //error

    while(ch!='/n')

     Readchar();

    error.SetError(strToken,rowCount-1);

    }

  }

 }//else

 

}//while

}

//----------------------------------------------------------------------------

---------

void Lexer::Test()

{

 cout<<"wordCount:"<<wordCount<<endl;

 for(int i=0;i<wordCount;i++){

 

  cout<<endl<<"row:"<<token[i].rowNum<<endl;

 

  switch(token[i].tokval)

  {

  case KW:cout<<"keyword";

   break;

  case ID:cout<<"identifer";

   break;

  case ELEMENT:cout<<"element";

   break;

  case CONST:cout<<"const string";

   break;

  case PLUS:cout<<'+';

   break;

  case MUL:cout<<'*';

   break;

  case ASSIGN:cout<<'=';

   break;

  case EQUAL:cout<<"==";

   break;

  case PRINT:cout<<';';

   break;

  case LP:cout<<'(';

   break;

  case RP:cout<<')';

   break;

  case COMMA:cout<<',';

   break;

  case INPUT:cout<<">>";

   break;

  case OUTPUT:cout<<"<<";

   break;

  case SEMI:cout<<'"';

   break;

  case ROWEND:cout<<"row_end";

   break;

  default:

   ;

  }

 }

}

 

 

祝您工作顺利。

 

percy

 

 

 

0 0

相关博文

我的热门文章

img
取 消
img