2017-06-11 15 views
0

Lexer.llex和yacc警告的,而不是按預期工作

%{ 
#include "y.tab.h" 
%} 

%% 

"define" return(TK_KEY_DEFINE); 
"as" return(TK_KEY_AS); 
"is" return(TK_KEY_IS); 
"if" return(TK_KEY_IF); 
"then" return(TK_KEY_THEN); 
"else" return(TK_KEY_ELSE); 
"endif" return(TK_KEY_ENDIF); 
"with" return(TK_KEY_WITH); 
"DEFINE" return(TK_KEY_DEFINE_UC); 
"AS" return(TK_KEY_AS_UC); 
"IS" return(TK_KEY_IS_UC); 
"IF" return(TK_KEY_IF_UC); 
"THEN" return(TK_KEY_THEN_UC); 
"ELSE" return(TK_KEY_ELSE_UC); 
"ENDIF" return(TK_KEY_ENDIF_UC); 
"WITH" return(TK_KEY_WITH_UC); 
"+" return(TK_PLUS); 
"-" return(TK_MINUS); 
"*" return(TK_MUL); 
"/" return(TK_DIV); 
"~" return(TK_NOT); 
"&" return(TK_AND); 
"|" return(TK_OR); 
"<=" return(TK_LEQ); 
"<" return(TK_LESS); 
">=" return(TK_GEQ); 
">" return(TK_GT); 
"==" return(TK_EQ); 
"=" return(TK_ASSIGN); 
"(" return(TK_OPEN); 
")" return(TK_CLOSE); 
";" return(TK_SEMI); 
"," return(TK_COMMA); 
[[:alpha:]_][[:alnum:]_]* return(IDENTIFIER); 
[+-]?[0-9]+ return(INTEGER); 
[+-]?([0-9]+([.][0-9]*)?|[.][0-9]+) return(REAL); 
[[:space:]]+ ; 

%% 

int yywrap(void) 
{ 
    return 1; 
} 

Parser.y

%{ 

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

    typedef struct node 
    { 
    struct node *left; 
    struct node *right; 
    char *token; 
    } node; 

    node *mknode(node *left, node *right, char *token); 
    void printtree(node *tree); 

#define YYSTYPE struct node * 

%} 

%start Program 

%token TK_KEY_DEFINE TK_KEY_DEFINE_UC 
%token TK_KEY_AS TK_KEY_AS_UC 
%token TK_KEY_IS TK_KEY_IS_UC 
%token TK_KEY_IF TK_KEY_IF_UC 
%token TK_KEY_THEN TK_KEY_THEN_UC 
%token TK_KEY_ELSE TK_KEY_ELSE_UC 
%token TK_KEY_ENDIF TK_KEY_ENDIF_UC 
%token TK_KEY_WITH TK_KEY_WITH_UC 
%token TK_PLUS TK_MINUS 
%token TK_MUL TK_DIV 
%token TK_NOT 
%token TK_AND 
%token TK_OR 
%token TK_LEQ TK_LESS TK_GEQ TK_GT 
%token TK_EQ 
%token TK_ASSIGN 
%token TK_OPEN TK_CLOSE 
%token TK_SEMI 
%token TK_COMMA 
%token IDENTIFIER 
%token INTEGER 
%token REAL 


%left TK_PLUS TK_MINUS 
%left TK_MUL TK_DIV 
%left TK_LEG TK_LESS TK_GEQ TK_GT 
%left TK_AND TK_OR 
%left TK_EQ 
%right TK_NOT TK_ASSIGN 

%% 


Program : Macros Statements; 

Macros : /* empty */ 
     | Macro Macros 
     ; 

Macro : TK_KEY_DEFINE MacroTemplate TK_KEY_AS Expression; 

MacroTemplate : IDENTIFIER MT; 

MT   : /*empty*/ 
       | TK_OPEN IdentifierList TK_CLOSE 
       ; 

IdentifierList : IDENTIFIER I; 

I : /*empty*/ 
    | TK_COMMA IdentifierList 
    ; 

Statements : /*empty*/ 
      | Statement Statements 
      ; 

IfStmt : TK_KEY_IF Condition TK_KEY_THEN Statements TK_KEY_ELSE Statements TK_KEY_ENDIF; 

Statement : AssignStmt 
      | IfStmt 
      ; 

AssignStmt : IDENTIFIER TK_KEY_IS Expression; 



Condition : C1 C11; 

C11 : /*empty*/ 
    | TK_OR C1 C11 
    ; 

C1 : C2 C22; 

C22 : /*empty*/ 
    | TK_AND C2 C22 
    ; 

C2 : C3 C33; 

C33 : TK_EQ C3 C33; 

C3 : C4 C44; 

C44 : /*empty*/ 
    | TK_LESS C4 C44 
    | TK_LEQ C4 C44 
    | TK_GT C4 C44 
    | TK_GEQ C4 C44 
    ; 

C4 : TK_NOT C5 | C5; 

C5 : INTEGER | REAL | TK_OPEN Condition TK_CLOSE; 

Expression : Term EE; 

EE : /*empty*/ 
    | TK_PLUS Term EE 
    | TK_MINUS Term EE 
    ; 

Term : Factor TT; 

TT : /*empty*/ 
    | TK_MUL Factor TT 
    | TK_DIV Factor TT 
    ; 

Factor : IDENTIFIER | REAL | INTEGER | TK_OPEN Expression TK_CLOSE; 

%% 

int main (void) {return yyparse ();} 

node *mknode(node *left, node *right, char *token) 
{ 
    /* malloc the node */ 
    node *newnode = (node *)malloc(sizeof(node)); 
    char *newstr = (char *)malloc(strlen(token)+1); 
    strcpy(newstr, token); 
    newnode->left = left; 
    newnode->right = right; 
    newnode->token = newstr; 
    return(newnode); 
} 

void printtree(node *tree) 
{ 
    int i; 
    if (tree->left || tree->right) 
    printf("("); 

    printf(" %s ", tree->token); 

    if (tree->left) 
    printtree(tree->left); 
    if (tree->right) 
    printtree(tree->right); 

    if (tree->left || tree->right) 
    printf(")"); 
} 

int yyerror (char *s) 
{ 
fprintf (stderr, "%s\n", s); 
} 

祝輸出到解析樹,如果如果有任何錯誤,並指出錯誤。 但是我得到了很多的警告,如

warning: rule useless in grammar 
warning: nonterminal useless in grammar 

我明白了這樣做的原因通過閱讀其他類似的問題,但不能糾正自己。請幫我解決這個問題。謝謝 !

RICI嗨,

太感謝你了,所以我不用擔心左遞歸,左保理語法等,並直接繼續前進,在YACC使用類似下面?

%% 

Program : Macros Statements; 

Macros : /*empty*/ 
     |Macro Macros 
     ; 

Macro : TK_KEY_DEFINE MacroTemplate TK_KEY_AS Expression; 

MacroTemplate : VarTemplate 
       | FunTemplate 
      ; 

VarTemplate : IDENTIFIER; 

FunTemplate : IDENTIFIER TK_OPEN IdentifierList TK_CLOSE; 

IdentifierList : IDENTIFIER TK_COMMA IdentifierList 
       | IDENTIFIER 
       ; 

Statements : /*empty*/ 
      | Statement Statements 
      ; 

IfStmt : TK_KEY_IF Condition TK_KEY_THEN Statements TK_KEY_ELSE Statements TK_KEY_ENDIF; 

Statement : AssignStmt 
      | IfStmt 
      ; 

AssignStmt : IDENTIFIER TK_KEY_IS Expression; 

Condition : Condition TK_AND Condition 
      | Condition TK_OR Condition 
      | Condition TK_LESS Condition 
      | Condition TK_LEQ Condition 
      | Condition TK_GT Condition 
      | Condition TK_GEQ Condition 
     | Condition TK_EQ Condition 
      | TK_NOT Condition 
      | TK_OPEN Condition TK_CLOSE 
      | INTEGER 
      | REAL 
      ; 

Expression : Expression TK_PLUS Expression 
      | Expression TK_MINUS Expression 
      | Expression TK_MUL Expression 
      | Expression TK_DIV Expression 
      | TK_OPEN Expression TK_CLOSE 
      | IDENTIFIER 
      | INTEGER 
      | REAL 
      ; 

%% 

還不錯,我注意到你的最後一點:)

+0

而問題是什麼? – user3344003

+0

您是否考慮提及哪些*終端被認定爲無用,或者您認爲這會讓您的問題變得過於簡單? – rici

+0

雅對不起。我下次記住他們。感謝您幫助我在這裏... – Nick

回答

1

不像C11C22C44等 「尾巴」 的規則,它可以產生%emptyC33只有一個生產:

C33 : TK_EQ C3 C33; 

由於它沒有非遞歸的生產,它不可能產生一個句子(僅由非端子)。而且因爲它是C2唯一生產這是C1唯一生產這是Condition唯一生產這是IfStmt唯一生產的一部分,一部分一部分的一部分,這些都不可以產生任何一句話。不能產生任何句子的規則在技術上被描述爲「無用的」,並且非終端的所有規則都是無用的(或者其唯一規則是無用的)是「無用的非終端」。

有沒用非終端中的另一個類別:那些不能由任何有用的規則而產生。 C4(只能由C3產生,這已被發現是無用的),因此與C44C5將是這種情況。

它應該是顯而易見的如何解決這個問題,但我想說明的是,通過嘗試避免左遞歸來綁定自己,這在使用自下而上的解析器時是不必要的和適得其反的發電機如bison/yacc。 (請參閱this answer的最後一段,以獲得更長久的抱怨。)人工製作(C33和朋友)只會使解析樹複雜化。另外,由於您的語法並不含糊 - 實際上,生產規則明確定義了操作符綁定的優勢 - 各種優先級聲明都是毫無意義的。 (與「無用」的,這不是一個技術術語:-))。優先級聲明僅適用於解決歧義,在這裏是不存在的。

最後,我認爲你應該重新檢查你的語法爲Condition s。什麼,例如,是~3 < ~4意思?爲什麼x * 2 < y無效?