提问人:user9634413 提问时间:11/23/2021 最后编辑:user9634413 更新时间:11/24/2021 访问量:390
如何使用 antlr4 解析 3 字节 utf8 字符串
How to use antlr4 to parse 3-byte utf8 string
问:
Blow 是我的语法文件。
grammar My;
tokens {
DELIMITER
}
string:SINGLE_QUOTED_TEXT;
SINGLE_QUOTED_TEXT: (
'\'' (.)*? '\''
)+
;
我正在尝试使用它来访问所有字符串(它实际上是 mysql 的 g4 的一部分)。 然后我使用以下代码来测试它:
#include "MyLexer.h"
#include "MyParser.h"
#include <string>
using namespace My;
int main()
{
std::string s = "'中'";
antlr4::ANTLRInputStream input(s);
MyLexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
MyParser parser(&tokens);
parser.string();
return 0;
}
汉字 中 的 utf8 代码为 3 个字节:\xe4 \xb8 \xad
语法文件和代码文件都以 utf8 编码。 我能做些什么来让它工作正常。
答:
0赞
user9634413
11/24/2021
#1
我已经弄清楚了问题所在。
参考 https://stackoverflow.com/a/26865200/9634413
Antlr C++运行时使用 std::u32string 来存储输入,\xe4 将被强制转换为 \xffffffe4,这超出了 unicode 范围 [0,0x10ffff]。
要解决此问题,只需重写 ANTLRInputStream 的构造函数,例如:
class MyStream : public antlr4::ANTLRInputStream {
public:
MyStream(const std::string& input = "")
: antlr4::ANTLRInputStream(input)
{
// Remove the UTF-8 BOM if present
const char bom[4] = "\xef\xbb\xbf";
if (input.compare(0, 3, bom, 3) == 0) {
std::transform(input.begin() + 3, input.end(), _data.begin(),
[](char c) -> unsigned char { return c; });
}
else {
std::transform(input.begin(), input.end(), _data.begin(),
[](char c) -> unsigned char { return c; });
}
p = 0;
}
MyStream(const char data_[], size_t numberOfActualCharsInArray)
: antlr4::ANTLRInputStream(data_, numberOfActualCharsInArray)
{
}
MyStream(std::istream& stream)
: antlr4::ANTLRInputStream(stream)
{
}
};
评论