为什么会出现此错误,我该如何解决

时间:2018-11-07 20:42:22

标签: parsing bison flex-lexer

我正在尝试运行我的第一个flex bison项目,并且发生了这种情况:

aky @ aky-VirtualBox:〜/ wk1 $ flex project1.l aky @ aky-VirtualBox:〜/ wk1 $野牛-d project1.y aky @ aky-VirtualBox:〜/ wk1 $ gcc -o project1 project1.c project1.tab.c lex.yy.c

project1.c:在“ main”函数中:

project1.c:18:9:警告:函数“ yyparse”的隐式声明

project1.tab.c:1213:16:警告:函数“ yylex”的隐式声明

lex.yy.c :(。text + 0x470):对“查找”的未定义引用

相关代码:

project1.c ----------------------------

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

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

    int main(int argc, char **argv)
    {
        extern FILE *yyin;
        ++argv; --argc;
        yyin = fopen(argv[0], "r");
        return yyparse();
    }

project1.l ------------------------

    %option noyywrap nodefault yylineno
    %{
    #include "project1.h"
    #include "project1.tab.h"
    %}


    EXP ([Ex][-+]?[0-9]+)

    %%

    ".." { return DOTS; }

    "+"  |
    "-"  |
    "*"  |
    "/"  |
    "="  |
    "|"  |
    ","  |
    ";"  |
    ":"  |
    "."  |
    "["  |
    "]"  |
    "{"  |
    "}"  |
    "("  |
    ")"  { return yytext[0]; }

    ">"  { yylval.fn = 1; return CMP; }
    "<"  { yylval.fn = 2; return CMP; }
    "<>" { yylval.fn = 3; return CMP; }
    "==" { yylval.fn = 4; return CMP; }
    ">=" { yylval.fn = 5; return CMP; }
    "<=" { yylval.fn = 6; return CMP; }
    "integer" { yylval.type_c = 'a'; return STD_TYPE; }
    "real"    { yylval.type_c = 'b'; return STD_TYPE; }
    "program" { return PROGRAM; }
    "var"     { return VAR; }
    "array"   { return ARRAY; }
    "of"      { return OF; }
    "begin"   { return BGN; }
    "end"     { return END; }


    "if"    { return IF; }
    "then"  { return THEN; }
    "else"  { return ELSE; }
    "while" {return WHILE; }
    "do"    { return DO; }
    "print" { return PRINT; }


    [a-zA-Z][a-zA-Z0-9]*  { yylval.s = lookup(yytext); return ID; }

    [0-9]+"."[0-9]+  |
    [0-9]+    { yylval.d = atof(yytext); return NUMBER; }

    "//".*
    [ \t\n]
    .  { yyerror("Mystery character.\n"); }
    %%

project1.y ------------------------

    %{
    #include <stdio.h>
    #include <stdlib.h>
    #include "project1.h"
    %}

    %union {
      struct ast *a;
      double d;
      struct symbol *s;
      struct symlist *sl;
      struct numlist *nl;
      int fn;
      char type_c;
    }

    /* declare tokens */
    %token <d> NUMBER
    %token <s> ID
    %token PROGRAM VAR ARRAY OF INTEGER REAL BGN END IF THEN ELSE WHILE DO         DOTS PRINT
    %token <type_c> STD_TYPE

    %nonassoc <fn> CMP
    %right '='
    %left '+' '-'
    %left '*' '/'
    %nonassoc '|' UMINUS

    %type <a> decl_list decl stmt_list stmt exp
    %type <sl> id_list
    %type <nl> num_list

    %start program
    %%

    program: PROGRAM ID '(' id_list ')' ';' decl_list BGN stmt_list END         '.'        
       { printf("new program.\n"); }
       ;

    decl_list:    { /*$$ = NULL;*/ }
        | decl ';' decl_list  { printf("new declaration.\n"); }
        ;

    decl: VAR id_list ':' STD_TYPE { }
        | VAR id_list ':' ARRAY '[' NUMBER DOTS NUMBER ']' OF STD_TYPE
        { }
        ;

    stmt: IF exp THEN '{' stmt_list '}' { }
        | IF exp THEN '{' stmt_list '}' ELSE '{' stmt_list '}' { }
        | WHILE exp DO '{' stmt_list '}' { }
        | exp
        ;

    stmt_list: stmt { printf("new statement.\n"); }
            | stmt_list ';' stmt { }
            ;

    exp: exp CMP exp { }
             | exp '+' exp    { }
             | exp '-' exp    { }
             | exp '*' exp    { }
             | exp '/' exp    { }
             | '|' exp        { }
             | '(' exp ')'    { }
             | '-' exp %prec UMINUS { }
             | NUMBER{ }
             | ID     { }
             | ID '[' exp ']'         { }
             | ID '[' exp ']' '=' exp { }
             | ID '=' exp             { }
             | ID '=' '{' num_list '}' { }
             | PRINT '(' exp ')'      { }
             ;

    num_list: NUMBER { }
        | NUMBER ',' num_list {}
        ;

    id_list: ID  { }
       | ID ',' id_list { }
       ;
    %%

project1.tab.h --------------------

    #ifndef YY_YY_PROJECT1_TAB_H_INCLUDED
    # define YY_YY_PROJECT1_TAB_H_INCLUDED
    /* Debug traces.  */
    #ifndef YYDEBUG
    # define YYDEBUG 0
    #endif
    #if YYDEBUG
    extern int yydebug;
    #endif

    /* Token type.  */
    #ifndef YYTOKENTYPE
    # define YYTOKENTYPE
      enum yytokentype
      {
        NUMBER = 258,
        ID = 259,
        PROGRAM = 260,
        VAR = 261,
        ARRAY = 262,
        OF = 263,
        INTEGER = 264,
        REAL = 265,
        BGN = 266,
        END = 267,
        IF = 268,
        THEN = 269,
        ELSE = 270,
        WHILE = 271,
        DO = 272,
        DOTS = 273,
        PRINT = 274,
        STD_TYPE = 275,
        CMP = 276,
        UMINUS = 277
      };
    #endif

    /* Value type.  */
    #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED

    union YYSTYPE
    {
    #line 7 "project1.y" /* yacc.c:1909  */

      struct ast *a;
      double d;
      struct symbol *s;
      struct symlist *sl;
      struct numlist *nl;
      int fn;
      char type_c;

    #line 87 "project1.tab.h" /* yacc.c:1909  */
    };

    typedef union YYSTYPE YYSTYPE;
    # define YYSTYPE_IS_TRIVIAL 1
    # define YYSTYPE_IS_DECLARED 1
    #endif


    extern YYSTYPE yylval;

    int yyparse (void);

    #endif /* !YY_YY_PROJECT1_TAB_H_INCLUDED  */

1 个答案:

答案 0 :(得分:1)

  1. yyparseproject1.tab.h中声明,因此您需要以任何引用#include的翻译单元yyparse来命名该文件。

  2. yylex未在任何标头中声明。在yacc / bison文件中,您需要插入正确的声明:

    int yylex(void);
    

    那应该在#include之后。

  3. 我不清楚在哪个文件中定义了lookup,但是您需要将其添加到最终的编译命令中。