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

qzwqbdag  于 2023-04-01  发布在  其他
关注(0)|答案(2)|浏览(145)

假设我想为一种编程语言(EBNF已经知道)做一个解析器,并且希望尽可能少地做。此外,我想支持任何UTF-8字母的标识符。我想用C来做。
flex/bison不支持UTF-8,ANTLR似乎没有工作的C
输出。
我考虑过boost::spirit,他们在他们的网站上说它实际上不适合完整的解析器。
还剩下什么?完全一只手滚动?

dl5txlt9

dl5txlt91#

如果你没有找到你想要的支持,别忘了flex基本上是独立于编码的。它lexes一个八位字节流,我已经用它来lex纯二进制数据。用UTF-8编码的东西是一个八位字节流,可以用flex处理,如果你接受手动做一些工作。即,而不是让

idletter [a-zA-Z]

如果你想接受除了NBSP之外的Latin 1范围内的所有内容(换句话说,在U 00 A1-U 00 FF范围内),你必须做一些类似的事情(我可能把编码搞砸了,但你明白了)

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

您甚至可以编写一个预处理器来为您完成大部分工作(例如,将\u00A1替换为\xC2\xA1,将[\u00A1-\u00FF]替换为\xC2[\xA1-\xFF])|\xC 3 [\x80-\xBF],预处理器的工作量取决于您希望输入的通用程度,有时您可能会更好地将工作集成到flex中并将其贡献给上游)

gojuced7

gojuced72#

解析器处理的是令牌流,理解编码不是他们的职责,因此解析器倾向于编码不可知论。
你似乎在问一个支持UTF-8的词法分析器。然而,大多数时候,词法分析器也不需要支持UTF-8来标记UTF-8流:
对于大多数编程结构,您将直接比较UTF-8的ASCII子集的值。例如,为了标记加号运算符,您将字节与'+'进行比较,就像它是纯ASCII一样,并且由于UTF-8的独创性,它在UTF-8中也将正确工作。同样,当标记字符串文字时,您只需扫描直到下一次出现引号,包括字符串中的所有UTF-8字节;不需要特殊处理。而且我怀疑你的目标是支持用乌尔都语数字写的数字。
至于标识符,作为一名程序员,我强烈建议您不要添加对非ASCII字符的支持。您可以简单地假设所有非ASCII字节都是标识符的一部分,但这不会有什么用处。问题不仅仅是根据Unicode将哪些字符分类为“字母”,你需要确定使用哪种范式,而这些范式都不一定符合用户的期望。
底线是,在要求一个“UTF-8解析器”之前,您应该首先了解Unicode的一些复杂性,然后定义您希望这样的解析器拥有哪些特性。

相关问题