如何用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 04 Python
探究Python多进程编程下线程之间变量的共享问题
May 05 Python
总结python爬虫抓站的实用技巧
Aug 09 Python
发布你的Python模块详解
Sep 15 Python
python判断列表的连续数字范围并分块的方法
Nov 16 Python
python实现图片彩色转化为素描
Jan 15 Python
详解重置Django migration的常见方式
Feb 15 Python
检测tensorflow是否使用gpu进行计算的方式
Feb 03 Python
Python基于数列实现购物车程序过程详解
Jun 09 Python
Python extract及contains方法代码实例
Sep 11 Python
Python中字符串对象语法分享
Feb 24 Python
Python之matplotlib绘制折线图
Apr 13 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或asp创建网页桌面快捷方式的代码
2010/03/23 PHP
php函数之子字符串替换&amp;#65279; str_replace
2011/03/23 PHP
ThinkPHP项目分组配置方法分析
2016/03/23 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
thinkphp分页集成实例
2017/07/24 PHP
浅谈thinkphp5 instance 的简单实现
2017/07/30 PHP
js弹窗代码 可以指定弹出间隔
2010/07/03 Javascript
lyhucSelect基于Jquery的Select数据联动插件
2011/03/29 Javascript
javascript firefox 自动加载iframe 自动调整高宽示例
2013/08/27 Javascript
jQuery 获取浏览器所在的IP地址的小例子
2013/11/08 Javascript
js中document.write的那点事
2014/12/12 Javascript
JS实现的文字与图片定时切换效果代码
2015/10/06 Javascript
动态加载JavaScript文件的两种方法
2016/04/22 Javascript
jQuery中each()、find()和filter()等节点操作方法详解(推荐)
2016/05/25 Javascript
jquery事件绑定解绑机制源码解析
2016/09/19 Javascript
AngularJS 过滤器(自带和自建)详解
2016/09/19 Javascript
微信小程序 es6-promise.js封装请求与处理异步进程
2017/06/12 Javascript
react-router4 配合webpack require.ensure 实现异步加载的示例
2018/01/18 Javascript
vue 弹框产生的滚动穿透问题的解决
2018/09/21 Javascript
React-redux实现小案例(todolist)的过程
2019/09/29 Javascript
一篇文章带你浅入webpack的DLL优化打包
2020/02/20 Javascript
Python和Perl绘制中国北京跑步地图的方法
2016/03/03 Python
Python scipy的二维图像卷积运算与图像模糊处理操作示例
2019/09/06 Python
关于python pycharm中输出的内容不全的解决办法
2020/01/10 Python
Python基于os.environ从windows获取环境变量
2020/06/09 Python
基于Python采集爬取微信公众号历史数据
2020/11/27 Python
python3.7中安装paddleocr及paddlepaddle包的多种方法
2020/11/27 Python
会计电算化专业毕业生自荐信
2013/12/20 职场文书
学校安全检查制度
2014/01/27 职场文书
《富饶的西沙群岛》教学反思
2014/04/09 职场文书
2014最新党员违纪检讨书
2014/10/12 职场文书
迁户口计划生育证明
2014/10/19 职场文书
防溺水主题班会教案
2015/08/12 职场文书
Golang生成Excel文档的方法步骤
2021/06/09 Golang
部分武汉产收音机展览
2022/04/07 无线电
HttpClient实现文件上传功能
2022/08/14 Java/Android