Parse indentation level with PEG.js

后端 未结 3 1511
离开以前
离开以前 2021-02-01 10:20

I have essentially the same question as PEG for Python style indentation, but I\'d like to get a little more direction regarding this answer.

The answer successfully gen

3条回答
  •  野的像风
    2021-02-01 10:37

    Parser:

    // do not use result cache, nor line and column tracking
    
    { var indentStack = [], indent = ""; }
    
    start
      = INDENT? l:line
        { return l; }
    
    line
      = SAMEDENT line:(!EOL c:. { return c; })+ EOL?
        children:( INDENT c:line* DEDENT { return c; })?
        { var o = {}; o[line] = children; return children ? o : line.join(""); }
    
    EOL
      = "\r\n" / "\n" / "\r"
    
    SAMEDENT
      = i:[ \t]* &{ return i.join("") === indent; }
    
    INDENT
      = &(i:[ \t]+ &{ return i.length > indent.length; }
          { indentStack.push(indent); indent = i.join(""); pos = offset; })
    
    DEDENT
      = { indent = indentStack.pop(); }
    

    Input:

    a
      b
      c
      d
        z
        y
        x
    

    Output:

    {
       "a": [
          "b",
          "c",
          {
             "d": [
                "z",
                "y",
                "x"
             ]
          }
       ]
    }
    

    It cannot parse an empty object (last x), however, it should be easy to solve. Trick here is the SAMEDENT rule, it succeeds when indentation level hasn't changed. INDENT and DEDENT change current indentation level without changing position in text pos = offset.

提交回复
热议问题