小女也爱葵花宝典---读懂编译原理(1)
欲练神功,必先看数据结构(图必看),内功心法之葵花宝典 最近在看葵花宝典(编译原理),买了本龙书来看,但是怎么看也看不明白,之后小女我先照的自己的想法写了一次,然后写的时候见的问题,在书中都可以找的到,这样我就看懂龙书了.在此写点东西给大家参考.
先看看什么是状态机,上图就是状态机
解答上图:识别一个字符串 I am a boy 首先是状态-是否是空格,然后是-是否是新的单词,只要这两种状态就行了.用两个指针 char* lexemBegin char* lexemEnd 指向单词的开始:
I am a boy
↑ ↑
lexemBegin lexemEnd
然后用指针, lexemEnd读取一个字符,如读I,然后状态 是否是新的单词=是 ,读空格 是否是空格=是,然后就可以判定一个单词的结束.
以上是原理:然后给出代码
typedef struct scrWord {//这是一个单词表,之后还要用在语义分析 char data[100]; int len; scrWord* next; scrWord* S;//非中终符 }scrWord; void cpystr(char* des ,char* scr,int len) { for(int i=0;i<len;i++) { *des=*scr; des++; scr++; } } bool cmptostr(char* scr ,char* lexemBegin ,int len) {//单词比较,这里先自己写着行,之后用kmp 算法替换(这样速度快) for(int i=0;i<len;i++) { if(tolower(*scr)!=tolower(*lexemBegin)) return false; lexemBegin++; scr++; } return true; } void toker(char* cinput ,scrWord *wordTable) {// cinput输入的单词, wordTable单词表之后讲解 int Wordlen=strlen(cinput);//得到输入串的长度 scrWord *lpWordTable=wordTable; char* lexemBegin=cinput;//串的开始指针 char* lexemEnd=cinput; //串的结束指针 bool isNewWord=false;//是否是新词单 bool isBreak=true;//是否是空格 int count=0;//记录一共有几个单 while(*lexemEnd!=';') { if((*(lexemEnd-1))!=' ' && (*lexemEnd==' ' || *lexemEnd=='(' || *lexemEnd==')'))//这里之后会改进 isNewWord=true;// else isNewWord=false; if((*lexemEnd==' ' || *lexemEnd=='(' || *lexemEnd==')') && isNewWord==true) { scrWord *wordTable2=new scrWord();//单词表 memset(wordTable2->data,0,100);//内存初始化 cpystr(wordTable2->data,lexemBegin,lexemEnd-lexemBegin);//单词表 lpWordTable->next=wordTable2;//用链表生成的单词表 lpWordTable->len=lexemEnd-lexemBegin;// 单词长度 lpWordTable=lpWordTable->next; lexemBegin=lexemEnd; } lexemEnd++; if(lexemEnd-lexemBegin>Wordlen) { return; } } } int main(int argc, char* argv[]) {//调用的例子 scrWord *wordTable=new scrWord(); char * str="create table hts(fe int)"; toker(str,wordTable); return 0; }
这上为自己写的sql词法分析器,在之后小女将出继编改进词法分析器,并对照龙书.