语法错误,意外为TRUE,期待'{'

时间:2010-08-05 17:27:56

标签: c bison flex-lexer

我正在Bison中编写一个基本编译器的解析器(然后将其扩展为包含子例程和动态内存分配)。语法在龙书的附录A中定义。我的Flex扫描仪工作 - 我通过它运行我的测试文件,它打印出它找到的所有正确的标记。对于下面的奇怪格式抱歉。我在emacs中的野牛和弹性模式有点乱,所以我只是使用C模式,直到我修复。

%{
#include <stdio.h>

#define YYERROR_VERBOSE 1066

  extern FILE* yyin ;
  extern int yylineno ;
  extern char* yytext ;
  extern int yylex() ;
  extern void yyerror() ;
  int YYDEBUG = 1 ;

%}

/* Tokens */
%token AND BASIC BREAK DO ELSE EQ FALSE
%token GREQ ID IF INDEX LEEQ MINUS NOEQ NUM OR REAL TEMP TRUE WHILE

/* Grammar rules from Appendix A */
%%
program: block { printf( "Matched program\n" ) ; }
;

block: '{' decls stmts '}' { printf( " Matched block\n" ) ; }
;

decls: decls decl |
;

decl: type ID ';'
;

type: type '[' NUM ']' | BASIC
;

stmts: stmts stmt |
;

stmt: loc '=' bool ';'
| IF '(' bool ')' stmt
| IF '(' bool ')' stmt ELSE stmt
| WHILE '(' bool ')' stmt
| DO stmt WHILE '(' bool ')' ';'
| BREAK ';'
| block
;

loc: loc '[' bool ']' | ID
;

bool: bool OR join | join
;

join: join AND equality | equality
;

equality: equality EQ rel | equality NOEQ rel | rel
;

rel: expr '<' expr | expr LEEQ expr | expr GREQ expr | expr '>' expr | expr
;

expr: expr '+' term | expr '-' term | term
;

term: term '*' unary | term '/' unary | unary
;

unary: '!' unary | '-' unary | factor
;

factor: '(' bool ')' | loc | NUM | REAL | TRUE | FALSE
;

%%

/*
 * Additional C Code
 * Main Routine
 * yyerror()
 */
int main( int argc, char *argv[] ) {

  int i ;

  if ( argc < 2 ) {
    fprintf( stderr, "No input files.\n\n" ) ;
    return 1 ;
  }

  for ( i = 0 ; i < argc ; i++ ) {

    yyin = fopen( argv[i], "r" ) ;

    if ( !yyin ) {
      fprintf( stderr, "Error opening file: %s.\n\n", argv[i] ) ;
      return 1 ;
    }

    yyparse() ;
  }
  return 0 ; 
}

void yyerror( char *s ) {

  /* fprintf( stderr, "Error parsing - %d: %s at %s\n", yylineno, s, yytext ) ; */
  fprintf( stderr, "Error parsing - %d: %s at %s\n", yylineno, s, yytext ) ;

}

我觉得我可能会遗漏一些重要的东西。我不认为这是规则。我将yyin设置为argv []中提供的输入文件。错误是

解析时出错 - 1:语法错误,意外为TRUE,期待'{'at

解析时出错 - 1:语法错误,意外为FALSE,期待ELF上的'{'

非常感谢任何帮助!

编辑:如果我将主函数更改为不设置yyin(因此yyparse只是从stdin读取),我得到了这个:

{int x; }

解析时出错 - 1:语法错误,意外为TRUE,在{

预期'{'

我不明白这是怎么回事......

2 个答案:

答案 0 :(得分:2)

当我使用存根yylex运行上面的示例输入时,输入程序匹配。我假设“int”标记为BASIC。 (你还需要修复“retrun”。)

您需要调试词法分析器。附加一个调试器,以便您可以看到它返回的内容,或者在yylex的末尾添加一个print语句。

这取代了底部的所有内容:

%%
FILE* yyin = NULL;
int yylineno = 0;
char* yytext = NULL;
int main()
{
  yyparse() ;
  return 0 ; 
}

void yyerror( char *s )
{
  fprintf( stderr, "Error parsing - %d: %s at %s\n", yylineno, s, yytext ) ;
}

int yylex()
{
    static int i = 0;
    static int tokens[] = { '{', BASIC, ID, ';', '}' };

    int tok = tokens[i];
    yylineno++;
    i++;
    return tok;
}

答案 1 :(得分:0)

如果没有在同一输入上看到标记化器的输出,则很难说解析器失败的位置。

我自己,我将所有内容都标记,将'{'和'}'转换为LC和RC等,以确保标记器中唯一出现的是严格处理的令牌。这样可以更容易地确定源文件的每个字符的处理位置。

如果将源文件的每个标记移动到单独的行,例如

{
int
x
;
}

报告了什么错误?