mih*_*jlv 3 c xml parsing lex utf-8
我写了一个解析ASCII文件的xml解析器,但我现在需要能够读取UTF-8编码的文件.我在lex中有以下正则表达式但它们与UTF-8不匹配.我不确定我做错了什么:
utf_8 [\x00-\xff]*
bom [\xEF\xBB\xBF]
Run Code Online (Sandbox Code Playgroud)
然后:
bom { fprintf( stderr, "OMG I SAW A BOM"); return BOM;}
utf_8 { fprintf( stderr, "OMG I SAW A UTF CHAR", yytext[0] ); return UTF_8;}
Run Code Online (Sandbox Code Playgroud)
我还有以下语法规则:
program
: UTF8 '<' '?'ID attribute_list '?''>'
root ...
Run Code Online (Sandbox Code Playgroud)
在哪里UTF8:
UTF8
: BOM {printf("i saw a bom\n");}
| UTF_8 {printf("i saw a utf\n");}
| {printf("i didn't see anything.'\n");}
;
Run Code Online (Sandbox Code Playgroud)
它总是出现i didn't see anything,我的解析器适用于ASCII文件,也就是当我将XML UTF-8文件粘贴到空文档中时.
任何帮助,将不胜感激.
编辑:
这是一个修剪过的.l文件供参考:
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
int lines = 1;
%}
utf_8 [\x0000-\xffff]*
bom [\xEF\xBB\xBF]
whitespace [ \t]
ev (.|{bom})
ev1 (.|{utf_8})
%%
{whitespace} { fprintf( stderr, "%s", yytext );}
\n { fprintf( stderr, "%s%d ", yytext, lines++ );}
. { fprintf( stderr, "{TOKEN:%c}", yytext[0] ); return yytext[0];}
bom { fprintf( stderr, "OMG I SAW A BOM"); return BOM;}
utf_8 { fprintf( stderr, "OMG I SAW A UTF CHAR", yytext[0] ); return UTF_8;}
%%
void error( char *message )
{
fprintf( stderr, "Error: %s\n", message );
exit(1);
}
Run Code Online (Sandbox Code Playgroud)
好的,这是你的问题:
utf_8 [\x0000-\xffff]*
bom [\xEF\xBB\xBF]
Run Code Online (Sandbox Code Playgroud)
这里有两个问题.首先,Flex实际上并不了解Unicode.它适用于字节.因此,您需要一个匹配任何有效UTF-8 字节序列的正则表达式宏.http://keithdevens.com/weblog/archive/2004/Jun/29/UTF-8.regex有一个正则表达式可以做到这一点,转换为Flex语法并不是很难(见下文).其次,BOM宏中的方括号使其匹配任何具有值EF,BB或BF的单字节,而不是您想要的三字节序列 EB BB BF.
(顺便说一句,UTF-8文件不应该有字节顺序标记,尽管许多文件仍然有.)
这是一个完整的Flex输入文件,它或多或少地执行了您尝试执行的操作:
%{
#include <stdio.h>
%}
bom \xEF\xBB\xBF
white [ \t]
u2a [\xC2-\xDF][\x80-\xBF]
u2b \xE0[\xA0-\xBF][\x80-\xBF]
u3a [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
u3b \xED[\x80-\x9F][\x80-\xBF]
u4a \xF0[\x90-\xBF][\x80-\xBF]{2}
u4b [\xF1-\xF3][\x80-\xBF]{3}
u4c \xF4[\x80-\x8F][\x80-\xBF]{2}
utf_8 {u2a}|{u2b}|{u3a}|{u3b}|{u4a}|{u4b}|{u4c}
%%
{white} { putchar(' '); }
\n { putchar('\n'); }
{bom} { putchar('B'); }
{utf_8} { putchar('u'); }
[\x21-\x7e] { putchar('.'); }
. { putchar('^'); }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1559 次 |
| 最近记录: |