我需要编写一个词法分析器,以正确突出显示我的命令行工具命令。

$ dvc add file.csv
$ dvc pipeline list

因此,该命令以dvc开头,并且可能具有一个或两个子命令-分别为addpipeline list

因此,在第一种情况和第二种情况下,应分别突出显示dvc adddvc pipeline list
contains: [
          {
            begin: /^\s*\$\s(dvc|git) [a-z-]+/,
            returnBegin: true,
            contains: [
              {
                begin: /dvc [a-z-]+ ?/,
                lexemes: '[a-z-]+',
                keywords: {
                  built_in:
                    'dvc'
                },
                contains: [
                  {
                    begin: /\w+(?![\S])/,
                    keywords: {
                      built_in: 'list'
                    }
                  }
                ],
                className: 'strong'
              }
            ]
          }
        ]

即使父正则表达式也匹配dvc pipeline list,即/^\s*\$\s(dvc|git) [a-z-]+/仅匹配到dvc pipeline。它到底如何运作?
/dvc [a-z-]+ ?/如何覆盖它并继续匹配表达式?

请在此处引用该库文档:https://highlightjs.readthedocs.io/en/latest/reference.html

最佳答案

开始仅开始比赛,但不限制比赛。第一个规则匹配,然后倒回...然后匹配/dvc [a-z-]+ ?/,这将开始在contains中寻找子代...因此匹配了/\w+(?![\S])/(您仍然在强大的规则之内),所以您会看到:

<strong>dvc pipeline list</strong>
<!-- matches /^\s*\$\s(dvc|git) [a-z-]+/ -->
  <!-- matches /dvc [a-z-]+ ?/ -->
  <strong>
    dvc pipeline
      <!-- contains matches  /\w+(?![\S])/ -->
      list
      <!-- no more matches for /\w+(?![\S])/ -->
      <!-- end fires, back up -->
    <!-- no more matches for /dvc [a-z-]+ ?/-->
    <!-- end fires -->
  </strong>
  <!-- back up -->
如果您想检测一堆不同的模式,我会为每种模式建议不同的模式:
{ begin: /dvc add .../, contains: ... }
{ begin: /dvc pipeline .../, contains: ... }
尽管您可能还想看看startscontains。编写语法来表示匹配项A,然后是B,然后是C可能非常困难。工具虽然存在,但是要正确正确,充满危险而不是做简单的事情可能会非常复杂。

09-04 09:59