Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
对unicode的Flex(lexer)支持_Unicode_Flex Lexer - Fatal编程技术网

对unicode的Flex(lexer)支持

对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的最新版本是否支持unicode

如果是,如何使用模式匹配汉字

更多:

目前,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]); }
%%