2009-11-17 3 views
0

Я сделал программу, которая должна распознавать простую грамматику. Когда я вводил то, что, как я думаю, должно быть допустимым, я получаю сообщение об ошибке. В частности, если я начинаю с идентификатора, я автоматически получаю синтаксическую ошибку. Однако я заметил, что использование идентификатора не приведет к возникновению ошибки, если ему предшествует «int». Если a является идентификатором, то если я набираю 'int a;' хорошо. Но если я наберу «a = 3», я получаю сообщение об ошибке. Просто ввод текста сам по себе приведет к ошибке.Программа, которую я сделал с flex/yacc, не всегда распознает идентификаторы

The Lex Файл:

%{ 
#include <stdlib.h> 
#include <ctype.h> 
#include <string.h> 

#include "y.tab.h" 

%} 

else else 
if if 
int int 
return return 
void void 
while while 
id [a-zA-Z]+ 
num [0-9]+ 
lte <= 
gte >= 
equal == 
notequal != 


%% 

{else} { return ELSE; } 
{if} { return IF; } 
{int} { return INT; } 
{return} { return RETURN; } 
{void} { return VOID; } 
{while} { return WHILE; } 
{id} {  return ID; } 
{num} {  return NUM; } 
{lte} {  return LTE; } 
{gte} {  return GTE; } 
{equal} { return EQUAL; } 
{notequal} { return NOTEQUAL; } 


[\[\];] { return yytext[0];} 


%% 

Yacc файл

/* C-Minus BNF Grammar */ 

%token ELSE 
%token IF 
%token INT 
%token RETURN 
%token VOID 
%token WHILE 

%token ID 
%token NUM 

%token LTE 
%token GTE 
%token EQUAL 
%token NOTEQUAL 
%% 

program : declaration_list ; 

declaration_list : declaration_list declaration | declaration ; 

declaration : var_declaration | fun_declaration ; 

var_declaration : type_specifier ID ';' 
       | type_specifier ID '[' NUM ']' ';' ; 

type_specifier : INT | VOID ; 

fun_declaration : type_specifier ID '(' params ')' compound_stmt ; 

params : param_list | VOID ; 

param_list : param_list ',' param 
      | param ; 

param : type_specifier ID | type_specifier ID '[' ']' ; 

compound_stmt : '{' local_declarations statement_list '}' ; 

local_declarations : local_declarations var_declaration 
        | /* empty */ ; 

statement_list : statement_list statement 
       | /* empty */ ; 

statement : expression_stmt 
      | compound_stmt 
      | selection_stmt 
      | iteration_stmt 
      | return_stmt ; 

expression_stmt : expression ';' 
       | ';' ; 

selection_stmt : IF '(' expression ')' statement 
       | IF '(' expression ')' statement ELSE statement ; 

iteration_stmt : WHILE '(' expression ')' statement ; 

return_stmt : RETURN ';' | RETURN expression ';' ; 

expression : var '=' expression | simple_expression ; 

var : ID | ID '[' expression ']' ; 

simple_expression : additive_expression relop additive_expression 
        | additive_expression ; 

relop : LTE | '<' | '>' | GTE | EQUAL | NOTEQUAL ; 

additive_expression : additive_expression addop term | term ; 

addop : '+' | '-' ; 

term : term mulop factor | factor ; 

mulop : '*' | '/' ; 

factor : '(' expression ')' | var | call | NUM ; 

call : ID '(' args ')' ; 

args : arg_list | /* empty */ ; 

arg_list : arg_list ',' expression | expression ; 

ответ

1

программа расширяется до decl_list, а decl_list только разрешает серию объявлений. Вы никогда не разрешаете операторам/выражениям/etc в грамматике (кроме определения функции).

1

Вы жевательной пробельные ?, что является важным фактором, так как вы высказали [пробел] = [пробел] 3 ,

+0

Это не связано с пробелами, потому что, если я просто набираю a и нажимаю enter, я все равно получаю сообщение об ошибке. – neuromancer

+0

Хорошо. Но я подумал бы пережевывать пробелы на уровне лексера, прежде чем обращаться с парсером. '' {; } Вы так не думаете? – t0mm13b

+0

Это не работает. Не просто. Работа? – neuromancer

 Смежные вопросы

  • Нет связанных вопросов^_^