【问题标题】:raku: markdown grammar to parse sectionsraku:解析部分的降价语法
【发布时间】:2021-02-27 10:15:22
【问题描述】:

我想创建一个 raku 语法,可用于解析缩减的 markdown 语法。这种简化的 markdown 语法必须满足以下条件:

  • markdown 中的标头必须以“#”开头,后跟一个空格,或者必须用“-”序列(至少 2 个)加下划线。
  • 文本不能独立存在。它必须以标题开头。

为了解析这个语法,我创建了以下脚本:

#!/usr/bin/perl6

use v6;

grammar gram {
    token TOP {
        <text>
    }
    token text {
        [ <section> ]+
    }
    token section {
        <headline> <textline>*
    }
    token headline {
        ^^ [<hashheadline> | <underlineheadline>] $$
    }
    token hashheadline {
        <hashprefix> <headlinecontent>
    }
    token hashprefix {
        [\#] <space>
    }
    token underlineheadline {
        <headlinecontent> [\n] <underline>
    }
    token underline {
        [\-]**2..*
    }
    token headlinecontent {
        [\N]+
    }
    token textline {
        ^^ (<[\N]-[\#]> (<[\N]-[\ ]> [\N]*)? )? [\n] <!before [\-][\-]>
    }
}

my @tests = "",                                         #should not match and doesn't match - OK
            "test1",                                    #should not match and doesn't match - OK
            "test2\n",                                  #should not match and doesn't match - OK
            "test3\nnewline",                           #should not match and doesn't match - OK
            "test4\n----",                              #should match and does match        - OK
            "test5\n----\nnewline",                     #should match but doesn't match     - NOK
            "#test6\nnewline",                          #should not match and doesn't match - OK
            "# test7\nnewline",                         #should match but doesn't match     - NOK
            "# test8",                                  #should match and does match        - OK
            "test9\n----\nnewline\nanother\nnew line",  #should match but doesn't match     - NOK
            "# test10\nnewline\nhead\n---\nanother",    #should match but doesn't match     - NOK
            ;

for @tests -> $test {
    say gram.parse($test).perl;
}

但我的语法有问题:正如测试数组的 cmets 中所述,语法有问题,但我不知道是什么。

【问题讨论】:

  • 您是否尝试过生成minimal reproducible example
  • 在我看来,这已经是一个最小的工作示例。因为我说我需要解析降价的部分,所以我想保留标题的两种变体。在我的具体示例中,我有一个额外的动作类来帮助处理语法中的内容。在这个问题中,我删除了解析器的其他内容以及这个动作类。因此,它已经减少了很多。唯一不需要的是测试字符串数组。但我想保留它,因为这是我通过测试的绝对要求。
  • "已经减少了很多。"谢谢! “唯一不需要的是测试字符串数组”我认为测试是必要的,如果你把它们排除在外,你的问题会更糟。 “这已经是一个最小的工作示例。”我说的是minimal reproducible example 页面上描述的内容,这意味着您可以从回答者的 POV 中查看它。虽然您可能已尝试仔细遵循该页面的建议,但您的token textline 是识别错误所需的全部内容,这也是解决您问题的任何人都必须将其减少到的内容。我的回答解释了我认为最好的方法。 YMMV。

标签: raku


【解决方案1】:

textline 令牌更改为:

token textline { \n* <!before <headline>> \N+ \n? }

我没有考虑过该更改是否是您真正想要的,但这意味着您的测试按您指定的方式工作。


一般来说,使用 CommaIDE 开发语法。大多数问题(例如您发布的问题)的位置会立即变得明显。 (解决方案当然是一个独特的步骤,但查明问题通常是大部分工作。)


一般来说,通过生成一个最小示例来调试非显而易见的问题(请参阅我对您的问题的评论中提供的链接,但跳过可重现的部分)。

这样做通常是相对快速地查明任何不明显问题所在的最有效方法。

这也是一款有趣的游戏,通过将直觉与松散的binary chop 类似的方法相结合,您会变得更快。


一般来说,在提出关于 SO 的问题时,首先制作一个最小示例(如刚才所讨论的),然后使其成为一个最小可重现示例(以最小示例为基础)。 (您问题中的示例是 100% 可重现的——谢谢!——但我正在为其他读者和你写这个答案。)

最低限度的可重现示例对于您自己而言是洞察力和效率的问题,对于其他人而言,这些事情加上礼貌。一旦我了解问题所在,解决您的问题大约需要 1 分钟。但是我花了 15 分钟的时间做你会“最好”做的事情,然后才在这里提问:

  • 最适合您,因为它很有趣(并且会稳步提高您寻找错误的效率)。

  • 对我来说是最好的,他享受了按理说应该属于你的乐趣。

  • 最适合尝试回答您问题的其他人,这样我们就不会重复不必要的工作。

  • 最适合后来的读者,他们会得到解决真正困惑的简单问题,而不是不幸的复杂问题,因为它们如此模糊真正的问题,以至于失去了对读者的价值。

  • 最适合 Rakoons,因为发布 Minimal Reproducible Examples 是 StackOverflow 的版主和普通读者认为一个好问题的基本要素,这意味着他们更有可能认真对待 Raku,帮助我们缓和我们的问题,并成为 Rakoons。

也就是说,我并不是要阻止您提出问题,远非如此。如果在阅读并尝试应用 Minimal Reproducible Example 页面中的指南后,您发现自己遇到了困难,请继续提出问题,并在问题中解释您在生成最小和/或可重现示例时遇到的任何问题,因为这会有所帮助。

【讨论】:

    【解决方案2】:

    raku 模块Text::Markdown 可能与某些用户相关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多