我正在使用Bison和flex来创建C编译器的语法。 运行Bison Flex和Gcc之后。 Everyting编译正常。 运行解析器时。输入的第一行工作正常;但是在输入的第二行中会引发以下野牛(yyerror)错误消息:
解析错误,预期为“ $”
我没有任何带有美元符号($)的代币。
为简单起见,我选择不显示y代码;但是如果您需要查看,我可以对其进行编辑。我只想知道此错误消息的原因。
编辑:添加了野牛密码
%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define YYERROR_VERBOSE
int yylex();
extern FILE *yyin;
int yyerror(char *s);
%}
%token T_abstract
%token T_alias
%token T_align
%token T_asm
%token T_assert
%token T_auto
%token T_body
%token T_bool
%token T_break
%token T_byte
%token T_case
%token T_cast
%token T_catch
%token T_cdouble
%token T_cent
%token T_cfloat
%token T_char
%token T_class
%token T_const
%token T_continue
%token T_creal
%token T_dchar
%token T_debug
%token T_default
%token T_delegate
%token T_deprecated
%token T_do
%token T_double
%token T_eles
%token T_enum
%token T_export
%token T_extern
%token T_false
%token T_final
%token T_finally
%token T_float
%token T_for
%token T_foreach
%token T_foreach_reverse
%token T_function
%token T_goto
%token T_idouble
%token T_if
%token T_ifloat
%token T_immutable
%token T_import
%token T_in
%token T_inout
%token T_int
%token T_interface
%token T_invariant
%token T_ireal
%token T_is
%token T_lazy
%token T_long
%token T_mixin
%token T_module
%token T_new
%token T_nothrow
%token T_null
%token T_out
%token T_override
%token T_package
%token T_pragma
%token T_private
%token T_protected
%token T_public
%token T_pure
%token T_real
%token T_ref
%token T_return
%token T_scope
%token T_shared
%token T_short
%token T_static
%token T_struc
%token T_super
%token T_switch
%token T_synchronized
%token T_template
%token T_this
%token T_throw
%token T_true
%token T_try
%token T_typeid
%token T_typeof
%token T_ubyte
%token T_ucent
%token T_uint
%token T_ulong
%token T_union
%token T_unittest
%token T_ushort
%token T_version
%token T_void
%token T_wchar
%token T_while
%token T_with
%token NUM
%token T_neq
%token T_bslash
%token T_land
%token T_andeq
%token T_and
%token T_lor
%token T_oreq
%token T_or
%token T_dec
%token T_deceq
%token T_minus
%token T_inc
%token T_inceq
%token T_plus
%token T_GEQ
%token T_GR
%token T_NOTEQ
%token T_OPAREN
%token T_CPAREN
%token T_OCOR
%token T_CCOR
%token T_SEMICOLON
%token T_EQUAL
%token T_multiply
%token T_COMA
%token T_LE
%token T_isEqual
%token DEC
%token ID
%token T_LT
%right T_EQUAL
%left T_and T_or
%left T_LE T_GEQ T_NOTEQ T_isEqual T_GR T_LT
%start prog
%%
prog: Function
|Declaration
;
Declaration: Type Assignment T_SEMICOLON
| Assignment T_SEMICOLON
| FunctionCall T_SEMICOLON
;
Assignment: ID T_EQUAL Assignment
| ID T_EQUAL FunctionCall
| ID T_plus Assignment
| ID T_minus Assignment
| ID T_multiply Assignment
| ID T_bslash Assignment
| NUM T_plus Assignment
| NUM T_minus Assignment
| NUM T_multiply Assignment
| NUM T_bslash Assignment
| T_OPAREN Assignment T_CPAREN
| T_minus T_OPAREN Assignment T_CPAREN
| T_minus NUM
| T_minus ID
| NUM
| DEC
| ID
;
FunctionCall : ID T_OPAREN T_CPAREN
| ID T_OPAREN Assignment T_CPAREN
;
Type: T_int
| T_float
| T_char
| T_double
;
Function: Type ID T_OPAREN ArgListOpt T_CPAREN CompoundStmt
;
ArgListOpt: ArgList
|
;
ArgList: ArgList T_COMA Arg
| Arg
;
Arg: Type ID
;
CompoundStmt: T_OCOR StmtList T_CCOR
;
StmtList: StmtList Stmt
|
;
Stmt: WhileStmt
| Declaration
| ForStmt
| IfStmt
| T_SEMICOLON
;
WhileStmt: T_while T_OPAREN Expr T_CPAREN Stmt
| T_while T_OPAREN Expr T_CPAREN CompoundStmt
;
ForStmt:T_for T_OPAREN Expr T_SEMICOLON Expr T_SEMICOLON Expr T_CPAREN Stmt
| T_for T_OPAREN Expr T_SEMICOLON Expr T_SEMICOLON Expr T_CPAREN CompoundStmt
| T_for T_OPAREN Expr T_CPAREN Stmt
| T_for T_OPAREN Expr T_CPAREN CompoundStmt
;
IfStmt : T_if T_OPAREN Expr T_CPAREN Stmt ;
Expr:
| ID T_LE ID
| ID T_GEQ ID
| ID T_NOTEQ ID
| ID T_isEqual ID
| ID T_GR ID
| ID T_LT ID
;
%%
#include<ctype.h>
int count=0;
int main(int argc, char *argv[])
{
yyin = fopen(argv[1], "r");
if(!yyparse())
printf("\nParsing complete\n");
else
printf("\nParsing failed\n");
fclose(yyin);
fclose(yyin);
return 0;
}
int yyerror(char *s) {
printf("%s\n",s);
}
答案 0 :(得分:1)
触发该错误是因为您的语法坚持一个程序必须是一个函数或声明。如果输入包含两件事,那么解析器将解析第一个,然后抱怨它期望输入结束。
我猜您的野牛版本代表EOF标记为$
。 (或者您没有准确地引用错误消息。)