Regex Maximum munch是如何实现的?
我在学习编译器,学习词汇分析。我知道有人将每个词素指定为正则表达式,使用Regex Maximum munch是如何实现的?,regex,parsing,unix,compiler-construction,flex-lexer,Regex,Parsing,Unix,Compiler Construction,Flex Lexer,我在学习编译器,学习词汇分析。我知道有人将每个词素指定为正则表达式,使用flex,可以自动生成一个词素分析器。我正在进一步学习如何将正则表达式转换为NFA,然后再转换为DFA,在DFA中可以快速对其进行计算 然而,我的问题是,最大芒克规则是如何实现的?在内部,词法分析者如何知道“继续”寻找尽可能长的词素 谢谢 通过向DFA执行器添加少量可变状态,并添加DFA执行器“倒带”输入的能力来实现最大munch算法:实际上,为其提供了tell()和seek()等功能 同样值得注意的是,DFA是不完整的,因
flex
,可以自动生成一个词素分析器。我正在进一步学习如何将正则表达式转换为NFA,然后再转换为DFA,在DFA中可以快速对其进行计算
然而,我的问题是,最大芒克规则是如何实现的?在内部,词法分析者如何知道“继续”寻找尽可能长的词素
谢谢 通过向DFA执行器添加少量可变状态,并添加DFA执行器“倒带”输入的能力来实现最大munch算法:实际上,为其提供了
tell()
和seek()
等功能
同样值得注意的是,DFA是不完整的,因为转换函数是不完整的。某些{state,input}
对没有定义的结果。[注2]
考虑到这一点,算法如下所示:
Set Accepted NFA State to ⊥
Set Accepted Position to Tell(Input Stream)
Set State to Starting State
Repeat:
If State ∈ Accepting:
Set Accepted NFA State to Accepting NFA State for State [Note 1]
Set Accepted Position to Tell(Input Stream)
Read one symbol from Input Stream into Next Symbol
If there is a transition from {State, Next Symbol} to New State:
Set State to New State
Continue the loop
Otherwise:
Rewind Input Stream to Accepted Position
Return Accepted NFA State
如果算法返回⊥,然后,没有识别到任何标记,输入流将被重绕到初始位置
注:
sink
状态,可以很容易地完成DFA,该状态是不可接受的,并且只向自身进行转换。然后我们可以添加sink
状态作为任何其他未指定转换的转换。如果我们调用sink
state⊥然后将明确如何修改所提供的算法;在实践中,这根本没有必要,因为在实践中,我们并不关心DFA是否不完整。不过,它确实对状态最小化算法有一些影响我想你是想用flex-lexer来标记它,flex-lexer用于词法分析器;不是用于Adobe/Apache UI框架的Flex。我更改了标记。我想在DFA中,只要记住最后一个可接受的状态,就可以使用尽可能多的字符进行转换。@JoSo:基本回答很好。更容易将DFA视为具有在运行时转换的状态。每个状态都标记为“接受”或“不接受”(例如,绿色和红色状态);它在运行时可能会经历多个绿色和红色状态。最终,它到达一个对于下一个输入字符没有有效出口的状态;如果该州是绿色的,它会接受,否则它会抱怨。所以它实际上不需要记住最后一个接受状态;当它终止时,它要么在一中,要么不在一中。@IraBaxter:如果我的标记字母是
{a,ab,aaa}
,并且我有输入aab
?如果不记得a
是可以接受的,那么在消费aa
之后,这将失败,而不是生成令牌列表[a,ab],不是吗?你是对的;每个状态都必须指向最后一个接受状态(例如,“aa”的状态不能在字符“b”上转换,但可以将“a”引用回接受状态)。关键是扫描仪不需要记住任何东西,只需检查当前状态即可。