3.4 词法分析 --- DFA的代码表示

DFA 的代码表示
概念上讲,DFA是一个有向图
实际上有不同的DFA的代码表示
转移表(类似于邻接矩阵)
哈希表
跳转表

取决于在实际实现中,对时间空间的权衡

转移表:

在这里插入图片描述
在这里插入图片描述
这个表的行,是所有字符,比分a,b,c,…
这个表的列,是所有状态, q0,q1
可以编码成 2 * 3的矩阵

char table[M][N] //默认256  M,N 是确定的 M是构造DFA不同状态的个数, N 是256
table[0]['a'] = 1
table[1]['b'] = 1
table[1]['c'] = 1
其他的表项都是 error 的表项

在这里插入图片描述

转移表 char table[M][N]
词法分析器的驱动代码,这个负责从文本文件中读输入,根据这个表项的内容做相应的控制
来回答给定的输入(就是一方面读入字符串,一方面查这个表,回答这个字符串是否能被这个表接受)

驱动代码:

nextToken() //下一个单词,每当调用这个函数就会返回
  state =0; //自动机上目前走到的状态
  stack = []
  while(state!=ERROR) //如果状态是有效状态进入循环
  {
    c = getchar() //读一个用户给定的输入
    if(state is ACCEPT) //有些状态是接受状态
       clear(stack)     //清空状态
    push(stack)         //把状态压栈
    state = table[state][c] //查表看state可以转换到什么地方
  }
  
  while(state is not ACCEPT)
  state = pop()  
  rollback     //把刚刚读入的字符串重新塞回字符流里面
  //算法执行 会识别到 abc 字符串
  
  //算法执行过程: 用户给定输入: "abcabc\0"
 
第 0 次 拿字符a   -->是在q0 起始状态的
  |  |
  |  |
  ----
   c = getchar()  拿到用户第一个输入,
    push(stack)   0号状态压入栈顶
    state = table[state][c] 0输入字符查表是a返回1
堆栈:
  |   |
  | 0 |
  -----  
 
第 1 次 拿字符b  -->是在 q1 状态的
  if(state is ACCEPT) //有些状态是接受状态
       clear(stack)     //清空状态
堆栈清空:
  |  |
  |  |
  ----
   push(stack)   0号状态压入栈顶
    state = table[state][c] 0输入字符查表是a返回1
  |   |
  | 1 |
  -----  
 
第 2 次 拿字符 b  -->是在 q1 状态的
   if(state is ACCEPT) //有些状态是接受状态
       clear(stack)     //清空状态
堆栈清空:
  |  |
  |  |
  ----
   push(stack)   0号状态压入栈顶
    state = table[state][c] 0输入字符查表是a返回1
  |   |
  | 1 |
  -----  
  
 新一轮拿到是 a  -->是在 q1  状态的
 但是这个状态  q1 中的 a 表项是空(error)所以就跳出了循环
   while(state!=ERROR)
 到了下一个循环 就识别出字符串 abc
 

在这个算法中特别要注意的是 stack = [] 这样一个栈数据结构
它是为了实现词法分析器或者说程序语言中经常出现的概念叫做最长匹配
最长匹配:如果一个程序设计语言有关键字 if,ifif 那么我们做词法分析是把他识别成两个关键字 if if 还是识别成一个
关键字 ifif 。

在这里插入图片描述
结论:
为了支持最长匹配的规定,我们在这里需要一个栈,它每次都以接受状态为栈顶向前尝试的
步骤作为 栈的元素,一旦尝试失败这个栈会回滚到最近的接受状态上面来

跳转表:

nextToken()
 state = 0
 stack = []
 goto q0       //q0 内部实际相当于 wilie 中的一次循环
 
q0:
  c = getchar()
   if(state is ACCEPT) //有些状态是接受状态
       clear(stack)     //清空状态
    push(stack)         //把状态压栈
    if(c=='a')          //非常明确接受状态 a 
      goto q1:

q1:
   c = getchar()
   if(state is ACCEPT) //有些状态是接受状态
       clear(stack)     //清空状态
    push(stack)         //把状态压栈
    if(c=='b'|| c=='c')          //非常明确接受状态 a 
      goto q1:
  
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值