有穷状态机思想——注释转换

有穷状态机思想——注释转换

画状态转换图

所谓自动机思想就是假设有一台机器,上面有状态指示灯,作用是通过传送带前后改变通过的物体。

当状态灯保持时,货物按一定规则输出,当状态灯突变时,货物根据另一种规则输出。

利用这种思想,可以将所有有穷的状态列出来,大大清晰了思路,只需要往每一个状态里填对应的处理函数。

例如注释转换问题,把形如/**/的c风格注释转换为c++风格//注释。

如图,开始状态默认为不是注释,线上代表现状态进入下一状态需要读入的字符。
这里写图片描述

  1. 枚举状态

    c语言通过enum列举所有的状态。

  2. 先写出状态转换框架

    利用switch case语句和while循环配合,完成状态之间跳转。

  3. 添加动作函数

    在每一个case里写函数需要做的任务

    扫描二维码关注公众号,回复: 1434462 查看本文章
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef enum State {
    Normal,         //普通
    MayToAnn,       //可能成为注释
    CAnn,           //c注释
    CppAnn,         //c++注释
    MayToNor        //可能回到普通
}State;

void StateMachine()
{
    FILE *in = fopen("input.c", "r");
    FILE *out = fopen("test.c", "w");
    int ch;
    State state = Normal;
    while ((ch = fgetc(in)) != EOF)
    {
        switch (state)
        {
        case Normal:

            if (ch == '/') {
                state = MayToAnn;
            }
            else {
                state = Normal;
            }
            fputc(ch, out);
            printf("读入%c 状态变为:%d \n", ch, state);
            break;
        case MayToAnn:
            if (ch == '/') {
                state = CppAnn;
                fputc(ch, out);
            }
            else if (ch == '*') {
                state = CAnn;
                fputc('/', out);
            }
            else {
                state = Normal;
                fputc(ch, out);
            }

            printf("读入%c 状态变为:%d \n", ch, state);
            break;
        case CAnn:
            if (ch == '*') {
                state = MayToNor;
                //欠
                int tmp;
                tmp = fgetc(in);
                if (tmp == '/') {

                }
                else {
                    fputc(ch, out);
                }
                ungetc(tmp, in);
            }
            else {
                if (ch == '\n') {
                    fputc(ch, out);
                    fputc('/', out);
                    fputc('/', out);
                }
                else {
                    fputc(ch, out);
                }
                state = CAnn;

            }
            printf("读入%c 状态变为:%d \n", ch, state);
            break;
        case CppAnn:
            if (ch == '\n') {
                state = Normal;
            }
            else
                state = CppAnn;
            fputc(ch, out);
            printf("读入%c 状态变为:%d \n", ch, state);
            break;
        case MayToNor:
            if (ch == '*') {
                state = MayToNor;
                fputc(ch, out);
            }
            else if (ch == '/') {
                state = Normal;
                int tmp;
                tmp = fgetc(in);
                if (tmp == '\n') {

                }
                else {
                    fputc('\n', out);
                }
                ungetc(tmp, in);
            }
            else {
                state = CAnn;
                fputc(ch, out);
            }
            printf("读入%c 状态变为:%d \n", ch, state);
            break;
        default:
            break;
        }
    }
    fclose(in);
    fclose(out);
}

测试样例:

// 1.一般情况
/* int i = 0; */

// 2.换行问题
/* int i = 0; */int j = 0;
/* int i = 0; */
int j = 0;

// 3.匹配问题
/*int i = 0;/*xxxxx*/

// 4.多行注释问题
/*
int i=0;
int j = 0;
int k = 0;
*/int k = 0;

// 5.连续注释问题
/**//**/

// 6.连续的**/问题
/***/

// 7.C++注释问题
// /*xxxxxxxxxxxx*/

输出:

// 1.一般情况
// int i = 0; 

// 2.换行问题
// int i = 0; 
int j = 0;
// int i = 0; 
int j = 0;

// 3.匹配问题
//int i = 0;/*xxxxx

// 4.多行注释问题
//
//int i=0;
//int j = 0;
//int k = 0;
//
int k = 0;

// 5.连续注释问题
//
//

// 6.连续的**/问题
//*

// 7.C++注释问题
// /*xxxxxxxxxxxx*/

猜你喜欢

转载自blog.csdn.net/hanzheng6602/article/details/80370441