#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. Go语言反射之反射调用

    ## 1 概述利用反射,不仅可以获取信息,还可以创建实例,执行函数和方法.就是反射代理执行. <!-- more -->## 2 创建实例创建实例的前提是具有 `reflect.Type` ...

  2. 201552-53 《Java程序设计》第五周问题汇总

    201552-53 <Java程序设计>第五周问题汇总 1.编译时,终端显示: 注:XXX.java使用了未经检查或不安全的操作,如何解决? 解答:并不是错误,可以忽视. 2.构造函数与类 ...

  3. 20155216 2016-2017-2 《Java程序设计》第九周学习总结

    20155216 2016-2017-2 <Java程序设计>第九周学习总结 教材学习内容总结 JDBC架构 JDBC API的使用 JDBC连接数据库 1.导入JDBC包: 添加impo ...

  4. (三)虚拟机与Linux新尝试——20155306白皎

    (三)虚拟机与Linux新尝试--20155306白皎 一.关于虚拟机的安装 在选择虚拟机的类型和版本时,Ubuntu只有32位,没有64位 解决:通过百度,后来也发现同学们好多遇到了这个问题,因此通 ...

  5. 浅入tcp

    1.认识TCP tcp协议是传输层协议,它的最主要的3个特点是面向连接.可靠保证.基于字节流.当应用层把数据给tcp层时,注意如果数据大于MSS是要在tcp层进行分段的.tcp协议为了保证不丢包会给每 ...

  6. [agc011F]Train Service Planning-[线段树优化dp+神秘思考题]

    Description 传送门 Solution 请围观lhx大佬的博客(大佬写的太好了我都没有写的动力了em) Code #include<iostream> #include<c ...

  7. 关于网易云验证码V1.0版本的服务介绍

    服务介绍 易盾验证码是一个用于区分人和机器的通用验证码组件.传统的字符型验证码由于存在破解率高,用户体验不友好等问题,已不适用于现今的互联网环境.易盾验证码抛弃了传统字符型验证码展示-填写字符-比对答 ...

  8. 【word基础】如何取消word首字母大写

  9. Spring学习(六)-----Spring使用@Autowired注解自动装配

    Spring使用@Autowired注解自动装配 在上一篇 Spring学习(三)-----Spring自动装配Beans示例中,它会匹配当前Spring容器任何bean的属性自动装配.在大多数情况下 ...

  10. swift实现UItableview上拉下拉刷新模块

    最近用写个项目 发现上拉下拉刷新模块没找到合适的 so 自己写了一个 由于最近忙 教程就不写了 里面有 直接贴地址https://github.com/DaChengTechnology/DCRefr ...