Bison I';我不知道如何输出(复杂)有用的信息时,在我的野牛解析器

Bison I';我不知道如何输出(复杂)有用的信息时,在我的野牛解析器,bison,yacc,lex,flex-lexer,Bison,Yacc,Lex,Flex Lexer,我正在写一个Flex/Bison Lexer/Parser来解析我自己设计的脚本,作为大学的一项作业。它运行得很好,我的脚本解析正确,检测到任何错误等,都能识别标记并传递语义 然而,我有点不确定如何将其转化为有用的信息。。。我只需要输出简单的文本,这本身就足够简单,但是我正在努力解决在yacc中在何处这样做的逻辑问题 例如,假设我的yacc是这样的- statement : DRAW shape AT location { printf("Draw shape at location"

我正在写一个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(形状,x,y,z);-但我不确定如何将位置的语义值反馈到语句中,或者如何获取找到的形状标记是立方体、金字塔还是球体

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

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


是否最好只创建一些变量来存储位置的语义值,并对每个语句使用它们?(这似乎有点草率,但我不知道如何做得更好。)

我已经把它改成了-

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); 
; 

这是正确的,但我会感兴趣,如果有一个更优雅的解决方案

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

%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; }
;
%union{
国际竞争力;
结构{
int x,y,z;
}协调;
}
%令牌号
%类型位置
%%
声明:
在位置{printf(“在(%d,%d,%d)\n“,$4.x,$4.y,$4.z处绘制形状);}
;
地点:
“(‘NUMBER’、‘NUMBER’、‘NUMBER’)”{$$.x=$2;$$.y=$4;$$.z=$6;}
;

我已经开始使用变量来保存我希望在输出语句中使用的任何值,这很好,但是如果有一个更优雅的解决方案,我会感兴趣:)(或者知道我是否天真,这已经是最好的解决方案!)问题是它不可伸缩——例如,如果你想添加一条语句从一个位置到另一个位置绘制一条线,这两个位置将在全局变量上发生冲突,因为我的语言很简单;但我认为它太乱了。很高兴有其他选择-谢谢!谢谢很高兴了解未来!:)