用于语法着色的状态机

时间:2009-05-08 10:02:19

标签: text lexer state-machine

我目前正在学习词法分析器和解析器的工作方式,并且我有关于状态机的问题。例如,我需要按照以下规则对文本进行着色: 对于此规则,简单状态转换表将如下所示:

current event next  action
IDLE    $     COLOR -
COLOR   any   -     OnColor()
COLOR   \n    IDLE  -

这将为'$'和行尾之间的每个字符调用OnColor()动作,这样我就可以着色它。当然同样可以从regexp自动生成,但我真的想知道它在重大魔法使用之前是如何工作的:)。接下来的问题是:如果我有一个规则:  (想要为以美元结尾的任何文本行着色,状态转换表不是很清楚:

current      event next             action
IDLE         any   -                -
IDLE         $     DOUND_DOLLAR     -
FOUND_DOLLAR \n    IDLE             OnDollar()
FOUND_DOLLAR any   IDLE             -

我可以教我的状态机调用OnDollar(),如果它在行尾找到一个'$'符号,但是我可以做些什么才能为遇到美元符号之前的文本着色?解决此类问题的常见模式有哪些?当然它将是一行regexp,但我真的很想知道如何通过状态机实现这样的解析器,它是否可能。

3 个答案:

答案 0 :(得分:1)

如果你被限制为一次为一个角色着色(即你没有缓冲,超前,重新着色或标记能力),那么这是不可能的。

否则,如果你有这样的能力,就可以做到;该技术取决于可用的内容。

  • 重新着色 - 有一个可以重新着色n个字符的动作。显然,这是一个微不足道的解决方案。

  • 缓冲/标记 - 有一个动作,将字符放在缓冲区的末尾/在源中设置命名标记,而不是让角色通过。然后,当您稍后发现要执行的操作时,请执行以某种方式提交缓冲区或从命名标记刷新的操作。使用它重新着色超过1个字符虽然有些复杂。

  • Lookahead - 有投机过渡,即使用NFA代替DFA

答案 1 :(得分:0)

大多数着色剂总是在较大的块上工作,例如整行(在大多数情况下已足够)加上“泄漏”标志,例如多行注释。有关此类API,请参阅Qt Syntax Highlighter示例。

答案 2 :(得分:0)

通过阅读“紫龙书”(原文如此),现代编译器和口译员似乎积极使用“向前看”缓冲并积累最近的文本,因此他们可以轻松检查下一个符号和几个先前的符号,以获得精确的词汇类型。

因此,在我的示例中,event()需要查看next和previous符号,以便确定可能累积的lexem的类型。