c/c++语言开发共享为什么flex / bison中的多行注释如此回避?

我正在尝试在我的flex(.l)文件中解析C风格的多行注释:

%s ML_COMMENT %% ... "/*" BEGIN(ML_COMMENT); "*/" BEGIN(INITIAL); [.n]+ { } 

我没有返回任何令牌,我的语法(.y)不以任何方式处理评论。

当我运行我的可执行文件时,我得到一个解析错误:

 $ ./a.out /* abc def Parse error: parse error $ echo "/* foo */" | ./a.out Parse error: parse error 

(我的yyerror函数执行printf(“解析错误:%s n”),这是冗余错误消息的前半部分来自)。

我可以看到为什么第二个示例失败,因为整个输入是注释,并且由于语法忽略了注释,因此没有语句。 因此输入不是有效的程序。 但是在我完成评论之前,第一部分抛出了一个解析错误。

同样令人困惑:

 $ ./a.out /* foo */ a = b; Parse error: parse error 

在这种情况下,注释在实际有效输入之前关闭(没有注释,解析就好了)。 在解析“a”之后实际发生失败,而不是在尝试解析赋值“a = b;”之后。 如果我在自己的行上输入“a”,它仍会抛出错误。

鉴于错误消息是解析器错误而不是扫描程序错误,我的.y文件中是否存在一些重要的内容? 或者我在扫描器规则中做错了什么传播到解析器端?

编辑: Per @ Rudi的建议,我打开调试,发现:

 $ ./a.out Starting parse Entering state 0 Reading a token: /* foo Next token is 44 (IDENTIFER) Shifting token 44 (IDENTIFER), Entering state 4 Reducing via rule 5 (line 130), IDENTIFER -> identifier state stack now 0 Entering state 5 

我关掉了调试,发现/* foo */ = bar; 确实解析foo = bar; 。 我正在使用flex 2.5.4; 它没有给我任何关于我试图使用的有状态规则的警告。

    我认为您需要将ML_COMMENT启动条件声明为独占启动条件,因此只有ML_COMMENT规则处于活动状态。 %x ML_COMMENT而不是%s ML_COMMENT

    否则,没有开始条件的规则也是活动的。

    以这种方式解析注释可能会导致错误,因为:

    在我的解析器中,我处理这样的评论。 首先为注释的开头定义lex规则,如下所示:

     /* { if (!SkipComment()) return(-1); } // { if (!SkipLine()) return(-1); } 

    然后编写SkipComment和SkipLine函数。 他们需要消耗所有的输入,直到找到注释的结尾(这是相当古老的代码,所以请原谅我有些过时的结构):

     bool SkipComment (void) { int Key; Key=!EOF; while (true) { if (Key==EOF) { /* yyerror("Unexpected EOF within comment."); */ break; } switch ((char)Key) { case '*' : Key=input(); if (char)Key=='/') return true; else continue; break; case 'n' : ++LineNr; break; } Key=input(); } return false; } bool SkipLine (void) { int Key; Key=!EOF; while (true) { if (Key==EOF) return true; switch ((char)Key) { case 'n' : unput('n'); return true; break; } Key=input(); } return false; } 

    除了%x vs %s的问题,你也有问题了.[.n]匹配(仅)一个文字. 而不是’除了换行之外的任何角色’就像裸露一样. 确实。 你想要一个像这样的规则

     .|"n" { /* do nothing */ } 

    代替

    我发现这种C语言语法的描述(实际上只是词法分析器)非常有用。 我认为它与帕特里克的答案大致相同,但略有不同。

      以上就是c/c++开发分享为什么flex / bison中的多行注释如此回避?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/560800.html

      (0)
      上一篇 2021年1月28日
      下一篇 2021年1月28日

      精彩推荐