【发布时间】:2017-07-10 07:58:25
【问题描述】:
我开始为我的编程语言编写词法分析器。
此语言中的字符串文字以 " 开头,并在遇到未转义的 " 时结束。除了转义序列(通常的\ns、\ts、\"s 等以及使用其 ASCII 码转义字符的方法外,其中的所有内容(包括换行符)都被保留,例如 \097 或 @987654327 @)。
这是我目前写的代码:
%{
#include <iostream>
#define YY_DECL extern "C" int yylex()
std::string buffstr;
%}
%x SSTATE
%%
\" {
buffstr.clear();
BEGIN(SSTATE);
}
<SSTATE>\\[0-9]{1,3} {
unsigned code = atoi(yytext + 1);
if (code > 255) {
std::cerr << "SyntaxError: decimal escape sequence larger than 255 (" << code << ')' << std::endl;
exit(1);
}
buffstr += code;
}
<SSTATE>\\a buffstr += '\a';
<SSTATE>\\b buffstr += '\b';
<SSTATE>\\f buffstr += '\f';
<SSTATE>\n buffstr += '\n';
<SSTATE>\r buffstr += '\r';
<SSTATE>\t buffstr += '\t';
<SSTATE>\v buffstr += '\v';
<SSTATE>\\\\ buffstr += '\\';
<SSTATE>\\\" buffstr += '\"';
<SSTATE>\\. {
std::cerr << "SyntaxError: invalid escape sequence (" << yytext << ')' << std::endl;
exit(1);
}
<SSTATE>\" {
std::cout << "Found a string: " << buffstr << std::endl;
BEGIN(INITIAL);
}
<SSTATE>. buffstr += yytext[0];
. ;
%%
int main(int argc, char** argv) {
yylex();
}
它运行良好,但正如您所见,它并没有特别优化。
对于正在解析的字符串文字中的每个字符,它会将一个字符附加到 std::string 一次,这并不理想。
我想知道是否有更好的方法,例如存储指针并增加长度,然后使用std::string(const char* ptr, size_t lenght) 构建字符串。
有吗?会是什么?
【问题讨论】:
-
您不需要
std::string。只需使用YYMORE、YYMORE()、yymore()或其他任何名称。这样会更快。
标签: c++ parsing flex-lexer stdstring string-literals