【问题标题】:Parsing Bison/YACC .y files without parsing all of the C language解析 Bison/YACC .y 文件而不解析所有 C 语言
【发布时间】:2015-01-17 04:09:48
【问题描述】:

我想从 Bison/YACC .y 文件中解析语法定义。规则的语法非常简单(我可以忽略语法规则部分之外的所有内容),并且我不需要有关语义操作的信息。但是,即使跳过这些操作似乎也需要解析任意 C 代码片段以确定 {...} 块的结束位置(因为您可以有嵌套块等)。

是否有不需要解析 C 的快捷方式?

我想一种解决方法是让 Bison 自己删除所有回调,并将语法规则留在文件中,这样解析起来就很简单了。

【问题讨论】:

    标签: parsing bison yacc


    【解决方案1】:

    如果您使用-v 标志运行bison,它将生成一个名为basename.output 的文件,该文件以语法开头(没有操作)。解析该报告非常容易。 (basename 是输入文件的名称,如果您指定了 --output 选项,则为输出文件的名称,去掉扩展名。)

    唯一的另一种方法是准备复制bison的大部分解析,如果没有完全解析,至少涉及lexing C,以及了解如何解析所有bison 的% 命令。

    注意-v 选项生成的语法将中间规则操作转换为右侧为空的非终结符。生成的非终结符具有$@<number>@<number> 形式的名称,因此很容易识别。

    【讨论】:

    • 同意,可能必须解析基本的野牛语法。但是要跳过嵌入式 C 的内容,您实际上不需要对所有 C C 进行 lex ;它只需要对 C 文本进行词法分析以可靠地计数/匹配嵌套的 {...},这意味着几乎可以忽略文字字符串中的大括号,并且可能在野牛允许的范围内忽略 #define 宏体中的括号。
    【解决方案2】:

    在 flex 中识别和跳过带大括号的 C 代码非常简单:

    %x cblk cstr cchr ccom cppcom
    %%
                           int brace_depth;
    {                      brace_depth=0; BEGIN(cblk);
    <cblk>{                brace_depth++;
    <cblk>}                if (!brace_depth--) BEGIN(INITIAL);
    <cblk>\"               BEGIN(cstr);
    <cblk>\'               BEGIN(cchr);
    <cblk>\/\*             BEGIN(ccom);
    <cblk>\/\/             BEGIN(ccpcom);
    <cstr,cchr>\\.         ;
    <cstr>\"               BEGIN(cblk);
    <cchr>\'               BEGIN(cblk);
    <ccom>\*\/             BEGIN(cblk);
    <cppcom>\n             BEGIN(cblk);
    <cblk,cchr,cstr,ccom,cppcom>.|\n   ;
    

    【讨论】:

    • 这是否解释了引号字符串中转义的 "?其他关键转义?如果不是,应该很容易修复。
    • @IraBaxter 它处理转义 (\\.) 但不处理 cmets。不过,解决这个问题也很容易。
    • @rici:是的,添加 cmets 很简单。 IraBaxter:还有哪些重要的逃生途径?正如所写,这允许字符串中的换行符(C 规范不允许并导致未定义的行为),但任何有效的 C/C++ 都应该没问题。
    • @ChrisDodd:在 flex 正则表达式中,/ 是一个运算符
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多