[编译原理学习]词法分析
此前一直没能系统完整地学过编译原理,只有很粗浅的理解,虽然其实对工作里的任务也没啥影响,但总觉得缺了一大块知识,加上对所谓程序员三大浪漫(编译器,操作系统,图形学)的向往,所以最近跟着网易云课堂推出的计算机专业课程来学习编译原理.无奈生性懒惰,常常下班之后觉得累了,打打游戏啊看看视频啊,拖延症就犯了.......所以在这里打算将学习的过程,心得记录下来,也算是对自己的一个督促.课程传送门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 symbol 10 { 11 //关键字if、符合C语言标准的标识符、空格符、回车符 12 KEYWORD, 13 ID, 14 BLANK, 15 ENTER 16 }; 17 18 struct result 19 { 20 string token; //符号名 21 int type; //符号类型 22 int line; //符号所在行 23 int row; //符号所在列 24 }; 25 26 class Tokenizer 27 { 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*1024 Tokenizer::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 }
作者:sdu20112013
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎转载,转载请注明出处.