如何用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爬虫神器Beautiful Soup用法
Jan 20 Python
CentOS下使用yum安装python-pip失败的完美解决方法
Aug 16 Python
Python 获得13位unix时间戳的方法
Oct 20 Python
pandas把dataframe转成Series,改变列中值的类型方法
Apr 10 Python
Python实现动态添加属性和方法操作示例
Jul 25 Python
Python Excel处理库openpyxl使用详解
May 09 Python
python实现12306登录并保存cookie的方法示例
Dec 17 Python
基于python生成英文版词云图代码实例
May 16 Python
Python __slots__的使用方法
Nov 15 Python
python 如何对logging日志封装
Dec 02 Python
python opencv实现图像配准与比较
Feb 09 Python
python中出现invalid syntax报错的几种原因分析
Feb 12 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转义输出HTML到JavaScript
2015/03/27 PHP
PHP使用内置dir类实现目录遍历删除
2015/03/31 PHP
在Mac OS上编译安装Nginx+PHP+MariaDB开发环境的教程
2016/02/23 PHP
CI(CodeIgniter)框架中URL特殊字符处理与SQL注入隐患分析
2019/02/28 PHP
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
2013/01/27 Javascript
JS、jquery实现几分钟前、几小时前、几天前等时间差显示效果的代码实例分享
2014/04/11 Javascript
node.js中的path.isAbsolute方法使用说明
2014/12/08 Javascript
javascript实现漂亮的拖动层,窗口拖拽特效
2015/04/24 Javascript
基于jQuery+JSON的省市二三级联动效果
2015/06/05 Javascript
jQuery代码实现发展历程时间轴特效
2015/07/30 Javascript
JS控制按钮10秒钟后可用的方法
2015/12/22 Javascript
js接收并转化Java中的数组对象的方法
2016/08/11 Javascript
Javascript实现代码折叠功能
2016/08/25 Javascript
Javascript从数组中随机取出不同元素的两种方法
2016/09/22 Javascript
微信小程序 Canvas增强组件实例详解及源码分享
2017/01/04 Javascript
关于axios返回空对象的问题解决
2017/04/04 Javascript
JS实现换肤功能的方法实例详解
2019/01/30 Javascript
深入理解javascript prototype的相关知识
2019/09/19 Javascript
jquery使用echarts实现有向图可视化功能示例
2019/11/25 jQuery
vue 解决data中定义图片相对路径页面不显示的问题
2020/08/13 Javascript
详解vue v-model
2020/08/31 Javascript
[00:15]天涯墨客终极技能展示
2018/08/25 DOTA
python3.0 字典key排序
2008/12/24 Python
Python获取apk文件URL地址实例
2013/11/01 Python
Python爬虫信息输入及页面的切换方法
2018/05/11 Python
numpy基础教程之np.linalg
2019/02/12 Python
pytorch实现线性拟合方式
2020/01/15 Python
全球销量第一生发产品:Viviscal
2017/12/21 全球购物
高中生自我鉴定范文
2013/10/30 职场文书
阿德的梦教学反思
2014/02/06 职场文书
上班打牌检讨书
2014/02/07 职场文书
李敖北大演讲稿
2014/05/24 职场文书
班子四风对照检查材料思想汇报
2014/09/29 职场文书
2014乡党委副书记党建工作汇报材料
2014/11/02 职场文书
大雁塔英文导游词
2015/02/10 职场文书
淮阳太昊陵导游词
2015/02/10 职场文书