野牛语法错误

时间:2016-03-08 22:09:09

标签: parsing bison

我最近开始学习野牛,我已经撞墙了。手动部分有点含糊不清,所以我猜错了。下面的代码是官方手册中的第一个教程 - 反向波兰表示法计算器,保存在一个文件中 - rpcalc.y。

/* Reverse polish notation calculator */

%{
    #include <stdio.h>
    #include <math.h>
    #include <ctype.h>
    int yylex (void);
    void yyerror (char const *);
%}

%define api.value.type {double}
%token NUM

%% /* Grammar rules and actions follow. */

input:
    %empty
|   input line
;

line:
    '\n'
|   exp '\n'    {printf ("%.10g\n", $1);}
;

exp:
    NUM         {$$ = $1;          }
|   exp exp '+' {$$ = $1 + $2;      }
|   exp exp '-' {$$ = $1 - $2;      }
|   exp exp '*' {$$ = $1 * $2;      }
|   exp exp '/' {$$ = $1 / $2;      }
|   exp exp '^' {$$ = pow ($1, $2); }
|   exp 'n'     {$$ = -$1;         }
;
%%

/* The lexical analyzer */

int yylex (void)
{
    int c;

    /* Skip white space */
    while((c = getchar()) == ' ' || c == '\t')
        continue;
    /* Process numbers */
    if(c == '.' || isdigit (c))
    {
        ungetc (c, stdin);
        scanf ("%lf", $yylval);
        return NUM;
    }
    /* Return end-of-imput */
    if (c == EOF)
        return 0;
    /* Return a single char */
    return c;
}

int main (void)
{
    return yyparse ();
}

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

在cmd中执行bison rpcalc.y会返回以下错误:

rpcalc.y:11.24-31: syntax error, unexpected {...}

什么似乎是问题?

1 个答案:

答案 0 :(得分:1)

该错误是由您使用3.0版本的野牛新功能引起的,而您安装的是较旧版本的bison。如果您无法升级到3.0版,则可以轻松地将语法转换为使用早期版本的bison的功能。

可以将%define api.value.type {double}更改为%type命令,并删除%empty命令。由此产生的野牛计划将是:

/* Reverse polish notation calculator */

%{
    #include <stdio.h>
    #include <math.h>
    #include <ctype.h>
    int yylex (void);
    void yyerror (char const *);
%}

%type <double> exp
%token <double> NUM

%% /* Grammar rules and actions follow. */

input:
|   input line
;

line:
    '\n'
|   exp '\n'    {printf ("%.10g\n", $1);}
;

exp:
    NUM         {$$ = $1;          }
|   exp exp '+' {$$ = $1 + $2;      }
|   exp exp '-' {$$ = $1 - $2;      }
|   exp exp '*' {$$ = $1 * $2;      }
|   exp exp '/' {$$ = $1 / $2;      }
|   exp exp '^' {$$ = pow ($1, $2); }
|   exp 'n'     {$$ = -$1;         }
;
%%

/* The lexical analyzer */

int yylex (void)
{
    int c;

    /* Skip white space */
    while((c = getchar()) == ' ' || c == '\t')
        continue;
    /* Process numbers */
    if(c == '.' || isdigit (c))
    {
        ungetc (c, stdin);
        scanf ("%lf", $yylval);
        return NUM;
    }
    /* Return end-of-imput */
    if (c == EOF)
        return 0;
    /* Return a single char */
    return c;
}

int main (void)
{
    return yyparse ();
}

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

这适用于更广泛的野牛版本。