got NUM(1)
Is NUM(1) an expr?
Is NUM(1) a term?
Is NUM(1) a number?
is_term got -(-)
-(-) was back
is_expr got -(-)
is_expr got NUM(2)
Is NUM(2) an expr?
Is NUM(2) a term?
Is NUM(2) a number?
is_term got *(*)
is_term got NUM(33)
Is NUM(33) a term?
Is NUM(33) a number?
is_term got None
is_expr got None import ply.lex as lex # pip install ply
tokens = ('NUM',); t_NUM = r'\d+'; literals = ['+', '-', '*', '/']
t_ignore = ' \t'
def t_error(t): raise SyntaxError()
lexer = lex.lex()
prev_tk = None
def get_tk(who):
global prev_tk
if prev_tk != None: tk = prev_tk; prev_tk = None
else: tk = lexer.token()
if tk == None: print('\t', who + ' got None')
else: print('\t', who + ' got ' + tk.type + '(' + tk.value + ')')
return tk
def put_token_back(tk):
global prev_tk
prev_tk = tk
print('\t', tk.type + '(' + tk.value + ') was back')
def print_token(tk, what, i): print(i * ' ', 'Is ' + tk.type + '(' + tk.value + ') ' + what + '?', sep='')
def Tk(fn, *args, **kwargs): fn(*args, **kwargs)
def is_NUM(tk, i):
print_token(tk, 'a number', i)
if tk.type != 'NUM': raise SyntaxError()
def is_term(tk, i):
'''t : NUM | NUM '*' t | NUM '/' t'''
print_token(tk, 'a term', i)
Tk(is_NUM, tk, i + 1)
tk = get_tk('is_term')
if tk == None: return
if tk.type == '*' or tk.type == '/': Tk(is_term, get_tk('is_term'), i + 1)
else: put_token_back(tk)
def is_expr(tk, i):
'''e : t | t '+' e | t '-' e'''
if tk == None:
if i == 0: return
raise SyntaxError()
print_token(tk, 'an expr', i)
Tk(is_term, tk, i + 1)
tk = get_tk('is_expr')
if tk == None: return
t = tk.type
if t == '+' or t == '-': Tk(is_expr, get_tk('is_expr'), i + 1)
lexer.input('1 - 2*33')
try: Tk(is_expr, get_tk(''), 0)
except SyntaxError: print('\nAbout what talking you are?')

产生式是一组规则。分析时不是根据规则产生语言去和输入比较,而是检查输入是否符合规则。所以我觉得函数名叫is_expr比expr好理解点。再如:Tom是主语吗?Tom是名词吗?it是代词吗?头一句:token 是 表达式。a)只看了头一个token; b)这个命题是真命题还是假命题,let's try 一 try. 我们并没有分析并生成机器码/中间代码/语法树。分析过程中函数的递归调用关系/顺序靠堆栈表达。它隐藏着一颗动态的、不完整的树。

import ply.lex as lex # pip install ply
import ply.yacc as yacc
from functools import reduce
tokens = ('NUM',); t_NUM = r'\d+'; literals = ['+', '-', '*', '/']
def t_error(t): t.lexer.skip(1)
precedence = (('left', '+', '-'), ('left', '*', '/'))
s = []
def p_1(p): "e : NUM"; s.append(p_1.__doc__); p[0] = int(p[1])
def p_2(p): "e : e '+' e"; s.append(p_2.__doc__); p[0] = p[1] + p[3]
def p_3(p): "e : e '-' e"; s.append(p_3.__doc__); p[0] = p[1] - p[3]
def p_4(p): "e : e '*' e"; s.append(p_4.__doc__); p[0] = p[1] * p[3]
def p_5(p): "e : e '/' e"; s.append(p_5.__doc__); p[0] = p[1] / p[3]
def p_error(p): raise Exception()
lexer = lex.lex()
istr = '3 + 2 * 5'
print(istr, '=', yacc.yacc().parse(istr))
s.reverse(); print(reduce(lambda x,y:x+'\n'+y, s, ''))

上面这样的语法能写出Top down的吗?左递归是什么?请看 https://files.cnblogs.com/files/blogs/714801/topdownparsing.zip search(top down operator precedence parsing)

import ply.lex as lex # pip install ply
import ply.yacc as yacc
from functools import reduce
tokens = ('NUM',); t_NUM = r'\d+'; literals = ['+', '-', '*', '/']
def t_error(t): t.lexer.skip(1)
s = []
def p_1(p): "e : t"; s.append(p_1.__doc__); p[0] = p[1]
def p_2(p): "e : t '+' e"; s.append(p_2.__doc__); p[0] = p[1] + p[3]
def p_3(p): "e : t '-' e"; s.append(p_3.__doc__); p[0] = p[1] - p[3]
def p_4(p): "t : NUM"; s.append(p_4.__doc__ + ' ' + p[1]); p[0] = int(p[1])
def p_5(p): "t : NUM '*' t"; s.append(p_5.__doc__); p[0] = int(p[1]) * p[3]
def p_6(p): "t : NUM '/' t"; s.append(p_6.__doc__); p[0] = int(p[1]) / p[3]
def p_error(p): raise Exception()
lexer = lex.lex()
istr = '1 + 2 * 3 - 4'
print(istr, '=', yacc.yacc().parse(istr))
s.reverse(); print(reduce(lambda x,y:x+'\n'+y, s, ''))

自然语言式parsing的更多相关文章

  1. F#之旅9 - 正则表达式

    今天,cozy群有个群友发了条正则,问正则匹配相关的问题.虽然他的问题用html selector去处理可能更好,但是我也再一次发现:我忘了正则怎么写的了! 忘掉正则是有原因的,这篇文章会简单记录下F ...

  2. 【论文小综】基于外部知识的VQA(视觉问答)

    ​ 我们生活在一个多模态的世界中.视觉的捕捉与理解,知识的学习与感知,语言的交流与表达,诸多方面的信息促进着我们对于世界的认知.作为多模态领域的一个典型场景,VQA旨在结合视觉的信息来回答所提出的问题 ...

  3. NLP | 自然语言处理 - 解析(Parsing, and Context-Free Grammars)

    什么是解析? 在自然语言的学习过程,个人一定都学过语法,比如句子能够用主语.谓语.宾语来表示.在自然语言的处理过程中.有很多应用场景都须要考虑句子的语法,因此研究语法解析变得很重要. 语法解析有两个基 ...

  4. Python自然语言处理笔记【一】文本分类之监督式分类

    一.分类问题 分类是为了给那些已经给定的输入选择正确的标签. 在基本的分类任务中,每个输入都被认为与其他的输入是隔离的.每个类别的标签集是预先定义好的(只有把类别划分好了,才能给输入划分类别). 分类 ...

  5. Python自然语言处理笔记【二】文本分类之监督式分类的细节问题

    一.选择正确的特征 1.建立分类器的工作中如何选择相关特征,并且为其编码来表示这些特征是首要问题. 2.特征提取,要避免过拟合或者欠拟合 过拟合,是提供的特征太多,使得算法高度依赖训练数据的特性,而对 ...

  6. 转-Python自然语言处理入门

      Python自然语言处理入门 原文链接:http://python.jobbole.com/85094/ 分享到:20 本文由 伯乐在线 - Ree Ray 翻译,renlytime 校稿.未经许 ...

  7. python and 我爱自然语言处理

    曾经因为NLTK的 缘故开始学习Python,之后渐渐成为我工作中的第一辅助脚本语言,虽然开发语言是C/C++,但平时的很多文本数据处理任务都交给了Python.离 开腾讯创业后,第一个作品课程图谱也 ...

  8. 自然语言处理(NLP)相关学习资料/资源

    自然语言处理(NLP)相关学习资料/资源 1. 书籍推荐 自然语言处理 统计自然语言处理(第2版) 作者:宗成庆 出版社:清华大学出版社:出版年:2013:页数:570 内容简介:系统地描述了神经网络 ...

  9. NLP 自然语言处理之综述

    (1) NLP 介绍 NLP 是什么? NLP (Natural Language Processing) 自然语言处理,是计算机科学.人工智能和语言学的交叉学科,目的是让计算机处理或"理解 ...

随机推荐

  1. CSS 盒子的边距塌陷

    tip:为能更直观地学习,本文章已省略部分 css 样式代码. 我相信下面的情形大家在日常工作中常常碰到:在制作静态页面中,为了页面整体的协调与美观,我们想让子盒子 image-div 的上边沿距离父 ...

  2. CANN5.0黑科技解密 | 别眨眼!缩小隧道,让你的AI模型“身轻如燕”!

    摘要:CANN作为释放昇腾硬件算力的关键平台,通过深耕先进的模型压缩技术,聚力打造AMCT模型压缩工具,在保证模型精度前提下,不遗余力地降低模型的存储空间和计算量. 随着深度学习的发展,推理模型巨大的 ...

  3. centos 下安装docker

    官方文档比较累赘,简化就三步 1.安装依赖 yum -y install gcc gcc-c++ yum-utils device-mapper-persistent-data lvm2 2.添加re ...

  4. Swoft+Docker

    Docker 以下纯属个人理解: Docker就是一种虚拟机,将环境打包成镜像,等于做了一个Linux系统裁剪. 镜像就是我们安装系统的镜像,里面包含了你的代码和环境. 容器就是一个虚拟机,你可以用一 ...

  5. Linux初学者:从不同角度理解Linux系统

    在我初学Linux系统时,虽然已经掌握了一些命令,但总觉得还是很混乱.大家新买的笔记本如果是Windows系统,那么第一件事往往就是分区,目的就是将系统和软件分开.然而Linux却没有类似于Windo ...

  6. [python]django关闭debug

    1.版本声明 python3.6.5 django2.0.6 2.打开项目-setting setting.py中DEBUG默认是等于True,这样的话当访问接口存在错误会直接展示项目的所有配置信息, ...

  7. 《手把手教你》系列技巧篇(四十一)-java+ selenium自动化测试 - 处理iframe -上篇(详解教程)

    1.简介 原估计宏哥这里就不对iframe这个知识点做介绍和讲解了,因为前边的窗口切换就为这种网页处理提供了思路,另一个原因就是虽然iframe很强大,但是现在很少有网站用它了.但是还是有小伙伴或者童 ...

  8. Oracle Error while trying to retrieve text for error ORA-01804

    我在Linux上编译C++程序,有这个错误. 本机情况: Linux上Oracle的安装情况,服务器上有两个Client版本.我在Makefile中使用了高版本的动态库. 原因: 1.首先排查下 tn ...

  9. Swift学习笔记(一)

    1.Constants and Variables(常量和变量) let定义常量,var定义变量. [Note] If a stored value in your code won't change ...

  10. ICCV2021 | Vision Transformer中相对位置编码的反思与改进

    ​前言  在计算机视觉中,相对位置编码的有效性还没有得到很好的研究,甚至仍然存在争议,本文分析了相对位置编码中的几个关键因素,提出了一种新的针对2D图像的相对位置编码方法,称为图像RPE(IRPE). ...