支持UTF-8的c++解析库

C++ Parsing Library with UTF-8 support

本文关键字:c++ UTF-8 支持      更新时间:2023-10-16

假设我想为一种编程语言(已经知道了EBNF)制作一个解析器,并希望尽可能少地完成它。另外,我希望支持任何UTF-8字母的标识符。我想用c++来写

flex/bison有不存在的UTF-8支持,正如我所读到的。ANTLR似乎没有一个工作的c++输出。

我考虑过boost::spirit,他们在他们的网站上声明它实际上并不意味着一个完整的解析器。

还剩下什么?完全用一只手擀?

如果你找不到你想要的支持,不要忘记flex基本上是独立于编码的。它lex一个八字节流,我已经用它来lex纯二进制数据。用UTF-8编码的内容是一个八字节流,如果您接受手动完成一些工作,则可以由flex处理。即,不用

idletter [a-zA-Z]

如果您想接受Latin1范围内的所有内容作为字母,除了NBSP(换句话说,在U00A1-U00FF范围内),您必须执行以下操作(我可能搞乱了编码,但您明白了)

idletter [a-zA-Z]|xC2[xA1-xFF]|xC3[x80-xBF]

你甚至可以写一个为你做大部分工作的预处理器(即用xC2xA1替换u00A1-u00FF),用xC2[xA1-xFF]替换[u00A1-u00FF] |xC3[x80-xBF],预处理器有多少工作取决于你想要的输入有多通用,总有一天你可能会更好地将工作集成在flex中并在上游贡献它)

解析器处理令牌流,理解编码不是它们的职责。因此,解析器往往是编码不可知论的。

你似乎问的是关于一个UTF-8识别的词法器。但是,大多数情况下,词法分析器也不需要支持UTF-8,以便对UTF-8流进行标记:

对于大多数编程结构,您将直接比较UTF-8的ASCII子集的值。例如,要对加号运算符进行标记,您可以将字节与'+'进行比较,就好像它是普通的ASCII一样,并且由于UTF-8的独创性,它也可以在UTF-8中正确工作。类似地,在对字符串字面值进行标记时,只需扫描到下一个出现引号的地方,包括字符串中的所有UTF-8字节;不需要特别处理。我怀疑你的目标是支持用乌尔都语数字书写的数字。

至于标识符,作为一个程序员,我强烈反对您添加对非ascii字符的支持。您可以简单地假设所有非ascii字节都是标识符的一部分,但这不会有用。问题不仅仅是根据Unicode对哪些字符进行分类,而且还要在编译器/解释器中定义这些字符串的合理比较。您需要确定使用哪种标准格式,而这些格式都不一定符合用户的期望。

底线是,在要求"UTF-8解析器"之前,您应该首先了解Unicode的一些复杂性,然后定义您希望这种解析器具有哪些特性。