m0_58082819 2023-09-29 11:33 采纳率: 50%
浏览 9
已结题

编译原理C++中提取文件中的记号进行分类时处理不了注释以及各种类型的数,以及不知道该如何进行mfc可视化界面布置(相关搜索:二进制|八进制|标识符)

编译原理相关问题:
编译环境:C++,MFC

/*
问题描述:
1. 把C++源代码中的各类单词(记号)进行拼装分类。
          C++语言包含了几种类型的单词(记号):标识符,关键字,数(包括整数、浮点数),字符串、注释、特殊符号(分界符)和运算符号等【详细的单词类别及拼装规则见最底下图片】。
      2.要求应用程序应为Windows界面。
      3.打开一个C++源文件,列出所有可以拼装的单词(记号)。
测试样例:
运行效果样本

C++源程序:

Test.cpp

#include<iostream.h>
main()
{
   int i;
   cin>>i;
   if (i>3) cout<<“ok”;
}


扫描结果:
#       特殊符号
Include    关键字
<iostream. h>    特殊符号
main    关键字
(        特殊符号
)        特殊符号
{      特殊符号
int    关键字
 i      标识符
;       特殊符号
cin   关键字
>>    特殊符号
i       标识符
;       特殊符号
if      关键字       
(       特殊符号
i       标识符
>      特殊符号
3       数
)        特殊符号
cout   关键字
<<     特殊符号
“ok”   串
;        特殊符号
}        特殊符号
*/




测试文件如下:
测试用例.txt:(未通过)
// ConsoleApplication81.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include<iomanip>
#include<algorithm>
#include<map>
#include<set>
using namespace std;
int next1[4][2] = { {1,0},{-1,0},{0,1},{0,-1} };
/*asfsdfsdfsdf*/
int main()
{
    int _abc;
    int _a123;
    int _____a;
    int _ABC;
    int _A12;
    int A;
    int b;
    int A12;
    int b12;
    int x = 0b1001;//二进制
    int y = 074;//八进制
    cout << y;
    int z = 0xa3;//16进制
    double e = 1.e-3;
    double f = 5e2f;
    double F = 5e2F;
    int B = 0B1001;
    int Z = 0XA3;
    double h = 1.0e-3;
    double g = 1e1;
    double o = 1.e3;
    double u = 1e3;
    double t = .12;
    int r = +1;
    int ab = -1;
    double E = -1.e-3;
    cout << t;
    int startState = 1;
    int state = startState;
    bool quit = false;
    while (quit == false)
    {
        for (int k = 0; k < 4; k++)
        {
            r += 1;
        }
        char ch = cin.get(); //ch属于[a-z] 
        switch (state)
        {
        case 1:
            switch (ch)
            {
            case 'a':
                state = 2;
                break;
            default:
                cout << "错误:出现意料外的字符!" << endl;
                cout << "匹配提前终止." << endl;
                quit = true;
                break;
            }
            break;
       
    }

}

标识符测试.txt:(通过)
a_bc
a_BC
abc
a12
A43b
A224B
aasg21B
_123ACB
_12abc
_abc12
_abc
_123
a_123
A_213
___________a
a_____b213
关键字测试.txt:(通过)
do while include define ifndef alignas alignof and and_eq asm auto 
bitand bitor bool break case catch char char8_t char16_t char32_t 
class compl concept const const_cast consteval constexpr constinit 
continue co_await co_return co_yield decltype default delete do 
double dynamic_cast else enum explicit export extern false float
for friend goto if inline int long mutable namespace new noexcept
not not_eq nullptr operator or or_eq private protected public register 
reinterpret_cast requires return short signed sizeof static static_assert 
static_cast struct switch template this thread_local throw true try typedef 
typeid typename union unsigned using
数字测试.txt:(未通过)
//整数
23;

//正整数、正浮点数
+434;
+4123.4213;
+.13123;
+0.12412;

//负整数、负浮点数

-431;
-213.124124;
-.1213;
-0.3114;

//科学计数法表示数
1.e-3;
52e232f;
512e22F;
1.0e-3213;
1e1;
12.e3;
321e31;
132.e-3;

//正科学计数法表示数
+1.e-3;
+52e232f;
+512e22F;
+1.0e-3213;
+1e1;
+12.e3;
+321e31;
+132.e-3;

//负科学计数法表示数
-1.e-3;
-52e232f;
-512e22F;
-1.0e-3213;
-1e1;
-12.e3;
-321e31;
-132.e-3;

//二进制数
0B01010
0b1110111

//八进制数
072

//十六进制数
0x1234567890ABCDEF
0X1234567890ABCDEF
特殊符号测试.txt:(通过)
new & && # reinterpret_cast - ; << typeid *= ( &= ~ ^ . -- * .* 
static_cast sizeof ) [ % > throw ? | \\ , ] >>= :: < ->* } dynamic_cast 
! / || { -> " ^= $ == : 
delete <= ?: = ++ <<= >> -= |= != \' const_cast >= +
 


目前自己编写的还不具有可视化界面以及未能成功检测注释,各种表示方法的数(正数,负数,科学计数法表示的数)的代码:

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

const vector<string> Keywords = {
    "include", "auto", "const", "double", "float", "int", "short", "struct", "unsigned", "enum",
    "break", "continue", "else", "for", "long", "signed", "switch", "void", "case", "default",
    "goto", "register", "sizeof", "typedef", "volatile", "char", "do", "extern", "if", "return",
    "static", "union", "while", "asm", "dynamic_cast", "bool", "explicit", "new", "static_cast", "typeid",
    "catch", "false", "operator", "template", "typename", "class", "friend", "private", "this", "using",
    "const_cast", "inline", "public", "throw", "virtual", "delete", "mutable", "protected", "true", "wchar_t",
    "namespace", "reinterpret_cast", "try", "cin", "cout"
};

bool isAlpha(char c) {
    return isalpha(c) || c == '_';
}

bool isDigit(char c) {
    return isdigit(c);
}

bool isSpace(char c) {
    return isspace(c);
}

bool isKeyword(const string& word) {
    return find(Keywords.begin(), Keywords.end(), word) != Keywords.end();
}

bool isOperator(char c) {
    return c == '+' || c == '-' || c == '*' || c == '/' || c == '=' || c == '&' || c == '|' || c == '!';
}

void processWord(const string& word) {
    if (isKeyword(word)) {
        cout << word << "\t\t关键字" << endl;
    }
    else {
        cout << word << "\t\t标识符" << endl;
    }
}

void processNumber(const string& number) {
    cout << number << "\t\t数值" << endl;
}

void processOperator(char c) {
    string op;
    op += c;
    char nextChar = cin.peek();
    if ((c == '+' || c == '-' || c == '=') && nextChar == c) {
        op += nextChar;
        cin.ignore();  // 忽略下一个字符
    }
    cout << op << "\t\t运算符号" << endl;
}

void processComment() {
    char c = cin.get();
    char nextChar = cin.peek();

    if (nextChar == '/') {
        cin.ignore(numeric_limits<streamsize>::max(), '\n');  // 忽略到行尾的所有字符
        cout << "//\t\t注释" << endl;
    }
    else if (nextChar == '*') {
        cin.ignore();  // 忽略 '*'
        while (true) {
            c = cin.get();
            nextChar = cin.peek();
            if (c == '*' && nextChar == '/') {
                cin.ignore();  // 忽略 '/'
                break;
            }
        }
        cout << "/*...*/\t\t注释" << endl;
    }
}

int main() {
    string input;
    char c;

    cout << "请选择需要分析的源文件:1,程序内置源文件;2,输入文件的路径" << endl;
    int choose;
    cin >> choose;

    if (choose == 2) {
        cout << "请输入文件路径: ";
        cin >> input;
        ifstream file(input);

        if (!file.is_open()) {
            cout << "无法打开文件!" << endl;
            return 1;
        }

        while (file.get(c)) {
            if (isAlpha(c)) {
                string word;
                word += c;
                while (file.get(c) && (isAlpha(c) || isDigit(c))) {
                    word += c;
                }
                file.unget();  // 将最后一个字符放回流中
                processWord(word);
            }
            else if (isDigit(c)) {
                string number;
                number += c;
                while (file.get(c) && (isDigit(c) || c == '.')) {
                    number += c;
                }
                file.unget();  // 将最后一个字符放回流中
                processNumber(number);
            }
            else if (isSpace(c)) {
                continue;  // 忽略空格
            }
            else if (c == '/' && (file.peek() == '/' || file.peek() == '*')) {
                file.unget();  // 将 '/' 字符放回流中
                processComment();
            }
            else if (isOperator(c)) {
                processOperator(c);
            }
        }
        file.close();
    }
    else {
        cout << "程序内置源文件分析:" << endl;
        cin.ignore();  // 忽略前一个输入的换行符

        while (cin.get(c)) {
            if (isAlpha(c)) {
                string word;
                word += c;
                while (cin.get(c) && (isAlpha(c) || isDigit(c))) {
                    word += c;
                }
                cin.unget();  // 将最后一个字符放回流中
                processWord(word);
            }
            else if (isDigit(c)) {
                string number;
                number += c;
                while (cin.get(c) && (isDigit(c) || c == '.')) {
                    number += c;
                }
                cin.unget();  // 将最后一个字符放回流中
                processNumber(number);
            }
            else if (isSpace(c)) {
                continue;  // 忽略空格
            }
            else if (c == '/' && (cin.peek() == '/' || cin.peek() == '*')) {
                cin.unget();  // 将 '/' 字符放回流中
                processComment();
            }
            else if (isOperator(c)) {
                processOperator(c);
            }
        }
    }

    return 0;
}

img

img

img

img

img

img

  • 写回答

7条回答 默认 最新

  • [PE]经典八炮 2023-09-29 11:50
    关注

    只是为了做题的话,可以考虑用正则表达式

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 9月29日
  • 创建了问题 9月29日