如何用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中使用smtplib和email模块发送邮件实例
Apr 22 Python
python中使用urllib2伪造HTTP报头的2个方法
Jul 07 Python
python任务调度实例分析
May 19 Python
Python正则表达式匹配中文用法示例
Jan 17 Python
pytorch 实现模型不同层设置不同的学习率方式
Jan 06 Python
pytorch1.0中torch.nn.Conv2d用法详解
Jan 10 Python
Python imutils 填充图片周边为黑色的实现
Jan 19 Python
Anaconda+Pycharm环境下的PyTorch配置方法
Mar 13 Python
解决django无法访问本地static文件(js,css,img)网页里js,cs都加载不了
Apr 07 Python
python 实现读取csv数据,分类求和 再写进 csv
May 18 Python
Python OpenCV之常用滤波器使用详解
Apr 07 Python
python基础之//、/与%的区别详解
Jun 10 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路由类
2016/05/29 PHP
JavaScript 字符串连接性能优化
2008/12/20 Javascript
不使用XMLHttpRequest实现异步加载 Iframe和script
2012/10/29 Javascript
JS Pro-深入面向对象的程序设计之继承的详解
2013/05/07 Javascript
jQuery中Ajax的get、post等方法详解
2015/01/20 Javascript
jq实现左侧显示图片右侧文字滑动切换效果
2015/08/04 Javascript
基于jQuery仿淘宝产品图片放大镜特效
2020/10/19 Javascript
解决vue跨域axios异步通信问题
2019/04/17 Javascript
Vue 实现分页与输入框关键字筛选功能
2020/01/02 Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
2020/04/25 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
2020/07/19 Javascript
使用httplib模块来制作Python下HTTP客户端的方法
2015/06/19 Python
使用Python判断质数(素数)的简单方法讲解
2016/05/05 Python
Python的装饰器用法学习笔记
2016/06/24 Python
Python中的迭代器与生成器高级用法解析
2016/06/28 Python
小小聊天室Python代码实现
2016/08/17 Python
Python 使用SMTP发送邮件的代码小结
2016/09/21 Python
浅析使用Python操作文件
2017/07/31 Python
Python 读取图片文件为矩阵和保存矩阵为图片的方法
2018/04/27 Python
Python numpy.zero() 初始化矩阵实例
2019/11/27 Python
python创建ArcGIS shape文件的实现
2019/12/06 Python
Pytorch之卷积层的使用详解
2019/12/31 Python
浅析Python __name__ 是什么
2020/07/07 Python
Python selenium环境搭建实现过程解析
2020/09/08 Python
python实现企业微信定时发送文本消息的示例代码
2020/11/24 Python
经济实惠的豪华背包和行李袋:Packs Project
2018/10/17 全球购物
Edwaybuy西班牙:小米在线商店
2019/12/04 全球购物
KTV的创业计划书范文
2014/02/02 职场文书
销售主管岗位职责
2014/02/08 职场文书
初三学习决心书
2014/03/11 职场文书
历史专业大学生职业生涯规划书
2014/03/13 职场文书
医学生就业推荐表自我鉴定
2014/03/26 职场文书
本科生求职信
2014/06/17 职场文书
go语言中http超时引发的事故解决
2021/06/02 Golang
Pycharm远程调试和MySQL数据库授权问题
2022/03/18 MySQL
Spring依赖注入多种类型数据的示例代码
2022/03/31 Java/Android