📌  相关文章
📜  LEX代码中的DFA,接受0的奇数和1的偶数(1)

📅  最后修改于: 2023-12-03 15:02:40.682000             🧑  作者: Mango

DFA for accepting odd number of 0s and even number of 1s in LEX code

在计算机科学中,确定的有限状态自动机(DFA)用于识别正则语言中的字符串。在这里,我们将使用LEX编写一个DFA,该DFA接受0的奇数和1的偶数。

正则表达式

我们先来定义这个正则表达式:

(1*01*01*)*0*

这里, (1*01*01*)* 表示在任何数量的1之间可以插入随意数量的0。我们用 0* 结尾,以接受任何数量的0。

状态转换图

下面是状态转换图:

                    0
                   ---->
    +-------+     |     +-------+
    |   q0  |     |     |   q1  |
--->|start  |-----+---->|final 1|
    +-------+           +-------+
      | ^    1             | ^    0
      | |__________       | |
      v              |      v |
    +-------+        |    +-------+
    |   q2  |        +--->|   q3  |
    |final 2|             |final 3|
    +-------+             +-------+
      | ^                   | ^  
      | |_________          | |  
      v             |         v |  
  0   ---          |      1  ---|  
<---+       |______|       +--->  
     |                     
     |_____0,1_____>

每个圆形表示DFA中的一个状态,并附有一个状态编号。在我们的DFA中,有4个状态,分别编号为q0、q1、q2和q3。

2个状态是最终状态(接受状态),分别编号为final 1和final 2,其他状态是非终态(不接受状态)。

从start状态出发,如果在遇到任何1之前,我们在其后跟随偶数个1和奇数个0,我们将进入final 1。如果在随后继续遇到任何数量的1和1之后的任何数量的0,那么我们将继续进入状态final 1。如果我们遇到偶数个1和奇数个0,我们将进入状态final 2。从任何状态,如果我们遇到0,我们将返回到开始状态q0。

LEX代码

下面是使用LEX编写的程序,该程序遵循上述状态转换图:

%{
// 定义状态
enum states {
    START,
    FINAL_ONE,
    FINAL_TWO,
    FINAL_THREE
};

%}

// 定义输入字符集(0或1)
%{
    0 { return '0'; }
    1 { return '1'; }
%}

%%

// 定义状态转换
{START} 0 {START}
{START} 1 {FINAL_ONE}
{FINAL_ONE} 0 {FINAL_TWO}
{FINAL_ONE} 1 {FINAL_THREE}
{FINAL_TWO} 0 {FINAL_ONE}
{FINAL_TWO} 1 {START}
{FINAL_THREE} 0 {FINAL_THREE}
{FINAL_THREE} 1 {FINAL_TWO}

// 忽略空格和换行
[ \n] {}

// 未定义的字符(非0和1)不被识别
. {}

%%

// main函数
int main() {
    yylex();
    return 0;
}
使用

生成代码,编译它,然后运行它即可:

$ lex dfa.l
$ gcc lex.yy.c -o dfa -ll
$ ./dfa

这将启动程序,等待从标准输入中读取输入。随意键入0和1的组合(没有空格或换行符),如果输入符合我们的正则表达式,程序将在终端输出一条消息。 例如,

101

这将打印:

String accepted!

如果输入不符合正则表达式,程序将保持沉默,等待下一个字符串。 例如,

11110

这将打印:


结论

这段代码演示了使用LEX编写DFA来识别正则语言的基础知识。 特别是,在此示例中,我们演示了如何识别0的奇数和1的偶数,并创建了一个状态转换图和LEX代码。 为了使用它,我们只需生成、编译和运行代码,然后输入希望检查其匹配性的字符串。