我用c++写了一段代码来分析JavaScript代码的词法。下面是相应的函数。作为参考,Kind
是一个包含各种lex的枚举类,函数toKind
的定义在函数analyzeLexeme
的下面。
auto analyzeLexeme(std::wstring & source_code) -> std::vector<Token> {
using std::__1::wregex;
using std::regex_search;
using std::vector;
using std::wsmatch;
using std::wstring;
using std::string;
using std::tuple;
using std::map;
wsmatch matched;
Kind result_kind;
map<string, bool> context = { { "in_tmplt", false }, };
auto result = vector<Token>();
auto reSearch = [&source_code, &matched] (const wregex & re) {
return regex_search(source_code, matched, re);
};
source_code += L'\0';
for (; source_code[0]; source_code = matched.suffix()) {
if (reSearch(kReWhiteSpace)) continue;
result.push_back({(
reSearch(kReNumLiteral) ? [] { return Kind::NumberLiteral; } :
reSearch(kReStrLiteral) ? [] { return Kind::StringLiteral; } :
reSearch(kReTmpltHdLiteral) && !context["in_tmplt"] ?
[&] {
context["in_tmplt"] = true;
return Kind::TemplateHeadLiteral;
} :
reSearch(kReTmpltTlLiteral) && context["in_tmplt"] ?
[&] {
context["in_tmplt"] = false;
return Kind::TemplateTailLiteral;
} :
reSearch(kReTmpltMdLiteral) && context["in_tmplt"] ? [] { return Kind::TemplateMiddleLiteral; } :
reSearch(kReTmpltLiteral) ? [] { return Kind::TemplateLiteral; } :
reSearch(kReIdentifierKyword) ? [&] { return toKind(matched.str(), Kind::Identifier); } :
reSearch(kReOperatorBracket) ? [&] { return toKind(matched.str()); } :
[] { return Kind::Unknown; }
)(),
matched.str(),
});
if (result.back().kind == Kind::Unknown) {
std::wcerr << L"[ERR] : Unknown Token : " << source_code.substr(0, 40) << std::endl;
// fwprintf(stderr, L"[ERR] : Unknown Token : %s", source_code.substr(0, 40).c_str());
exit(1);
}
}
return result;
}
个字符
此处发生错误(reSearch(kReOperatorBracket) ? [&] { return toKind(matched.str()); }
)。原因是error: incompatible operand types ('(lambda at ~/projects/lexer.cc:69:72)' and '(lambda at ~/projects/lexer.cc:70:17)')
。
我不明白,因为toKind
的返回类型是Kind,所以lambda函数([&] { return toKind(matched.str())
)必须返回Kind值,而lambda函数([] { return Kind::Unknown; }
)也别无选择,只能返回Kind类型的值。
一开始我以为g++不能解释我的代码(在python中,有时候如果我写了不该写的行,解释器就不能解释它)。但是,经过多次尝试,我发现这也不是主要原因。
另外,如果代码被编译,我会运行gdb来调试它,但我也不能这样做,因为这是编译过程的问题。
1条答案
按热度按时间mgdq6dx11#
由于在三进制操作中使用lambda表达式作为操作数,因此需要将这些lambda表达式 Package 在
std::function
中。正如您所看到的,所有lambda表达式都有自己独特的类型,而不是
std::function
。如果你想让一个表达式返回一种类型或另一种类型,你需要某种类型的擦除。但是,你似乎在现场调用了函数,在表达式中一行。考虑到这一点,您还可以删除所有单语句lambda表达式,并在三进制中调用多语句。
如果你当场给他们打电话,情况会是这样的:
字符串
下面是将它们全部 Package 在类型擦除 Package 器(如
std::function
)中的情况:型