免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4602 | 回复: 15
打印 上一主题 下一主题

yacc的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-09-20 11:59 |只看该作者 |倒序浏览
//语法定义
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)?

论坛徽章:
0
2 [报告]
发表于 2010-09-20 12:00 |只看该作者
回复 1# kallytin


顶一下

论坛徽章:
2
摩羯座
日期:2013-10-10 14:29:04天蝎座
日期:2014-01-03 09:14:49
3 [报告]
发表于 2010-09-20 12:35 |只看该作者
你需要定义一个union,来保存yylval_sval中的值,这样就不会被覆盖了。

论坛徽章:
2
摩羯座
日期:2013-10-10 14:29:04天蝎座
日期:2014-01-03 09:14:49
4 [报告]
发表于 2010-09-20 12:38 |只看该作者
比如binson中,http://www.gnu.org/software/biso ... html#Multiple-Types

For example:

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

论坛徽章:
0
5 [报告]
发表于 2010-09-20 13:26 |只看该作者
比如binson中,

For example:

     %union {              /* define stack type */
       double  ...
EricFisher 发表于 2010-09-20 12:38


改动如下(在语法分析文件(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

.......
}

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

论坛徽章:
0
6 [报告]
发表于 2010-09-20 14:22 |只看该作者
比如binson中,

For example:

     %union {              /* define stack type */
       double  ...
EricFisher 发表于 2010-09-20 12:38



EricFisher,

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

论坛徽章:
0
7 [报告]
发表于 2010-09-20 14:47 |只看该作者
回复 6# kallytin


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

论坛徽章:
2
摩羯座
日期:2013-10-10 14:29:04天蝎座
日期:2014-01-03 09:14:49
8 [报告]
发表于 2010-09-20 16:22 |只看该作者
lex确实标识符的返回值为 ID,但是,同时它应该有一个变量来保存额外的数据,比如flex中,如下代码,

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

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

论坛徽章:
0
9 [报告]
发表于 2010-09-20 17:25 |只看该作者
lex确实标识符的返回值为 ID,但是,同时它应该有一个变量来保存额外的数据,比如flex中,如下代码,

{i ...
EricFisher 发表于 2010-09-20 16:22


不太明白你里面的 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;

论坛徽章:
2
摩羯座
日期:2013-10-10 14:29:04天蝎座
日期:2014-01-03 09:14:49
10 [报告]
发表于 2010-09-20 17:45 |只看该作者
我是用的flex, bison,可能不同的工具不一样,呵呵。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP