zoukankan      html  css  js  c++  java
  • 手写编译器之词法分析器一

      写一个编译器,首先要知道的就是什么是编译器,我觉得能看到我这篇文章的基本上都知道了。我认为,编译器就是

    让计算机读懂代码的程序,在这个程序里,定义了各种规则(编程语言的语法),只要人们按照这个规则和计算机说

    话(编程)就能让计算机懂得我们想干嘛。

      编译器包括几个模块,也可以说是过程,即词法分析,语法分析,中间代码生成等等。好吧我承认我知道的不清楚,

    不过万物起源词法分析(我编的)一定没问题。这里我们就先来第一步,词法分析。词法分析是编译器中比较简单的模块了,

    也是最基础的模块。它的作用就是将输入的程序文本文件切割成一个一个的单词和符号,以便接下来的模块使用。

      好了,高深的道理就不讲了,我现在的目标就是要写一个函数,这个函数接收一个文件地址,将该文件中的代码分割

    成单词和符号,每个单词和符号被称为一个token,返回一个链表,存储所有的token。函数定义就写为:

    TokenList_tag LexExcute(string sourcefilepath);//TokenList_tag是链表头指针,指向头节点,sourcefilepath为源文件地址
    

       我将词法分析程序写在lex.cpp文件中,二话不说先上几行代码,顿时感觉自信心爆棚。代码4-7行可以用一行

    using namespace std;代替

    1 #include<iostream>
    2 #include<string >
    3 #include<fstream>
    4 using std::cout;
    5 using std::string;
    6 using std::endl;
    7 using std::ifstream;

       讲道理现在应该先定义一下token了,不过我还不知道token怎么定义,就先不这么搞了,先解决读取文件的问题,

    定义一个string变量(filepath)存储文件地址,定义文件流(in)用于读取文件内容,然后从流中每次读取一行,存入

    字符串变量line_str,这样思路就很清晰了,我们从line_str中逐个取出字符,然后分析。

    1 ifstream  in;//文件流
    2 string    filepath;//文件路径
    3 string    line_str;//存储每次读出的行
    4 int       line_len;//读出行的长度
    5 int       line_pos;//逐字符处理时,用于记录位置
    6 int       line_num;//记录当前源文件第几行,可能以后报语法错误的时候有用
    7 char      ch;//逐字符处理时,记录当前字符
    8 string    token_str;//记录token字符串

      为防止出错,我们定义初始化函数init(),将所有变量的初始化放在该函数中,如下:

     1 void init()
     2 {
     3     cout<<"func enter: init"<<endl;
     4     line_pos=0;
     5     line_num=0;
     6     token_str="";
     7     ch='';
     8     //end_of_file=false;
     9     //end_of_lex=false;
    10     //tokenlist=new TokenNode_tag;
    11     //tokenlist->token_str="#";
    12     //tokenlist->next=NULL;
    13     //listtail=tokenlist;
    14     in.open(filepath.c_str());
    15     cout<<"func end: init"<<endl;
    16 }

      在此函数执行之前,filepath就已经在函数外赋值了,我懒得传参数,就在该函数调用前加了一句: 

    filepath=sourcefilepath;  //sourcefilepath是传进来的参数。

      下面,我们就开始定义token数据结构,目前我能想到的数据结构属性只有两个,一个token_str,

    一个token_type。token_str用来保存token字符串,而token_type记录该token是什么类型,比如标识符,

    关键字,数字等等。在定义token前先定义TokenType(枚举类型),如下:

     1 enum TokenType
     2 {
     3 //顺序不可改变
     4     KEYWORDS_INT,
     5     KEYWORDS_DOUBLE,
     6     KEYWORDS_FLOAT,
     7     KEYWORDS_IF,
     8     KEYWORDS_ELSE,
     9     KEYWORDS_ELSIF,
    10     KEYWORDS_WHILE,
    11     KEYWORDS_FOR,
    12 
    13 
    14     IDENTIFY,
    15     OP_EQUAL,//==
    16     OP_ASSIGN,//=
    17     OP_LP,//(
    18     OP_RP,//)
    19     OP_ADD,//+
    20     OP_SUB,//-
    21     OP_MUL,//*
    22     OP_DIV,// /
    23     OP_SEMI,//;
    24     NUM_FLOAT,
    25     NUM_INT
    26 };

      TokenType里面的注释肯定就很清晰了,就不多介绍,下面就是TokenNode的定义:

    1 typedef struct TokenNode_tag
    2 {
    3     string    token_str;
    4     TokenType token_type;
    5     struct    TokenNode_tag   *next;//用于制作链表
    6 }*TokenList_tag,TokenNode_tag;

      可能会有人疑惑,命名为什么要加一个tag呢?首先,名字是什么都无所谓(关键字除外),其次

    加一个tag是为了区别内部使用和外部调用,所谓内部就是lex.cpp中的函数使用,外部就是为了以后的

    其他模块调用(到时候会给这些结构重新起名为TokenNode)。

      好了,万事俱备,只欠最关键的函数了:

    1 TokenList_tag LexExcute(string sourcefilepath)
    2 {  
    3     cout<<"func enter: main"<<endl;
    4     filepath=sourcefilepath;//;
    5     init();
        //这里将写关键代码,一个大while循环
    6 cout<<"func end: main"<<endl; 7 }

      这个函数作为主函数,他的工作原理就是循环从line_str中取出字符,然后根据字符判断目前是不是一个单词

    或符号,比如出现空格就说明字符串结束等(说法不准确)。好吧,我知道这里有个自动机什么的,我也讲不清楚,

    下面直接说我的实现方法:

      我将词法分析运作过程分为几个阶段,每个阶段都用一种状态记录,比如说,当while大循环第一次运作的时候,

    此时为初始状态(STATUS_NON),在这个状态下若取出字符ch为数字(0-9),那么词法分析状态就转变为数字

    态(STATUS_NUM),在该状态下若取出字符ch为数字则状态不变,若ch为 ‘.’ (小数点)说明数字为浮点型,状态转为浮点

    态(STATUS_FLOAT),若ch为空或者其他字符,说明数字结束,状态转为初始态,开始下一个循环。

      可能我自己觉得讲的挺清晰,看到的人反而有困难,不如我就画个图:

      好吧,真是不画不知道自己画多丑,不过抛开这些还是挺清晰的吧。。。额,这不重要,这应该就有传说

    中的自动机的影子了吧,好吧,不强求能不能看懂了,最下面会有函数完整代码,看懂代码肯定就没问题了。

      在写主函数(LexExcute)之前,我们还要做一些必要工作:

     1 bool      end_of_file;//初始为false,当读取文件结束的时候置为true
     2 bool      end_of_lex;//当读取文件结束,而其当前行也分析完毕时置为true(词法分析结束标志)
     3 TokenList_tag tokenlist;//词法分析器执行结束后产生的 token  串(主函数返回链表的头指针)
     4 TokenNode_tag*listtail;//链表尾指针,用于尾部插入节点 5 void getline();//文件中读取一行
     6 void getch();//获取一个字符
     7 bool ischar();//是否为a-z或者A-Z
     8 bool isnum();//是否为0-9
     9 void concat();//连接到token_str
    10 //
    11 void backwords();//回退一个字符 12 void tokenlist_insert(TokenNode_tag*);//链表插入函数 13 void tokenlist_visit();//链表遍历函数,用于检查正误,对功能没用用 14 int iskeywords(string );//判断是否是关键字

      关键字数组,自动机状态定义具体函数实现就看下面的完整代码吧:

     1  string keywords[]=
     2 {
     3     //顺序不可改变
     4     "int",
     5     "double",
     6     "float",
     7     "if",
     8     "else",
     9     "elsif",
    10     "while",
    11     "for"
    12 };
    13 
    14 enum LexStatus
    15 {
    16     STATUS_NON,
    17     STATUS_NUM,
    18     STATUS_STR,
    19     STATUS_FLOAT,
    20     STATUS_ASSIGN,
    21 
    22 };
      1 TokenList_tag LexExcute(string sourcefilepath)
      2 {
      3     cout<<"func enter: main"<<endl;
      4     filepath=sourcefilepath;//;
      5     init();
      6     getline();
      7     LexStatus lexstatus=STATUS_NON;
      8     TokenNode_tag *tokennode;
      9     while(!end_of_lex)
     10     {
     11         getch();
     12         if(lexstatus==STATUS_NON)//初始状态下
     13         {
     14             cout<<"LexStatus: STATUS_NON"<<endl;
     15             if(ischar()||ch=='_')
     16             {
     17                 lexstatus=STATUS_STR;
     18                 cout<<"LexStatus: STATUS_NON -> STATUS_STR"<<endl;
     19                 concat();
     20 
     21             }
     22             else if(isnum())
     23             {
     24                 lexstatus=STATUS_NUM;
     25                 cout<<"LexStatus: STATUS_NON -> STATUS_NUM"<<endl;
     26                 concat();
     27             }
     28             else if(ch=='(')
     29             {
     30                 concat();
     31                 tokennode=new TokenNode_tag;
     32                 tokennode->token_str=token_str;
     33                 tokennode->token_type=OP_LP;
     34                 tokennode->next=NULL;
     35                 tokenlist_insert(tokennode);
     36                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
     37                 lexstatus=STATUS_NON;
     38                 token_str="";
     39             }
     40             else if(ch==')')
     41             {
     42                 concat();
     43                 tokennode=new TokenNode_tag;
     44                 tokennode->token_str=token_str;
     45                 tokennode->token_type=OP_RP;
     46                 tokennode->next=NULL;
     47                 tokenlist_insert(tokennode);
     48                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
     49                 lexstatus=STATUS_NON;
     50                 token_str="";
     51             }
     52             else if(ch==' ')
     53             {
     54                 cout<<"do nothing"<<endl;
     55             }
     56             else if(ch=='
    ')
     57             {
     58                 cout<<"do nothing"<<endl;
     59             }
     60             else if(ch=='=')
     61             {
     62                 concat();
     63                 cout<<"LexStatus: STATUS_NON -> STATUS_ASSIGN"<<endl;
     64                 lexstatus=STATUS_ASSIGN;
     65                 token_str="";
     66             }
     67             else if(ch=='+')
     68             {
     69                 concat();
     70                 tokennode=new TokenNode_tag;
     71                 tokennode->token_str=token_str;
     72                 tokennode->token_type=OP_ADD;
     73                 tokennode->next=NULL;
     74                 tokenlist_insert(tokennode);
     75                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
     76                 lexstatus=STATUS_NON;
     77                 token_str="";
     78 
     79             }
     80             else if(ch=='-')
     81             {
     82                 concat();
     83                 tokennode=new TokenNode_tag;
     84                 tokennode->token_str=token_str;
     85                 tokennode->token_type=OP_SUB;
     86                 tokennode->next=NULL;
     87                 tokenlist_insert(tokennode);
     88                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
     89                 lexstatus=STATUS_NON;
     90                 token_str="";
     91             }
     92             else if(ch=='*')
     93             {
     94                 concat();
     95                 tokennode=new TokenNode_tag;
     96                 tokennode->token_str=token_str;
     97                 tokennode->token_type=OP_MUL;
     98                 tokennode->next=NULL;
     99                 tokenlist_insert(tokennode);
    100                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    101                 lexstatus=STATUS_NON;
    102                 token_str="";
    103             }
    104             else if(ch=='/')
    105             {
    106                 concat();
    107                 tokennode=new TokenNode_tag;
    108                 tokennode->token_str=token_str;
    109                 tokennode->token_type=OP_DIV;
    110                 tokennode->next=NULL;
    111                 tokenlist_insert(tokennode);
    112                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    113                 lexstatus=STATUS_NON;
    114                 token_str="";
    115             }
    116             else if(ch==';')
    117             {
    118                 concat();
    119                 tokennode=new TokenNode_tag;
    120                 tokennode->token_str=token_str;
    121                 tokennode->token_type=OP_SEMI;
    122                 tokennode->next=NULL;
    123                 tokenlist_insert(tokennode);
    124                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    125                 lexstatus=STATUS_NON;
    126                 token_str="";
    127             }
    128 
    129         }//lexstatus
    130         else if(lexstatus==STATUS_ASSIGN)
    131         {
    132             if(ch=='=')//==
    133             {
    134                 concat();
    135                 tokennode=new TokenNode_tag;
    136                 tokennode->token_str=token_str;
    137                 tokennode->token_type=OP_EQUAL;
    138                 tokennode->next=NULL;
    139                 tokenlist_insert(tokennode);
    140                 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl;
    141                 lexstatus=STATUS_NON;
    142                 token_str="";
    143             }
    144             else  //=
    145             {
    146                 tokennode=new TokenNode_tag;
    147                 tokennode->token_str=token_str;
    148                 tokennode->token_type=OP_ASSIGN;
    149                 tokennode->next=NULL;
    150                 tokenlist_insert(tokennode);
    151                 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl;
    152                 lexstatus=STATUS_NON;
    153                 token_str="";
    154                 backwords();
    155             }
    156         }
    157         else if(lexstatus==STATUS_FLOAT)
    158         {
    159             if(isnum())
    160             {
    161                 concat();
    162             }
    163             else
    164             {
    165                 tokennode=new TokenNode_tag;
    166                 tokennode->token_str=token_str;
    167                 tokennode->token_type=NUM_FLOAT;
    168                 tokennode->next=NULL;
    169                 tokenlist_insert(tokennode);
    170                 cout<<"LexStatus: STATUS_FLOAT -> STATUS_NON"<<endl;
    171                 lexstatus=STATUS_NON;
    172                 token_str="";
    173                 backwords();
    174             }
    175         }
    176         else if(lexstatus==STATUS_NUM)
    177         {
    178             if(isnum())
    179             {
    180                 concat();
    181             }
    182             else if(ch=='.')
    183             {
    184                 concat();
    185                 lexstatus=STATUS_FLOAT;
    186             }
    187             else
    188             {
    189                 tokennode=new TokenNode_tag;
    190                 tokennode->token_str=token_str;
    191                 tokennode->token_type=NUM_INT;
    192                 tokennode->next=NULL;
    193                 tokenlist_insert(tokennode);
    194                 cout<<"LexStatus: STATUS_NUM -> STATUS_NON"<<endl;
    195                 lexstatus=STATUS_NON;
    196                 token_str="";
    197                 backwords();
    198             }
    199         }
    200         else if(lexstatus==STATUS_STR)
    201         {
    202             if(ischar()||ch=='_'||isnum())
    203             {
    204                 concat();
    205             }
    206             else
    207             {
    208                 tokennode=new TokenNode_tag;
    209                 tokennode->token_str=token_str;
    210                 int check=iskeywords(token_str);
    211                 if(check!=-1)tokennode->token_type=(TokenType)check;
    212                 else tokennode->token_type=IDENTIFY;
    213                 tokennode->next=NULL;
    214                 tokenlist_insert(tokennode);
    215                 cout<<"LexStatus: STATUS_STR -> STATUS_NON"<<endl;
    216                 lexstatus=STATUS_NON;
    217                 token_str="";
    218                 backwords();
    219             }
    220         }
    221 
    222 
    223 
    224     }
    225 
    226     cout<<"func end: main"<<endl;
    227     tokenlist_visit();
    228     return tokenlist;
    229 }

    完整代码:(代码是从好多文件剪出来的,应该可以运行吧,额。。。)感觉代码好长,高手应该用很短就行了吧,惭愧。

      1 #include<iostream>
      2 #include<string >
      3 #include<fstream>
      4 using std::cout;
      5 using std::string;
      6 using std::endl;
      7 using std::ifstream;
      8  string keywords[]=
      9 {
     10     //顺序不可改变
     11     "int",
     12     "double",
     13     "float",
     14     "if",
     15     "else",
     16     "elsif",
     17     "while",
     18     "for"
     19 };
     20 
     21 enum LexStatus
     22 {
     23     STATUS_NON,
     24     STATUS_NUM,
     25     STATUS_STR,
     26     STATUS_FLOAT,
     27     STATUS_ASSIGN,
     28 
     29 };
     30 enum TokenType
     31 {
     32 //顺序不可改变
     33     KEYWORDS_INT,
     34     KEYWORDS_DOUBLE,
     35     KEYWORDS_FLOAT,
     36     KEYWORDS_IF,
     37     KEYWORDS_ELSE,
     38     KEYWORDS_ELSIF,
     39     KEYWORDS_WHILE,
     40     KEYWORDS_FOR,
     41 
     42 
     43     IDENTIFY,
     44     OP_EQUAL,//==
     45     OP_ASSIGN,//=
     46     OP_LP,//(
     47     OP_RP,//)
     48     OP_ADD,//+
     49     OP_SUB,//-
     50     OP_MUL,//*
     51     OP_DIV,// /
     52     OP_SEMI,//;
     53     NUM_FLOAT,
     54     NUM_INT
     55 };
     56 typedef struct TokenNode_tag
     57 {
     58     string    token_str;
     59     TokenType token_type;
     60     struct    TokenNode_tag   *next;
     61 }*TokenList_tag,TokenNode_tag;
     62 
     63 
     64 ifstream  in;
     65 string    filepath;
     66 string    line_str;
     67 int       line_len;
     68 int       line_pos;
     69 int       line_num;
     70 char      ch;
     71 string    token_str;
     72 
     73 bool      end_of_file;
     74 bool      end_of_lex;
     75 TokenList_tag tokenlist;//词法分析器执行结束后产生的 token  串
     76 TokenNode_tag*listtail;
     77 void init();
     78 void getline();
     79 void getch();
     80 bool ischar();
     81 bool isnum();
     82 void concat();
     83 void backwords();
     84 void tokenlist_insert(TokenNode_tag*);
     85 void tokenlist_visit();
     86 int iskeywords(string );
     87 TokenList_tag LexExcute(string sourcefilepath)
     88 {
     89     cout<<"func enter: main"<<endl;
     90     filepath=sourcefilepath;//;
     91     init();
     92     getline();
     93     LexStatus lexstatus=STATUS_NON;
     94     TokenNode_tag *tokennode;
     95     while(!end_of_lex)
     96     {
     97         getch();
     98         if(lexstatus==STATUS_NON)//初始状态下
     99         {
    100             cout<<"LexStatus: STATUS_NON"<<endl;
    101             if(ischar()||ch=='_')
    102             {
    103                 lexstatus=STATUS_STR;
    104                 cout<<"LexStatus: STATUS_NON -> STATUS_STR"<<endl;
    105                 concat();
    106 
    107             }
    108             else if(isnum())
    109             {
    110                 lexstatus=STATUS_NUM;
    111                 cout<<"LexStatus: STATUS_NON -> STATUS_NUM"<<endl;
    112                 concat();
    113             }
    114             else if(ch=='(')
    115             {
    116                 concat();
    117                 tokennode=new TokenNode_tag;
    118                 tokennode->token_str=token_str;
    119                 tokennode->token_type=OP_LP;
    120                 tokennode->next=NULL;
    121                 tokenlist_insert(tokennode);
    122                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    123                 lexstatus=STATUS_NON;
    124                 token_str="";
    125             }
    126             else if(ch==')')
    127             {
    128                 concat();
    129                 tokennode=new TokenNode_tag;
    130                 tokennode->token_str=token_str;
    131                 tokennode->token_type=OP_RP;
    132                 tokennode->next=NULL;
    133                 tokenlist_insert(tokennode);
    134                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    135                 lexstatus=STATUS_NON;
    136                 token_str="";
    137             }
    138             else if(ch==' ')
    139             {
    140                 cout<<"do nothing"<<endl;
    141             }
    142             else if(ch=='
    ')
    143             {
    144                 cout<<"do nothing"<<endl;
    145             }
    146             else if(ch=='=')
    147             {
    148                 concat();
    149                 cout<<"LexStatus: STATUS_NON -> STATUS_ASSIGN"<<endl;
    150                 lexstatus=STATUS_ASSIGN;
    151                 token_str="";
    152             }
    153             else if(ch=='+')
    154             {
    155                 concat();
    156                 tokennode=new TokenNode_tag;
    157                 tokennode->token_str=token_str;
    158                 tokennode->token_type=OP_ADD;
    159                 tokennode->next=NULL;
    160                 tokenlist_insert(tokennode);
    161                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    162                 lexstatus=STATUS_NON;
    163                 token_str="";
    164 
    165             }
    166             else if(ch=='-')
    167             {
    168                 concat();
    169                 tokennode=new TokenNode_tag;
    170                 tokennode->token_str=token_str;
    171                 tokennode->token_type=OP_SUB;
    172                 tokennode->next=NULL;
    173                 tokenlist_insert(tokennode);
    174                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    175                 lexstatus=STATUS_NON;
    176                 token_str="";
    177             }
    178             else if(ch=='*')
    179             {
    180                 concat();
    181                 tokennode=new TokenNode_tag;
    182                 tokennode->token_str=token_str;
    183                 tokennode->token_type=OP_MUL;
    184                 tokennode->next=NULL;
    185                 tokenlist_insert(tokennode);
    186                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    187                 lexstatus=STATUS_NON;
    188                 token_str="";
    189             }
    190             else if(ch=='/')
    191             {
    192                 concat();
    193                 tokennode=new TokenNode_tag;
    194                 tokennode->token_str=token_str;
    195                 tokennode->token_type=OP_DIV;
    196                 tokennode->next=NULL;
    197                 tokenlist_insert(tokennode);
    198                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    199                 lexstatus=STATUS_NON;
    200                 token_str="";
    201             }
    202             else if(ch==';')
    203             {
    204                 concat();
    205                 tokennode=new TokenNode_tag;
    206                 tokennode->token_str=token_str;
    207                 tokennode->token_type=OP_SEMI;
    208                 tokennode->next=NULL;
    209                 tokenlist_insert(tokennode);
    210                 cout<<"LexStatus: STATUS_NON -> STATUS_NON"<<endl;
    211                 lexstatus=STATUS_NON;
    212                 token_str="";
    213             }
    214 
    215         }//lexstatus
    216         else if(lexstatus==STATUS_ASSIGN)
    217         {
    218             if(ch=='=')//==
    219             {
    220                 concat();
    221                 tokennode=new TokenNode_tag;
    222                 tokennode->token_str=token_str;
    223                 tokennode->token_type=OP_EQUAL;
    224                 tokennode->next=NULL;
    225                 tokenlist_insert(tokennode);
    226                 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl;
    227                 lexstatus=STATUS_NON;
    228                 token_str="";
    229             }
    230             else  //=
    231             {
    232                 tokennode=new TokenNode_tag;
    233                 tokennode->token_str=token_str;
    234                 tokennode->token_type=OP_ASSIGN;
    235                 tokennode->next=NULL;
    236                 tokenlist_insert(tokennode);
    237                 cout<<"LexStatus: STATUS_ASSIGN -> STATUS_NON"<<endl;
    238                 lexstatus=STATUS_NON;
    239                 token_str="";
    240                 backwords();
    241             }
    242         }
    243         else if(lexstatus==STATUS_FLOAT)
    244         {
    245             if(isnum())
    246             {
    247                 concat();
    248             }
    249             else
    250             {
    251                 tokennode=new TokenNode_tag;
    252                 tokennode->token_str=token_str;
    253                 tokennode->token_type=NUM_FLOAT;
    254                 tokennode->next=NULL;
    255                 tokenlist_insert(tokennode);
    256                 cout<<"LexStatus: STATUS_FLOAT -> STATUS_NON"<<endl;
    257                 lexstatus=STATUS_NON;
    258                 token_str="";
    259                 backwords();
    260             }
    261         }
    262         else if(lexstatus==STATUS_NUM)
    263         {
    264             if(isnum())
    265             {
    266                 concat();
    267             }
    268             else if(ch=='.')
    269             {
    270                 concat();
    271                 lexstatus=STATUS_FLOAT;
    272             }
    273             else
    274             {
    275                 tokennode=new TokenNode_tag;
    276                 tokennode->token_str=token_str;
    277                 tokennode->token_type=NUM_INT;
    278                 tokennode->next=NULL;
    279                 tokenlist_insert(tokennode);
    280                 cout<<"LexStatus: STATUS_NUM -> STATUS_NON"<<endl;
    281                 lexstatus=STATUS_NON;
    282                 token_str="";
    283                 backwords();
    284             }
    285         }
    286         else if(lexstatus==STATUS_STR)
    287         {
    288             if(ischar()||ch=='_'||isnum())
    289             {
    290                 concat();
    291             }
    292             else
    293             {
    294                 tokennode=new TokenNode_tag;
    295                 tokennode->token_str=token_str;
    296                 int check=iskeywords(token_str);
    297                 if(check!=-1)tokennode->token_type=(TokenType)check;
    298                 else tokennode->token_type=IDENTIFY;
    299                 tokennode->next=NULL;
    300                 tokenlist_insert(tokennode);
    301                 cout<<"LexStatus: STATUS_STR -> STATUS_NON"<<endl;
    302                 lexstatus=STATUS_NON;
    303                 token_str="";
    304                 backwords();
    305             }
    306         }
    307 
    308 
    309 
    310     }
    311 
    312     cout<<"func end: main"<<endl;
    313     tokenlist_visit();
    314     return tokenlist;
    315 }//main
    316 int iskeywords(string str)
    317 {
    318     int i=0;
    319     int len=sizeof(keywords)/sizeof(string);
    320     cout<<"length of keyword[]: "<<len<<endl;
    321     while(i<len)
    322     {
    323         if(str==keywords[i])
    324         {
    325             cout<<str<<" is keywords"<<endl;
    326             return i;
    327         }
    328         ++i;
    329     }
    330     cout<<str<<" isn't keywords"<<endl;
    331     return -1;
    332 }
    333 void tokenlist_visit()
    334 {
    335     TokenNode_tag *tn;
    336     tn=tokenlist;
    337     while(tn->next!=NULL)
    338     {
    339         cout<<tn->next->token_str<<"   token_type"<<tn->next->token_type<<endl;
    340         tn=tn->next;
    341     }
    342 
    343 }
    344 void tokenlist_insert(TokenNode_tag* token)
    345 {
    346     cout<<"func enter: tokenlist_insert"<<endl;
    347     listtail->next=token;
    348     listtail=listtail->next;
    349     cout<<"func end: tokenlist_insert"<<endl;
    350 }
    351 bool ischar()
    352 {
    353     cout<<"func enter: ischar  ->ch:"<<ch<<endl;
    354     if((ch>='a'&&ch<='z')||(ch>='A'&&ch<='Z'))
    355     {
    356         cout<<"func end: ischar ->"<<ch<<" is char"<<endl;
    357         return true;
    358     }
    359     else
    360     {
    361         cout<<"func end: ischar ->"<<ch<<" isn't char"<<endl;
    362         return false;
    363     }
    364 }
    365 bool isnum()
    366 {
    367     cout<<"func enter: isnum ->ch:"<<ch<<endl;
    368     if(ch>='0'&&ch<='9')
    369     {
    370         cout<<"func end: isnum ->"<<ch<<" is num"<<endl;
    371         return true;
    372     }
    373     else
    374     {
    375         cout<<"func end: isnum ->"<<ch<<" isn't num"<<endl;
    376         return false;
    377     }
    378 
    379 }
    380 /**
    381 将ch加到token_str后
    382 */
    383 void concat()
    384 {
    385     cout<<"func enter: concat ->token:"<<token_str<<" ch:"<<ch<<endl;
    386     token_str+=ch;
    387     cout<<"func end: concat ->token:"<<token_str<<endl;
    388 }
    389 void backwords()
    390 {
    391     cout<<"func enter: backwords -> pos:"<<line_pos<<endl;
    392     if(line_pos>0)line_pos--;
    393     else cout<<"this is first ch in this line,can not backwords!";
    394     cout<<"func end: backwords -> pos:"<<line_pos<<endl;
    395 }
    396 void getch()
    397 {
    398     cout<<"func enter: getch"<<endl;
    399     if(line_pos<line_len)//从当前行获取一个字符
    400     {
    401         ch=line_str[line_pos++];
    402         cout<<"ch: "<<ch<<endl;
    403     }
    404     else//此行结束
    405     {
    406         cout<<"end of line"<<endl;
    407         if(end_of_file)
    408         {
    409             cout<<"file over!!!"<<endl;
    410             end_of_lex=true;
    411             ch='';//结束标志
    412         }
    413         else//文件并未结束,获取新行
    414         {
    415             cout<<"new line"<<endl;
    416             getline();
    417             getch();
    418         }
    419     }
    420     cout<<"func end: getch"<<endl;
    421 }
    422 void init()
    423 {
    424     cout<<"func enter: init"<<endl;
    425     line_pos=0;
    426     line_num=0;
    427     token_str="";
    428     ch='';
    429     end_of_file=false;
    430     end_of_lex=false;
    431     tokenlist=new TokenNode_tag;
    432     tokenlist->token_str="#";
    433     tokenlist->next=NULL;
    434     listtail=tokenlist;
    435     in.open(filepath.c_str());
    436     cout<<"func end: init"<<endl;
    437 }
    438 
    439 void getline()
    440 {
    441     cout<<"func enter: getline"<<endl;
    442     if(in)
    443     {
    444         line_num++;
    445         getline(in,line_str);
    446         //in>>line_str;
    447         line_str+='
    ';
    448         line_len=line_str.length();
    449         if(line_len==0)cout<<"line"<<line_num<<": "<<line_str<<endl;
    450         else
    451         {
    452             cout<<"line"<<line_num<<": "<<line_str<<endl;
    453             cout<<"length: "<<line_len<<endl;
    454         }
    455         line_pos=0;
    456     }
    457     else
    458     {
    459         cout<<"end of file"<<endl;
    460         end_of_file=true;
    461     }
    462     cout<<"func end: getline"<<endl;
    463 }
    View Code

     欢迎发现错误,欢迎留言!!!

  • 相关阅读:
    [windows菜鸟]C#中调用Windows API参考工具
    [windows菜鸟]C#中调用Windows API的技术要点说明
    [windows菜鸟]Windows API函数大全(完整)
    C#卸载加载到进程里的dll
    C# 防火墙操作之开启与关闭
    CMD命令行管道命令
    linux kernel elv_queue_empty野指针访问内核故障定位与解决
    U-Boot Driver Model领域模型设计
    linux I/O stack cache 强制刷新
    基于lcov实现的增量代码UT覆盖率检查
  • 原文地址:https://www.cnblogs.com/PPWEI/p/8391555.html
Copyright © 2011-2022 走看看