如何用python写一个简单的词法分析器


Posted in Python onDecember 18, 2018

编译原理老师要求写一个java的词法分析器,想了想决定用python写一个。

目标

能识别出变量,数字,运算符,界符和关键字,用excel表打印出来。

有了目标,想想要怎么实现词法分析器。

1.先进行预处理,把注释,多余的空格,空行去掉。

2.一行一行扫描,行里逐字扫描,把界符和运算符当做分割符,遇到就先停下开始判断。

  • 若是以 英文字母、$、下划线开头,则可能是变量和关键字,在判断是关键字还是变量。
  • 若是数字开头,则判断下一位是不是也是数字,直到遇到非数字停止,在把数字取出来。
  • 再来判断分割符是什么类型,是界符还是运算符。

在给不同词添加上识别码

在用excel表打印出来。

代码实现

 1. 用列表创建一个关键字表,java关键字有50个。

#保留字
key_word = ['abstract','assert','boolean','break','byte',
      'case','catch','char','class','const',
      'continue','default','do','double','else',
      'enum','extends','final','finally','float',
      'for','goto','if','implements','import',
      'instanceof','int','interface','long','native',
      'new','package','private','protected','public',
      'return','short','static','strictfp','super',
      'switch','synchronized','this','throw','throws',
      'transient','try','void','volatile','while']

2.用列表创建一个运算符表。

#运算符
operator = ['+','-','*','/','%','++','--','+=','-=','+=','/=',#算术运算符
      '==','!=','>','<','>=','<=',#关系运算符
      '&','|','^','~','<<','>>','>>>',#位运算符
      '&&','||','!',#逻辑运算符
      '=','+=','-=','*=','/=','%=','<<=','>>=','&=','^=','|=',#赋值运算符
      '?:']#条件运算符

3. 用列表创建一个界符表。

#界符
delimiters = ['{','}','[',']','(',')','.',',',':',';']

4.预处理

用正则表达式把注释去掉,在把多余的空行去掉

#预处理
def filterResource(file,new_file):
  f2 = open(new_file,'w+')
  txt = ''.join(open(file,'r').readlines())
  deal_txt = re.sub(r'\/\*[\s\S]*\*\/|\/\/.*','',txt) 
  for line in deal_txt.split('\n'):
      line = line.strip()
      line = line.replace('\\t','')
      line = line.replace('\\n','')
      if not line:
        continue
      else:
        f2.write(line+'\n')
  f2.close()
  return sys.path[0]+'\\'+ new_file

5.逐行扫描

按照刚刚的思路进行判断,把每一行的单词,添加到word_line列表中,最后在把每一行添加到token列表中。

def Scan(file):
  lines = open(file,'r').readlines()
  for line in lines:
    word = ''
    word_line = []
    i = 0
    while i <len(line):
      word +=line[i]
      if line[i]==' ' or line[i] in delimiters or line[i] in operator:
        if word[0].isalpha() or word[0]=='$' or word[0]=='_':
          word = word[:-1]
          if searchReserve(word):
            # 保留字
            word_line.append({word[:-1]:key_word.index(word)})
          else:
            # 标识符
            identifier.append({word:-2})
            word_line.append({word:-2})
        # 常数
        elif word[:-1].isdigit():
          word_line.append({word:-1})
        #else:
          #error_word.append(word)
        # 字符是界符
        if line[i] in delimiters:
          word_line.append({line[i]:len(key_word)+delimiters.index(line[i])})
        # 字符是运算符
        elif line[i] in operator:
          s = line[i] +line[i+1]
          if s in operator:
            word_line.append({s:len(key_word)+len(delimiters)+operator.index(s)})
            i +=1
          else:
            word_line.append({line[i]:len(key_word)+len(delimiters)+operator.index(line[i])})
        word = ''
      i+=1
    token.append(word_line)

6.根据单词返回是什么类型

按照保留字--界符--运算符--常数的顺序来当识别码。常数识别码是-1,标识符识别码是-2

def check(number):
  hanzi = ''
  q = len(key_word)
  w = len(delimiters)
  e = len(operator)
  if 0<number<=q:
    hanzi = '保留字'
  elif q<number <= q+w:
    hanzi = '界符'
  elif q+w<number <=q+w+e:
    hanzi = '运算符'
  elif number == -1:
    hanzi ='常数'
  elif number == -2:
    hanzi ='标识符'
  return hanzi

7. 用thinker写一个简单的界面

导入

from tkinter import * 
from tkinter.filedialog import askdirectory,askopenfilename
root = Tk()
  root.title('词法分析')
  root.resizable(0, 0)
  path = StringVar() 
  Label(root,text = "目标路径:").grid(row = 0, column = 0) 
  Entry(root, textvariable = path).grid(row = 0, column = 1) 
  Button(root, text = "路径选择", command = openfiles).grid(row = 0, column = 2)
  Button(root,text='词法分析',command= open_excel).grid(row = 0,column = 3)
  root.mainloop()

打开文件

def openfiles():
  fname = askopenfilename(title='打开文件', filetypes=[('All Files', '*')])
  path.set(fname)

如何用python写一个简单的词法分析器

简单的界面

8.导入到excel表中

需要安装包xwings

pip install xwings

导入

import xlwings as xw

把token里的单词,按照 单词 ---- 识别码 ---类型 打印到excel表中

def open_excel():
  # 预处理
  row,col=0,0
  if path.get()!='':

    txt = java_analysis.filterResource(path.get(),new_file)
    print(txt)
    #扫描
    java_analysis.Scan(txt)
    app = xw.App(visible=True,add_book=False)
    wb =app.books.open(sys.path[0]+'\\'+'test.xlsx')
    sheet = wb.sheets.active
    sheet.clear() 
    print(java_analysis.token)
    for i in range(len(java_analysis.token)):
      sheet[row,0].value = '第'+str(i+1)+'行'
      row +=1
      for word in java_analysis.token[i]:
        for k,w in word.items():
          sheet[row,3].value = k
          sheet[row,5].value = w
          sheet[row,7].value = java_analysis.check(w)
        row +=1
    sheet.autofit()#整个sheet自动调整
    #wb.save()

最后就像这样

如何用python写一个简单的词法分析器

效果

代码很烂,不过也算是大致明白词法分析器了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
详细解析Python中的变量的数据类型
May 13 Python
Python贪心算法实例小结
Apr 22 Python
目前最全的python的就业方向
Jun 05 Python
Python实现App自动签到领取积分功能
Sep 29 Python
python实现对任意大小图片均匀切割的示例
Dec 05 Python
深度辨析Python的eval()与exec()的方法
Mar 26 Python
Python类中的魔法方法之 __slots__原理解析
Aug 26 Python
Pytorch evaluation每次运行结果不同的解决
Jan 02 Python
Python使用Tkinter实现转盘抽奖器的步骤详解
Jan 06 Python
利用django model save方法对未更改的字段依然进行了保存
Mar 28 Python
如何基于Python爬取隐秘的角落评论
Jul 02 Python
Python日志器使用方法及原理解析
Sep 27 Python
详解Python requests 超时和重试的方法
Dec 18 #Python
解决新django中的path不能使用正则表达式的问题
Dec 18 #Python
python 获取url中的参数列表实例
Dec 18 #Python
python 函数内部修改外部变量的方法
Dec 18 #Python
Python实现获取汉字偏旁部首的方法示例【测试可用】
Dec 18 #Python
python监测当前联网状态并连接的实例
Dec 18 #Python
Python实现繁体中文与简体中文相互转换的方法示例
Dec 18 #Python
You might like
php注入实例
2006/10/09 PHP
php escape URL编码
2008/12/10 PHP
让Nginx支持ThinkPHP的URL重写和PATHINFO的方法分享
2011/08/08 PHP
在WordPress中实现评论头像的自定义默认和延迟加载
2015/11/24 PHP
Linux安装配置php环境的方法
2016/01/14 PHP
PHP实现对xml进行简单的增删改查(CRUD)操作示例
2017/05/19 PHP
如何通过PHP实现Des加密算法代码实例
2020/05/09 PHP
JavaScript 函数调用规则
2009/09/14 Javascript
jquery 页眉单行信息滚动显示实现思路及代码
2014/06/26 Javascript
jQuery添加/改变/移除CSS类及判断是否已经存在CSS
2014/08/20 Javascript
javascript中的3种继承实现方法
2016/01/27 Javascript
jquery实现多次上传同一张图片
2017/01/09 Javascript
Vue.js 2.0中select级联下拉框实例
2017/03/06 Javascript
详解RequireJS按需加载样式文件
2017/04/12 Javascript
vue源码解析之事件机制原理
2018/04/21 Javascript
详解基于Vue-cli搭建的项目如何和后台交互
2018/06/29 Javascript
JS数组去重的6种方法完整实例
2018/12/08 Javascript
elementUI多选框反选的实现代码
2019/04/03 Javascript
js实现简易点击切换显示或隐藏
2020/11/29 Javascript
[46:14]完美世界DOTA2联赛PWL S3 Magma vs INK ICE 第一场 12.11
2020/12/16 DOTA
Python中的二叉树查找算法模块使用指南
2014/07/04 Python
Python中getattr函数和hasattr函数作用详解
2016/06/14 Python
Python虚拟环境项目实例
2017/11/20 Python
Python将list中的string批量转化成int/float的方法
2018/06/26 Python
Python socket实现的简单通信功能示例
2018/08/21 Python
Python批处理更改文件名os.rename的方法
2018/10/26 Python
Python中Numpy mat的使用详解
2019/05/24 Python
pygame实现俄罗斯方块游戏(基础篇2)
2019/10/29 Python
python 中的[:-1]和[::-1]的具体使用
2020/02/13 Python
加拿大领先家居家具网上购物:Aosom.ca
2020/05/27 全球购物
中兴通讯全球官方网站:ZTE
2020/12/26 全球购物
Java中实现多态的机制是什么?
2014/12/07 面试题
大学毕业感言一句话
2014/02/06 职场文书
工作证明范本(2篇)
2014/09/14 职场文书
对照检查剖析材料
2014/09/30 职场文书
MySQL令人咋舌的隐式转换
2021/04/05 MySQL