stream, parser, 文法的一些概念

15 篇文章 0 订阅

stream就是个Iterable<Unit>,最基础的unit是bit,对应二进制流,

从二进制流到character流Iteralbe<Character>是encoding解决的问题,

再往上一个层次是token流,或者word流

1)基础的tokenize就是自然token,即按分隔符切割的,alphabet字符(a-z,1-9等)和非alphabet字符(空格,标点,括号等。

2)自然token不一定是和合法的token,token还必须是语言接受的(预定义的),英文字典里没有的单词就是非法英文单词,再者,像中文这种没有空格分隔的语言,是不存在自然token的,必须用预定义的某种规则识别。

预定义的方式可以是像英文词典那样的有限的,罗列出所有实例,还有一个例子是程序语言的关键字集合;更多是用规则定义,即所谓formal language的概念,就是可以用有限的规则定义出无限的集合。比如正则表达式。规则往往不只一种,一种规则对应一种类型的token。

比如程序语言里,当前字符流是以int开始的,可以解读为identifier,也可以解读为keyword,这里就有一个问题,用哪个规则去匹配呢,有两个原则

1)规则是有优先级的,或者说有顺序的,按顺序一个一个试,前面的匹配了,就不用考虑后面的规则了

2)匹配多长问题,优先匹配长的,比如 “==”,单等号可以赋值匹配运算符,双等号可以匹配比较运算符,匹配长的,即双等号。

这一部分叫词法分析,lexical analysis、tokenize,输出是一个合法的token stream:Iterable<Token>。注意token即包含了分出的词的文本,也包含了类别信息,这一点和01流到Character流不同,Character是没有类别的,token除了文本还有类别,(动词?名词?冠词?)

之前都是从一种流到另一种流

01流 ---encoding--> Character流 --tokenize---> token流

之后的parse部分,不再是输出另一种流,不再是一种线性结构,而是树结构,语法树。这里用到的文法一般是上下文无关文法,对应上下文无关语言。上下文无关意思是非终结字符的展开不依赖于两边的上下文。

正则文法 < 上下文无关文法 < formal grammar

正则文法就是用字符和三种规则(union, concatenation, iteration) 表达的语言。因为正则是CFG的子集,可以用CFG描述正则文法:

R -> alphabet character

R-> RT

T->R| e

R-> R|R

为什么要把左递归该为右递归?

因为右递归是先parse了一部分才递归的,也就是输入在收敛的递归,这种递归是真正的递归。左递归,输入没有任何变化。


为什么要Left Factor?

一个产生式的多个alternative有相同的开始token,改写一下,提取公共factor,最终使得每个alternative的开始token都不同,left factor 保证只有一个production是可行的,因为起始token不同。

自顶向下的parse基本是个路径搜索问题,从start非终结字符(相当于root)开始,分别尝试不同的alternative的产生式。要消除左递归,并且进行left factoring(剪枝作用,根据当前token有预见性的选择alternative)。一个输入token流,如果可以对应多棵parse tree,则这个CFG文法是具有二义性的。无二义性的的CFG从路径搜索的角度就是有且只有一条路径,一个可行解。

leetcode wordbreak ||是分词问题还是parse问题?答案是parse问题,parse问题的特点是整体性,要使得整体匹配。分词只需要考虑自己,不需要考虑对后续其他词的影响。word break以现在的知识点看应该是一种二义性(有多个可行解)、上下文相关的文法。









评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值