博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Init中的next_token()函数
阅读量:2383 次
发布时间:2019-05-10

本文共 12813 字,大约阅读时间需要 42 分钟。

next_token函数

init/tokenizer.cpp中next_token函数

6 int next_token(struct parse_state *state)                                         7 {                                                                                 8     char *x = state->ptr;                                                         9     char *s;                                                                     10                                                                                  11     if (state->nexttoken) {                                                      12         int t = state->nexttoken;                                                13         state->nexttoken = 0;                                                    14         return t;                                                                15     }                                                                            16                                                                                  17     for (;;) {                                                                   18         switch (*x) {                                                            19         case 0:                                                                  20             state->ptr = x;                                                      21             return T_EOF;                                                        22         case '\n':                                                               23             x++;                                                                 24             state->ptr = x;                                                      25             return T_NEWLINE;                                                    26         case ' ':                                                                27         case '\t':                                                               28         case '\r':                                                               29             x++;                                                                 30             continue;                                                            31         case '#':                                                                32             while (*x && (*x != '\n')) x++;                                      33             if (*x == '\n') {                                                    34                 state->ptr = x+1;                                                35                 return T_NEWLINE;                                                36             } else {                                                             37                 state->ptr = x;                                                  38                 return T_EOF;                                                    39             }                                                                    40         default:                                                                 41             goto text;                                                           42         }                                                                        43     }                44                                                                                  45 textdone:                                                                        46     state->ptr = x;                                                              47     *s = 0;                                                                      48     return T_TEXT;                                                               49 text:                                                                            50     state->text = s = x;                                                         51 textresume:                                                                      52     for (;;) {                                                                   53         switch (*x) {                                                            54         case 0:                                                                  55             goto textdone;                                                       56         case ' ':                                                                57         case '\t':                                                               58         case '\r':                                                               59             x++;                                                                 60             goto textdone;                                                       61         case '\n':                                                               62             state->nexttoken = T_NEWLINE;                                        63             x++;                                                                 64             goto textdone;                                                       65         case '"':                                                                66             x++;                                                                 67             for (;;) {                                                           68                 switch (*x) {                                                    69                 case 0:                                                          70                         /* unterminated quoted thing */                          71                     state->ptr = x;                                              72                     return T_EOF;                                                73                 case '"':                                                        74                     x++;                                                         75                     goto textresume;                                             76                 default:                                                         77                     *s++ = *x++;                                                 78                 }                                                                79             }                                                                    80             break;                                                      81         case '\\':                                                               82             x++;                                                                 83             switch (*x) {                                                        84             case 0:                                                              85                 goto textdone;                                                   86             case 'n':                                                            87                 *s++ = '\n';                                                     88                 break;                                                           89             case 'r':                                                            90                 *s++ = '\r';                                                     91                 break;                                                           92             case 't':                                                            93                 *s++ = '\t';                                                     94                 break;                                                           95             case '\\':                                                           96                 *s++ = '\\';                                                     97                 break;                                                           98             case '\r':                                                           99                     /* \ 
-> line continuation */ 100 if (x[1] != '\n') { 101 x++; 102 continue; 103 } 104 case '\n': 105 /* \
-> line continuation */ 106 state->line++; 107 x++; 108 /* eat any extra whitespace */ 109 while((*x == ' ') || (*x == '\t')) x++; 110 continue; 111 default: 112 /* unknown escape -- just copy */ 113 *s++ = *x++; 114 } 115 continue; 116 default: 117 *s++ = *x++; 118 } 119 } 120 return T_EOF; 121 }

next_token函数整体逻辑:把文件中所有内容保存到字符串str。

在17行到43行的第一个for循环处理逻辑: 从文本找到待处理字符串的第一个字符。
具体操作: 在字符串找到有用字符,则会进入text中,分割字符串,保存内容;如果遇到字符串中非有用字符是"#",继续在字符串str中轮询,直接遇到换行符(’\n’),或者轮询到结束符(EOF),分别在35行返回T_NEWLINE,或者在38行中返回return T_EOF;如果遇到空行"\n",则返回T_NEWLINE;如到’ ‘,’\t’,'r’等特殊字符继续向前轮询字符。

在52行开始的第二个for循环:找到需要待处理字符串后一个字符(例如:空格、结束符号、换行)。

有个数据结构struct parse_state。

struct parse_state                                                                 {                                                                                      char *ptr;      ------>指向剩余字符串                                                                   char *text;     ------>保存                                                               int   line;    --->处理的行数                                                                                                                                                                                     int nexttoken;  ---->处理过的分割符                                                               };

举个例子:处理如下配置文件。

配置文件内容如下,使用vim set list查看,$是转行符,^I是table,其他就是看见的空格。

1 import /init.environ.rc$                                                          2 import /init.usb.rc$                                                              3 $                                                                                 4 on fs$                                                                                                                                                                                                    5 ^Imount_all ./fstab.uml $                                                         6 $                                                                                 7 on early-init$                                                                    8     # Set init and its forked children's oom_adj.$                                9     write /proc/1/oom_score_adj -1000$                                           10     tom-init-rc$                                                                 11 $                                                                               ~

处理流程:

1)调用next_token(),如果遇到注释语句,从31行处理,直接轮询到行末换行符(’\n’),并且从35行出。
2)调用next_token(),处理到第4行,第一个字符是’o’,运行到40行,goto text,state->text = s=x。因为x=‘o’,匹配116行的default的case,执行到 s++ = x++;则x=‘n’,然后再匹配116行的default的case,执行完s++ = x++;则x是空格,则匹配56行的case,运行textdone,然后在s后面加结束符,则state->text=“on”,返回T_TEXT。
3) 调用next_token(),处理字符串“fs”,因为
s=’\n’(换行符),匹配到61行,执行state->nexttoken = T_NEWLINE;运行到textdone,运行后,则state->text=“on”,返回T_TEXT。
4)调用next_token(),运行到11行,返回T_NEWLINE,并且把state->nexttoken=0。

这样完成1行数据的处理。

附表

|转义字符| 意义 |ASCII码值(十进制)|

|–|--|
| \n |换行(LF),将当前位置移到下一行开头 |010|
| \r |回车(CR) ,将当前位置移到本行开头 |013|
| \t |水平制表(HT) ( 跳到下一个TAB位置)|009|

\r是回车(CR),将光标移动到行前.

#include
#include
int main(int argc, char* argv[]){ printf("ab c\n"); // 输出:ab c printf("\td\n"); // 输出: d printf("abc\rf\n"); // 输出:fbc char str1[20]="abc\rf"; printf("%x %x %x %x %x",str1[0],str1[1],str1[2],str1[3],str1[4]);//0x61 0x62 0x63 0xd 0x66 return 0;}

转载地址:http://xafab.baihongyu.com/

你可能感兴趣的文章
C++ static 语义
查看>>
C++ static 语义
查看>>
Linux Cgroups概述
查看>>
centos7 硬盘性能测试
查看>>
cgroup使用--cpu资源限制
查看>>
cgroup使用--memory资源限制
查看>>
Redis 单机环境搭建
查看>>
elasticsearch 单机环境搭建
查看>>
spark 独立模式部署
查看>>
Redis 基础命令 --- String篇
查看>>
Redis 基础命令 --- Hash篇
查看>>
Redis 基础命令 --- List篇
查看>>
Redis 基础命令 --- Set篇
查看>>
Redis数据库篇 -- 生存时间
查看>>
面向对象设计基本原则
查看>>
Redis数据库篇 -- 事务
查看>>
hadoop 完全分布式环境搭建
查看>>
HDFS 回收站
查看>>
hadoop 完全分布式HA高可用集群(手工切换)搭建
查看>>
hadoop 完全分布式HA高可用集群(自动切换)搭建
查看>>