手写编译器之词法分析器一


`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='\0';  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=='\n')  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=='\n') 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='\0';//结束标志 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='\0'; 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+='\n'; 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

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值