kallytin 发表于 2010-09-20 11:59

yacc的问题

//语法定义
struct_or_union_spec        :        struct_or_union ID LBRACE struct_declaration_list RBRACE pos
                                        {printf("1) id = %s \n", yylval_sval}

direct_dec                        :        ID pos
                                        {printf("2) id = %s \n", yylval_sval}

//语法关联过程
struct_or_union_spec -> struct_declaration -> dec ->direct_dec


例子:

struct xyz
{
        int a;
        double b;
}g;


当执行后的结果如下:

struct xyz
{
        int a;2) id = a
        double b;2) id = b
}1) id = b(正确的应该是 1) id = xyz)
g;


发现,对于 direct_dec的2个变量(结构体里的a和b)是对的,但对于 strcut_or_union_spec 里的ID(结构体里的xyz)是错的,正确的应该是: 1) id = xyz

我感觉是yacc在展开公式(语法定义)时,在最开始时 yylval_sval 的值是 xyz 的。但 yacc 先展开 struct_declaration_list 并将里面的变量 a 和 b 打印出来(先执行 printf("2) id = %s \n", yylval_sval)。在打印完 struct_declaration_list 里面的变量后,yylval_sval 的值为 b(原来的xyz早就被覆盖了),因此再打印 xyz 时就变为 b(最后才执行 printf("1) id = %s \n", yylval_sval)。

现在的问题是,怎样才可以提取出结构体的ID(即 xyz)?

kallytin 发表于 2010-09-20 12:00

回复 1# kallytin


顶一下

EricFisher 发表于 2010-09-20 12:35

你需要定义一个union,来保存yylval_sval中的值,这样就不会被覆盖了。

EricFisher 发表于 2010-09-20 12:38

比如binson中,http://www.gnu.org/software/bison/manual/html_mono/bison.html#Multiple-Types

For example:

   %union {            /* define stack type */
       double val;
       symrec *tptr;
   }
   %token <val> NUM      /* define token NUM and its type */

kallytin 发表于 2010-09-20 13:26

比如binson中,

For example:

   %union {            /* define stack type */
       double...
EricFisher 发表于 2010-09-20 12:38 http://linux.chinaunix.net/bbs/images/common/back.gif

改动如下(在语法分析文件(yacc的文件中)):

%token STRUCT_UNION_ID
(注:增加 STRUCT_UNION_ID)

%type <string>        STRUCT_UNION_ID
(注:之前对ID的定义为:%type <string>        ID。 这里增加 STRUCT_UNION_ID)

struct_or_union STRUCT_UNION_ID LBRACE struct_declaration_list RBRACE pos
(注:将ID改为 STRUCT_UNION_ID)

struct_or_union STRUCT_UNION_ID pos
(注:将ID改为 STRUCT_UNION_ID)

执行后发现:

int hello(int i, int j)
{
.....
        struct xyz
                  ^
      syntax error

.......
}

这回是连扫描都过不了了。是我改错了吗?

kallytin 发表于 2010-09-20 14:22

比如binson中,

For example:

   %union {            /* define stack type */
       double...
EricFisher 发表于 2010-09-20 12:38 http://linux.chinaunix.net/bbs/images/common/back.gif


EricFisher,

这样似乎是不行的......因为在lex里面已经规定了标识符的返回值为 ID。如果在这里另外定义一个(如:STRUCT_UNION_ID),系统会不认的.....

kallytin 发表于 2010-09-20 14:47

回复 6# kallytin


各位有什么好的点子阿........

EricFisher 发表于 2010-09-20 16:22

lex确实标识符的返回值为 ID,但是,同时它应该有一个变量来保存额外的数据,比如flex中,如下代码,

<fn>{identifier} {
    yylval.str = xstrdup (yytext);
    BEGIN (INITIAL);
    return FN_NAME;
}

返回的是一个FN_NAME,但我同时将yytext复制到了yylval中。

kallytin 发表于 2010-09-20 17:25

lex确实标识符的返回值为 ID,但是,同时它应该有一个变量来保存额外的数据,比如flex中,如下代码,

{i ...
EricFisher 发表于 2010-09-20 16:22 http://linux.chinaunix.net/bbs/images/common/back.gif

不太明白你里面的 BEGIN(INITIAL) 和 FN_NAME.......

另,我的如下:

// lex文件
{L}({L}|{D})*        {count(); yylval_p.sval=String((char *)yytext);return check_type();}

int check_type()
{
        return(ID);
}

//String包含在另一个文件里,如下:
char* String(char *s)
{string p = checked_malloc(strlen(s)+1);
strcpy(p,s);
return p;
}

// yylval的结构如下:
typedef union
{
        int pos;
        int ival;
        char * sval;
        double fval;
} YYSTYPE_P;
YYSTYPE_P yylval_p;

EricFisher 发表于 2010-09-20 17:45

我是用的flex, bison,可能不同的工具不一样,呵呵。
页: [1] 2
查看完整版本: yacc的问题