- 论坛徽章:
- 20
|
本帖最后由 nswcfd 于 2016-08-31 17:06 编辑
第一部分声明了一些状态(start conditons)
%x COMMAND HELP STRING PARAM
以及ws(空白)和n(数字或字母)两个“宏”
第二部分
- [ \t]*#.*\n |
- [ \t]*\n {
- current_file->lineno++;
- return T_EOL;
- }
- //匹配行末空白或注释(#开始)
- [ \t]*#.*
- //忽略注释以及之前的空白
- [ \t]+ {
- BEGIN(COMMAND);
- }
- //空格进入COMMAND状态
- . {
- unput(yytext[0]);
- BEGIN(COMMAND);
- }
- //任意字符进入COMMAND状态, unput放回当前字符(重新解析)
- <COMMAND>{
- //COMMAND状态下的pattern & action
- {n}+ {
- struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
- BEGIN(PARAM);
- current_pos.file = current_file;
- current_pos.lineno = current_file->lineno;
- if (id && id->flags & TF_COMMAND) {
- zconflval.id = id;
- return id->token;
- }
- alloc_string(yytext, yyleng);
- zconflval.string = text;
- return T_WORD;
- }
- //匹配标识符(可能已经存在),切换到PARAM状态
- .
- //忽略其它字符
- \n {
- BEGIN(INITIAL);
- current_file->lineno++;
- return T_EOL;
- }
- //换行切换为INIT状态
- }
- <PARAM>{
- //PARAM状态下的pattern & action
- "&&" return T_AND;
- "||" return T_OR;
- "(" return T_OPEN_PAREN;
- ")" return T_CLOSE_PAREN;
- "!" return T_NOT;
- "=" return T_EQUAL;
- "!=" return T_UNEQUAL;
- //字符串常量,各种操作符
- \"|\' {
- str = yytext[0];
- new_string();
- BEGIN(STRING);
- }
- //单引号或双引号,切换为STRING状态
- \n BEGIN(INITIAL); current_file->lineno++; return T_EOL;
- //换行切换为INIT状态
- --- /* ignore */
- //忽略---
- ({n}|[-/.])+ {
- struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
- if (id && id->flags & TF_PARAM) {
- zconflval.id = id;
- return id->token;
- }
- alloc_string(yytext, yyleng);
- zconflval.string = text;
- return T_WORD;
- }
- //匹配标识符
- #.* /* comment */
- //注释,忽略
- \\\n current_file->lineno++;
- //line continue,忽略
- .
- //忽略其它字符
- <<EOF>> {
- BEGIN(INITIAL);
- }
- }
- <STRING>{
- //STRING状态下的pattern & action
- [^'"\\\n]+/\n {
- append_string(yytext, yyleng);
- zconflval.string = text;
- return T_WORD_QUOTE;
- }
- //行末的串,不包括引号和转义
- [^'"\\\n]+ {
- append_string(yytext, yyleng);
- }
- //非行未的(部分)串,不包括引号和转义
- \\.?/\n {
- append_string(yytext + 1, yyleng - 1);
- zconflval.string = text;
- return T_WORD_QUOTE;
- }
- //行末的转义,串结束
- \\.? {
- append_string(yytext + 1, yyleng - 1);
- }
- //非行末的转义,串未结束
- \'|\" {
- if (str == yytext[0]) {
- BEGIN(PARAM);
- zconflval.string = text;
- return T_WORD_QUOTE;
- //字符串结束
- } else
- append_string(yytext, 1);
- //引号本身作为字符串的一部分
- }
- \n {
- printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
- current_file->lineno++;
- BEGIN(INITIAL);
- return T_EOL;
- }
- //换行结束STRING状态
- <<EOF>> {
- BEGIN(INITIAL);
- }
- }
- <HELP>{
- //HELP状态下的pattern & acttion
- [ \t]+ {
- ts = 0;
- for (i = 0; i < yyleng; i++) {
- if (yytext[i] == '\t')
- ts = (ts & ~7) + 8;
- else
- ts++;
- }
- last_ts = ts;
- if (first_ts) {
- if (ts < first_ts) {
- zconf_endhelp();
- return T_HELPTEXT;
- }
- ts -= first_ts;
- while (ts > 8) {
- append_string(" ", 8);
- ts -= 8;
- }
- append_string(" ", ts);
- }
- }
- //看起来像是tab展开,基于缩进量判断help是否结束(python风格……)
- [ \t]*\n/[^ \t\n] {
- current_file->lineno++;
- zconf_endhelp();
- return T_HELPTEXT;
- }
- //下一行没有缩进,help结束
- [ \t]*\n {
- current_file->lineno++;
- append_string("\n", 1);
- }
- //忽略行末空白,help可以包含换行
- [^ \t\n].* {
- while (yyleng) {
- if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
- break;
- yyleng--;
- }
- append_string(yytext, yyleng);
- if (!first_ts)
- first_ts = last_ts;
- }
- //help正文本身(未结束),忽略末尾的空白,并计算第一行的缩进量
- <<EOF>> {
- zconf_endhelp();
- return T_HELPTEXT;
- }
- }
复制代码
第三部分是原封不动的代码,不解释。 |
|