2009-11-17 3 views
0

간단한 문법을 ​​인식하는 프로그램을 만들었습니다. 유효한 진술이라고 생각되는 내용을 입력하면 오류가 발생합니다. 특히, 내가 입력 할 경우flex 및 yacc로 만든 프로그램에서 구문 오류가 발생하는 이유는 무엇입니까?

int a;

int b;

작동하지 않습니다. int를 입력 한 후; 프로그램은 울부 짖는다. 몇 가지 이유. 그런 다음 int b를 입력하면; 구문 오류가 발생합니다.

렉스 파일 :

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

#include "y.tab.h" 

%} 

else ELSE 
if IF 
int 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; } 
%% 

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

좋아 ... 당신이 언어 사양에뿐만 아니라 표시로 세미콜론을 추가 할 필요가 ... fyi로서 이것에 대한 구글 검색을해라. .. C 프로그래밍 언어를위한 몇 가지 lex/yacc 파일도있다. ... 이것에 관한 많은 튜토리얼이있다. flex/bison은 프로그램에서 용서하지 않는다. spec errors ... 어떻게 작동하는지 요소를 이해할 필요가 있습니다 ... 컴파일러를 만드는 방법에 대한 Jack Crenshaw의 유명한 튜토리얼을 찾으십시오.

+0

, 내가 무엇을 반환? ';'의 모든 인스턴스를 변경해야합니까? yacc 파일에서, 또는 내가 그들을 떠날 수 있을까? – neuromancer

1

렉스 : 나는 세미콜론을 추가 한 경우

id [a-zA-Z]* 
num [0-9]* 

두 경우 모두가 '+'를 사용 빈 문자열을 만날 수있는 대신

+0

문제는 해결되지 않지만 사실입니다. – neuromancer

+0

@Phenom - lex에 다음 줄 추가 : "newline \ n"기본적으로 우주 치료는 \ r \ n 조합을 인식 할 수 없습니다 – Dewfy

관련 문제