一个带有图形界面的C语言词法分析器,版本为Python2.7。

  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3. import sys
  4. from Tkinter import *
  5. from tkFont import *
  6. from FileDialog import *
  7.  
  8. KEYWORD_LIST = ['if', 'else', 'while', 'break', 'continue', 'for', 'double', 'int', 'float', 'long', 'short', 'bool',
  9. 'switch', 'case', 'return', 'void']
  10.  
  11. SEPARATOR_LIST = ['{', '}', '[', ']', '(', ')', '~', ',', ';', '.', '?', ':', ' ']
  12.  
  13. OPERATOR_LIST = ['+', '++', '-', '--', '+=', '-=', '*', '*=', '%', '%=', '->', '|', '||', '|=',
  14. '/', '/=', '>', '<', '>=', '<=', '=', '==', '!=', '!', '&']
  15.  
  16. CATEGORY_DICT = {
  17. # KEYWORD
  18. "far": 257,
  19. "near": 258,
  20. "pascal": 259,
  21. "register": 260,
  22. "asm": 261,
  23. "cdecl": 262,
  24. "huge": 263,
  25. "auto": 264,
  26. "double": 265,
  27. "int": 266,
  28. "struct": 267,
  29. "break": 268,
  30. "else": 269,
  31. "long": 270,
  32. "switch": 271,
  33. "case": 272,
  34. "enum": 273,
  35. "register": 274,
  36. "typedef": 275,
  37. "char": 276,
  38. "extern": 277,
  39. "return": 278,
  40. "union": 279,
  41. "const": 280,
  42. "float": 281,
  43. "short": 282,
  44. "unsigned": 283,
  45. "continue": 284,
  46. "for": 285,
  47. "signed": 286,
  48. "void": 287,
  49. "default": 288,
  50. "goto": 289,
  51. "sizeof": 290,
  52. "volatile": 291,
  53. "do": 292,
  54. "if": 293,
  55. "while": 294,
  56. "static": 295,
  57. "interrupt": 296,
  58. "sizeof": 297,
  59. "NULL": 298,
  60. # SEPARATOR
  61. "{": 299,
  62. "}": 300,
  63. "[": 301,
  64. "]": 302,
  65. "(": 303,
  66. ")": 304,
  67. "~": 305,
  68. ",": 306,
  69. ";": 307,
  70. ".": 308,
  71. "#": 309,
  72. "?": 310,
  73. ":": 311,
  74. # OPERATOR
  75. "<<": 312,
  76. ">>": 313,
  77. "<": 314,
  78. "<=": 315,
  79. ">": 316,
  80. ">=": 317,
  81. "=": 318,
  82. "==": 319,
  83. "|": 320,
  84. "||": 321,
  85. "|=": 322,
  86. "^": 323,
  87. "^=": 324,
  88. "&": 325,
  89. "&&": 326,
  90. "&=": 327,
  91. "%": 328,
  92. "%=": 329,
  93. "+": 330,
  94. "++": 331,
  95. "+=": 332,
  96. "-": 333,
  97. "--": 334,
  98. "-=": 335,
  99. "->": 336,
  100. "/": 337,
  101. "/=": 338,
  102. "*": 339,
  103. "*=": 340,
  104. "!": 341,
  105. "!=": 342,
  106. "sizeof": 343,
  107. "<<=": 344,
  108. ">>=": 345,
  109. "inum": 346,
  110. "int16": 347,
  111. "int8": 348,
  112. "char": 350,
  113. "string": 351,
  114. "bool": 352,
  115. "fnum": 353,
  116. "IDN": 354
  117. }
  118.  
  119. current_row = -1
  120. current_line = 0
  121. out_line = 1
  122.  
  123. def getchar(input_str):
  124. global current_row
  125. global current_line
  126. current_row += 1
  127.  
  128. if current_row == len(input_str[current_line]):
  129. current_line += 1
  130. current_row = 0
  131.  
  132. if current_line == len(input_str) - 1:
  133. return 'SCANEOF'
  134.  
  135. return input_str[current_line][current_row]
  136.  
  137. def ungetchar(input_str):
  138. global current_row
  139. global current_line
  140. current_row = current_row - 1
  141. if current_row < 0:
  142. current_line = current_line - 1
  143. current_row = len(input_str[current_row]) - 1
  144. return input_str[current_line][current_row]
  145.  
  146. def error(msg, line=None, row=None):
  147. global out_line
  148. if line is None:
  149. line = current_line + 1
  150. if row is None:
  151. row = current_row + 1
  152. analysis.insert(str(out_line) + '.0', str(line) + ':' + str(row) + 'Error: ' + msg)
  153. analysis.insert(str(out_line) + '.end', "\n")
  154. out_line = out_line + 1
  155.  
  156. def scanner(input_str):
  157. global current_line
  158. global current_row
  159. current_char = getchar(input_str)
  160. if current_char == 'SCANEOF':
  161. return ('SCANEOF', '', '')
  162. if current_char.strip() == '':
  163. return
  164. if current_char.isdigit():
  165. int_value = 0
  166. while current_char.isdigit():
  167. int_value = int_value * 10 + int(current_char)
  168. current_char = getchar(input_str)
  169. if current_char not in OPERATOR_LIST and current_char not in SEPARATOR_LIST and current_char != 'e':
  170. line = current_line + 1
  171. row = current_row + 1
  172. # ungetchar(input_str)
  173. error('illigal identifier', line, row)
  174. # return ('SCANEOF', '', '')
  175. return ('', '', '')
  176. if current_char != '.' and current_char != 'e':
  177. ungetchar(input_str)
  178. return ('INUM', int_value, CATEGORY_DICT['inum'])
  179. if current_char == 'e':
  180. power_value = str(int_value) + 'e'
  181. current_char = getchar(input_str)
  182. if current_char == '+' or current_char == '-':
  183. power_value += current_char
  184. current_char = getchar(input_str)
  185. while current_char.isdigit():
  186. power_value += current_char
  187. current_char = getchar(input_str)
  188. if current_char not in OPERATOR_LIST and current_char not in SEPARATOR_LIST:
  189. line = current_line + 1
  190. row = current_row + 1
  191. # ungetchar(input_str)
  192. error('illigal const int value in power', line, row)
  193. # return ('SCANEOF', '', '')
  194. return ('', '', '')
  195. ungetchar(input_str)
  196. return ('INUM', power_value, CATEGORY_DICT['inum'])
  197. if current_char == '.':
  198. float_value = str(int_value) + '.'
  199. current_char = getchar(input_str)
  200. while current_char.isdigit():
  201. float_value += current_char
  202. current_char = getchar(input_str)
  203. if current_char not in OPERATOR_LIST and current_char not in SEPARATOR_LIST or current_char == '.':
  204. line = current_line + 1
  205. row = current_row + 1
  206. # ungetchar(input_str)
  207. error('illigal const float value', line, row)
  208. # return ('SCANEOF', '', '')
  209. return ('', '', '')
  210. ungetchar(input_str)
  211. return ('FNUM', float_value, CATEGORY_DICT['fnum'])
  212. if current_char.isalpha() or current_char == '_':
  213. string = ''
  214. while current_char.isalpha() or current_char.isdigit() or current_char == '_' and current_char != ' ':
  215. string += current_char
  216. current_char = getchar(input_str)
  217. if current_char == 'SCANEOF':
  218. break
  219. ungetchar(input_str)
  220. if string in KEYWORD_LIST:
  221. return (string, '', CATEGORY_DICT[string])
  222. else:
  223. return ('IDN', string, CATEGORY_DICT['IDN'])
  224.  
  225. if current_char == '\"':
  226. str_literal = ''
  227. line = current_line + 1
  228. row = current_row + 1
  229.  
  230. current_char = getchar(input_str)
  231. while current_char != '\"':
  232. str_literal += current_char
  233. current_char = getchar()
  234. if current_char == 'SCANEOF':
  235. error('missing terminating \"', line, row)
  236. current_line = line
  237. current_row = row
  238. return ('SCANEOF', '', '')
  239. return ('STRING_LITERAL', str_literal, CATEGORY_DICT['string'])
  240.  
  241. if current_char == '/':
  242. next_char = getchar(input_str)
  243. line = int(current_line) + 1
  244. row = int(current_row) + 1
  245. if next_char == '*':
  246. comment = ''
  247. next_char = getchar(input_str)
  248. while True:
  249. if next_char == 'SCANEOF':
  250. error('unteminated /* comment', line, row)
  251. return ('SCANEOF', '', '')
  252. if next_char == '*':
  253. end_char = getchar(input_str)
  254. if end_char == '/':
  255. return None
  256. if end_char == 'SCANEOF':
  257. error('unteminated /* comment', line, row)
  258. return ('SCANEOF', '', '')
  259. comment += next_char
  260. next_char = getchar(input_str)
  261. else:
  262. ungetchar(input_str)
  263. op = current_char
  264. current_char = getchar(input_str)
  265. if current_char in OPERATOR_LIST:
  266. op += current_char
  267. else:
  268. ungetchar(input_str)
  269. return ('OP', op, CATEGORY_DICT[op])
  270.  
  271. if current_char in SEPARATOR_LIST:
  272. return ('SEP', current_char, CATEGORY_DICT[current_char])
  273.  
  274. if current_char in OPERATOR_LIST:
  275. op = current_char
  276. current_char = getchar(input_str)
  277. if current_char in OPERATOR_LIST:
  278. op += current_char
  279. else:
  280. ungetchar(input_str)
  281. return ('OP', op, CATEGORY_DICT[op])
  282. else:
  283. error('unknown character: ' + current_char)
  284.  
  285. def fileloader():
  286. global root
  287. code.delete(1.0, END)
  288. fd = LoadFileDialog(root)
  289. filename = fd.go()
  290. fin = open(filename, "r")
  291. input_file = fin.read()
  292. input_lines = input_file[0].split("\n")
  293. code.insert(1.0, input_file)
  294. fin.close()
  295.  
  296. def lexer_analysis(input_str):
  297. global current_row
  298. global current_line
  299. global out_line
  300. current_row = -1
  301. current_line = 0
  302. analysis_result = []
  303.  
  304. while True:
  305. r = scanner(input_str)
  306. if r is not None:
  307. if r[0] == 'SCANEOF':
  308. break
  309. analysis_result.append(str(r[0]) + "\t\t" + str(r[1]) + "\t\t" + str(r[2]))
  310. return analysis_result
  311.  
  312. def lexer():
  313. input_str = []
  314. analysis.delete(1.0, END)
  315. input_raw = code.get(1.0, END)
  316. input_str = input_raw.split("\n")
  317. lexer_analysis(input_str)
  318.  
  319. out_line = 1
  320. result = lexer_analysis(input_str)
  321. for each in result:
  322. analysis.insert(str(out_line) + '.end', each)
  323. analysis.insert(str(out_line) + '.end', "\n")
  324. out_line = out_line + 1
  325.  
  326. def pre_interface():
  327.  
  328. global root
  329. global code
  330. global analysis
  331. root = Tk()
  332. code = Text(root, width=60, height=20, font=15)
  333. analysis = Text(root, width=60, height=20, font=15)
  334.  
  335. t = StringVar()
  336. t.set('Patrick的词法分析器')
  337. label = Label(root, textvariable=t, font=15)
  338. Analysis = Button(root, text='词法分析', command=lexer, font=15)
  339. load = Button(root, text=' 载入代码 ', command=fileloader, font=15)
  340. root.title("LEXER")
  341. label.pack(side=TOP)
  342. Analysis.pack(side=BOTTOM)
  343. load.pack(side=BOTTOM)
  344. code.pack(side=LEFT)
  345. analysis.pack(side=RIGHT)
  346. root.mainloop()
  347.  
  348. def main():
  349. pre_interface()
  350.  
  351. # lexer()
  352.  
  353. if __name__ == '__main__':
  354. main()

Python版C语言词法分析器的更多相关文章

  1. 编码的秘密(python版)

    编码(python版) 最近在学习python的过程中,被不同的编码搞得有点晕,于是看了前人的留下的文档,加上自己的理解,准备写下来,分享给正在为编码苦苦了挣扎的你. 编码的概念 编码就是将信息从一种 ...

  2. 豆瓣top250(go版以及python版)

      最近学习go,就找了一个例子练习[go语言爬虫]go语言爬取豆瓣电影top250,思路大概就是获取网页,然后根据页面元素,用正则表达式匹配电影名称.评分.评论人数.原文有个地方需要修改下patte ...

  3. 【Python】《大话设计模式》Python版代码实现

    <大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...

  4. python之 python 起源、语言特点

    一. 1.1  什么是 PythonPython 是一门优雅而健壮的编程语言,它继承了传统编译语言的强大性和通用性,同时也借鉴了简单脚本和解释语言的易用性.它可以帮你完成工作,而且一段时间以后,你还能 ...

  5. ROS Learning-011 beginner_Tutorials (编程) 编写 ROS 话题版的 Hello World 程序(Python版)

    ROS Indigo beginner_Tutorials-10 编写 ROS 话题版的 Hello World 程序(Python版) 我使用的虚拟机软件:VMware Workstation 11 ...

  6. 《大话设计模式》Python版代码实现

    上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界.<大话设计模式>的代码使用C#写成的 ...

  7. 自己动手实现智能家居之树莓派GPIO简介(Python版)

    [前言] 一个热爱技术的人一定向往有一个科技感十足的环境吧,那何不亲自实践一下属于技术人的座右铭:“技术改变世界”. 就让我们一步步动手搭建一个属于自己的“智能家居平台”吧(不要对这个名词抬杠啦,技术 ...

  8. 移动端自动化测试Appium 从入门到项目实战Python版☝☝☝

    移动端自动化测试Appium 从入门到项目实战Python版 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌)  说到APP自动化测试,Appium可是说是非常流 ...

  9. python调用C语言接口

    python调用C语言接口 注:本文所有示例介绍基于linux平台 在底层开发中,一般是使用C或者C++,但是有时候为了开发效率或者在写测试脚本的时候,会经常使用到python,所以这就涉及到一个问题 ...

随机推荐

  1. 基于4.5Framework web程序、SQLSERVER数据库打包

    原文:基于4.5Framework web程序.SQLSERVER数据库打包 估计很多朋友和我一样,对于C/S程序打包很熟悉,但对于B/S程序打包一头雾水... 最近公司要求我们把项目和数据库(SQL ...

  2. 开源的.Net ORM微型框架SuperHelper

    SuperHelper——灵活通用的.开源的.Net ORM微型框架 SuperHelper是博主利用业余时间编写的一个ORM微型框架,除了可以提高开发效率,与其它ORM框架相比,博主更加喜欢Supe ...

  3. LeetCode之Maximum Product Subarray

    1.(原文)问题描述 Find the contiguous subarray within an array (containing at least one number) which has t ...

  4. 安装WindowsXP操作系统(安装版) - 初学者系列 - 学习者系列文章

    本文主要介绍下Windows XP操作系统的安装. 1.             将光驱装入光驱.启动电脑,在开始界面按下DEL键,进入BIOS设置界面.将光驱设置为第一启动项.下面以虚拟机为例子. ...

  5. windows下架设SVN服务器并设置开机启动

    原文:windows下架设SVN服务器并设置开机启动 1.安装SVN服务器,到http://subversion.apache.org/packages.html上下载windows版的SVN,并安装 ...

  6. oracle中sql语句的优化

    oracle中sql语句的优化 一.执行顺序及优化细则 1.表名顺序优化 (1) 基础表放下面,当两表进行关联时数据量少的表的表名放右边表或视图: Student_info   (30000条数据)D ...

  7. 30个HTML初学者建议

    The most difficult aspect of running Nettuts+ is accounting for so many different skill levels. If w ...

  8. iis处理请求随记回顾

    ----http是无状态的, 每次http请求户不影响,都是独立的:不会记的上次请求: -------iis原理:输入地址--socket封装请求体报文--发送---iis解析封装响应体---返回: ...

  9. Web面试之JQuery

    程序员Web面试之JQuery   又到了一年一度的毕业季了,青春散场,却等待下一场开幕. 在求职大军中,IT行业的程序员.码农是工科类大学生的热门选择之一, 尤其是近几年Web的如火如荼,更是吸引了 ...

  10. [置顶] android调用第三方库——第四篇——调用多个第三方库

    0:前言: 在前面三篇中我们介绍了android调用第三方库的形式,在这一篇中我们介绍调用多个第三方库的Android.mk的写法,由于其他三篇介绍的很详细,这里只给出Android.mk的内容. [ ...