#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. U盘,移动硬盘显示显示需要格式化怎么修复

    冷静别怕,用windows系统自带磁盘修复CHKDSK命令即可解决此问题. 首先,在开始菜单栏站到“运行”窗口,也就是c:\(命令提示符),win7可直接在开始菜单的搜索窗口中输入“cmd”. 其次, ...

  2. Leecode刷题之旅-C语言/python-434 字符串中的单词数

    /* * @lc app=leetcode.cn id=434 lang=c * * [434] 字符串中的单词数 * * https://leetcode-cn.com/problems/numbe ...

  3. [转]Web登录中的信心安全问题

    1. 一个简单的HTML例子看看用户信息安全 标准的HTML语法中,支持在form表单中使用<input></input>标签来创建一个HTTP提交的属性,现代的WEB登录中, ...

  4. ASP.NET的服务端验证(干货)

    最近有项目需要使用.net的web,啥也不说,直接开始学习.net的mvc框架.感觉微软的web项目其实还是很好用的,今天和大家分享一下服务端验证的事情.其实原理就是用到了c#的特性,特性不用多说,大 ...

  5. xshell sftp可用命令,sftp: cannot open d: to write![解决]

    sftp可用命令: cd 路径 更改远程目录到“路径” lcd 路径 更改本地目录到“路径” chgrp group path 将文件“path”的组更改为“group” chmod mode pat ...

  6. 20155210潘滢昊 2016-2017-2 《Java程序设计》第4周学习总结

    20155210 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 extends:单一继承. 抽象方法.抽象类: abstract:Java中有抽象方法的类一 ...

  7. 20155222 2016-2017-2 《Java程序设计》第4周学习总结

    20155222 2016-2017-2 <Java程序设计>第4周学习总结 教材学习内容总结 子类会继承父类的private成员,但是无法直接存取,必须通过父类提供的方法. 多态就是使用 ...

  8. # 2016-2017-2 20155319 《Java程序设计》实验四Android程序开发实验报告

    2016-2017-2 20155319 <Java程序设计>实验四Android程序开发实验报告 实验一 实验内容 Android Stuidio的安装测试: 参考<Java和An ...

  9. 20145207《Java程序设计》实验二(Java面向对象程序设计)实验报告

    <Java程序设计>实验二(Java面向对象程序设计)实验报告 目录 改变 Java面向对象程序设计实验要求 实验成果 课后思考 改变 看了下之前实验二的整体,很搞笑,大图+代码,没了.. ...

  10. C#基础之委托

    委托常常和事件在一起使用,可以理解委托是方法的容器,事件则是委托的另一种表现形式.委托和事件虽然写得还比较多,不过也只是用的熟练而已,趁周末没课好好巩固下基础,一点一点积累吧. 1.一个简单的小例子 ...