#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int main()
{
    char p[30][30];//存放文法
    char q[30][30];
    int line=0;
    int n;
    int i,j;
    int count=0;
    int k,t=0;
    int flag=0;
    int l,m=0;
    char VN[30]={'\0'};//存放非终结符号
    char VT[30]={'\0'};//存放终结符号
    printf("请输入规则个数");
    scanf("%d",&n);
    line=n;
    for(i=0;i<30;i++)//给字符串数组p,q全部赋值为'\0'
        for(j=0;j<30;j++)
        {
            p[i][j]='\0';
            q[i][j]='\0';
        }
        printf("请输入文法:\n");
        for(i=0;i<line;i++)
        {
            scanf("%s",p[i]);
        }
        //把字符分为终结符和非终结符
        l=0;
        m=0;
        for(i=0;i<line;i++)
        {
            for(j=0;j<30&&(p[i][j]!='\0');j++) { //非终结符放入数组VN中
                if(p[i][j]<='z'&&p[i][j]>='a'||(p[i][j]<='9'&&p[i][j]>='0'))
                {
                    flag=0;
                    for(t=0;VN[t]!='\0';t++)
                    {
                        if(VN[t]==p[i][j])
                        {
                            flag=1;break;
                        }
                    }
                    if(flag==0)
                    {
                        VN[l]=p[i][j];
                        l++;
                    }
                }
                //终结符放在数组VT中
                if(p[i][j]<='Z'&&p[i][j]>='A')
                {
                    flag=0;
                    for(t=0;t<30&&(VT[t]!='\0');t++)
                    {
                        if(VT[t]==p[i][j])
                        {
                            flag=1;
                            break;
                        }
                    }
                    if(flag==0)
                    {
                        VT[m]=p[i][j];
                        m++;
                    }
                }
            }
        }
        //把规则右部分分离,放入数组q中
        count=0;
        k=0;
        for(i=0;i<line;i++)
        {
            for(j=4;j<30&&(p[i][j]!='\0');j++)
            {
                if((p[i][j]<='z'&&p[i][j]>='a')||(p[i][j]<='Z'&&p[i][j]>='A')||(p[i][j]<='9'&&p[i][j]>='0'))
                {
                    q[count][k]=p[i][j];
                    k++;
                }
                else
                {
                    count++;
                    k=0;
                }
            }
            count++;
            k=0;
        }
        //判断是确定的还是非确定的有穷状态自动机,并进行前半部分打印
        //判断依据:q数组中每一行字符串是否相同
        flag=0;
        for(i=0;i<count;i++)
        {
            for(j=i+1;j<count;j++)
            {
                if(strcmp(q[i],q[j])==0)
                {
                    flag=1;
                    break;
                }
            }
        }
        if(flag==1)
        {
            printf("是非确定的有穷状态自动机,即NFA\n\n");
            printf("构造的有穷状态自动机为:\n");
            printf("NFA   N=(K,E(总和的意思),M,{S},{Z})\n");
        }
        else
        {
            printf("是确定的有穷状态自动机,即DFA\n\n\n");
            printf("构造的有穷状态自动机为:\n");
            printf("DFA   N=(K,E(总和的意思),M,{S},{Z})\n");
        }
        printf("其中,\nK={S");
        for(i=0;i<30&&(VT!='\0');i++)
        {
            printf(",%c",VT[i]);
        }
        printf("}\n");
        printf("E={");
        for(i=0;i<30&&(VN[i]!='\0');i++)
        {
            printf("%c   ",VN[i]);
        }
        printf("}\n");
        //分离文法
        k=0;
        count=0;
        for(i=0;i<line;i++)
        {
            j=4;
            while(p[i][j]!='\0')
            {
                if(k<4)
                {
                    q[count][k]=p[i][k];
                    k++;
                }
                else
                {
                    if((p[i][j]<='z'&&p[i][j]>='a')||(p[i][j]<='Z'&&p[i][j]>='A')||(p[i][j]<='9'&&p[i][j]>='0'))
                    {
                        q[count][k]=p[i][j];
                        k++;
                        j++;
                    }
                    if(p[i][j]=='l')
                    {
                        count++;
                        k=0;
                        j++;
                    }
                }
            }
            count++;
            k=0;
        }
        printf("\n");
        //打印M后部分
        printf("M:\n");
        l=0;
        while(VN[l]!='\0')
        {
            printf("M(S,%c)={",VN[l]);
            for(i=0;i<30;i++)
            {
                for(j=4;j<30&&(q[i][j]!='\0');j++)
                {
                    if(VN[l]==q[i][j]&&(q[i][j+1]=='\0')&&(q[i][j-1]=='='))
                        printf("%c",q[i][0]);
                }
            }
            printf("}\t");
            l++;
        }
        printf("\n");
        l=0;k=0;
        while(VT[k]!='\0')
        {
            l=0;
            while(VN[l]!='\0')
            {
                printf("M(%c,%c)={",VT[k],VN[l]);
                for(i=0;i<30;i++)
                {
                    for(j=4;j<30&&(q[i][j]!='\0');j++)
                    {
                        if(VT[k]==q[i][j]&&VN[l]==q[i][j+1])
                            printf("%c",q[i][0]);
                    }
                }
                printf("}\t");
                l++;
            }
            k++;
            printf("\n");
        }
        system("pause");
}

正规文法转化DFA的更多相关文章

  1. 第九次作业 DFA最小化,语法分析初步

    1.将DFA最小化:教材P65 第9题 Ⅰ {1,2,3,4,5} {6,7} {1,2}b={1,2,3,4,5} 3,4}b={5} {6,7} Ⅱ {1,2}{3,4}{5} {6,7} 2.构 ...

  2. 把自动机用作 Key-Value 存储

    以前只有代码,最近简单写了一点文档: google code 上的链接(总是最新) 自动机是什么 DFA 的最小化 将 DFA 用做字典 无环DFA (ADFA, Acyclic DFA) 编译 内存 ...

  3. 有穷自动机(NFA、DFA)&正规文法&正规式之间的相互转化构造方法

    在编译原理(第三版清华大学出版社出版)中第三章的词法分析中,3.4.3.5.3.6小节中分别讲解了 1.什么是NFA(不确定的有穷自动机)和DFA(确定的有穷自动机) 2.如何将  不确定的有穷自动机 ...

  4. 如何将 不确定的有穷自动机(NFA) 转化为 确定的有穷自动机(DFA) 并将DFA最简化

    一.从NFA到DFA的转换 例如下图: DFA的每个状态都是一个由NFA中的状态构成的集合,即NFA状态集合的一个子集 r =aa*bb*cc* 二.从带有ε-边的NFA到DFA的转换 r=0*1*2 ...

  5. 编译原理-DFA与正规式的转化

  6. 湖大OJ-实验C----NFA转换为DFA

    实验C----NFA转换为DFA Time Limit: 1000ms, Special Time Limit:2500ms, Memory Limit:65536KB Total submit us ...

  7. 利用子集构造法实现NFA到DFA的转换

    概述 NFA非有穷自动机,即当前状态识别某个转换条件后到达的后继状态不唯一,这种自动机不便机械实现,而DFA是确定有限状态的自动机,它的状态转换的条件是确定的,且状态数目往往少于NFA,所以DFA能够 ...

  8. 使用DFA算法对敏感词进行过滤

    项目目录结构如下: 其中resources资源目录中: stopwd.txt :停顿词,匹配时间直接过滤. wd.txt:敏感词库. 1.WordFilter敏感词过滤类: package com.s ...

  9. 简单的词法设计——DFA模拟程序

    实验一.简单的词法设计--DFA模拟程序 一.实验目的 通过实验教学,加深学生对所学的关于编译的理论知识的理解,增强学生对所学知识的综合应用能力,并通过实践达到对所学的知识进行验证.通过对 DFA 模 ...

随机推荐

  1. 简单记录一下ruby 循环

    今天整理一下ruby中的循环用法: 备注:“do~end”部分也可以写做{~} 1.break:直接跳出整个循环 i= 0 ["perl","python",& ...

  2. Burp 之Intruder

    攻击类型: (1)Sniper:测试完第一个变量后,就测试下一个变量,一次向下测试,每次只测试一个变量 适用于单变量 (2)Battering ram:只有一个payload,该payload会同时测 ...

  3. Linux入门进阶第五天——用户管理(帐号管理 )上

    一.帐号与群组 关于使用者帐号: 用户的ID与帐号信息所在位置是 /etc/passwd,而管理密码的数据则是在 /etc/shadow 每个登陆的使用者至少都会取得两个 ID , 一个是使用者 ID ...

  4. Linux下IPC机制

    Linux下IPC机制 实践要求 研究Linux下IPC机制:原理,优缺点,每种机制至少给一个示例,提交研究博客的链接 共享内存 管道 FIFO 信号 消息队列 IPC 进程间通信(IPC,Inter ...

  5. ConfigurationManager 读写AppSettings键值对

    using System; using System.Configuration; namespace ConsoleApplication1 { class Program { static voi ...

  6. python 多线程笔记(6)-- 闭包

    在类里弄一个闭包出来 很多资料上说,类内部的变量有两种. 按定义所在的位置,分__init__上方的和__init__下方的 按内存所在的位置,分类的和实例的,或者说公共的和私有的 现在,我想在类里定 ...

  7. 【LG3320】[SDOI2015]寻宝游戏

    [LG3320][SDOI2015]寻宝游戏 题面 洛谷 题解 不需要建虚树的虚树2333... 贪心地想一下,起始节点肯定是在关键点上,访问顺序就是\(dfs\)序. 那么对于每次询问, \[ An ...

  8. 【BZOJ4016】[FJOI2014]最短路径树问题

    [BZOJ4016][FJOI2014]最短路径树问题 题面 bzoj 洛谷 题解 虽然调了蛮久,但是思路还是蛮简单的2333 把最短路径树构出来,然后点分治就好啦 ps:如果树构萎了,这组数据可以卡 ...

  9. vcruntime140.dll 丢失64位系统

    1. 下载VC Redistributable for VS2015,网址https://www.microsoft.com/en-us/download/confirmation.aspx?id=4 ...

  10. 无旋treap的区间操作实现

    最近真的不爽...一道维修数列就做了我1上午+下午1h+1晚上+晚上1h+上午2h... 一道不错的自虐题... 由于这一片主要讲思想,代码我放这里了 不会无旋treap的童鞋可以进这里 呵呵... ...