第一次输入后期待$ end

时间:2014-12-21 06:28:15

标签: parsing bison flex-lexer

我尝试使用flex和bison为编程语言构建一个简单的解析器。

当我从终端(stdin)测试时,它总是说(yyerror()是自定义的):

Error: syntax error, unexpected SOME_TOKEN, expecting $end, on line: 2

在第二个输入上。换句话说,它只适用于第一个输入。

我只能猜测,在第一个声明之后,野牛的内部解析堆栈没有冲洗。

这是我的野牛代码:

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

#define YYDEBUG 1
%}

%token TOKEN_DECLARE TOKEN_SET TOKEN_STR TOKEN_SYMBOL EOL
%error-verbose

%%

statement: statement
    | declare_var EOL { puts("Reach declare EOL branch"); }
    | set_value EOL { puts("Reach set_value EOL branch"); }

;

declare_var: TOKEN_DECLARE TOKEN_SYMBOL { printf("Declare var\n"); }
        | TOKEN_DECLARE set_value
;

set_value : TOKEN_SYMBOL TOKEN_SET { printf("Set var"); }
        | set_value TOKEN_STR { printf(" to string\n"); }
        | set_value TOKEN_SYMBOL { printf(" to symbol\n"); }
;

%%

这是我的弹性代码

%%
[\t\n ] {/*Ignore*/}

var {
    return (TOKEN_DECLARE);
}

";" {
    //puts("Got EOL");
    return (EOL);
}

\"[a-zA-Z]+\" {
    return (TOKEN_STR);
} 
\'[a-zA-Z]+\' {
    return (TOKEN_STR);
}

[a-zA-Z]+ {
    return (TOKEN_SYMBOL);
}

"=" {
    return (TOKEN_SET);
}
%%

由于

1 个答案:

答案 0 :(得分:1)

您的yacc代码只接受单个语句 - EOL唯一有效的标记为$end(文件/输入结束)之后,因此您在第二行收到语法错误。此外,规则statement: statement是无用的,永远无法减少(您应该从yacc收到有关它的错误消息)。

您想要的是匹配多个语句的明确规则:

statements: statements statement
          | statement
;

这是第一个(开始)规则。那么你的陈述规则就是:

statement: declare_var EOL { puts("Reach declare EOL branch"); }
         | set_value EOL { puts("Reach set_value EOL branch"); }
;