#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. python基础知识你学会了多少

    前言 学习是一个循序渐进的过程,不在于你学了多少,而在于你学会了多少.(装个b好吧,hhhh) 知识总结 之前一直想在网上找一个总结好的笔记,但是一直都没有找到,因此下定决心要总结一下,里面的都是在学 ...

  2. 郁金香指标开源库的使用--(tulipindicators-0.8.4)

    瞎逛发现最新出了这么一个指标库,有100多种指标的函数库,文档写的比较好,重要的是作者一直在维护. 把它编成库,然后测试一下,可用于自动交易,策略交易等开发. 1.下载地址 https://githu ...

  3. [POJ1741]Tree(点分治)

    树分治之点分治入门 所谓点分治,就是对于树针对点的分治处理 首先找出重心以保证时间复杂度 然后递归处理所有子树 对于这道题,对于点对(u,v)满足dis(u,v)<=k,分2种情况 路径过当前根 ...

  4. 关于makefile中自动产生依赖的理解

    本博文是在学习了<GNU Make中文手册>后记录下来的自己的关于自动产生makefile依赖的语句的理解,向大家分享. <GNU make中文手册>中的相关章节见一下链接: ...

  5. 20155202 2016-2017-2 《Java程序设计》第1周学习总结

    20155202 2016-2017-2 <Java程序设计>第1周学习总结 考核方式于成绩构成 100分构成  翻转课堂考核12次(5*12 = 60):每次考试20-30道题目,考试 ...

  6. java Hibernate UUID代码

    package mypack; import java.io.Serializable; import java.net.InetAddress; /** * 唯一主键生成办法.从Hibernate中 ...

  7. 成都Uber优步司机奖励政策(4月15日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  8. python 多线程笔记(6)-- 生产者/消费者模式(续)

    用 threading.Event() 也可以实现生产者/消费者模式 (自己拍脑袋想出来的,无法知道其正确性,请大神告知为谢!) import threading import time import ...

  9. day 4 继承

    1.继承引入,减少代码量 1)版本1: class Animal: '''定义一个动物类''' def eat(self): print("----吃----") def drin ...

  10. 12、Java并发编程:阻塞队列

    Java并发编程:阻塞队列 在前面几篇文章中,我们讨论了同步容器(Hashtable.Vector),也讨论了并发容器(ConcurrentHashMap.CopyOnWriteArrayList), ...