如何用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 相关文章推荐
简单的编程0基础下Python入门指引
Apr 01 Python
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
Apr 25 Python
基于python requests库中的代理实例讲解
May 07 Python
详解pandas如何去掉、过滤数据集中的某些值或者某些行?
May 15 Python
Django实现微信小程序的登录验证功能并维护登录态
Jul 04 Python
Python利用requests模块下载图片实例代码
Aug 12 Python
Python爬虫爬取煎蛋网图片代码实例
Dec 16 Python
python实现异常信息堆栈输出到日志文件
Dec 26 Python
详解用Python爬虫获取百度企业信用中企业基本信息
Jul 02 Python
Win10环境中如何实现python2和python3并存
Jul 20 Python
python将数据插入数据库的代码分享
Aug 16 Python
Python3爬虫ChromeDriver的安装实例
Feb 06 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
DOTA2 探索永无止境 玩家自创强悍插眼攻略
2020/04/20 DOTA
php.ini中的php-5.2.0配置指令详解
2008/03/27 PHP
php adodb介绍
2009/03/19 PHP
php错误级别的设置方法
2013/06/17 PHP
JS文本获得焦点清除文本文字的示例代码
2014/01/13 Javascript
js加入收藏以及使用Jquery更改透明度
2014/01/26 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
JavaScript实现图片自动加载的瀑布流效果
2016/04/11 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
用jQuery实现可输入多选下拉组合框实例代码
2017/01/18 Javascript
Vue2.0用 watch 观察 prop 变化(不触发)
2017/09/08 Javascript
JS库particles.js创建超炫背景粒子插件(附源码下载)
2017/09/13 Javascript
jQuery ajax仿Google自动提示SearchSuggess功能示例
2019/03/28 jQuery
微信小程序云函数使用mysql数据库过程详解
2019/08/07 Javascript
JS立即执行的匿名函数用法分析
2019/11/04 Javascript
Nodejs文件上传、监听上传进度的代码
2020/03/27 NodeJs
JavaScript实现无限轮播效果
2020/11/19 Javascript
[01:08:32]DOTA2-DPC中国联赛 正赛 DLG vs PHOENIX BO3 第二场 1月18日
2021/03/11 DOTA
python数据库操作常用功能使用详解(创建表/插入数据/获取数据)
2013/12/06 Python
Python爬取读者并制作成PDF
2015/03/10 Python
python图像常规操作
2017/11/11 Python
Django Rest framework权限的详细用法
2019/07/25 Python
下载官网python并安装的步骤详解
2019/10/12 Python
基于python解线性矩阵方程(numpy中的matrix类)
2019/10/21 Python
wxpython+pymysql实现用户登陆功能
2019/11/19 Python
python常用运维脚本实例小结
2020/02/14 Python
整理HTML5移动端开发的常用触摸事件
2016/04/15 HTML / CSS
微软俄罗斯官方网站:Microsoft俄罗斯
2016/09/18 全球购物
水果超市创业计划书
2014/01/27 职场文书
违反工作纪律检讨书
2014/02/15 职场文书
预备党员思想汇报1000字
2014/10/07 职场文书
2014年银行个人工作总结
2014/12/05 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
伏羲庙导游词
2015/02/09 职场文书
公路施工安全责任书
2015/05/08 职场文书
Redis IP地址的绑定的实现
2021/05/08 Redis