在构建词法分析器/标记器时,依赖诸如 isdigit/isalpha/... 之类的函数(在C中)是错误的吗?据我所知,它们依赖于语言环境。我是否应该选择一个字符集并专注于它并自己制作一个字符映射,从中查找分类?然后问题就变成了能够使用多个字符集。我是为每个字符集生成一个词法分析器/标记器,还是尝试对我编写的那个进行编码,这样我唯一要做的就是更改字符映射。什么是常见的做法?
4 回答
现在,我将专注于首先使用纯 ASCII 字符集让词法分析器工作,然后当词法分析器工作时,为不同的字符类型添加映射支持,例如 UTF-16 和语言环境支持。
不,依赖 ctype 的函数,例如isdigit
,isalpha
等等,并不是一个错误……
实际上,也许在稍后阶段,对于宽字符' wctype.h '有一个 Posix 等效的 ctype ,因此稍后定义一个宏可能符合您的最佳利益......这样您就可以透明地更改处理不同语言环境集的代码...
#ifdef LEX_WIDECHARS #include <wctype.h> #define isdigit iswdigit #别的 #define isdigit #万一
在那种情况下,它会被定义为类似的东西......
希望这会有所帮助,最好的问候,汤姆。
尝试构建本地敏感的解析器可能不会走得太远——它会让你发疯。ASCII 可以很好地满足大多数解析需求——不要与之抗争:D
如果您确实想与之抗争并使用某些字符分类,您应该查看虔诚地实现 Unicode的ICU库。
ctype.h 函数对于包含除 ASCII 以外的任何字符的字符不是很有用。C
无论系统语言环境是什么,默认语言环境都是(基本上与大多数机器上的 ASCII 相同)。即使您使用setlocale
更改语言环境,系统也有可能使用大于 8 位字符的字符集(例如 UTF-8),在这种情况下,您无法从单个字符中分辨出任何有用的信息。
宽字符可以正确处理更多情况,但即使它们也经常失败。
所以,如果你想可靠地支持非 ASCII isspace,你必须自己做(或者可能使用现有的库)。
注意:ASCII 只有字符代码 0-127(或 32-127),有些人称之为 8 位 ASCII 实际上是一些其他字符集(通常是 CP437、CP1252、ISO-8859-1 以及其他一些字符)。
一般来说,你需要问自己:
- 你到底想做什么,什么样的解析?
- 您想支持哪些语言,广泛的语言还是仅支持西欧语言?
- 您想使用哪种编码方式 UTF-8 或本地化 8 位编码?
- 您使用的是什么操作系统?
让我们开始吧,如果您使用具有本地化 8 位编码的西方语言,那么可能是的,如果安装并配置了语言环境,您可以使用 is*。
然而:
- 如果你使用 UTF-8,你就不能,因为只有 ASCII 会被覆盖,你不能,因为 ASCII 之外的所有内容都需要超过一个字节。
- 如果您想支持东方语言,那么您对解析的所有假设都是错误的,例如中文不使用空格分隔单词。大多数语言甚至没有大写或小写,甚至是基于字母的,如希伯来语或阿拉伯语。
那么,你到底想做什么?
我建议查看具有各种中断迭代器的 ICU 库,或者其他提供一些基本边界分析的工具包(如 Qt)。