Синтаксическая ошибка, неожиданное ИСТИНА, ожидание '{'

Я пишу парсер в Bison для базового компилятора (а затем расширяю его, чтобы он содержал подпрограммы и динамическое распределение памяти). Грамматика определена в Приложении А книги о драконах. Мой 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: синтаксическая ошибка, неожиданное ИСТИНА, ожидание '{' в

Ошибка синтаксического анализа - 1: синтаксическая ошибка, неожиданное FALSE, ожидание '{' в ELF

Любая помощь будет принята с благодарностью!

РЕДАКТИРОВАТЬ: Если я изменю основную функцию, чтобы не устанавливать yyin (так что yyparse просто читает из stdin), я получаю это:

{int x; }

Ошибка синтаксического анализа - 1: синтаксическая ошибка, неожиданное ИСТИНА, ожидание '{' в {

Я не понимаю, как это неправильно ...

1
задан lesmana 6 May 2013 в 20:57
поделиться

2 ответа

Когда я запускаю ваш пример ввода, приведенный выше, используя заглушку yylex, программа ввода совпадает. Я делаю предположение, что "int" токенизируется как BASIC. (Вам также нужно исправить "retrun".)

Вам нужно отладить ваш лексер. Либо подключите отладчик, чтобы вы могли видеть, что он возвращает, либо поместите оператор print в конец yylex.

Это заменяет все в нижней секции:

%%
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;
}
2
ответ дан 2 September 2019 в 22:24
поделиться

Не видя выходных данных вашего токенизатора на том же входе, трудно сказать, где происходит сбой синтаксического анализатора.

Я сам токенизирую все, превращая '{' и '}' в LC и RC и т. Д., Чтобы гарантировать, что единственное, что выходит из токенизатора, - это токены строгой обработки. Это упрощает решение о том, где обрабатывается каждый отдельный символ вашего исходного файла.

Если вы переместите каждый токен исходного файла в отдельную строку, например

{
int
x
;
}

, о какой ошибке будет сообщено?

0
ответ дан 2 September 2019 в 22:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: