当前位置:  开发笔记 > 开发工具 > 正文

使用野牛时的错误

如何解决《使用野牛时的错误》经验,为你挑选了1个好方法。

现在我正在接受其他事情.当我这样做时,我bison -d calc.y在控制台中获得了许多源代码(有很多m4_define),但它不会生成任何文件.现在我的代码是这样的:

%{
#define YYSTYPE double
#include 
%}
%token NUM
%%
input:    /* empty */
        | input line
;

line:     '\n'
        | exp '\n'  { printf ("\t%.10g\n", $1); }
;

exp:      NUM             { $$ = $1;         }
        | exp exp '+'     { $$ = $1 + $2;    }
        | exp exp '-'     { $$ = $1 - $2;    }
        | exp exp '*'     { $$ = $1 * $2;    }
        | exp exp '/'     { $$ = $1 / $2;    }
      /* Exponentiation */
        | exp exp '^'     { $$ = pow ($1, $2); }
      /* Unary minus    */
        | exp 'n'         { $$ = -$1;        }
;
%%

/* Lexical analyzer returns a double floating point 
   number on the stack and the token NUM, or the ASCII
   character read if not a number.  Skips all blanks
   and tabs, returns 0 for EOF. */

#include 
#include 

yylex ()
{
  int c;

  /* skip white space  */
  while ((c = getchar ()) == ' ' || c == '\t')  
    ;
  /* process numbers   */
  if (c == '.' || isdigit (c))                
    {
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    }
  /* return end-of-file  */
  if (c == EOF)                            
    return 0;
  /* return single chars */
  return c;                                
}

yyerror (s)  /* Called by yyparse on error */
     char *s;
{
  printf ("%s\n", s);
}

main ()
{
  yyparse ();
}

原始问题

我正在尝试创建自己的开发语言,但它很难开始,因为我开始,我遇到很多错误,我不知道如何解决.这是我的代码:

#include 
#include 

yylex ()
{
  int c;

  /* skip white space  */
  while ((c = getchar ()) == ' ' || c == '\t')  
    ;
  /* process numbers   */
  if (c == '.' || isdigit (c))                
    {
      ungetc (c, stdin);
      scanf ("%lf", &yylval);
      return NUM;
    }
  /* return end-of-file  */
  if (c == EOF)                            
    return 0;
  /* return single chars */
  return c;                                
}

main ()
{
  yyparse ();
}

calc.y源代码文件:

%token NUM
%%
input:
        | input line
;

line:     '\n'
        | exp '\n'  { printf ("\t%.10g\n", $1); }
;

exp:      NUM             { $$ = $1;         }
        | exp exp '+'     { $$ = $1 + $2;    }
        | exp exp '-'     { $$ = $1 - $2;    }
        | exp exp '*'     { $$ = $1 * $2;    }
        | exp exp '/'     { $$ = $1 / $2;    }
      /* Exponentiation */
        | exp exp '^'     { $$ = pow ($1, $2); }
      /* Unary minus    */
        | exp 'n'         { $$ = -$1;        }
;
%%

现在编译日志:

C:\Documents and Settings\Nathan Campos\Desktop>gcc calc.tab.c -lm -o rpcalc
calc.tab.c: In function `yylex':
calc.tab.c:15: error: `yylval' undeclared (first use in this function)
calc.tab.c:15: error: (Each undeclared identifier is reported only once
calc.tab.c:15: error: for each function it appears in.)
calc.tab.c:16: error: `NUM' undeclared (first use in this function)

怎么了?



1> Jonathan Lef..:

修改后的答案

您提供的修改代码编译几乎干净利落地-你应该#include printf()使用它之前宣布.(您还应该将原型用于函数 - 例如yyerror(const char *str),并且通常将代码拖到21世纪.)

它甚至可以正确响应'1 2 +'.

使用单个文件,您不需要使用' bison -d'.

如果您看到垃圾,则需要查看构建命令和构建环境.


原始答案

从哪里开始?

建议:掌握O'Reilly关于Lex和Yacc(来自图书馆)或Flex和Bison(2009年8月更新/重写 - 可能还没有在图书馆中)的书.如果您需要更快的资源,那么我建议使用Unix版本7手册或GNU Bison手册 - 这两本手册都可以在线获取.特别是阅读关于Lex和Yacc的第7版文件; 你并没有尝试做原始描述中没有涉及的内容(尽管C代码在C89标准之前已经过了十年或更长时间).

您需要使用bison -d生成包含令牌编号的标头.对于源文件'zzz.y',这将生成C代码'zzz.tab.c'和'zzz.tab.h'.

您需要在主程序中包含"zzz.tab.h".

您需要使用C99,因此应该在yylex()和上具有返回类型main().

你需要申报yylval.幸运的是,Bison的"zzz.tab.h"文件可以正确地执行此操作; 它并不像看起来那么简单.

您可能希望在词法分析器中允许使用负数(-3.1416).您可能也希望允许显式正数(+3.1416).

您可能需要确保'$$'和朋友的类型double而不是默认类型int(#define YYSTYPE double).

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有