【问题标题】:C++ error: expected unqualified-id before 'else'C++ 错误:“else”之前的预期不合格 ID
【发布时间】:2019-10-18 07:44:37
【问题描述】:
#include <fortran.h>

real function f() code
    return 0.0;
endfunction

program(main)
    if 3 == 3 then
        print(*) "Your PC is fine.";
    elseif 3 == 4 then
        print(*) "Your PC is broken.";
    else
        print(*) "Your PC is trash.";
    endif

    write(*, "(I)") 5);
end

我在第 10 行收到错误 expected unqualified-id before 'else'。我不知道为什么。

在第 16 行,程序应该在屏幕上写 '5',但出现运行时错误。

另外,C++ 是区分大小写的语言,有没有办法不让 C++ 区分大小写?

FORTRAN.H 是:

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#define IF if(
#define THEN ){
#define ELSEIF } else if(
#define ELSE }else{
#define ENDIF }
#define if IF
#define then THEN
#define elseif ELSEIF
#define else ELSE
#define endif ENDIF
#define PROGRAM(x) main(){
#define program PROGRAM
#define END }
#define end END
#define STOP exit(0);
#define stop STOP
#define call
#define subroutine
#define recursive
#define function
#define FOR for(
#define for FOR
#define LOOP ){
#define loop LOOP
#define ENDFOR }
#define endfor ENDFOR
#define WHILE while(
#define DO ){
#define ENDDO }
#define enddo ENDDO
#define PRINT(t) std::cout<<
#define _ <<
#define READ std::cin>>
#define $ >>
#define Read READ
#define read READ
#define Print PRINT
#define print PRINT
#define selectcase(x) switch(x){
#define endselectcase }
#define endfunction }
#define code {
typedef char character;
typedef int integer;
typedef double doubleprecision;
typedef float real;

char* function __FORTRAN_WRITE_ARGS(const char* f) code
    integer i;
    std::__cxx11::string arg = "";

    if f[0] != '(' || f[strlen(f)-1] != ')' then
        return "";
    endif

    for i = 0; i < strlen(f); i++ loop
        selectcase(f[i])
            case ' ':
                continue;
                break;
            case '(':
                continue;
                break;
            case ')':
                continue;
                break;
            case ',':
                continue;
                break;
            case 'I':
                if f[i+1] >= 48 && f[i+1] <= 57 then
                    arg += "%";
                    arg += f[i+1];
                    arg += "d";
                else
                    arg += "%d";
                endif

                break;
            default:
                continue;
        endselectcase
    endfor
    char retval[arg.length()] = "";
    strcat(retval, arg.c_str());
    return retval;
endfunction
#define write(t, f) printf(__FORTRAN_WRITE_ARGS(f),
#define endwrite )
#define WRITE write
#define precision

有没有办法解决这个问题或这个错误?

【问题讨论】:

  • 您可以只在您的代码上运行预处理器并查看预处理器生成的内容:Can gcc output C code after preprocessing?(其他编译器应该可以使用类似的选项)
  • 不幸的是,C++ 语言在定义上是区分大小写的,就像许多其他语言一样。请参阅此link 了解更多信息。如果你想成为一名多语言程序员,你必须克服这个障碍。

标签: c++


【解决方案1】:

虽然我喜欢这个项目的想法,但目前的实施存在缺陷,我不确定您是否能够获得 100% 的转化。 fortran.h 使用了一些旧的、已弃用的做法,并包含两个实际的编译错误。

当您通过预处理器运行代码时,主要问题(您提出这个问题的原因)显而易见。

int main(){
    if( 3 == 3 ){
        std::cout<< "Your PC is fine.";
    } }else{ if(( 3 == 4 ){  // *** The issue you're having ***
        std::cout<< "Your PC is broken.";
    }else{
        std::cout<< "Your PC is trash.";
    }

    printf(__FORTRAN_WRITE_ARGS("(I)"), 5);
}

ELSEIF(我消除了大多数小写变体)被替换,但不是您想要的方式。 ELSEIF 进行了替换,但是您已经完成了 #define else ELSE#define if IF。这显然与真正的 C++ 冲突,并且您进行了双重替换,从而创建了损坏的代码。

下面是我修改过的fortran.h 和main.cpp。值得在我的 fortran.h 上运行一个 diff 以确切了解我所做的更改。它现在可以编译,但仍然损坏。说我的电脑没问题后打印垃圾。我在您的 WRITE 函数上四处寻找,但为了保留您的语法(这可能是不正确的,我不知道 Fortran,但 '()' 不匹配),我想不出任何合理的东西。它可能需要嵌套宏调用。一个用于生成字符串,另一个用于将字符串实际替换到printf 语句中。在弄清楚这一点时,仅预处理器标志-E 将成为您的朋友,以查看您尝试的替换是否有效。

fortran.h

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>

#define IF if(
#define THEN ){
#define ELSEIF } else if(
#define ELSE }else{
#define ENDIF }
#define PROGRAM(x) int main(){
#define program PROGRAM
#define END }
#define end END
#define STOP exit(0);
#define stop STOP
#define call
#define subroutine
#define recursive
#define function
#define FOR for(
#define LOOP ){
#define ENDFOR }
#define WHILE while(
#define DO ){
#define ENDDO }
#define PRINT(t) std::cout<<
#define _ <<
#define READ std::cin>>
#define $ >>
#define selectcase(x) switch(x){
#define endselectcase }
#define endfunction }
#define CODE {
typedef char character;
typedef int integer;
typedef double doubleprecision;
typedef float real;

char* function __FORTRAN_WRITE_ARGS(const char* f) CODE
    integer i;
    std::string arg = "";  // Removed __cx11, not needed

    IF f[0] != '(' || f[strlen(f)-1] != ')' THEN
        return "";
    ENDIF

    FOR i = 0; i < strlen(f); i++ LOOP
        selectcase(f[i])
            case ' ':
            case '(':
            case ')':
            case ',':
                continue;
                break;
            case 'I':
                IF f[i+1] >= 48 && f[i+1] <= 57 THEN
                    arg += "%";
                    arg += f[i+1];
                    arg += "d";
                ELSE
                    arg += "%d";
                ENDIF

                break;
            default:
                continue;
        endselectcase
    ENDFOR
    char retval[arg.length() + 1];  // Removed pointless initialization, fixed size
    for (auto& I : retail) i = '\0';  // null character initialization
    strncpy(retval, arg.c_str(), arg.length());
    return retval;
endfunction
#define write(t, f) printf(__FORTRAN_WRITE_ARGS(f),
#define endwrite )
#define WRITE write
#define precision

主要

#include "fortran.h"  // Not a system include for me, so changed to " "

real function f() CODE
    return 0.0;
endfunction

program(main)
    IF 3 == 3 THEN
        PRINT(*) "Your PC is fine.";
    ELSEIF 3 == 4 THEN
        PRINT(*) "Your PC is broken.";
    ELSE
        PRINT(*) "Your PC is trash.";
    ENDIF

    write(*, "(I)") 5);
END

如果最终目标是使用 fortran 语法合法地编写 C++ 代码,而不是为了新奇的东西,我会说迅速放弃这个想法,而只是学习 C++。

【讨论】:

  • 关于“将 fortran 语法用于新颖性之外的东西”可能值得注意的是,问题的代码远非 Fortran 语法。唯一与 Fortran 语法匹配的非空行是 elseendifendfunctionend
  • 是的,很高兴知道。我根本不了解 Fortran,而且我认为自己不需要学习它。不过,如果我曾经这样做过,我只会使用 Fortran。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多