1

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

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

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

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

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

4

3 回答 3

1

如果您一次只能为一个字符着色(即您没有缓冲、前瞻、重新着色或标记能力),那么这是不可能的。

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

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

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

  • Lookahead - 具有推测性转换,即使用NFA而不是DFA

于 2009-05-08T10:15:37.780 回答
0

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

于 2009-05-08T10:32:51.233 回答
0

通过阅读“Purple Dragon Book”(原文如此),现代编译器和解释器似乎在积极使用“前瞻”缓冲区并积累最近的文本,因此他们可以轻松地检查几个下一个符号和几个前一个符号以获得准确的词法类型。

因此,在我的示例中, event() 需要查看下一个和上一个符号,以确定可能累积的词法类型。

于 2009-05-10T12:46:02.003 回答