lex和yacc警告并没有按预期工作

时间:2017-06-11 12:34:03

标签: yacc lex

Lexer.l

%{
#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
           ;

%%

同样是的,我注意到你的最后一点:)

1 个答案:

答案 0 :(得分:1)

C11C22C44和其他&#34; tail&#34;不同。规则,可以产生%emptyC33只有一个产品:

C33 : TK_EQ C3 C33;

由于它没有非递归产生,因此不可能产生一个句子(仅由非终端组成)。并且因为它是C2的唯一产品的一部分,C1Condition的唯一产品的一部分,IfStmtC4的唯一产品的一部分,C3C44的唯一产品的一部分{1}},这些都不会产生任何句子。不能产生任何句子的规则在技术上被描述为&#34;无用的&#34;所有规则都无用(或者其唯一规则无用)的非终端是一个无用的非终端&#34;。

还有另一类无用的非终端:无法通过任何有用规则生成的终端。 C5就是这种情况(只能由C33生成,已被发现无效),因此Condition~3 < ~4也是如此。

应该明白如何解决这个问题,但是我想指出你是通过试图避免左递归而将自己捆绑在一起,这在使用自下而上时既不必要又适得其反解析器生成器,如bison / yacc。 (请参阅this answer的最后一段,了解更长时间的抱怨。)人工制作(x * 2 < y和朋友)仅用于使解析树复杂化。

此外,由于您的语法不明确 - 实际上,生产规则明确定义了运算符绑定强度 - 各种优先级声明都没有意义。 (与&#34;无用的&#34;不同,这不是技术术语:-))。优先级声明仅适用于解决语法歧义,此处不存在。

最后,我认为你应该重新审视UIImageView的语法。例如,UIView的含义是什么?为什么FormatException无效?