免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 1996 | 回复: 12
打印 上一主题 下一主题

[内核入门] Linux Kbuild 的词法分析器问题 [复制链接]

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-08-31 10:27 |只看该作者 |倒序浏览
Kbuild 的词法分析器,也就是 make config 对配置的词法分析和语法分析,最后通过 Kconfig 文件生产对应的 .config。
其源码位于 /srctree/scripts/kconfig/ 目录下。
请问有哪位朋友研究过 zonconf.l 的编译命令?

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
2 [报告]
发表于 2016-08-31 14:25 |只看该作者
没仔细分析过这个flex文件,楼主具体的问题是什么?

PS,可以通过info flex查询具体的语法点。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
3 [报告]
发表于 2016-08-31 14:32 |只看该作者
5 Format of the Input File
**************************

The `flex' input file consists of three sections, separated by a line
containing only `%%'.


         definitions
         %%
         rules
         %%
         user code


简单的例子
  1.                  int num_lines = 0, num_chars = 0;

  2.          %%
  3.          \n      ++num_lines; ++num_chars;
  4.          .       ++num_chars;

  5.          %%
  6.          main()
  7.                  {
  8.                  yylex();
  9.                  printf( "# of lines = %d, # of chars = %d\n",
  10.                          num_lines, num_chars );
  11.                  }
复制代码


论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
4 [报告]
发表于 2016-08-31 15:28 |只看该作者
回复 3# nswcfd


Kbuild 系统中,当我们使用命令 “make config” 的时候,他就会去调用 scripts/kconfig/zconf.l 的词法分析器分析 KCONFIG。
通过源码分析, Kbuild 同时使用了两个词法分析器,为了分开两个词法分析器, Kbuild 会使用 flex 带上一定的编译参数来生成这两个词法分析器。
我就是想知道 flex 生产这两个词法分析器时候使用的命令是什么?

默认的词法分析器是 yylex() 另外一个是 zconflex()

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
5 [报告]
发表于 2016-08-31 17:04 |只看该作者
本帖最后由 nswcfd 于 2016-08-31 17:06 编辑

第一部分声明了一些状态(start conditons)
%x COMMAND HELP STRING PARAM
以及ws(空白)和n(数字或字母)两个“宏”

第二部分

  1. [ \t]*#.*\n     |
  2. [ \t]*\n        {
  3.         current_file->lineno++;
  4.         return T_EOL;
  5. }
  6. //匹配行末空白或注释(#开始)

  7. [ \t]*#.*
  8. //忽略注释以及之前的空白

  9. [ \t]+  {
  10.         BEGIN(COMMAND);
  11. }
  12. //空格进入COMMAND状态

  13. .       {
  14.         unput(yytext[0]);
  15.         BEGIN(COMMAND);
  16. }
  17. //任意字符进入COMMAND状态, unput放回当前字符(重新解析)

  18. <COMMAND>{
  19. //COMMAND状态下的pattern & action
  20.         {n}+    {
  21.                 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
  22.                 BEGIN(PARAM);
  23.                 current_pos.file = current_file;
  24.                 current_pos.lineno = current_file->lineno;
  25.                 if (id && id->flags & TF_COMMAND) {
  26.                         zconflval.id = id;
  27.                         return id->token;
  28.                 }
  29.                 alloc_string(yytext, yyleng);
  30.                 zconflval.string = text;
  31.                 return T_WORD;
  32.         }
  33. //匹配标识符(可能已经存在),切换到PARAM状态
  34.         .
  35. //忽略其它字符
  36.         \n      {
  37.                 BEGIN(INITIAL);
  38.                 current_file->lineno++;
  39.                 return T_EOL;
  40.         }
  41. //换行切换为INIT状态
  42. }

  43. <PARAM>{
  44. //PARAM状态下的pattern & action
  45.         "&&"    return T_AND;
  46.         "||"    return T_OR;
  47.         "("     return T_OPEN_PAREN;
  48.         ")"     return T_CLOSE_PAREN;
  49.         "!"     return T_NOT;
  50.         "="     return T_EQUAL;
  51.         "!="    return T_UNEQUAL;
  52. //字符串常量,各种操作符
  53.         \"|\'   {
  54.                 str = yytext[0];
  55.                 new_string();
  56.                 BEGIN(STRING);
  57.         }
  58. //单引号或双引号,切换为STRING状态
  59.         \n      BEGIN(INITIAL); current_file->lineno++; return T_EOL;
  60. //换行切换为INIT状态
  61.         ---     /* ignore */
  62. //忽略---
  63.         ({n}|[-/.])+    {
  64.                 struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
  65.                 if (id && id->flags & TF_PARAM) {
  66.                         zconflval.id = id;
  67.                         return id->token;
  68.                 }
  69.                 alloc_string(yytext, yyleng);
  70.                 zconflval.string = text;
  71.                 return T_WORD;
  72.         }
  73. //匹配标识符
  74.         #.*     /* comment */
  75. //注释,忽略
  76.         \\\n    current_file->lineno++;
  77. //line continue,忽略
  78.         .
  79. //忽略其它字符
  80.         <<EOF>> {
  81.                 BEGIN(INITIAL);
  82.         }
  83. }

  84. <STRING>{
  85. //STRING状态下的pattern & action
  86.         [^'"\\\n]+/\n   {
  87.                 append_string(yytext, yyleng);
  88.                 zconflval.string = text;
  89.                 return T_WORD_QUOTE;
  90.         }
  91. //行末的串,不包括引号和转义
  92.         [^'"\\\n]+      {
  93.                 append_string(yytext, yyleng);
  94.         }
  95. //非行未的(部分)串,不包括引号和转义
  96.         \\.?/\n {
  97.                 append_string(yytext + 1, yyleng - 1);
  98.                 zconflval.string = text;
  99.                 return T_WORD_QUOTE;
  100.         }
  101. //行末的转义,串结束
  102.         \\.?    {
  103.                 append_string(yytext + 1, yyleng - 1);
  104.         }
  105. //非行末的转义,串未结束
  106.         \'|\"   {
  107.                 if (str == yytext[0]) {
  108.                         BEGIN(PARAM);
  109.                         zconflval.string = text;
  110.                         return T_WORD_QUOTE;
  111. //字符串结束
  112.                 } else
  113.                         append_string(yytext, 1);
  114. //引号本身作为字符串的一部分
  115.         }
  116.         \n      {
  117.                 printf("%s:%d:warning: multi-line strings not supported\n", zconf_curname(), zconf_lineno());
  118.                 current_file->lineno++;
  119.                 BEGIN(INITIAL);
  120.                 return T_EOL;
  121.         }
  122. //换行结束STRING状态
  123.         <<EOF>> {
  124.                 BEGIN(INITIAL);
  125.         }
  126. }

  127. <HELP>{
  128. //HELP状态下的pattern & acttion
  129.         [ \t]+  {
  130.                 ts = 0;
  131.                 for (i = 0; i < yyleng; i++) {
  132.                         if (yytext[i] == '\t')
  133.                                 ts = (ts & ~7) + 8;
  134.                         else
  135.                                 ts++;
  136.                 }
  137.                 last_ts = ts;
  138.                 if (first_ts) {
  139.                         if (ts < first_ts) {
  140.                                 zconf_endhelp();
  141.                                 return T_HELPTEXT;
  142.                         }
  143.                         ts -= first_ts;
  144.                         while (ts > 8) {
  145.                                 append_string("        ", 8);
  146.                                 ts -= 8;
  147.                         }
  148.                         append_string("        ", ts);
  149.                 }
  150.         }
  151. //看起来像是tab展开,基于缩进量判断help是否结束(python风格……)
  152.         [ \t]*\n/[^ \t\n] {
  153.                 current_file->lineno++;
  154.                 zconf_endhelp();
  155.                 return T_HELPTEXT;
  156.         }
  157. //下一行没有缩进,help结束
  158.         [ \t]*\n        {
  159.                 current_file->lineno++;
  160.                 append_string("\n", 1);
  161.         }
  162. //忽略行末空白,help可以包含换行
  163.         [^ \t\n].* {
  164.                 while (yyleng) {
  165.                         if ((yytext[yyleng-1] != ' ') && (yytext[yyleng-1] != '\t'))
  166.                                 break;
  167.                         yyleng--;
  168.                 }
  169.                 append_string(yytext, yyleng);
  170.                 if (!first_ts)
  171.                         first_ts = last_ts;
  172.         }
  173. //help正文本身(未结束),忽略末尾的空白,并计算第一行的缩进量
  174.         <<EOF>> {
  175.                 zconf_endhelp();
  176.                 return T_HELPTEXT;
  177.         }
  178. }
复制代码


第三部分是原封不动的代码,不解释。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
6 [报告]
发表于 2016-08-31 17:14 |只看该作者
回复 4# Buddy_Zhang1

看同目录下的makefile

conf-objs       := conf.o  zconf.tab.o

$(obj)/zconf.tab.o: $(obj)/lex.zconf.c $(obj)/zconf.hash.c

$(obj)/zconf.tab.c: $(src)/zconf.y
$(obj)/lex.zconf.c: $(src)/zconf.l


%.tab.c: %.y
        bison -l -b $* -p $(notdir $*) $<
        cp $@ $@_shipped

lex.%.c: %.l
        flex -L -P$(notdir $*) -o$@ $<
        cp $@ $@_shipped

不知道有没有理解错误楼主的问题。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
7 [报告]
发表于 2016-08-31 17:25 |只看该作者
flex:
  -P,  --prefix=STRING     use STRING as prefix instead of "yy"
  -L,  --noline            suppress #line directives in scanner

bison:
  -p, --name-prefix=PREFIX   prepend PREFIX to the external symbols
  -l, --no-lines             don't generate `#line' directives

$*代表%匹配的部分,所以,对于匹配lex.%.c的lex.zonf.c而言,%就是zconf
所以yylex就是zconflex

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
8 [报告]
发表于 2016-08-31 17:26 |只看该作者
不好意思审题不仔细

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
9 [报告]
发表于 2016-08-31 17:48 |只看该作者
回复 8# nswcfd


牛逼,我就是要这样的答案,通过你的答复,我已经找到满意回复了

牛逼

今天论坛回复给力,幸好今天没水逆。

你在微信群里叫什么名字,大神。

论坛徽章:
9
程序设计版块每日发帖之星
日期:2016-02-11 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:00程序设计版块每日发帖之星
日期:2016-02-14 06:20:0015-16赛季CBA联赛之吉林
日期:2016-03-23 17:25:0015-16赛季CBA联赛之浙江
日期:2016-04-01 08:25:0615-16赛季CBA联赛之山西
日期:2016-04-01 10:09:1915-16赛季CBA联赛之广夏
日期:2016-06-03 15:58:212016科比退役纪念章
日期:2016-07-28 17:42:5215-16赛季CBA联赛之广东
日期:2017-02-20 23:32:43
10 [报告]
发表于 2016-08-31 17:50 |只看该作者
回复 7# nswcfd


我就是想要这个东西

%.tab.c: %.y
        bison -l -b $* -p $(notdir $*) $<
        cp $@ $@_shipped

lex.%.c: %.l
        flex -L -P$(notdir $*) -o$@ $<
        cp $@ $@_shipped

今天本来这是碰碰运气看能否解决

大神果然牛逼!!!
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP