如何在 Raku 语法中匹配换行符或文件结尾?

发布于 2025-01-17 04:37:52 字数 1239 浏览 3 评论 0原文

我在尝试强制语法匹配文件的最后一行(如果后面没有换行符)时遇到了麻烦:

Line 1
Line 2 EOF

这种尝试的解决方案使换行符成为可选,导致无限循环:

my grammar HC4 {
    token TOP {  <line>+ }
    token line { [ <header> | <not-header> ] \n? } # optional newline

    token header { <header-start> <header-content> }
    token not-header { <not-header-content> }
    token header-start { \s* '#' ** 1..6 }
    token header-content { \N* }
    token not-header-content { \N* }
}

\N*< /code> 位将永远匹配最后一行最后一个字符后面的 '' 字符串。

我尝试过使用 <[\n\Z]> 但编译器会抱怨并建议使用 \n?$ 我尝试过但也不起作用。经过大量试验和错误后,我发现唯一有效的解决方案要求我创建一个新的 捕获并将 \N* 更改为 \N+

my grammar HC3 {
    token TOP {  <line>+ }
    token line { [ <header> | <blank> | <not-header> ] \n? }

    token header { <header-start> <header-content> }
    token blank { \h* <?[\n]> }
    token not-header { <not-header-content> }
    token header-start { \s* '#' ** 1..6 }
    token header-content { \N+ }
    token not-header-content { \N+ }
}

不过,我想知道是否有更简单的方法可以实现这一点。谢谢。

I have run into headaches trying to coerce a grammar to match the last line of a file if it is not followed by a newline:

Line 1
Line 2 EOF

This attempted solution, which makes the newline optional, causes an infinite loop:

my grammar HC4 {
    token TOP {  <line>+ }
    token line { [ <header> | <not-header> ] \n? } # optional newline

    token header { <header-start> <header-content> }
    token not-header { <not-header-content> }
    token header-start { \s* '#' ** 1..6 }
    token header-content { \N* }
    token not-header-content { \N* }
}

The \N* bits will match the '' string after the last character in the last line forever.

I have tried using <[\n\Z]> but then the compiler complains and suggests using \n?$ which I tried but that does not work either. After a lot of trial and error, the only solution I discovered that works requires me to create a new <blank> capture and to change the \N* to \N+:

my grammar HC3 {
    token TOP {  <line>+ }
    token line { [ <header> | <blank> | <not-header> ] \n? }

    token header { <header-start> <header-content> }
    token blank { \h* <?[\n]> }
    token not-header { <not-header-content> }
    token header-start { \s* '#' ** 1..6 }
    token header-content { \N+ }
    token not-header-content { \N+ }
}

I'd like to know if there is a more straightforward accomplishing this, though. Thanks.

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

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

发布评论

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

评论(3

人生百味 2025-01-24 04:37:52

我想我可能已经找到了一些可以工作并且很简单的东西:

my grammar G {
    token TOP {  (^^ <line>)+ }
    token line { \N* \n? }
}

^^ 符号,用于行的开头,停止无限循环。

I think I may have found something that can work and is simple:

my grammar G {
    token TOP {  (^^ <line>)+ }
    token line { \N* \n? }
}

The ^^ symbol, for the beginning of a line, stops the infinite loop.

情绪失控 2025-01-24 04:37:52

好吧,经过一番调查,我发现了我的困境的根本原因:

在此处输入图像描述

此屏幕截图来自 IntelliJ IDE 的编辑器 ->常规设置。默认情况下,“确保每个保存的文件都以换行符结尾”未选中。因此,如果我保存一个文件并删除最后一行以进行清理,则它会删除最后一个 \n 字符。检查这一设置以避免我的痛苦、磨难和深刻的心理创伤。

OK, after some investigation, I discovered the root cause of my woes:

enter image description here

This screenshot is from the IntelliJ IDE's Editor -> General settings. By default, the "Ensure every saved file ends with a line break" is not checked off. So if I saved a file with the very last line deleted to clean it up, it was stripping the last \n character. Check that setting on to avoid my pain, suffering and deep psychological trauma.

羁客 2025-01-24 04:37:52

我相信最简单的解决方案是这样的:

grammar LineOriented {
    token TOP {
        <line>* %% \n
    }

    token line {
        ^^ \N*
    }
}

使用 %% 允许但不要求最后一行。

I believe the simplest solution is something like this:

grammar LineOriented {
    token TOP {
        <line>* %% \n
    }

    token line {
        ^^ \N*
    }
}

Using %% allows, but not requires, the last trailing line.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文