Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
处理yacc中的块_C_Yacc - Fatal编程技术网

处理yacc中的块

处理yacc中的块,c,yacc,C,Yacc,我正在使用lex+yacc为以下简单语言构建解析器: lines are parsed ok foo { lines of the "foo" category come here } # closing this block 在我的语法中,块的以下定义有效: item : block | lines; /* lines without a block */ block: WORD BRACE_OPEN NL lines BRACE_CLOSE { printf(

我正在使用lex+yacc为以下简单语言构建解析器:

lines are parsed ok

foo {
   lines of the "foo" category come here
} # closing this block
在我的语法中,块的以下定义有效:

item : block
     | lines; /* lines without a block */

block: WORD BRACE_OPEN NL lines BRACE_CLOSE
     { printf("category: %s\n", $1 );}
问题是
printf
发生在解析块之后,但我需要获取类别名称(“示例中的foo”)作为解析块内行的信息

我想出了一个解决方案,但它似乎不太优雅:

item : line
     | block_open
     | block_close;

block_open : WORD BRACE_OPEN { printf("%s {\n", $1); };

block_close : BRACE_CLOSE { printf("}\n"); };
我现在可以在打开块时获取“类别”名称。但这是正确的还是最好的方法

谢谢

问题是printf发生在解析块之后

这是因为yacc是一个自底向上的解析器。AST的叶在中间节点之前构建

如果希望块的类型影响其内部的解析,则自顶向下的方法(如递归下降解析器)可能更自然

但我需要获取类别名称(示例中的“foo”)作为解析块中的行的信息

我认为最简单的方法是为每种类型的块使用不同的语法规则,而不是通用的“块”规则。例如:

foo_block: FOO BRACE_OPEN foo_lines BRACE_CLOSE;

bar_block: BAR BRACE_OPEN bar_lines BRACE_CLOSE;

baz_block: BAZ BRACE_OPEN baz_lines BRACE_CLOSE;
这假设“foo”和“bar”以及“baz”是词法分析人员知道的关键字,而不仅仅是一般性的单词

block: WORD BRACE_OPEN NL lines BRACE_CLOSE
    { printf("category: %s\n", $1 );}
您可以将操作放在任何位置(尽管它可能会导致s/r冲突):

这相当于

block
    : category BRACE_OPEN NL lines BRACE_CLOSE
    ;
category
    : WORD
        { printf("category: %s\n", $1 );}
    ;

您可能更喜欢后者。

块内的行的语法是否因类别而异?不,与“类别”块外的行的语法相同。
block
    : category BRACE_OPEN NL lines BRACE_CLOSE
    ;
category
    : WORD
        { printf("category: %s\n", $1 );}
    ;