Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4584049
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Python/Ruby

2012-04-26 15:28:04

今天看regular expression,在文档中看到一个类似于解释编译器的小东西,十分elegant。
又把python的快速方便赞叹一次。Python can do anything!

  1. import collections
  2. import re

  3. Token = collections.namedtuple('Token', ['typ', 'value', 'line', 'column'])

  4. def tokenize(s):
  5.     keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
  6.     token_specification = [
  7.         ('NUMBER', r'\d+(\.\d*)?'), # Integer or decimal number
  8.         ('ASSIGN', r':='), # Assignment operator
  9.         ('END', r';'), # Statement terminator
  10.         ('ID', r'[A-Za-z]+'), # Identifiers
  11.         ('OP', r'[+*\/\-]'), # Arithmetic operators
  12.         ('NEWLINE', r'\n'), # Line endings
  13.         ('SKIP', r'[ \t]'), # Skip over spaces and tabs
  14.     ]
  15.     tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification) # 得到re
  16.     print(tok_regex)
  17.     get_token = re.compile(tok_regex).match   # 得到match对象
  18.     line = 1
  19.     pos = line_start = 0
  20.     mo = get_token(s)
  21.     while mo is not None:
  22.         typ = mo.lastgroup
  23.         # print(mo.groups(), typ) # 打印匹配结果,方便调试查看
  24.         if typ == 'NEWLINE': # 换行,pos在换行符的位置上,line_start 实际是上一行最后一个字符的位置
  25.             line_start = pos
  26.             line += 1
  27.         elif typ != 'SKIP':
  28.             val = mo.group(typ)
  29.             if typ == 'ID' and val in keywords:
  30.                 typ = val        # typ 换成语言关键词
  31.             yield Token(typ, val, line, mo.start()-line_start) # 每次返回打印,然后接着执行
  32.         pos = mo.end()
  33.         mo = get_token(s, pos)
  34.     if pos != len(s): #中间有不符合语法的字符,比如'&',就会报错
  35.         raise RuntimeError('Unexpected character %r on line %d' %(s[pos], line)) # %r - repr(), %s - str()

  36. statements = '''
  37.     IF quantity THEN
  38.         total := total + price * quantity;
  39.         tax := price * 0.05;
  40.     ENDIF;
  41. '''

  42. for token in tokenize(statements): # 这里返回generator,所以需要迭代
  43.     print(token)

通过这段代码,我们可以结合语境做语法分析,找错误。甚至更多。
阅读(1399) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~