0

我有这个语法:

let lexer = moo.compile({    
    comment: { match: /[\/\/.*?$|][^\n]+/, value: (s:string) => s.slice(1).trim() },
    newline: { match: /[\n]+/, lineBreaks: true }
});
%}
@lexer lexer

main ->
    element
  | main %newline element 
element -> comment    

comment -> %comment

现在,当我向 nearley 提供以下输入时://\n//\n//\n//\n//我得到了这个结果:

[
  [
    [
      [
        [
          [
            [
              [
                {
                  "type": "comment",
                  "value": "/",
                  "text": "//",
                  "offset": 0,
                  "lineBreaks": 0,
                  "line": 1,
                  "col": 1
                }
              ]
            ]
          ],
          {
            "type": "newline",
            "value": "\n",
            "text": "\n",
            "offset": 2,
            "lineBreaks": 1,
            "line": 1,
            "col": 3
          },
          [
            [
              {
                "type": "comment",
                "value": "/",
                "text": "//",
                "offset": 3,
                "lineBreaks": 0,
                "line": 2,
                "col": 1
              }
            ]
          ]
        ],
        {
          "type": "newline",
          "value": "\n",
          "text": "\n",
          "offset": 5,
          "lineBreaks": 1,
          "line": 2,
          "col": 3
        },
        [
          [
            {
              "type": "comment",
              "value": "/",
              "text": "//",
              "offset": 6,
              "lineBreaks": 0,
              "line": 3,
              "col": 1
            }
          ]
        ]
      ],
      {
        "type": "newline",
        "value": "\n",
        "text": "\n",
        "offset": 8,
        "lineBreaks": 1,
        "line": 3,
        "col": 3
      },
      [
        [
          {
            "type": "comment",
            "value": "/",
            "text": "//",
            "offset": 9,
            "lineBreaks": 0,
            "line": 4,
            "col": 1
          }
        ]
      ]
    ],
    {
      "type": "newline",
      "value": "\n",
      "text": "\n",
      "offset": 11,
      "lineBreaks": 1,
      "line": 4,
      "col": 3
    },
    [
      [
        {
          "type": "comment",
          "value": "/",
          "text": "//",
          "offset": 12,
          "lineBreaks": 0,
          "line": 5,
          "col": 1
        }
      ]
    ]
  ]
]

我不太明白为什么生成的数组嵌套如此之深,以及是否有办法让每个元素都保持平坦。相同语义级别的类似注释应该是一个数组的一部分,而不是嵌套的。

4

1 回答 1

0

好的,事实证明,如果您不希望它们嵌套在数组中,则必须将后处理器传递给每个规则。例如像这样:

main ->
    element {% d => ({ type: "main_element", data: d[0]}) %}
  | main %newline element {% d => ({ type: "main_element", data: d[2], main_data: d[0]}) %}


element -> %comment
{% d => ({ type: "element", data: d[0]}) %}

这将产生预期的扁平结构:

[
  {
    "type": "main_element",
    "data": {
      "type": "element",
      "data": {
        "type": "comment",
        "value": "/",
        "text": "//",
        "offset": 12,
        "lineBreaks": 0,
        "line": 5,
        "col": 1
      }
    },
    "main_data": {
      "type": "main_element",
      "data": {
        "type": "element",
        "data": {
          "type": "comment",
          "value": "/",
          "text": "//",
          "offset": 9,
          "lineBreaks": 0,
          "line": 4,
          "col": 1
        }
      },
      "main_data": {
        "type": "main_element",
        "data": {
          "type": "element",
          "data": {
            "type": "comment",
            "value": "/",
            "text": "//",
            "offset": 6,
            "lineBreaks": 0,
            "line": 3,
            "col": 1
          }
        },
        "main_data": {
          "type": "main_element",
          "data": {
            "type": "element",
            "data": {
              "type": "comment",
              "value": "/",
              "text": "//",
              "offset": 3,
              "lineBreaks": 0,
              "line": 2,
              "col": 1
            }
          },
          "main_data": {
            "type": "main_element",
            "data": {
              "type": "element",
              "data": {
                "type": "comment",
                "value": "/",
                "text": "//",
                "offset": 0,
                "lineBreaks": 0,
                "line": 1,
                "col": 1
              }
            }
          }
        }
      }
    }
  }
]
于 2021-12-21T09:19:19.243 回答