假设我想为编程语言(EBNF已知)创建解析器,并希望尽可能少地完成它.另外,我想支持任何UTF-8字母的标识符.我想用C++.
flex/我bison有一个不存在的UTF-8支持,因为我读了它.ANTLR似乎没有可用的C++输出.
我考虑过boost :: spirit,他们在他们的网站上声明它实际上不适合完整的解析器.
还剩下什么?每手完全滚动?
如果您没有找到具有所需支持的内容,请不要忘记flex在编码上几乎是独立的.它是一个八位字节流,我用它来说明纯二进制数据.以UTF-8编码的东西是八位字节流,可以通过flex处理,你接受手动做一些工作.IE而不是拥有
idletter [a-zA-Z]
Run Code Online (Sandbox Code Playgroud)
如果你想接受作为字母的所有内容,除了NBSP(换句话说,在U00A1-U00FF范围内)范围内的所有内容,你必须做类似的事情(我可能搞砸了编码,但你明白了)
idletter [a-zA-Z]|\xC2[\xA1-\xFF]|\xC3[\x80-\xBF]
Run Code Online (Sandbox Code Playgroud)
您甚至可以编写一个预处理器来完成大部分工作(即用\ xC2\xA1替换\ u00A1并用\ xC2 [\ xA1-\xFF] |\xC3 [\ x80-]替换[\ u00A1-\u00FF]\xBF],预处理器的工作量取决于您希望输入的通用程度,有时候您可能更好地将工作集成到flex中并将其贡献给上游)
解析器处理标记流,理解编码不是它们的责任。因此解析器往往与编码无关。
您似乎要问的是关于 UTF-8 感知的词法分析器。然而,大多数时候,词法分析器也不需要识别 UTF-8 即可标记 UTF-8 流:
对于大多数编程结构,您将直接比较 UTF-8 的 ASCII 子集的值。例如,要标记加号运算符,您可以将字节与“+”进行比较,就好像它是纯 ASCII 一样,并且凭借 UTF-8 的独创性,它也可以在 UTF-8 中正常工作。类似地,当标记字符串文字时,您只需扫描直到下一次出现引号,包括字符串中的所有 UTF-8 字节;无需特殊处理。我怀疑您的目标是支持用乌尔都语数字书写的数字。
至于标识符,作为一名程序员,我强烈建议您不要添加对非 ASCII 字符的支持。您可以简单地假设所有非 ASCII 字节都是标识符的一部分,但这没有用。问题不仅在于根据 Unicode 对哪些字符被视为“字母”进行分类,还在于稍后在编译器/解释器中定义这些字符串的合理比较。您需要确定使用哪种范式,而这些范式都不一定符合用户的期望。
最重要的是,在要求“UTF-8 解析器”之前,您应该首先了解 Unicode 的一些复杂性,然后定义您希望此类解析器拥有哪些功能。