如何用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中使用SQLite的简单教程
Apr 29 Python
python查找指定具有相同内容文件的方法
Jun 28 Python
Scrapy的简单使用教程
Oct 24 Python
python判断字符串是否是json格式方法分享
Nov 07 Python
Python中利用xpath解析HTML的方法
May 14 Python
Python实现将Excel转换成为image的方法
Oct 23 Python
python 字符串只保留汉字的方法
Nov 16 Python
在Pycharm中将pyinstaller加入External Tools的方法
Jan 16 Python
python并发编程 Process对象的其他属性方法join方法详解
Aug 20 Python
Python如何基于smtplib发不同格式的邮件
Dec 30 Python
pytorch查看模型weight与grad方式
Jun 24 Python
python绘制雷达图实例讲解
Jan 03 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
zf框架的session会话周期及次数限制使用示例
2014/03/13 PHP
PHP正则验证Email的方法
2015/06/15 PHP
无需数据库在线投票调查php代码
2016/07/20 PHP
PHP实现QQ快速登录的方法
2016/09/28 PHP
PHP使用Redis实现防止大并发下二次写入的方法
2017/10/09 PHP
javascript 全等号运算符使用说明
2010/05/31 Javascript
使用jQuery同时控制四张图片的伸缩实现代码
2013/04/19 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
把input初始值不写value的具体实现方法
2013/07/04 Javascript
js获取鼠标点击的位置实现思路及代码
2014/05/09 Javascript
JavaScript中Function详解
2015/02/27 Javascript
angularjs学习笔记之简单介绍
2015/09/26 Javascript
jquery显示隐藏元素的实现代码
2016/05/19 Javascript
Bootstrap使用基础教程详解
2016/09/05 Javascript
详解JavaScript调用栈、尾递归和手动优化
2017/06/03 Javascript
Vue2.0学习之详解Vue 组件及父子组件通信
2017/12/12 Javascript
echarts实现获取datazoom的起始值(包括x轴和y轴)
2020/07/20 Javascript
vue3.0自定义指令(drectives)知识点总结
2020/12/27 Vue.js
[49:43]VG vs FNATIC 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python通过正则表达式选取callback的方法
2015/07/18 Python
Python+微信接口实现运维报警
2016/08/27 Python
浅谈python中的实例方法、类方法和静态方法
2017/02/17 Python
python3中利用filter函数输出小于某个数的所有回文数实例
2019/11/24 Python
python画图时设置分辨率和画布大小的实现(plt.figure())
2021/01/08 Python
西班牙创意礼品和小工具网上商店:Curiosite
2016/07/26 全球购物
Habitat家居英国官方网站:沙发、家具、照明、厨房和户外
2019/12/12 全球购物
就业推荐自我鉴定
2013/10/06 职场文书
环保志愿者活动方案
2014/08/14 职场文书
六查六看个人剖析材料
2014/10/14 职场文书
大学生违纪检讨书300字
2014/10/25 职场文书
社区三八妇女节活动总结
2015/02/06 职场文书
2015年光棍节活动总结
2015/03/24 职场文书
童年读书笔记
2015/06/26 职场文书
运动员入场前导词
2015/07/20 职场文书
《折线统计图》教学反思
2016/02/22 职场文书
Spring Boot 实现敏感词及特殊字符过滤处理
2021/06/29 Java/Android