我正在为Markdown写词法器。在此过程中,我意识到我不完全了解其核心责任。
词法分析器最常见的定义是将个字符的输入流转换为 tokens 的输出流。
Input → Output
(characters) (tokens)
一开始听起来很简单,但是这里出现的问题是,在将令牌的输出传递给解析器之前,词法分析器应该做多少语义解释 。
以Markdown语法为例:
### Headline
*This* is an emphasized word.
词法分析器可能会将其翻译为以下一系列标记:
.headline("Headline")
.emphasis("This")
.text"(" is an emphasized word.")
但也可以根据使用的语法(或一组词素)在更细粒度的级别上进行翻译:
.controlSymbol("#")
.controlSymbol("#")
.controlSymbol("#")
.text(" Headline")
.controlSymbol("*")
.text("This")
.controlSymbol("*")
.text"(" is an emphasized word.")
让词法分析器产生类似于词法分析器1 的输出似乎更加实用,因为这样解析器将可以轻松完成工作。但这也意味着词法分析器需要在语义上理解代码的含义。这不仅是将字符序列映射到令牌。它需要向前看并确定模式。 (例如,它需要能够区分**Hey* you*
和**Hey** you
。它不能简单地将双星号**
转换为.openingEmphasis
,因为这取决于以下上下文。)
根据this Stackoverflow post和CommonMark definition,首先将Markdown输入分解为多个块(代表一行或多行),然后分析每个块的内容似乎很有意义。在第二步。对于上面的示例,这意味着:
.headlineBlock("Headline")
.paragraphBlock("*This* is an emphasized word.")
但是,这不会算作令牌的有效序列,因为尚未解析某些词素(“ *”),并且将此paragraphBlock
传递给解析器是不正确的。 / p>
这是我的问题:
该词法分析器应该做多少语义工作?我不知道的词法分析器定义是否有些硬性规定?
为词法分析器定义语法的最佳方法是什么?