如何用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深入学习之对象的属性
Aug 31 Python
用Python遍历C盘dll文件的方法
May 06 Python
Python json 错误xx is not JSON serializable解决办法
Mar 15 Python
Python3计算三角形的面积代码
Dec 18 Python
python 时间信息“2018-02-04 18:23:35“ 解析成字典形式的结果代码详解
Apr 19 Python
Scrapy框架爬取Boss直聘网Python职位信息的源码
Feb 22 Python
Python数据类型之Tuple元组实例详解
May 08 Python
选择Python写网络爬虫的优势和理由
Jul 07 Python
Python爬虫爬取煎蛋网图片代码实例
Dec 16 Python
Python tensorflow实现mnist手写数字识别示例【非卷积与卷积实现】
Dec 19 Python
Python pip install如何修改默认下载路径
Apr 29 Python
python使用建议与技巧分享(一)
Aug 17 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中利用substr_replace将指定两位置之间的字符替换为*号
2011/01/27 PHP
Thinkphp使用mongodb数据库实现多条件查询方法
2014/06/26 PHP
thinkphp分页集成实例
2017/07/24 PHP
Javascript调用XML制作连动下拉列表框
2006/06/25 Javascript
js下写一个事件队列操作函数
2010/07/19 Javascript
页面js遇到乱码问题的解决方法是和无法转码的情况
2014/04/30 Javascript
Javascript中神奇的this
2016/01/20 Javascript
jQuery树形插件jquery.simpleTree.js用法分析
2016/09/05 Javascript
AngularJS实现树形结构(ztree)菜单示例代码
2016/09/18 Javascript
JS ES6中setTimeout函数的执行上下文示例
2017/04/27 Javascript
jQuery动画_动力节点节点Java学院整理
2017/07/04 jQuery
nodejs初始化init的示例代码
2018/10/10 NodeJs
Node.js从字符串生成文件流的实现方法
2019/08/18 Javascript
微信小程序列表时间戳转换实现过程解析
2019/10/12 Javascript
[26:40]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第一局
2016/02/25 DOTA
python实现的阳历转阴历(农历)算法
2014/04/25 Python
利用Python命令行传递实例化对象的方法
2016/11/02 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
对python中的高效迭代器函数详解
2018/10/18 Python
python使用pandas处理大数据节省内存技巧(推荐)
2019/05/05 Python
PyQt5实现QLineEdit添加clicked信号的方法
2019/06/25 Python
python二分法查找算法实现方法【递归与非递归】
2019/12/06 Python
Python基于Tkinter编写crc校验工具
2020/05/06 Python
keras 读取多标签图像数据方式
2020/06/12 Python
HTML5标签嵌套规则详解【必看】
2016/04/26 HTML / CSS
捷克浴室和厨房设备购物网站:SIKO
2018/08/11 全球购物
Footshop乌克兰:运动鞋的最大选择
2019/12/01 全球购物
金融专业求职信
2014/08/05 职场文书
森马旗舰店双十一营销方案
2014/09/29 职场文书
党员自我剖析材料(群众路线)
2014/10/06 职场文书
学校捐书倡议书
2015/04/27 职场文书
Nginx服务器如何设置url链接
2021/03/31 Servers
php 原生分页
2021/04/01 PHP
OpenCV-Python模板匹配人眼的实例
2021/06/08 Python
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL
「偶像大师 MILLION LIVE!」七尾百合子手办开订
2022/03/21 日漫