首页 > 代码库 > [编译原理学习]词法分析

[编译原理学习]词法分析

此前一直没能系统完整地学过编译原理,只有很粗浅的理解,虽然其实对工作里的任务也没啥影响,但总觉得缺了一大块知识,加上对所谓程序员三大浪漫(编译器,操作系统,图形学)的向往,所以最近跟着网易云课堂推出的计算机专业课程来学习编译原理.无奈生性懒惰,常常下班之后觉得累了,打打游戏啊看看视频啊,拖延症就犯了.......所以在这里打算将学习的过程,心得记录下来,也算是对自己的一个督促.课程传送门http://mooc.study.163.com/learn/USTC-1000002001#/learn/announce

首先要明确一个概念,语言是设计出来的,不是写代码写出来的,编译器才是写出来的.源代码其实就是一堆字符而已,只不过些字符是按照事先规定好的规则组织起来.

编译器是一个程序,完成的功能是把源代码(c/c++,python,java。。。。)转换为目标代码.这其中又涉及到很多过程.简单的讲就是下面这个过程

 

 以if(a > 1)为例,词法分析器的任务就是要将这一句拆分出if,(,a,>,1,)并判断出他们的类型,比如if是个关键字,a是一个变量,名字叫a,>是一个大于号,1是一个整数,值为1等等...... 

下面是一个完成下列功能的简单分析器代码示例:

分析器的输入:存储在文本文件中的字符序列,字符取自ASCII字符集。文件中可能包括四种记号:关键字if、符合C语言标准的标识符、空格符、回车符\n。

分析器的输出:打印出所识别的标识符的种类、及行号、列号信息。

 

 1 #ifndef TOKENIZER_H 2 #define TOKENIZER_H 3  4 #include <iostream> 5 #include <string> 6 #include <vector> 7 using namespace std; 8  9 enum symbol10 {11     //关键字if、符合C语言标准的标识符、空格符、回车符12     KEYWORD,13     ID,14     BLANK,15     ENTER16 };17 18 struct result 19 {20     string token; //符号名21     int type;     //符号类型22     int line;     //符号所在行23     int row;      //符号所在列24 };25 26 class Tokenizer27 {28 public:29     Tokenizer(void);30     ~Tokenizer(void);31 32 public:33     //34     void ReadSourceFile(const string& fileName);35     //36     void Parse();37     //38     void HandleToken(const string token,int line,int row);39     //40     void ShowResult();41 private:42     char* m_buffer;43     vector<result> m_resultVec;44 };45 46 #endif
#include "Tokenizer.h"#include <fstream>#define  BUFFSIZE 1024*1024Tokenizer::Tokenizer(void){    m_buffer = (char*)malloc(BUFFSIZE);    memset(m_buffer,0,BUFFSIZE);}Tokenizer::~Tokenizer(void){}void Tokenizer::ReadSourceFile(const string& fileName){    FILE* fp = fopen(fileName.c_str(),"r");    if (fp != NULL)    {        fread(m_buffer,1,BUFFSIZE,fp);                fclose(fp);    }    else    {        cout<<"打开文件失败";    }}void Tokenizer::Parse(){    std::string token;        int currentLine = 1;//标记当前行数    int pos = 1;//标记token在该行的位置    int i = 0;    char c = m_buffer[i];    while(c != NULL)    {        if (c !=   && c != \n)        {            token.append(1,c);        }        if (c ==  )        {            HandleToken(token,currentLine,pos);            token.clear();                    pos = (i + 1) + 1; //.下一个字符的下标为i+1.代表第(i+1)+1列.        }        if (c == \n)        {            HandleToken(token,currentLine,pos);            token.clear();            pos = 1;            currentLine += 1;        }        c = m_buffer[++i];    }    //处理最后一个token    HandleToken(token,currentLine,pos);}void Tokenizer::HandleToken(const string token,int line,int row){    if (token == "")    {        return;    }    result ret;    ret.token = token;    ret.line = line;    ret.row = row;    if (token == "if")    {        ret.type = KEYWORD;    }    else if(token == " ")    {        ret.type = BLANK;    }    else if(token == "\n")    {        ret.type = ENTER;    }    else    {        ret.type = ID;    }    m_resultVec.push_back(ret);}void Tokenizer::ShowResult(){    for (int i = 0;i<m_resultVec.size();i++)    {        switch(m_resultVec[i].type)        {        case KEYWORD:            {                cout<<m_resultVec[i].token<<"  "<<"("<<m_resultVec[i].line<<","<<m_resultVec[i].row<<")"<<endl;                break;            }        case ID:            {                cout<<"ID("<<m_resultVec[i].token<<")"<<"  "<<"("<<m_resultVec[i].line<<","<<m_resultVec[i].row<<")"<<endl;                break;            }        case BLANK:            {                break;            }        case ENTER:            {                break;            }        }    }}
 1 #include "Tokenizer.h" 2  3 int main() 4 { 5     Tokenizer tokenizer; 6     tokenizer.ReadSourceFile("./test.txt"); 7     tokenizer.Parse(); 8     tokenizer.ShowResult(); 9 10     system("pause");11     12     return 0;13 }

 

[编译原理学习]词法分析