DIYBYPERL 发表于 2013-10-11 22:20

yacc与lex问题

本帖最后由 DIYBYPERL 于 2013-10-11 22:24 编辑

YACC对应的文件:%{
/* 计算器 */
%}

%{
#include <stdio.h>
#include <stdlib.h>

#define PRT(n, s, r) {printf("---------[%d:%s][$=%d]\n", n , s, r);}

extern FILE *yyin;
void yyerror(const char* s);

double vbltable;
%}

%union{
        double dval;
        int vblno;
}

%token <vblno> NAME
%token <dval> NUMBER
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS

%type <dval> expression
%%
statement_list: statement '\n'
        | statement_list statement '\n'
        ;
statement:
        NAME '=' expression
                { vbltable[$1] = $3; PRT(7, "=", 0);}
        | expression
                { printf("= %d\n", $1);}
        ;

expression:
        expression '+' expression
                { $ = $1 + $3; PRT(1, "+", $);}
        | expression '-' expression
                { $ = $1 - $3; PRT(2, "-", $);}
        | expression '*' expression
                { $ = $1 * $3; PRT(3, "*", $);}
        | expression '/' expression
                {
                        if($3) $ = $1 / $3;
                        else yyerror("divided by zero!");
                        PRT(4, "/", $);
                }
        | '-' expression %prec UMINUS
                { $ = -$2; PRT(5, "-", $); }
        | '(' expression ')'
                { $ = $2; PRT(6, "()", $); }
        | NUMBER
                { $ = $1; PRT(7, "N", $1);}
        | NAME
                { $ = vbltable[$1]; PRT(8, "NAME", $);}
        ;

%%
int main(void)
{

                yyparse();

}


void yyerror(const char* s)
{
        printf("\n%s\n", s);
}


LEX对应的文件:%{
/* 计算器 */
%}

%{
#include "y.tab.h"
#include <math.h>

%}

%%

(+|(*\.+)([-+]?+)?)        {
                yylval.dval = atof(yytext);
                return NUMBER;
        }
[ \t]        ;
        {
                yylval.vblno = yytext - 'a'; return NAME;
        }
"$"        {
                return 0;
        }
\n        |       
.        return yytext;

%%

int yywrap(void)
{
        return 1;
}
这两个文件编译后的程序为“ly”,运行结果如下,为什么结果都是0??? 高手指导下!!!是在CENT-OS 6.3上测试的root:/root/桌面/test/tflex>ly
2
---------[$=0]
= 0
2+3
---------[$=0]
---------[$=0]
---------[$=0]
= 0

EricFisher 发表于 2013-10-12 09:26

问题可能出在这里:

你应该使用{ $$ = $1 + $3; PRT(1, "+", $$);},而不是{ $ = $1 + $3; PRT(1, "+", $);}。

DIYBYPERL 发表于 2013-10-12 13:56

回复 2# EricFisher


    源代码里都是两个$,这是网页显示的问题。
要是代码是一个$能编译通过?
再帮我看看?

fly3ds 发表于 2013-10-12 14:04

我认为,能搞懂lex与yacc都是非人类    :D)

DIYBYPERL 发表于 2013-10-12 14:40

回复 4# fly3ds
哈哈
高手指教!!!

   

EricFisher 发表于 2013-10-12 14:47

哦,那可能是因为,你$$中缺省使用的union类型为double,但是却在printf使用的%d。改成%f试试。

DIYBYPERL 发表于 2013-10-12 15:10

果然是。代码改动太多,看了好多遍也没发现。谢谢版主

cjaizss 发表于 2013-10-17 19:03

fly3ds 发表于 2013-10-12 14:04 static/image/common/back.gif
我认为,能搞懂lex与yacc都是非人类
有这么夸张?:mrgreen:
编译原理看一遍之后,再来用lex/yacc,我想你会理解的快一些。
页: [1]
查看完整版本: yacc与lex问题