匹配Lua的“长括号” 字符串语法

发布于 2024-07-24 09:07:36 字数 456 浏览 7 评论 0原文

我正在为 Lua 编写一个 jFlex 词法分析器,并且在设计正则表达式以匹配语言规范的一个特定部分时遇到问题:

文字字符串也可以使用长括号括起来的长格式来定义。 我们将第 n 级的左长括号定义为一个左方括号,后跟 n 个等号,最后跟另一个左方括号。 因此,级别 0 的左长括号写为 [[,级别 1 的左长括号写为 [=[,依此类推。 右长括号的定义类似; 例如,4 级的右长括号写为]====]。 长字符串以任何级别的左长括号开始,并以同一级别的第一个右长括号结束。 这种括号形式的文字可以运行多行,不解释任何转义序列,并忽略任何其他级别的长括号。 它们可以包含除适当级别的右括号之外的任何内容。

简而言之,我正在尝试设计一个正则表达式,它将匹配左长括号、中间的字符串内容以及右长括号。 仅当左长括号和右长括号具有相同数量的等号(可以是零或多个)时,才会发生匹配。

I'm writing a jFlex lexer for Lua, and I'm having problems designing a regular expression to match one particular part of the language specification:

Literal strings can also be defined using a long format enclosed by long brackets. We define an opening long bracket of level n as an opening square bracket followed by n equal signs followed by another opening square bracket. So, an opening long bracket of level 0 is written as [[, an opening long bracket of level 1 is written as [=[, and so on. A closing long bracket is defined similarly; for instance, a closing long bracket of level 4 is written as ]====]. A long string starts with an opening long bracket of any level and ends at the first closing long bracket of the same level. Literals in this bracketed form can run for several lines, do not interpret any escape sequences, and ignore long brackets of any other level. They can contain anything except a closing bracket of the proper level.

In a nutshell, I am trying to design a regular expression that will match an opening long bracket, the string contents in between, and the closing long bracket. A match should only occur when the opening long bracket and closing long bracket have the same number of equal signs, which can be zero or more.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙气飘飘 2024-07-31 09:07:37

好吧,恐怕用正则表达式进行标记不足以完成这项任务。 正则表达式还不够强大。

在 jFlex 中无法使用普通正则表达式来比较“=”标记的数量。 Perl 对此有一个 hack(如上面建议的 \1),但我们不是在谈论 Perl 编程,而是在谈论 jFlex 词法分析器。

解决方案是使用 \[=*\[ 作为左括号标记,\]=*\] 作为右括号标记,然后在上面的层(解析器)中比较它们的长度是否匹配。

无论如何,你可以查看 llex.c 中 lua 源代码中的 read_long_string() ,看看他们是如何在完全不使用正则表达式的情况下做到这一点的。

Well, I'm afraid tokenizing with regular expressions isn't good enough for this task. Regular expressions just aren't powerful enough.

There's no way to compare the number of '=' marks using plain regular expressions in jFlex. Perl would have a hack for that ( \1 as suggested above), but we're not talking about programming Perl, but jFlex lexer.

The solution is to go with \[=*\[ for the left bracket token, \]=*\] for the right bracket token, and then in the layer above (a parser) compare if they match in length.

Anyway, you can look at read_long_string() in the lua source code in llex.c and see how they did it without using regular expressions at all.

眼波传意 2024-07-31 09:07:37
\[(=*)\[.*?\]\1\]

\1 捕获第一个 ()。

\[(=*)\[.*?\]\1\]

the \1 captures the first ().

与酒说心事 2024-07-31 09:07:37
\[(=*)\[.*?\]\1\]
\[(=*)\[.*?\]\1\]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文