【发布时间】:2023-02-08 00:14:21
【问题描述】:
我在我的项目中使用RE/flex lexer。在那,我想匹配对应于('*)".*?"\1的语法。例如,它应该匹配"foo"、''"bar"'',但不应匹配''"baz"'。
但是 RE/flex 匹配器不适用于前瞻、后视和反向引用。那么,是否有使用反射匹配器来匹配它的正确方法?我能实现的最接近的是以下词法分析器:
%x STRING
%%
'*\" {
textLen = 0uz;
quoteLen = size();
start(STRING);
}
<STRING> {
\"'* {
if (size() - textLen < quoteLen) goto MORE_TEXT;
matcher().less(textLen + quoteLen);
start(INITIAL);
res = std::string{matcher().begin(), textLen};
return TokenKind::STR;
}
[^"]* {
MORE_TEXT:
textLen = size();
matcher().more();
}
<<EOF>> {
std::cerr << "Lexical error: Unterminated 'STRING' \n";
return TokenKind::ERR;
}
}
%%
RE-flex 中的元字符. 匹配任何字符,无论是有效的还是无效的 UTF8 序列。而反转字符类 - [^...] - 仅匹配字符类中不存在的有效 UTF8 序列。
因此,上述词法分析器的问题在于,它只匹配字符串中有效的 UTF8 序列。然而,我希望它匹配字符串中的任何内容,直到分隔符。
我考虑了三种解决方法。但是这三个似乎都有一些问题。
- 使用
skip()。这将跳过所有字符,直到到达定界符。但是在这个过程中,它消耗了所有的字符串内容。我不能保留它们。 - 使用
.*?/\"而不是[^"]*。这适用于每个正确终止的字符串。但是如果字符串没有终止,词法分析器就会卡住。 - 使用
.逐个字符使用字符串内容。由于.正在同步,它甚至可以匹配无效的 UTF8 序列。但是这种方法感觉太慢了。那么有没有更好的方法来解决这个问题?
【问题讨论】:
标签: regex lexer parser-generator reflex