0

所以我完全失去了......

在我的代码中,我有

void Parser(FILE* file)
{
    Parser par(file);
    par.Parse();
}

我在我的主函数中调用它,我 Parser(file); 得到的头文件(我包含在主文件中)看起来像:

class Parser: public Lexer
{
public:
    Parser(FILE* file):Lexer(file);
    int Parse();
};

我得到的错误是:

p02.cpp: In function 'void Parser(FILE*)':
p02.cpp:20: error: expected ';' before 'par'
p02.cpp:21: error: 'par' was not declared in this scope
make: *** [p02.o] Error 1

我不明白的是为什么它在 par 之前需要一个分号。这不是该类变量的合法声明吗?

Edit2:将我的函数名称更改为不像类名那样的 Parser 并不能解决此问题。它确实给了我一个额外的错误,告诉我 Parser 没有在这个范围内声明,但是当我在函数声明的正上方添加包含 Parser 类的包含文件时,我看不到这是怎么回事。

编辑:我的文件 p02.cpp:

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

#include "p02lex.h"
#include "y.tab.h"

using namespace std;

void Parser(FILE* file)
{
    Parser par(file);
    par.Parse();
}

int main(int argc, char* argv[])
{
    char fileName[255];

    switch(argc)
    {
            case 1:
                    cout << "Enter the input file name. ";
                    cin >> fileName;
                    break;
            case 2:
                    strcpy(fileName, argv[1]);
                    break;
            default:
                    cout << "Too many arguments!\n";
                    exit(1);
    }

    FILE* file = fopen(fileName, "r");
    Parser(file);
    fclose(file);

    return 0;
}

p02lex.l:

#include "p02lex.h"

#define ID              257
...
#define PROGRAM         304

int TokenMgr(int t);
const char* getTokens(int tokenCode);

unsigned lineCount = 1, columnCount = 1;
%}

LETTER [a-z]|[A-Z]
DIGIT [0-9]

%%
// rules defined here, calling TokenMgr()
%%
int TokenMgr(int t)
{
/*      int tc = t;
    if (t == IDENTIFIER)
    {
            char s[1024];
            ToLower(s, yytext, strlen(yytext));
            tc = RW[s];
            if (tc == 0)
                    tc = t;
    }

    PrintToken(tfs, tc, line, col);
    col += yyleng; */ //JEG

    printf("Token:Code=%d Name=%10s line=%3u col=%3u Spelling=\"%s\"\n", t, getTokens(t), lineCount, columnCount, yytext);

    columnCount += yyleng;

    return /* tc */ 0; // JEG
}

Lexer::Lexer(FILE* file)
{
    yyin = file;
}

int Lexer::Scan(void)
{
    return yylex();
}

const char* getTokens(int tokenCode)
{
    switch(tokenCode)
    {
            case ID:
                    return "ID";
            ... // more cases, returning strings
            default:
                    return NULL;
    }
 }

p02lex.h:

#ifndef p02lex_h
#define p02lex_h 1
#endif

int yylex(void);

class Lexer
{
public:
    Lexer(FILE* file);

    int Scan(void);
};

p02par.h:

#ifndef p02par_h
#define p02par_h 1
#endif

using namespace std;

#ifdef __cplusplus
extern "C"
#endif

int yyparse(void);

class Parser: public Lexer
{
public:
    Parser(FILE* file):Lexer(file){}

    void Parse();

    // int Scan(void);
};

p02par.y:

#include <stdio.h>

#include "p02lex.h"
#include "p02par.h"

void yyerror(const char* m);
%}

%token PROGRAM
%token ID
%token SEMICOLON

%%
program:
    PROGRAM ID SEMICOLON
    { printf("Stuff happens!\n"); }

%%
void yyerror(const char* m)
{
    printf("%s\n", m);
}

/*Parser::Parser(FILE* file):Lexer(file)
{
}*/

int Parser::Parse()
{
    return yyparse();
}

p02制作:

#LEX = flex
#YACC = yacc -d

CC = g++
OBJ = p02.o p02par.o p02lex.o

p02:    ${OBJ}
    $(CC) -o p02 ${OBJ} -ll -ly

y.tab.h p02par.cpp:     p02par.y
    yacc -d -v p02par.y
    mv y.tab.c p02par.cpp

p02lex.cpp:     p02lex.l
    lex p02lex.l
    mv lex.yy.c p02lex.cpp

p02par.o:       p02par.cpp p02par.h
    $(CC) -c -g p02par.cpp

p02.o:  p02.cpp p02lex.h p02par.h
    $(CC) -c -g p02.cpp

p02lex.o:       p02lex.cpp p02lex.h y.tab.h
    $(CC) -c -g p02lex.cpp
4

4 回答 4

1

您只能在构造函数定义中包含初始化列表,而不是构造函数声明,因此它必须后跟函数体(通常为空),而不是分号。名称冲突还有一点问题:

void Parser(FILE* file) // here you've defined Parser as the name of a function
{
    Parser par(file); // but here you're trying to use it as the name of a class.
    par.Parse();
}

编辑:这是一些可以干净编译的代码,至少使用我方便的编译器:

#include <stdio.h>

class Lexer {
    FILE *infile;
public:
    Lexer(FILE *f) : infile(f) {}
};

class Parser : public Lexer {
public:
    Parser(FILE *f) : Lexer(f) {}
    void Parse() {}
};

void do_parse(FILE *file) {
    Parser p(file);
    p.Parse();
}
于 2012-11-07T06:53:26.640 回答
1

那应该是:

Parser(File* file):Lexer(file) {}

等等,我检查了该代码,将函数重命名为:void Parser(FILE *f)其他名称。

于 2012-11-07T06:52:08.457 回答
0

您需要限定Parser,因为该函数具有与类相同的标识符:

void Parser(FILE* file)
{
    class Parser par(file);
    par.Parse();
}

您也可以重命名该函数。

您还需要大括号:

Parser(FILE* file):Lexer(file) {}
于 2012-11-07T06:56:57.537 回答
-1

改变

void Parser(FILE* file)

Parser::Parser(FILE* file)

构造函数没有返回类型。

于 2012-11-07T06:53:12.380 回答