2014-07-17 3 views
0

어떤 이유에서 들소는 특정 규칙, notequal_expression을 거부하고 있습니다. 내 생각의 라인이 그렇게 성숙하지 않도록 전체 개념을 배우기 시작한 것입니다. (오류 : string.y는 비단 쓸모 1 1 쓸모없는 규칙을 포함 ")들소에서 쓸데없는 규칙

/* Parser for StringC */ 

%{ 

/* ------------------------------------------------------------------ 
    Initial code (copied verbatim to the output file) 
    ------------------------------------------------------------------ */ 

// Includes 
#include <malloc.h> // _alloca is used by the parser 
#include <string.h> // strcpy 

#include "lex.h"  // the lexer 

// Some yacc (bison) defines 
#define YYDEBUG 1   // Generate debug code; needed for YYERROR_VERBOSE 
#define YYERROR_VERBOSE // Give a more specific parse error message 

// Error-reporting function must be defined by the caller 
void Error (char *format, ...); 

// Forward references 
void yyerror (char *msg); 

%} 

/* ------------------------------------------------------------------ 
    Yacc declarations 
    ------------------------------------------------------------------ */ 

/* The structure for passing value between lexer and parser */ 
%union { 
    char *str; 
} 

%token ERROR_TOKEN IF ELSE PRINT INPUT ASSIGN EQUAL NOTEQUAL 
%token CONCAT END_STMT OPEN_PAR CLOSE_PAR 
%token BEGIN_CS END_CS 
%token <str> ID STRING BOOLEAN 

/*%type <type> type simple_type cast*/ 

%expect 1 /* shift/reduce conflict: dangling ELSE */ 
      /* declaration */ 
%% 

/* ------------------------------------------------------------------ 
    Yacc grammar rules 
    ------------------------------------------------------------------ */ 

program 
     : statement_list 
     ; 

statement_list 
     : statement_list statement 
     | /* empty */ 
     ; 

statement 
     : END_STMT     {puts ("Empty statement");} 
     | expression END_STMT   {puts ("Expression statement");} 
     | PRINT expression END_STMT {puts ("Print statement");} 
     | INPUT identifier END_STMT {puts ("Input statement");} 
     | if_statement    {puts ("If statement");} 
     | compound_statement   {puts ("Compound statement");} 
     | error END_STMT    {puts ("Error statement");} 
     | notequal_expression   {puts ("Not equal statement");} 
     ; 

/* NOTE: This rule causes an unresolvable shift/reduce conflict; 
    That's why %expect 1 was added (see above) */ 
if_statement 
     : IF OPEN_PAR expression CLOSE_PAR statement optional_else_statement 
     ; 

optional_else_statement 
     : ELSE statement 
     | /* empty */ 
     ; 

compound_statement 
     : BEGIN_CS statement_list END_CS 
     ; 

expression 
     : equal_expression 
     | OPEN_PAR expression CLOSE_PAR 
     ; 

equal_expression 
     : expression EQUAL assign_expression 
     | assign_expression 
     ; 

notequal_expression 
     : expression NOTEQUAL assign_expression 
     | NOTEQUAL assign_expression 
     ; 

assign_expression 
     : identifier ASSIGN assign_expression 
     | concat_expression 
     ; 

concat_expression 
     : concat_expression CONCAT simple_expression 
     | simple_expression 
     ; 

simple_expression 
     : identifier 
     | string 
     ; 

identifier 
     : ID    {} 
     ; 

string 
     : STRING   {} 
     ; 

bool 
     : BOOLEAN   {} 
     ; 

%% 
/* ------------------------------------------------------------------ 
    Additional code (again copied verbatim to the output file) 
    ------------------------------------------------------------------ */ 

렉서 :.

/* Lexical analyzer for StringC */ 

%{ 

/* ------------------------------------------------------------------ 
    Initial code (copied verbatim to the output file) 
    ------------------------------------------------------------------ */ 

// Includes 
#include <string.h> // strcpy, strncpy 
#include <io.h>  // isatty 
#ifdef MSVC 
#define isatty _isatty // for some reason isatty is called _isatty in VC.. 
#endif 

#define _LEX_CPP_ // make sure our variables get created 
#include "lex.h" 
#include "lexsymb.h" 

extern "C" int yywrap(); // the yywrap function is declared by the caller 

// Forward references 
void Identifier(); 
void StringConstant(); 
void BoolConstant(); 
void EatComment(); 

//// End of inititial code 
%} 

/* ------------------------------------------------------------------ 
    Some macros (standard regular expressions) 
    ------------------------------------------------------------------ */ 

LETTER [a-zA-Z_] 
DIGIT [0-9] 
IDENT {LETTER}({LETTER}|{DIGIT})* 
STR  \"[^\"]*\" 
BOOL  \(false|true)\ 
WSPACE [ \t]+ 


/* ------------------------------------------------------------------ 
    The lexer rules 
    ------------------------------------------------------------------ */ 
%% 

"if"  {return IF;} 
"else" {return ELSE;} 
"print" {return PRINT;} 
"input" {return INPUT;} 
"="  {return ASSIGN;} 
"=="  {return EQUAL;} 
"!="  {return NOTEQUAL;}       /* Not equal to */ 
"+"  {return CONCAT;} 
";"  {return END_STMT;} 
"("  {return OPEN_PAR;} 
")"  {return CLOSE_PAR;} 
"{"  {return BEGIN_CS;} 
"}"  {return END_CS;} 
{BOOL} {BoolConstant(); return BOOLEAN;} 
{STR} {StringConstant(); return STRING;} 
{IDENT} {Identifier();  return ID;} 
"//"  {EatComment();}       /* comment: skip */ 
\n  {lineno++;}        /* newline: count lines */ 
{WSPACE} {}           /* whitespace: (do nothing) */ 
.  {return ERROR_TOKEN;}      /* other char: error, illegal token */ 

%% 

/* ------------------------------------------------------------------ 
    Additional code (again copied verbatim to the output file) 
    ------------------------------------------------------------------ */ 

// The comment-skipping function: skip to end-of-line 
void EatComment() { 
    char c; 

    while ((c = yyinput()) != '\n' && c != 0); 
    lineno++; 
} 

// Pass the id name 
void Identifier() { 
    yylval.str = new char[strlen(yytext)+1]; 
    strcpy (yylval.str, yytext); 
} 

// Pass the string constant 
void StringConstant() { 
    int l = strlen(yytext)-2; 
    yylval.str = new char[l+1]; 
    strncpy (yylval.str, &yytext[1], l); yylval.str[l] = 0; 
} 


void BoolConstant() { 
    int l = strlen(yytext)-2; 
    yylval.str = new char[l+1]; 
    strncpy(yylval.str, &yytext[1], l); yylval.str[l] = 0; 
} 
+0

'alloca' (나쁜 생각 일 수도 있음)는''을 사용하고, 'malloc'은 ''을 사용하십시오. ''을 포함시키는 것은 나쁜 생각입니다. –

답변

1

당신은이 문제를 일으키는 notequal_expression을 있다고 확신? 나는 그것을 읽을 때, 사용되지 않는 비 터미널 및 규칙

bool 
     : BOOLEAN   {} 
     ; 

아마도 대신

simple_expression 
     : identifier 
     | string 
     ; 

의 당신이 문법 두 가지 문제가 있습니다

simple_expression 
     : identifier 
     | string 
     | bool 
     ; 
+0

Im 그다지 틀린 점 ... 다른 문서를 첨부했습니다. –

+0

@MiguelP : 게시 된'.y' 파일에서 들소를 실행할 때 오류 메시지는 쓸모없는 규칙으로 'bool : BOOLEAN'을 식별하고, David은 설명하는 것과 같이 non-terminal을 식별합니다. –

0

를 코딩하기위한 것입니다 . 첫 번째는 이미 보았던 이동/축소 충돌입니다 (대신 %expect 1으로 해결됨). 대신 문법으로 처리하고 %expect 0을 사용하는 것이 좋습니다. %token 목록에서 ELSE을 제거하고 줄을 추가하여

줄을 추가하면됩니다. .
%right THEN ELSE 

당신의 언어가 실제로 THEN 키워드가없는 권리 연관성을 선언하지만 괜찮아 그런 다음 optional_else_statement을 위해 완전히 규칙을 제거하고 if_statement의 규칙을 바꾸어 말하다 수 있습니다 다음과 같습니다.

if_statement 
     : IF OPEN_PAR expression CLOSE_PAR statement %prec THEN 
     | IF OPEN_PAR expression CLOSE_PAR statement ELSE statement 
     ; 

이런 방식으로 해결하기를 원하는 사람들과 %expect 1 접근 방식을 옹호하는 사람들이 있습니다. 나는이 방법을 선호하지만, 이제는 두 가지 방법을 모두 사용할 수 있습니다. 확실히 선택할 수 있습니다. 다른 문제에 대한

는 쓸모없는 규칙은 확실히이 하나입니다

bool 
     : BOOLEAN   {} 
     ; 

비 터미널 bool 문법에 다른 곳에서는 사용되지 않기 때문에. bison이보고 한 것처럼 "쓸모없는 비 터미널 1 개와 쓸모없는 1 개의 규칙"을 설명합니다. 당신이 그런 당신의 IF-ELSE 같은 해결 시프트 감소 오류 (포함 크지 만 읽을 수있는 보고서를 포함하는 string.output 파일을 만듭니다

bison --report=solved -v string.y 

을 사용할 수 있습니다, 자신에 대한 이런 종류를 식별 할 수 있어야합니다 건설), 그리고 바이슨에 의해 만들어진 완전한 국가들도있다. 문법 문제를 해결할 때 매우 유용합니다.

관련 문제