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. NavigationView使用简介

    Android支持直接创建带有NavigationView的Activity,这里主要介绍NavigationView的逻辑. NavigationView通常是跟DrawerLayout一起使用.D ...

  2. 转帖:新版vivado2019.2新增增量综合功能

    从 Vivado 2019.1 版本开始,Vivado 综合引擎就已经可以支持增量流程了.这使用户能够在设计变化较小时减少总的综合运行时间. Vivado IDE 和 Tcl 命令批处理模式都可以启用 ...

  3. populating-next-right-pointers-in-each-node-ii leetcode C++

    Follow up for problem "Populating Next Right Pointers in Each Node". What if the given tre ...

  4. 【java+selenium3】时间控件 (九)

    1.问题描述: 在应用selenium实现web自动化时,经常会遇到处理日期控件点击问题,手工很简单,可以一个个点击日期控件选择需要的日期,但自动化执行过程中,完全复制手工这样的操作就有点难了. 如图 ...

  5. selenium2.x 与 selenium3.x 最大区别

    一.selenium2.x 与 selenium3.x 最大区别 (1) 从3.0版本selenium开始使用火狐浏览器完成web自动化就需要用到驱动包了. (2) 而2.0版本的selenium使用 ...

  6. Robot Framework操作MySQL数据库

    1.安装databaselibrary.pymysql 通过cmd命令执行:pip install robotframework-databaselibrary cmd命令执行:pip install ...

  7. MyBatis-Plus 快速入门

    1.简介 MyBatis-Plus (简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发.提高效率而生. 1.1.特性 无侵入:只做增强不做改变, ...

  8. 2021广东省强网杯WriteUp

    个人赛 网络诈骗 参考 https://github.com/Heyxk/notes/issues/1 先把EnMicroMsg.db提出来 CompatibleInfo.cfg是0kb,用第一种方法 ...

  9. MyScript 开发文档

    一.IInk SDK runtime 1.1 引擎创建 1.2 对象释放 1.3 获取并设置配置 配置 访问配置 配置识别 二.文件存储 2.1 支持的内容的类型 2.2 模型结构 2.3 Conte ...

  10. CF285D.D. Permutation Sum

    CF285D. Permutation Sum 题目 大意 寻找a,b两个排列从0到n-1,有c[i]=(a[i]+b[i])%n+1,使得c[i]也为全排列的排列方式 思路 a中元素和b中元素的对应 ...