Parsing 为什么会出现此错误,如何修复

Parsing 为什么会出现此错误,如何修复,parsing,bison,flex-lexer,Parsing,Bison,Flex Lexer,我正在尝试运行我的第一个flex bison项目,发生了以下情况: aky@aky-VirtualBox:~/wk1$flex project1.l aky@aky-VirtualBox:~/wk1$bison-d项目1.y aky@aky-VirtualBox:~/wk1$gcc-o project1 project1.c project1.tab.c lex.yy.c project1.c:在函数“main”中: project1.c:18:9:警告:函数“yyparse”的隐式声明 pro

我正在尝试运行我的第一个flex bison项目,发生了以下情况:

aky@aky-VirtualBox:~/wk1$flex project1.l aky@aky-VirtualBox:~/wk1$bison-d项目1.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.选项卡c:1213:16:警告:函数'yylex'的隐式声明

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

相关代码:

项目1.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();
    }
    %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"); }
    %%
    %{
    #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 { }
       ;
    %%
    #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  */
  • yyparse
    project1.tab.h
    中声明,因此您需要将该文件包含在引用
    yyparse
    的任何翻译单元中

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

    int yylex(void);
    
    应该在
    后面加上
    s

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


  • 此时我留下的唯一错误是关于“lookup()”函数。它由lex.yy.c代码引用,如下所示:案例38:yy_RULE_SETUP#第55行“project1.l”{yylval.s=lookup(yytext);return ID;}这个函数可以在哪里定义?谢谢@aky:我帮不了你,因为它不是bison/flex框架的一部分。它必须是您从中复制的源代码的一部分。@aky要添加到rici所说的内容中:
    lex.yy.c
    包含对
    lookup
    的调用,因为您编写了
    yylval.s=lookup(yytext)
    project1.l
    中的操作中。如果没有在项目中定义名为
    lookup
    的函数,则不应在lexer中调用此类函数。