词法分析
怎样去匹配。分割。
正则表达式--
集合
集合的运算。
元素相加 并 -- X|Y
元素相乘 连接--XY,笛卡尔积.
加入循环-- 克林闭包-- 记作X*
逻辑运算符
^--排除,[^ab]就表示除了ab以外所有字符求并。
X?--可选
更多规则
X+表示XX*。这等于限制了X至少要重复1次
简化替代-
状态机
把正则表达式转换成可以计算机执行的语言。
这些的内涵都是正则语言,
有穷状态机(FA)--有限状态。
状态-图的节点
初始状态
接受状态-黑圈表示
状态转换- 图的边
确定性有穷状态机(DFA)--一个状态只有一种状态转换
非确定性有穷状态机(NFA)-一个状态有多种状态转换。
这个理解不对。还要加入’某个条件下‘这个限定。
一个状态在不同条件下有多个状态转换,也是DFA
这里有个ε(表示空)符号的边。不输入字符也算一种状态转换。
主要这里导致变得复杂好多。
比如要匹配一个字符,并没有定义结束符,那输入一个字母后,随时都可以转到接受状态。
而且一个状态可以由好几个ε边。
有点这个状态潜在可能发生的改变。
有点先把框架定下来,
[a-z][a-z0-9]*
克林闭包-就是画个循环圈
正则可以画出NFA,NFA可以转化成多个DFA,DFA就能判定结果?
NFA-DFA的转化
感觉就是穷举遍历所有路径,每条路径上的组合就是一个DFA。
基本术语。
一个状态 ,由所有路径连接的终点,可以形成一个关系。达到的状态形成一个集合。
沿着字符c的路径 ,形成的集合记作-- edge(s,c)
ε-闭包--这个是’关系‘上面的闭包概念?
表示从状态s出发,沿着ε边到达的状态关系。相当于edge(s,ε)?
然后这个闭包关系可以作用到一个集合--记作closure(X)。
这里一般理解都是
多种转换可能作为一个集合。多种转换能遍历完,得到的每个集合都是一个DFA
初始状态集合。开始状态+ε边。
输入字符C的集合,i边,([2],[5,8,6],[15]) ->f边,(2->[3],6->[7,8,6]);->字母,数字边
a-h,j-h ([5,8,6],[15])
0-9 ([10,13,11],[15])
other [15]
看着就是边所有连接的状态,再加该状态的ε闭包。
这个路线能看懂,那一个个集合是啥,整体看着是一个DFA图,只是里面的状态是一个集合。
这个状态集合就是DFAedge?
这里感觉是怎么画出NFA图是很有讲究的。
DFA转化到‘状态转换表‘--》扫描器
最长匹配。
语法分析
上下文无关语言
语法的定义-产生式
非终结符N
产生关系→
终结符‘()‘
这个看着很神奇,
N → a ( N, N )
N → ε
这样就能表达一个二叉树了。。这个式子即能定义值,又能定义结构。还能迭代。
推导
把表达式-------》语法分析树
这里怎么把语法转化成产生式。语法五花八门的。
这个产生式还要是能正确转换到分析树的格式。
递归下降法来实现分析树。。。?
A(B(,C(,)),D(,) )--》思维分析过程
如果是产生式的模式呢。
N->a(N,N) csj1
N-> ε csj2
loopfun(parentnode,childtag,substring)
if char=a then
node=cv;
substing=括号内数据,哪个括号结束难以明确哎。
parentnode.childtag=node
loopfun(node,lefttag,substring);
else if char=‘,‘
loopfun(poarentnode,righttag,substring);
parsenode()
if char==letter
{
label=char
leftnode=parsenode()
skipdot;
right=parsenode()
}
这里产生式感觉是要全局来看,保持结构的完整性,空白也要保持结构。
函数内只关注自己是不是个节点,是的话就按结构展开,获取左右节点,处理结构内的标记符号。
不管这个节点下面包含了多少子节点,就写跳过逗号 ,不用管这个逗号具体在哪里,它就出现在改待的位置。
真是很奇特的感觉
这里文法上下面没有子节点,也要把结构字符都写完整(,)
和原先那种步进思维相比
1.每一层都赋值好节点值。
2.调用下面的节点等赋值,赋值好后自己返回。