2012-11-07 155 views
0

所以我完全茫然......聲明類變量C++

在我的代碼我有

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類的包含文件時,我看不到這是怎麼回事。

編輯:我的文件 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(); 
} 

p02make:

#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 
+0

不要給函數和類相同的標識符,它只會混淆你。 –

回答

1

應該是:

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

等待我檢查了代碼,重命名功能:void Parser(FILE *f)到別的。

+0

已更新我的代碼來執行此操作。同樣的錯誤。 – James

-1

變化

void Parser(FILE* file) 

Parser::Parser(FILE* file) 

構造函數沒有返回類型。

+0

刪除前面的空白給出了一個新的錯誤: 'p02.cpp:18:錯誤:ISO C++禁止聲明'Parser'沒有類型' 然後原來的錯誤仍然在那之後。 – James

+0

它不是一個構造函數,那會是'Parser :: Parser'。 –

+0

從函數原型來看,他好像在試圖編寫構造函數。但是,你是對的,我在答案中錯過了範圍解析操作符。 –

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(); 
} 
+0

當我將'void Parser ...'更改爲'void myParser ...',然後嘗試運行它時,我得到:''Parser'未在此範圍內聲明,然後是原始錯誤消息。 – James

+0

@James:我已經添加了一些乾淨編譯的代碼,作爲有效的指導原則。 –

+0

我試過了,它開始搞亂了我的詞法分析器。我想我會繼續將所有文件中的所有代碼添加到我的原始問題中。然而,我警告你,它不漂亮。 – James

0

您需要資格Parser因爲函數具有相同的標識符類:

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

你也可以重命名功能。

您還需要在這裏括號:

Parser(FILE* file):Lexer(file) {} 
+0

有關命名衝突的好消息。更好的解決方案當然是重命名一個。 –

+0

好的,所以當我按照這個去掉了我給出的錯誤,而是給了我'p02.cpp:20:error:variable'解析器參數'有初始化器但是不完整類型' – James

+0

@James是包含'解析器類包含在函數聲明之前?如果沒有,那就這樣做。 – Pubby