对unicode的Flex(lexer)支持
我想知道flex的最新版本是否支持unicode 如果是,如何使用模式匹配汉字 更多:对unicode的Flex(lexer)支持,unicode,flex-lexer,Unicode,Flex Lexer,我想知道flex的最新版本是否支持unicode 如果是,如何使用模式匹配汉字 更多: 目前,flex只生成8位扫描仪,这基本上限制了您使用UTF-8。因此,如果你有一个模式: 肖晗 { printf ("xiaohan\n"); } 它将按预期工作,因为模式和输入中的字节序列将是相同的。更难的是人物课。如果要匹配角色的肖 或晗, 你不能写: [肖晗] { printf ("xiaohan/2\n"); } 因为这将匹配六个字节0xe8、0x82、0x96、0xe6、0x99和0x9
目前,flex只生成8位扫描仪,这基本上限制了您使用UTF-8。因此,如果你有一个模式:
肖晗 { printf ("xiaohan\n"); }
它将按预期工作,因为模式和输入中的字节序列将是相同的。更难的是人物课。如果要匹配角色的肖 或晗, 你不能写:
[肖晗] { printf ("xiaohan/2\n"); }
因为这将匹配六个字节0xe8、0x82、0x96、0xe6、0x99和0x97中的每一个,这实际上意味着如果您提供肖晗代码>作为输入,模式将匹配六次。因此,在这个简单的例子中,您必须将模式重写为(肖|晗)代码>
对于范围,Hans Aberg编写了一个将这些转换为8位模式的程序:
Unicode> urToRegU8 0 0xFFFF
[\0-\x7F]|[\xC2-\xDF][\x80-\xBF]|(\xE0[\xA0-\xBF]|[\xE1-\xEF][\x80-\xBF])[\x80-\xBF]
Unicode> urToRegU32 0x00010000 0x001FFFFF
\0[\x01-\x1F][\0-\xFF][\0-\xFF]
Unicode> urToRegU32L 0x00010000 0x001FFFFF
[\x01-\x1F][\0-\xFF][\0-\xFF]\0
这并不漂亮,但应该可以使用。Flex不支持Unicode。但是,Flex支持“8位干净”二进制输入。因此,您可以编写与UTF-8匹配的词汇模式。您可以在输入语言的特定词汇区域使用这些模式,例如标识符、注释或字符串文本
这对于典型的编程语言非常有效,您可以向实现的用户声明源语言是用ASCII/UTF-8编写的(并且不支持其他编码,句号)
如果您的扫描仪必须处理可以采用任何编码的文本,则此方法不起作用。如果您需要专门为Unicode元素表达词汇规则,则此方法也不起作用(非常好)。例如,扫描仪本身需要Unicode字符和Unicode正则表达式
其思想是,您可以使用lex规则识别包含UTF-8字节的模式(然后可能获取yytext
,并将其从UTF-8中转换出来,或者至少验证它)
有关工作示例,请参阅TXR语言的源代码,特别是此文件:
向下滚动到此部分:
ASC [\x00-\x7f]
ASCN [\x00-\t\v-\x7f]
U [\x80-\xbf]
U2 [\xc2-\xdf]
U3 [\xe0-\xef]
U4 [\xf0-\xf4]
UANY {ASC}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
UANYN {ASCN}|{U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
UONLY {U2}{U}|{U3}{U}{U}|{U4}{U}{U}{U}
如您所见,我们可以定义模式来匹配ASCII字符以及UTF-8开始和继续字节。UTF-8是一种词法符号,这是一个词法分析器生成器,所以…没问题
一些解释:UANY
表示匹配任何字符,单字节ASCII或多字节UTF-8。UANYN
表示类似于UANY
,但不匹配换行符。这对于不跨行的标记非常有用,例如从
到行尾的注释,包含国际文本。UONLY
表示只匹配UTF-8扩展字符,而不是ASCII字符。这对于编写需要排除某些特定ASCII字符(不仅仅是换行符)但所有扩展字符都可以的lex规则非常有用
免责声明:请注意,扫描仪的规则使用一个名为utf8_dup_from
的函数将yytext
转换为包含Unicode码点的宽字符串。该函数非常健壮;它可以检测超长序列和无效字节等问题并正确处理它们。也就是说,该程序不依赖这些lex-rul这些规则将识别超长的表单(如使用几个字节编码的ASCII码)作为有效语法,但转换函数将正确处理它们。在任何情况下,我不希望程序源代码中出现与UTF-8相关的安全问题,因为您必须信任源代码才能运行它(但程序处理的数据可能不可信!)如果您正在为不受信任的UTF-8数据编写扫描程序,请小心
我想知道flex的最新版本是否支持unicode
如果是,如何使用模式匹配汉字
<>将汉字与其他Unicode代码点与Flex兼容的词法分析器匹配,可以使用C++ for /P>
RE/flex安全地支持完整的Unicode 12标准,并接受UTF-8、UTF-16和UTF-32输入文件,而不需要UTF-8黑客甚至不支持UTF-16/32输入
另外,使用Flex的UTF-8黑客不允许您编写Unicode正则表达式,例如[肖晗]代码>在RE/flex中完全受支持
它与Bison无缝协作,构建词法分析器和解析器
事实上,使用RE/flex,我们可以在lexer.l
规范中将任何Unicode模式编写为基于UTF-8的正则表达式,例如:
%option flex unicode
%%
[肖晗] { printf ("xiaohan/2\n"); }
%%
这将生成一个lexer,自动扫描UTF-8、UTF-16和UTF-32文件。根据UTF标准化,对于UTF-16/32输入,输入中需要UTF BOM,而UTF-8 BOM是可选的
我们可以使用全局%option unicode
来启用unicode和%option flex
来指定flex规范。可以使用局部修饰符(?u:)
来将unicode限制为单个模式(因此其他所有内容仍然是flex中的ASCII/8位):
选项flex
启用flex兼容性,因此您可以使用yytext
、yyleng
、ECHO
等等。如果没有flex
选项,RE/flex需要Lexer方法调用:text()
(或者str()
和wstr()
用于std::string
),size()
(或wsize()
表示宽字符长度)和echo()
.RE/flex方法调用更干净,并且包含宽字符操作。我将我的回复从邮件列表复制到了答案中。谢谢。似乎给了我很多启发!你能给我一些帮助吗?我试图编译你提到的程序源代码,但格拉斯哥哈斯克尔编译器输出解析错误。你编译了你的源代码吗elf成功了?如果是这样,你能给我一些提示吗?很抱歉,我使用了错误的工具。我应该使用拥抱
,而不是拥抱
%option flex
%%
(?u:[肖晗]) { printf ("xiaohan/2\n"); }
(?u:\p{Han}) { printf ("Han character %s\n", yytext); }
. { printf ("8-bit character %d\n", yytext[0]); }
%%