Parse indentation level with PEG.js

后端 未结 3 1570
离开以前
离开以前 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:34

    Here is a fix for @Jakub Kulhan´s grammar which works in PEG.js v 0.10.0. The last line needs to be changed to = &{ indent = indentStack.pop(); return true;} because PEG.js now does not allow standalone actions ({...}) in a grammar any more. This line is now a predicate (&{...}) which always succeeds (return true;).

    i also removed the pos = offset; because it gives an error offset is not defined. Probably Jakub was referring to some global variable available in older versions of PEG.js. PEG.js now provides the location() function which returns an object which contains offset and other information.

    // 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(""); })
    
    DEDENT
      = &{ indent = indentStack.pop(); return true;}
    

    Starting with v 0.11.0 PEG.js also supports the Value Plucking operator, @ which would allow to write this grammar even simpler, but as it is currently not in the online parser i will refrain from adding it to this example.

提交回复
热议问题