在我的野牛解析器中,我不确定如何输出(复杂的)有用信息

时间:2012-01-08 21:44:01

标签: bison yacc lex flex-lexer

我正在编写一个Flex / Bison Lexer / Parser来解析我自己设计的脚本,作为大学的一项任务。它进展顺利,我的脚本正确解析,检测到任何错误等,并且都识别令牌并传递语义含义。

但是,我有点不确定如何将其转换为有用的信息......我只需要输出简单的文本,这本身就很容易,但是我在yacc中做到这一点的逻辑挣扎。

例如,说我的yacc是这样的 -

statement : 
   DRAW shape AT location  { printf("Draw shape at location"); } 
;

shape : 
   CUBE 
  | PYRAMID
  | SPHERE 
; 

location : 
   '(' NUMBER ',' 'NUMBER' ',' 'NUMBER' ')' { int x = $2; int y = $4; int z = $6;
                                              printf("%d,%d,%d",x,y,z); 
; 

我想要的是打印出类似drawShape(shape,x,y,z)的东西; - 但我不确定如何将语义值从位置反馈到语句中,或者如何确定找到的形状标记是立方体,金字塔还是球体。

此时位置的print语句首先触发,所以我的输出类似于

  

1,2,3在位置绘制形状

最好只创建一些变量来存储来自该位置的语义值并将它们用于每个语句吗? (这看起来有点草率,但我不确定如何更好地做到这一点。)

2 个答案:

答案 0 :(得分:2)

通常的方法是让每个操作创建一个通过$$返回并由以后的操作使用的数据结构。例如,你可能有

%union {
    int      ival;
    struct {
        int  x,y,z;
    }        coord;
}

%token<ival>  NUMBER
%type<coord>  location

%%

statement:
    DRAW shape AT location { printf("Draw shape at (%d,%d,%d)\n", $4.x, $4.y, $4.z); }
;

location:
    '(' NUMBER ',' NUMBER ',' NUMBER ')'  { $$.x = $2; $$.y = $4; $$.z = $6; }
;

答案 1 :(得分:0)

我已经将其改为 -

statement:
    DRAW shape AT location {printf("Draw shape at (%d, %d, %d)",x,y,z); }
;

location :
    '(' NUMBER ',' NUMBER ',' NUMBER ')' {x=$2; y=$4; z=$6); 
; 

这是正常的,但是如果有更优雅的解决方案我会感兴趣吗?