1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
{
const INDENT_STEP = 2;
let indentLevel = 0;
}
Start
= PropertyStatements
ItemStatements
= statements:ItemStatement* { return [].concat(... statements) }
ItemStatement
= Samedent "-" B value:Expression { return value }
PropertyStatements
= statements:PropertyStatement* { return Object.assign({}, ... statements) }
PropertyStatement
= B? ("#" (!EOL .)+)? EOL_ANY+ { return {} }
/ Samedent property:Name B? ":" B? value:Expression { return {[property]: value} }
// Compatibility with the old lockfile format (key-values without a ":")
/ Samedent property:LegacyName B? ":" B? value:Expression { return {[property]: value} }
// Compatibility with the old lockfile format (key-values without a ":")
/ Samedent property:LegacyName B value:LegacyLiteral EOL_ANY+ { return {[property]: value} }
// Compatibility with the old lockfile format (multiple keys for a same value)
/ Samedent property:LegacyName others:(B? "," B? other:LegacyName { return other })+ B? ":" B? value:Expression { return Object.assign({}, ... [property].concat(others).map(property => ({[property]: value}))) }
Expression
= &(EOL Extradent "-" B) EOL_ANY Indent statements:ItemStatements Dedent { return statements }
/ EOL Indent statements:PropertyStatements Dedent { return statements }
/ expression:Literal EOL_ANY+ { return expression }
Samedent "correct indentation"
= spaces:" "* &{ return spaces.length === indentLevel * INDENT_STEP }
Extradent
= spaces:" "* &{ return spaces.length === (indentLevel + 1) * INDENT_STEP }
Indent
= &{ indentLevel++; return true }
Dedent
= &{ indentLevel--; return true }
Name
= string
/ pseudostring
LegacyName
= string
/ pseudostringLegacy+ { return text() }
Literal
= null
/ boolean
/ string
/ pseudostring
LegacyLiteral
= null
/ string
/ pseudostringLegacy
/**
*/
pseudostring "pseudostring"
= [^\r\n\t ?:,\][{}#&*!|>'"%@`-] (B? [^\r\n\t ,\][{}:#"'])* { return text().replace(/^ *| *$/g, '') }
pseudostringLegacy
= "--"? [a-zA-Z\/0-9] [^\r\n\t :,]* { return text().replace(/^ *| *$/g, '') }
/**
* String parsing
*/
null
= "null" { return null }
boolean
= "true" { return true }
/ "false" { return false }
string "string"
= '"' '"' { return "" }
/ '"' chars:chars '"' { return chars }
chars
= chars:char+ { return chars.join(``) }
char
= [^"\\\0-\x1F\x7f]
/ '\\"' { return `"` }
/ "\\\\" { return `\\` }
/ "\\/" { return `/` }
/ "\\b" { return `\b` }
/ "\\f" { return `\f` }
/ "\\n" { return `\n` }
/ "\\r" { return `\r` }
/ "\\t" { return `\t` }
/ "\\u" h1:hexDigit h2:hexDigit h3:hexDigit h4:hexDigit {
return String.fromCharCode(parseInt(`0x${h1}${h2}${h3}${h4}`));
}
hexDigit
= [0-9a-fA-F]
/**
* Spaces
*/
B "blank space"
= [ \t]+
S "white space"
= [ \t\n\r]+
EOL_ANY
= EOL (B? EOL)*
EOL
= "\r\n"
/ "\n"
/ "\r"
|