去除注释中的代码

    在编译原理中,源代码在转换为机器码之前,会经历一系列的处理步骤,其中之一就是预处理。预处理主要负责处理源代码文件中的预处理指令和文本替换工作,这包括宏定义的展开、文件包含的处理以及注释的删除等。具体到去除代码注释,这是预处理过程中的一个重要环节,其目的是清理掉程序中不会影响程序执行的辅助性文本,即注释部分,以便于后续的词法分析、语法分析和代码生成等步骤能够顺利进行。

方法一:直接实现

考虑C++中的注释:
1.单行注释://
2.多行注释:/* */
3.引号中的注释符号应该被视为字符串(直接去实现这里比较复杂,dfa方法解决了这一问题)

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

void remove_comments(ifstream& in, ofstream& out) {
    //引用传参,节省空间
    string line;
    bool multiline_comment = false;

    while (getline(in, line)) {
        //一次只处理一行代码
        int pos = 0;
        while (pos < line.length()) {
            if (!multiline_comment && line[pos] == '/' && pos + 1 < line.length() && line[pos + 1] == '*') {
                multiline_comment = true;
                pos += 2;
            }
            else if (multiline_comment && line[pos] == '*' && pos + 1 < line.length() && line[pos + 1] == '/') {
                multiline_comment = false;
                pos += 2;
            }
            else if (!multiline_comment && line[pos] == '/' && pos + 1 < line.length() && line[pos + 1] == '/') {
                break; // 忽略单行注释的代码
            }
            else if (!multiline_comment) {
                out << line[pos];
                pos++;
            }
            else {
                pos++;
                //忽略多行注释的中间部分
            }
        }

        if (!multiline_comment) {
            out << endl;
        }
    }
}

int main() {
    ifstream in("C:\\Users\\86183\\Desktop\\大二下考试\\编译原理\\input.cpp");
    ofstream out("C:\\Users\\86183\\Desktop\\大二下考试\\编译原理\\output.cpp");

    remove_comments(in, out);

    in.close();
    out.close();

    return 0;
}

方法二:使用有穷自动机(DFA)

该方法参考自这篇文章:http://t.csdnimg.cn/6hMPA

另外不懂DFA的原理的小伙伴可以看一下这篇文章:http://t.csdnimg.cn/m7iCB

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;

enum states
{
    S0 = 0,S1,S2,S3,S4,S5,S6
};

//只需要注意处理引号里面的注释符号

void remove_comments(ifstream& in, ofstream& out)
{
    /*读取完整的文件并存入字符串变量中*/
    string fileContents;
    char c;
    while (in.get(c)) {
        fileContents += c;
    }
    enum states curState = S0;
    enum states lastState = S0;
    char str;
    vector<char> tmp;
    for (int i = 0; i < fileContents.size(); i++)
    {
        str = fileContents[i];
        switch (curState)
        {
            case S0:
            {
                lastState = curState;
                if (str == '/')
                {
                    curState = S3;
                    //识别到第一个符号/的时候,还不能确定是否是注释,当识别到下一个/或者*的时候才能确定;
                    //因此此时需要把/和其后的内容放入一个额外的存储空间,那么该如何确认呢?注释最后识别完
                    //成的时候都会返回S0的状态,若上一个状态是S6,那么需要清空tmp;如果上一个状态是S5,那
                    //那么也需要清空tmp;但如果上一个状态是S3,就需要将tmp中的内容写入out。
                    tmp.push_back(str);
                }
                else if (str == '\"')
                {
                    curState = S1;
                    out << str;
                }
                else if (str == '\'')
                {
                    curState = S2;
                    out << str;
                }
                else
                {
                    out << str;
                }
                break;
            }

            case S1:
            {
                lastState = curState;
                out << str;
                if (str == '\"')
                {
                    curState = S0;
                }
                else
                {
                    curState = S1;
                }
                break;
            }

            case S2:
            {
                lastState = curState;
                out << str;
                if (str == '\'')
                {
                    curState = S0;
                }
                else
                {
                    curState = S2;
                }
                break;
            }

            case S3:
            {
                lastState = curState;
                tmp.push_back(str);
                if (str == '*')
                {
                    curState = S4;
                }
                else if (str == '/')
                {
                    curState = S6;
                }
                else
                {
                    curState = S0;
                    //out << str;如果在此时写入,会丢失/符号
                }
                break;
            }

            case S4:
            {
                lastState = curState;
                tmp.push_back(str);
                if (str == '*')
                {
                    curState = S5;
                }
                else
                {
                    curState = S4;
                }
                break;
            }

            case S5:
            {
                lastState = curState;
                tmp.push_back(str);
                if (str == '/')
                {
                    curState = S0;
                }
                else
                {
                    curState = S4;
                }
                break;
            }

            case S6:
            {
                lastState = curState;
                
                if (str == '\n')
                {
                    curState = S0;
                    out << endl;
                }
                else
                {
                    curState = S6;
                    tmp.push_back(str);
                }
                break;
            }

            default:
                break;
        }

        if (curState == S0 && !tmp.empty())
        {
           if (lastState == S3)
           {
                for (int i = 0; i < tmp.size(); i++)
                    out << tmp[i];
           }
           tmp.clear();
        }

    }
}

int main() {
    ifstream in("C:\\Users\\86183\\Desktop\\大二下考试\\编译原理\\input.cpp", ios_base::in);
    ofstream out("C:\\Users\\86183\\Desktop\\大二下考试\\编译原理\\output.cpp");
    //cout << "File open successfully." << endl;
    cout << "File contents without comments" << endl;
    remove_comments(in, out);
    in.close();
    out.close();
    
    return 0;
}

          喜欢的小伙伴还请点赞收藏,(❁´◡`❁)( o=^•ェ•)o ┏━┓


  • 20
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值