Pegjs: рдЕрдиреБрдХреНрд░рдо рд╕реЗ рдПрдХрд▓ рд╡рд╛рдкрд╕реА рдореВрд▓реНрдп рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рддрд░реАрдХрд╛ рдкреНрд░рджрд╛рди рдХрд░реЗрдВ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 29 рдЬрдире░ 2014  ┬╖  21рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pegjs/pegjs

рдпрд╣ рдореЗрд░реЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕рд╛рдорд╛рдиреНрдп рд╣реИред рдореИрдВ init рд▓реЗрдмрд▓ рдореЗрдВ рдЕрдиреБрдХреНрд░рдо рдХреЗ рдХреЗрд╡рд▓ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рднрд╛рдЧ рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдмрд╕ рдЕрд╕рд╛рдЗрдирдореЗрдВрдЯ рдПрдХреНрд╕рдкреНрд░реЗрд╢рдиред

pattern:Pattern init:(_ "=" _ a:AssignmentExpression {return a})?

рдореИрдВ рдЕрдиреБрд╢рдВрд╕рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдХрд┐ рдЖрдк @ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЬреЛрдбрд╝реЗрдВ рдЬреЛ рдЕрдиреБрдХреНрд░рдо рд╕реЗ рдХреЗрд╡рд▓ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рд▓реМрдЯрд╛рдПрдЧрд╛ред рддреЛ рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:

pattern:Pattern init:(_ "=" _ @AssignmentExpression)?

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ:

  • #427 рдХрд┐рд╕реА рдирд┐рдпрдо рдореЗрдВ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдХреНрд░рд┐рдпрд╛ рдХреЗ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╡реНрдпрдВрдЬрдХ рдХреЗ рдорд┐рд▓рд╛рди рдкрд░рд┐рдгрд╛рдо рдХреЛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ
  • #545 рд╡реНрдпрд╛рдХрд░рдг рдХреЛ рдЫреЛрдЯрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░рд▓ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдПрдХреНрд╕рдЯреЗрдВрд╢рди

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдХреНрдпрд╛ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА npm рдкрд░ рджреЗрд╡ рдЯреИрдЧ рдХреЗ рд▓рд┐рдП рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛?

https://www.npmjs.com/package/pegjs/v/0.11.0-dev.325

рд╕рднреА 21 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдореИрдВ рдорд╛рдирддрд╛ рд╣реВрдВ рдХрд┐ рдпрд╣ рдПрдХ рдЖрдо рд╕рдорд╕реНрдпрд╛ рд╣реИред рд▓реЗрдХрд┐рди рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рд╣рд▓ рдХрд░рдиреЗ рд▓рд╛рдпрдХ рд╣реИ рдпрд╛ рдирд╣реАрдВред рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдЕрдХреНрд╕рд░ рдкрд░реНрдпрд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХреНрдпрд╛ рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдХреЗ рдкреАрдИрдЬреА.рдЬреЗрдПрд╕ рдореЗрдВ рдЬрдЯрд┐рд▓рддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рджрд░реНрдж рдХрд╛ рдХрд╛рд░рдг рдмрдирддрд╛ рд╣реИ, рдЪрд╛рд╣реЗ рд╡рд╣ рдХреБрдЫ рднреА рд╣реЛред

рдореИрдВ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдЦреБрд▓рд╛ рд░рдЦреВрдВрдЧрд╛ рдФрд░ 1.0.0 рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рд╡рд┐рдЪрд╛рд░ рдХреЗ рд▓рд┐рдП рдЪрд┐рд╣реНрдирд┐рдд рдХрд░реВрдВрдЧрд╛ред

рдорд╛рдирд╛ред рдореИрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЗрд╕реЗ 1.0 рдореЗрдВ рджреЗрдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореИрдВ @ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЗрддрдирд╛ рдЙрддреНрд╕рд╛рд╣рд┐рдд рдирд╣реАрдВ рд╣реВрдВред рдЖрдИрдПрдордПрдЪрдУ рдРрд╕рд╛ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдмреЗрд╣рддрд░ рд╡рд┐рдЪрд╛рд░ рд╣реЛрдЧрд╛: рдпрджрд┐ рдХреЗрд╡рд▓ рдПрдХ "рд╢реАрд░реНрд╖ рд╕реНрддрд░" рд▓реЗрдмрд▓ рд╣реИ рддреЛ рдЙрд╕ рд▓реЗрдмрд▓ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд╛рдкрд╕ рдХрд░ рджреЗрдВред рддреЛ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп:

rule = space* a:(text space+ otherText)+ newLine* { return a; }

рдЖрдкрдХреЛ рдорд┐рд▓рд╛:

rule = space* a:(text space+ otherText)+ newLine*

рдФрд░ рдЬрдм рд▓реЗрдмрд▓ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рд╕рд╛рд░реНрдердХ рдХреБрдЫ рднреА рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕рдХреА рдЕрдиреБрдорддрд┐ рджреЗрдВ:

rule = space* :(text space+ otherText)+ newLine*

рдЗрд╕рд▓рд┐рдП рд▓реЗрдмрд▓ рдирд╛рдо рдХреЛ рдмрд┐рд▓реНрдХреБрд▓ рдЫреЛрдбрд╝ рджреЗрдВред

@mulderr рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @ рдСрдкрд░реЗрдЯрд░ рдмреЗрд╣рддрд░ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХреБрдЫ рдХрд░рдиреЗ рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдореИрдВ рдХрд┐рд╕реА рдФрд░ рдХреЗ рдХреЛрдб рдХреЛ рдкрдврд╝рддрд╛ рд╣реВрдВ рдЬреЛ рдЙрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдореБрдЭреЗ рдпрд╣ рд╕рдордЭрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЙрд╕рдиреЗ рд╡рд╣рд╛рдВ рдХреНрдпрд╛ рдХрд┐рдпрд╛ рд╣реИ, рдореБрдЭреЗ рдХрд╛рдлреА рдЧреБрдЧрд▓ рд╕реЗ рдЧреБрдЬрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдПрдХ рд╕реНрдкрд╖реНрдЯ рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдореБрдЭреЗ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реЛрдВ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ рдЦреЛрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдорд┐рд▓ рдЬрд╛рдПрдЧреАред

+1 рдХреЗ рд▓рд┐рдП @ - рдпрд╣ рдореЗрд░реЗ рдкреВрд░реЗ рдХреЛрдб рдореЗрдВ рдмрд╣реБрдд рдХреБрдЫ рд░рд┐рдХрд░реНрд╕ рдХрд░рддрд╛ рд╣реИред

рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рдХреБрдЫ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рддрд░реАрдХреЗ рдХреЗ рд▓рд┐рдП +1ред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рджрд░реНрдж JS рдореЗрдВ рд╡рд░реНрдмреЛрдЬрд╝ function рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рд╕рдорд╛рди рд╣реИ, рдЬрд┐рд╕реЗ ES6 рдПрд░реЛ рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдмреЛрдзрд┐рдд

rule = (space* a:(text space+ otherText) newLine*) => a

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдмрд╣реБрдд рд▓рдЪреАрд▓рд╛ рд╣реИ, рдЕрднреА рднреА рд╕реНрдкрд╖реНрдЯ рд╣реИ (рдПрдХ рд▓рд╛ @wildeyes рдХреА рдЪрд┐рдВрддрд╛), рдФрд░ рдЬрдЯрд┐рд▓рддрд╛ рдЬреЛрдбрд╝рдиреЗ рдХреА рддрд░рд╣ рдХрдо рд▓рдЧрддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдФрд░ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рджреЛрдиреЛрдВ рдореЗрдВ рдпрд╣ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдЬреЗрдПрд╕ рдХреЛ рд░реЛрдХрддрд╛ рд╣реИ ...

рдореИрдВ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдЪрд┐рддреНрд░рд┐рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:

additive = left:multiplicative "+" right:additive {= left + right; }

рдЬрд╣рд╛рдВ = (рдЪрд░рд┐рддреНрд░ рдХреА рдкрд╕рдВрдж рдкрд░ рдмрд╣рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рддрдВрддреНрд░ рдорд╣рд╕реВрд╕ рдХрд░реЗрдВ) рдПрдХ рдмреНрд▓реЙрдХ рдХреЗ рдкрд╣рд▓реЗ рдЧреИрд░-рд╡реНрд╣рд╛рдЯреНрд╕рдПрдк рдЪрд░рд┐рддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ return рдореЗрдВ рдмрджрд▓ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдпрд╣ рдкреВрд░реНрдг рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рднреА рдХрд╛рдо рдХрд░реЗрдЧрд╛ рдФрд░ рдкрд░рд┐рд╡рд░реНрддрди рдкрд╛рд╕ рдХреЗ рд╕рд╛рде рд╕рдВрднрд╡ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдХреЛрдИ рдЦрдмрд░? additive = left:multiplicative "+" right:additive { => left + right } рдХреНрдпреЛрдВ рдирд╣реАрдВ?

рдпрд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рд╕рд╣рдЬ рдорд╣рд╕реВрд╕ рдХрд░реЗрдЧрд╛ рдХрд┐ рддреАрд░ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ ( (left, right) => left + right )ред

рдЖрдкрдХреА parser.pegjs рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдерд╛рдиреЛрдВ рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рджреНрд╡рд╛рд░рд╛ рдмреЗрд╣рддрд░ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

  = head:ActionExpression tail:(__ "/" __ ActionExpression)* {
      return tail.length > 0
        ? {
            type: "choice",
            alternatives: buildList(head, tail, 3),
            location: location()
          }
        : head;
    }

рдмрд┐рд▓реНрдбрд▓рд┐рд╕реНрдЯ рдХреЙрд▓ рдореЗрдВ рдореИрдЬрд┐рдХ рдирдВрдмрд░ 3 рдХреЗ рдХрд╛рд░рдг рдирд╛рдЬреБрдХ рд╣реИ рдЬреЛ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдЖрдкрдХреЗ рдПрдХреНрд╢рдирдПрдХреНрд╕рдкреНрд░реЗрд╕ рдХреА рд╕реНрдерд┐рддрд┐ рд╕реЗ рдЧреИрд░-рд╕рд╣рдЬ рд░реВрдк рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реБрдЖ рд╣реИред рджреЛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдСрдкрд░реЗрд╢рдиреЛрдВ рдХреЛ рдорд┐рд▓рд╛рдХрд░ рдмрд┐рд▓реНрдбрд▓рд┐рд╕реНрдЯ рдлрд╝рдВрдХреНрд╢рди рд╕реНрд╡рдпрдВ рдЬрдЯрд┐рд▓ рд╣реИред @ рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдФрд░ es6 рд╕реНрдкреНрд░реЗрдб рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдпрд╣ рдХреНрд▓реАрдирд░ рдмрди рдЬрд╛рддрд╛ рд╣реИ:

  = head:ActionExpression tail:(__ "/" __ @ActionExpression)* {
      return tail.length > 0
        ? {
            type: "choice",
            alternatives: [head, ...tail],
            location: location()
          }
        : head;
    }

рдЪреВрдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рд╣реА рд╕рд┐рдВрдЯреИрдХреНрдЯрд┐рдХ рдЪреАрдиреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдкрд╛рд░реНрд╕рд░ рдореЗрдВ рдПрдХреНрд╢рдирдПрдХреНрд╕рдкреНрд░реЗрд╕ рдХреЛ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рдХреЗ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рдЖрдкрдХреЗ рдкрд╛рд░реНрд╕рд░ рдореЗрдВ рдЬреЛрдбрд╝рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдерд╛ред

  = ExtractSequenceExpression
  / expression:SequenceExpression code:(__ CodeBlock)? {
      return code !== null
        ? {
            type: "action",
            expression: expression,
            code: code[1],
            location: location()
          }
        : expression;
    }

ExtractExpression
  = "@" __ expression:PrefixedExpression {
      return {
        type: "labeled",
        label: "value",
        expression: expression,
        location: location()
      };
    }

ExtractSequenceExpression
  = head:(__ PrefixedExpression)* _ extract:ExtractExpression tail:(__ PrefixedExpression)* {
      return {
        type: "action",
        expression: {
          type: "sequence",
          elements: extractList(head, 1).concat(extract, extractList(tail, 1)),
          location: location()
        },
        code: "return value;",
        location: location()
      }
    }

рдореИрдВрдиреЗ рдПрдХ рд╕рд╛рд░ рдореЗрдВ рдЬрд╛рдБрдЪ рдХреА рдЬреЛ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдХреИрд╕реЗ @ рдиреЛрдЯреЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ parser.pegjs рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

ExtractOptional, ExtractList рдФрд░ buildList рдлрд╝рдВрдХреНрд╢рдВрд╕ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╣рдЯрд╛ рджрд┐рдП рдЧрдП рд╣реИрдВ, рдХреНрдпреЛрдВрдХрд┐ @ рдиреЛрдЯреЗрд╢рди рдЕрдиреБрдХреНрд░рдо рд╕реЗ рд╡рд╛рдВрдЫрд┐рдд рдорд╛рди рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдЫреЛрдЯрд╛ рдмрдирд╛рддрд╛ рд╣реИред

https://gist.github.com/krisnye/a6c2aac94ffc0e222754c52d69e44b83

@krisnye рдпрд╣рд╛рдВ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ рдХрд┐ рдЕрдЧрд░ рдФрд░ рднреА рд╕рд┐рдВрдЯреИрдХреНрд╕ рдЪреАрдиреА рд╣реЛрддреА рддреЛ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛:

https://github.com/polkovnikov-ph/newpeg/blob/master/parse.np

рдореИрдВ рдЗрд╕ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЗ рд▓рд┐рдП :: рдФрд░ # рдХреЗ рд╕рдВрдпреЛрдЬрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ ( #545 рдореЗрдВ рдореЗрд░рд╛ рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг/рдХрд╛рд░рдг рджреЗрдЦреЗрдВ):

  • :: рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдСрдкрд░реЗрдЯрд░
  • # рд╡рд┐рд╕реНрддрд╛рд░ рдСрдкрд░реЗрдЯрд░
// this is imported into grammar
class List extends Array {
  constructor() { this.isList = true; }
}

// grammar
number = _ ::value+ _
value = ::int #(_ "," _ ::int)* { return new List(); }
int = $[0-9]+
_ = [ \t]*
  • рдирд┐рдпрдо рдХреЗ рдореВрд▓ рдЕрдиреБрдХреНрд░рдо рдкрд░, :: рдирд┐рдпрдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рдПрдЧрд╛
  • рдиреЗрд╕реНрдЯреЗрдб рдЕрдиреБрдХреНрд░рдо рдореЗрдВ, :: рдиреЗрд╕реНрдЯреЗрдб рдПрдХреНрд╕рдкреНрд░реЗрд╢рди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдЕрдиреБрдХреНрд░рдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рд▓реМрдЯрд╛рдПрдЧрд╛
  • рдпрджрд┐ рдЕрдзрд┐рдХ рд╣реИ рддреЛ рдПрдХ :: рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЪрд┐рд╣реНрдирд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛
  • рдпрджрд┐ # рдХрд╛ рдЙрдкрдпреЛрдЧ рдиреЗрд╕реНрдЯреЗрдб рдЕрдиреБрдХреНрд░рдо рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ :: , рддреЛ рдкрд░рд┐рдгрд╛рдо рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреА рд╕рд░рдгреА рдореЗрдВ рдзрдХреЗрд▓ рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗ
  • рдпрджрд┐ рдирд┐рдпрдо рдореЗрдВ :: / # рдХреЗ рд╕рд╛рде рдПрдХ рдХреЛрдб рдмреНрд▓реЙрдХ рд╣реИ, рддреЛ рдкрд╣рд▓реЗ рдЗрд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ, рдлрд┐рд░ рдкрд░рд┐рдгрд╛рдо push рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

рдЗрди рдирд┐рдпрдореЛрдВ рдХрд╛ рдкрд╛рд▓рди рдХрд░рддреЗ рд╣реБрдП, рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдХреЗ рдЬреЗрдирд░реЗрдЯ рдХрд┐рдП рдЧрдП рдкрд╛рд░реНрд╕рд░ рдХреЛ 09 , 55, 7 рдХрд░рдиреЗ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧрд╛:

result = [
    isList: true
    0: "09"
    1: "55"
    2: "7"
]

result instanceof Array # true in ES2015+ enviroments
result instanceof List # true

рдирд┐рдпрдо рдХреЗ рдореВрд▓ рдЕрдиреБрдХреНрд░рдо рдкрд░ :: рдирд┐рдпрдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рдПрдЧрд╛
рдиреЗрд╕реНрдЯреЗрдб рдЕрдиреБрдХреНрд░рдо рдореЗрдВ, :: рдЕрдиреБрдХреНрд░рдо рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ рдиреЗрд╕реНрдЯреЗрдб рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд▓реМрдЯрд╛рдПрдЧрд╛

рдпреЗ рдЕрд▓рдЧ рдХреНрдпреЛрдВ рд╣реИрдВ? рдХреНрдпреЛрдВ рди рдХреЗрд╡рд▓ " :: рдПрдХ рдЕрдиреБрдХреНрд░рдо рдкрд░ рдЕрдиреБрдХреНрд░рдо рдХреЗ рддрд░реНрдХ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдмрдирд╛рддрд╛ рд╣реИ"?

рдпрджрд┐ рдЕрдзрд┐рдХ рд╣реИ рддреЛ рдПрдХ :: рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЪрд┐рд╣реНрдирд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдПрдХ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд╛рдкрд╕ рдХрд░ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред

рдпрд╣ рдПрдХ рдмреБрд░рд╛ рд╡рд┐рдЪрд╛рд░ рд╣реИред рдмрд▓реНрдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдЬрдорд╛рдирдд рд╣реЛ рдЬрд╛рдПрдЧреАред рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЕрд░реНрде рдирд╣реАрдВ рд╣реИред (рдпрд╣ рдПрдХ рдЯреБрдкрд▓ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╡реЗ рдЬреЗрдПрд╕ рдореЗрдВ рдХрд╛рдлреА рдмреЗрдХрд╛рд░ рд╣реИрдВред)

рдпрджрд┐ рдЕрдиреБрдХреНрд░рдо рдкрд░ # рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдо Array#concat'ed рдХреЛ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

рдЕрдм рдпрд╣ рдПрдХ рднрдпрд╛рдирдХ рд╡рд┐рдЪрд╛рд░ рд╣реИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрд╛рд╣рд░реА { return xs.push(x), xs } рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреАрдЪрдбрд╝ рд╣реИред рдРрд╕рд╛ рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓рд╛ рдмрдирд╛рдиреЗ рдХрд╛ рдХреЛрдИ рдорддрд▓рдм рдирд╣реАрдВ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░рдпреБрдХреНрдд рдирд┐рдпрдореЛрдВ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рд┐рдВрдЧрд▓-рдЪрд╛рд░ рдЕрдиреБрдХреНрд░рдо рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпрджрд┐ рдирд┐рдпрдо рдореЗрдВ ::/# рдХреЗ рд╕рд╛рде рдПрдХ рдХреЛрдб рдмреНрд▓реЙрдХ рд╣реИ, рддреЛ рдЗрд╕реЗ рдкрд╣рд▓реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ, рдлрд┐рд░ рдкрд░рд┐рдгрд╛рдо рдкреБрд╢ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

рддреЛ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ f = ::"a" { return "b" } рдореЗрдВ ["a", "b"] рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

09 рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реИред 55: 7 рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдкрд╛рд░реНрд╕рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛:

рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдХреЛрдИ . рдпрд╛ : рдЙрд▓реНрд▓реЗрдЦрд┐рдд рдирд╣реАрдВ рд╣реИред рдореИрдВ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рд╡рд░реНрдгрд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреИрд╕реЗ рдкрд░рд┐рдгрд╛рдо рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред

рд╕рдВрдЦреНрдпрд╛ = _ :: рдорд╛рди+ _

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ _ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдпрд╛ рддреЛ рджрд╛рдИрдВ рдУрд░ рдпрд╛ рдЯреЛрдХрди рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдЪреБрдирд╛ рдЧрдпрд╛ рдкрдХреНрд╖ред рдпрджрд┐ рдпрд╣ рджрд╛рдИрдВ рдУрд░ рд╣реИ, рддреЛ рдореБрдЦреНрдп рдирд┐рдпрдо рднреА _ рд╢реБрд░реВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрддред

start = _ value
value = ::int #("," _ ::int)* { return new List(); }
number = ::$[0-9]+ _
_ = [ \t]*

рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рд┐рдд рдХрдХреНрд╖рд╛рдУрдВ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг (рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд▓рд┐рдП рдирд╣реАрдВ):

ClassMethod
  = head:FunctionHead __ params:FunctionParameters __ body:FunctionBody {
      return {
        type: "method",
        name: head[ 1 ],
        modifiers: head[ 0 ],
        params: params,
        body: body
      };
    }

// `::` inside the zero_or_more "( ... )*" builds an array as we want,
// so this rule returns `[FunctionModifier[], Identifier]` as expected
MethodHead = (::MethodModifier __)* ("function" __)? ::Identifier

// https://github.com/tc39/proposal-class-fields#private-fields
MethodModifier
  = "#"
  / "static"
  / "async"

FunctionParameters
  = "(" __ head:FunctionParam tail:(__ "," __ ::FunctionParam)* __ ")" {
      // due to `::`, tail is `FunctionParam[]` instead of `[__, "", __, FunctionParam][]`
      return [ head ].concat( tail );
    }
    / "(" __ ")" { return []; }

FunctionParam
  = name:Identifier value:(__ "=" __ ::Expression)? {
      return { name, value };
    }

FunctionBody = "{" __ ::SourceElements? __ "}"

рдпреЗ рдЕрд▓рдЧ рдХреНрдпреЛрдВ рд╣реИрдВ? рдЕрдиреБрдХреНрд░рдо рдкрд░ рдХреЗрд╡рд▓ :: рдХреНрдпреЛрдВ рдирд╣реАрдВ рдЕрдиреБрдХреНрд░рдо рдХреЗ рддрд░реНрдХ рдкрд░рд┐рдгрд╛рдо рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдмрдирд╛рддрд╛ рд╣реИ"?

рдХреНрдпрд╛ рдпрд╣ рд╡рд╣реА рдмрд╛рдд рдирд╣реАрдВ рд╣реИ? рдореИрдВрдиреЗ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реНрдкрд╖реНрдЯ рдХрд┐рдпрд╛ рд╣реИ рддрд╛рдХрд┐ MethodHead , FunctionParam рдФрд░ FunctionBody рдЬреИрд╕реЗ рд╡рд┐рднрд┐рдиреНрди рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓реЛрдВ рдХреЗ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдЖрд╕рд╛рдиреА рд╕реЗ рд╕рдордЭрд╛ рдЬрд╛ рд╕рдХреЗред

рдХрдИ рдкреНрд░рдХрд╛рд░ рдХреЗ рдорд╛рдиреЛрдВ рдХреЛ рдПрдХ рд╕рд░рдгреА рдореЗрдВ рд╕рдВрдпреЛрдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдЕрд░реНрде рдирд╣реАрдВ рд╣реИред (рдпрд╣ рдПрдХ рдЯреБрдкрд▓ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рд╡реЗ рдЬреЗрдПрд╕ рдореЗрдВ рдХрд╛рдлреА рдмреЗрдХрд╛рд░ рд╣реИрдВред)

рдПрдПрд╕рдЯреА (рдЬреЗрдирд░реЗрдЯ рдХрд┐рдП рдЧрдП рдкрд╛рд░реНрд╕рд░ рдХрд╛ рд╕рдмрд╕реЗ рдЖрдо рдкрд░рд┐рдгрд╛рдо) рдмрдирд╛рддреЗ рд╕рдордп, рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрдЬрд╛рдп MethodHead рдЬреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЛ рд╕рд░рд▓ рдмрдирд╛ рджреЗрдЧрд╛:

MethodHead
  = modifiers:(::MethodModifier __)* ("function" __)? name:Identifier {
      return [ modifiers, name ];
    }

рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рд╕реЛрдЪрдиреЗ рдХреЗ рдмрд╛рдж, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдпрд╣ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рддрд╛ рд╣реИ, рдпрд╣ рдбреЗрд╡рд▓рдкрд░ рдХреА рдЧрд▓рддреА рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рднреА рдЦреЛрд▓рддрд╛ рд╣реИ (рдпрд╛ рддреЛ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╡реЗ рдЕрдкрдиреЗ рд╡реНрдпрд╛рдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рдХреНрд░рд┐рдпрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдХреИрд╕реЗ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ), рдЗрд╕рд▓рд┐рдП рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдЗрд╕реЗ рдбрд╛рд▓рдирд╛ multipleSingleReturns рдЬреИрд╕реЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдкреАрдЫреЗ рдХреЗрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ: false ) рдпрд╣рд╛рдВ рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣реЛрдЧрд╛ (рдпрджрд┐ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛ рд▓рд╛рдЧреВ рд╣реЛ рдЬрд╛рддреА рд╣реИ рддреЛ)ред

рдпрджрд┐ рдЕрдиреБрдХреНрд░рдо рдкрд░ # рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдо Array#concat'ed рдХреЛ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

рдЕрдм рдпрд╣ рдПрдХ рднрдпрд╛рдирдХ рд╡рд┐рдЪрд╛рд░ рд╣реИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдмрд╛рд╣рд░реА рд╕реЗ рдЫреБрдЯрдХрд╛рд░рд╛ рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреАрдЪрдбрд╝ рд╣реИ {рд╡рд╛рдкрд╕реА xs.push (x), xs}

рдпрд╣ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рднреА рдорджрдж рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ FunctionParameters рдЬрд╣рд╛рдВ рдпрд╣ рд▓рд┐рдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛:

// should always return `FunctionParam[]`
FunctionParameters
  = "(" __ ::FunctionParam #(__ "," __ ::FunctionParam)* __ ")"
  / "(" __ ")" { return []; }

рдЗрд╕реЗ рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рдкреИрд░рд╛рдореАрдЯрд░рдпреБрдХреНрдд рдирд┐рдпрдореЛрдВ рдХреЗ рд╕рд╛рде рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ

рдореИрдВ рд╕реЛрдЪ рд░рд╣рд╛ рд╣реВрдВ рдХрд┐ рдореБрдЭреЗ рдкреИрд░рд╛рдореАрдЯрд░рдпреБрдХреНрдд рдирд┐рдпрдореЛрдВ рд╕реЗ рдкрд╣рд▓реЗ рд╕рд┐рдВрдЧрд▓ рд░рд┐рдЯрд░реНрди рд╡реИрд▓реНрдпреВ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдЕрднреА рднреА рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдмрд╛рдж рдореЗрдВ рдХреИрд╕реЗ рдЖрдЧреЗ рдмрдврд╝рдирд╛ рд╣реИ (рдореБрдЭреЗ рдЯреЗрдореНрдкрд▓реЗрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдкрд╕рдВрдж рд╣реИ, рд▓реЗрдХрд┐рди rule < .., .. > = .. рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рд╢реЛрд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдкреАрдИрдЬреА.рдЬреЗрдПрд╕ рд╡реНрдпрд╛рдХрд░рдг, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕реЗ рдмреЗрд╣рддрд░ рддрд░реАрдХреЗ рд╕реЗ рдлрд┐рдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдереЛрдбрд╝рд╛ рд╕рд╛ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░ рд░рд╣рд╛ рд╣реВрдВ), рд▓реЗрдХрд┐рди рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдореБрджреНрджрд╛ рд╣реИред

рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рд╕рд╛рд░реЗ рд╕рд┐рдВрдЧрд▓-рдЪрд╛рд░ рдЕрдиреБрдХреНрд░рдо рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдмрд░реНрдмрд╛рдж рдирд╣реАрдВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред

рдпрд╣ рд╕рдЪ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ рдЬрдм рдЕрд╡рд╕рд░ рд╕реНрд╡рдпрдВ рдЗрд╕ рддрд░рд╣ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЙрддрдирд╛ рд╣реА рдмреБрд░рд╛ рд╣реИред

рдореИрдВрдиреЗ рдЗрд╕ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП # рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрд╛ рдерд╛, рдпрд╣ рдпрд╛рдж рд░рдЦрдиреЗ рдХреЗ рдмрд╛рдж рдХрд┐ рдЗрд╕реЗ рдХреБрдЫ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдпрд╣ рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдпрд╣ рдЙрдкрдпреЛрдЧ рдорд╛рдорд▓рд╛ рдпрд╣рд╛рдВ рдХрд╡рд░ рдХрд░ рд░рд╣рд╛ рд╣реИред

рддреЛ рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ f = ::"a" { return "b" } рдореЗрдВ ["a", "b"] рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП?

рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкрд╛рд░реНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рдХреЛрдб рдмреНрд▓реЙрдХ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рд╡рд╣ рдПрдХ рд╕рд░рдгреА-рдЬреИрд╕реА рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рдП рдЬрд┐рд╕рдореЗрдВ push рд╡рд┐рдзрд┐ рд╣реЛ (рдЗрд╕рд▓рд┐рдП рдпрд╣ f = ::"a" { return [ "b" ] } рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ [ "b", "a" ] рд▓реМрдЯрд╛рдПрдЧрд╛), рдЗрд╕рд▓рд┐рдП рди рдХреЗрд╡рд▓ рд╕рд░рдгрд┐рдпреЛрдВ рдореЗрдВ рдзрдХреЗрд▓рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рдХрд╕реНрдЯрдо рдиреЛрдбреНрд╕ рдЬрд┐рдирдХреЗ рдкрд╛рд╕ рд╕рдорд╛рди рддрд░реАрдХреЗ рд╕реЗ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╡рд┐рдзрд┐ рд▓рд╛рдЧреВ рд╣реЛрддреА рд╣реИред рдпрд╣ рджреЗрдЦрдиреЗ рдХреЗ рдмрд╛рдж рдХрд┐ рдпрд╣ рдкрдврд╝рдиреЗ рдХреЗ рдмрд╛рдж рдЖрдкрдХреЗ рд╡рд┐рдЪрд╛рд░ рдХреА рдкрд╣рд▓реА рдЯреНрд░реЗрди рдХреИрд╕реА рдереА, рдХреНрдпрд╛ рдпрд╣ рд╕рдордЭрдирд╛ рдмреЗрд╣рддрд░ рд╣реЛрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдпрд╣ pushSingleReturns рдЬреИрд╕реЗ рд╡рд┐рдХрд▓реНрдк рдХреЗ рдкреАрдЫреЗ рдерд╛? рдпрджрд┐ рдпрд╣ рд╡рд┐рдХрд▓реНрдк false (рдбрд┐рдлрд╝реЙрд▓реНрдЯ) рд╣реИ, рддреЛ рдПрдХ рдЕрдиреБрдХреНрд░рдо рдХреЗ рдмрд╛рдж рдПрдХ рдХреЛрдб рдмреНрд▓реЙрдХ рд╣реЛрдиреЗ рд╕реЗ рдЬрд┐рд╕рдореЗрдВ рдПрдХрд▓ рд░рд┐рдЯрд░реНрди рдорд╛рди рд╣реЛрддреЗ рд╣реИрдВ, рдПрдХ рддреНрд░реБрдЯрд┐ рд╣реЛрдЧреАред

09 рдЧреБрдЬрд░ рд░рд╣рд╛ рд╣реИред 55: 7 рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдкрд╛рд░реНрд╕рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдЧрд╛:

рдРрд╕рд╛ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдХреЛрдИ . рдпрд╛ : рдЙрд▓реНрд▓реЗрдЦрд┐рдд рдирд╣реАрдВ рд╣реИред

рдХреНрд╖рдорд╛ рдХрд░реЗрдВ, рдпрд╣ рдПрдХ рдЧрд▓рддреА рдереА рдЬреЛ рдореИрдВрдиреЗ рджрд┐рдП рдЧрдП рдЙрджрд╛рд╣рд░рдг рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдиреЗ рдкрд░ рдЫреЛрдбрд╝ рджреА рдереАред

рд╕рд╛рде рд╣реА _ рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣ рдпрд╛ рддреЛ рджрд╛рдИрдВ рдУрд░ рдпрд╛ рдЯреЛрдХрди рдХреЗ рдмрд╛рдИрдВ рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдЪреБрдирд╛ рдЧрдпрд╛ рдкрдХреНрд╖ред рдпрджрд┐ рдпрд╣ рджрд╛рдИрдВ рдУрд░ рд╣реИ, рддреЛ рдореБрдЦреНрдп рдирд┐рдпрдо рднреА _ рд╢реБрд░реВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрддред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд░реАрдпрддрд╛ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ: рдореБрд╕реНрдХрд╛рди:, рд╣рд╛рд▓рд╛рдВрдХрд┐ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдХреЛ рд╕рдордЭрдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛:

number = _ ::value+ EOS
...
EOS = !.

рдореИрдВ рдирд╣реАрдВ рджреЗрдЦрддрд╛ рдХрд┐ рд╡рд░реНрдгрд┐рдд рд╡реНрдпрд╡рд╣рд╛рд░ рдХреИрд╕реЗ рдкрд░рд┐рдгрд╛рдо рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛ред

рдХреНрдпрд╛ рдпрд╣ рдЕрджреНрдпрддрди рдЯрд┐рдкреНрдкрдгреА рдпрд╣ тАЛтАЛрд╕рдордЭрдиреЗ рдореЗрдВ рдорджрдж рдХрд░рддреА рд╣реИ рдХрд┐ рдореИрдВ рдХреНрдпрд╛ рдХрд╣рдирд╛ рдЪрд╛рд╣ рд░рд╣рд╛ рд╣реВрдВ, рдФрд░ рдпрджрд┐ рдирд╣реАрдВ, рддреЛ рдЖрдк рдХреНрдпрд╛ рдирд╣реАрдВ рд╕рдордЭрддреЗ рд╣реИрдВред

рдореИрдВ @ polkovnikov-ph рд╕реЗ рд╕рд╣рдордд рд╣реВрдВ рдХрд┐ рд╕реНрдерд╛рдиреЛрдВ рджреНрд╡рд╛рд░рд╛ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдкрд░рд┐рд╡рд░реНрддрди рдмреЗрд╣рдж рд╕реНрдкрд╖реНрдЯ рд╣реИрдВ рдФрд░ рдХреЗрд╡рд▓ рдЕрддрд┐рд░рд┐рдХреНрдд рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХрд╛ рд╕реНрд░реЛрдд рд╣реЛрдВрдЧреЗред

рдпрджрд┐ рдЕрдиреБрдХреНрд░рдо рдкрд░ # рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдо Array#concat'ed рдХреЛ рдорд╛рддрд╛-рдкрд┐рддрд╛ рдХреЗ рд╕рд░рдгреА рдореЗрдВ рдЬреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

рд╡реНрдпрд╛рдХрд░рдг рдореЗрдВ рдХреНрдпрд╛ рд▓реМрдЯрд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП start = #('a') ? рдЬрд╣рд╛рдБ рддрдХ рдореИрдВ рд╕рдордЭрддрд╛ рд╣реВрдБ, рдЙрд╕рдиреЗ рд╕реЛрдЪрд╛ рдХрд┐ рдХреИрд╕реЗ рд╕рдорддрд▓ рд╕рд░рдгрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд┐рдВрдЯреЗрдХреНрд╕ рдЪреАрдиреА? рдореБрдЭреЗ рдирд╣реАрдВ рд▓рдЧрддрд╛ рдХрд┐ рдпрд╣ рдСрдкрд░реЗрдЯрд░ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдЗрд╕рдХреЗ рд╕рдмрд╕реЗ рд╕реНрдкрд╖реНрдЯ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП - рд╡рд┐рднрд╛рдЬрдХреЛрдВ рдХреЗ рд╕рд╛рде рд╕рджрд╕реНрдп рд╕реВрдЪрд┐рдпреЛрдВ рдХреА рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ - рд╡рд┐рд╢реЗрд╖ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдмрдирд╛рдирд╛ рдмреЗрд╣рддрд░ рд╣реИ (рджреЗрдЦреЗрдВ #30 рдФрд░ рдореЗрд░рд╛ рдХрд╛рдВрдЯрд╛, https://github.com/Mingun/pegjs/commit/db4b2b102982a53dbed1f579477c85c06f8b92e6)ред

рдпрджрд┐ рдирд┐рдпрдо рдореЗрдВ ::/# рдХреЗ рд╕рд╛рде рдПрдХ рдХреЛрдб рдмреНрд▓реЙрдХ рд╣реИ, рддреЛ рдЗрд╕реЗ рдкрд╣рд▓реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ, рдлрд┐рд░ рдкрд░рд┐рдгрд╛рдо рдкреБрд╢ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ

рдЕрддреНрдпрдВрдд рд╕реНрдкрд╖реНрдЯ рд╡реНрдпрд╡рд╣рд╛рд░ред рд╡реНрдпрд╛рдХрд░рдг рд╕реНрд░реЛрдд рдореЗрдВ рдХреНрд░рд┐рдпрд╛рдПрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдмрд╛рдж рд╕реНрдерд┐рдд рд╣реЛрддреА рд╣реИрдВ рдФрд░ рдЖрдорддреМрд░ рдкрд░ рдЙрдиреНрд╣реЗрдВ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдкрд╛рд░реНрд╕ рдХреЗ рдмрд╛рдж рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рдФрд░ рдЕрдЪрд╛рдирдХ рдХрд┐рд╕реА рддрд░рд╣ рдЙрдиреНрд╣реЗрдВ рдкрд╛рд░реНрд╕ рд╕реЗ рдкрд╣рд▓реЗ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдиреЗ рд▓рдЧрд╛ред рд▓реЗрдмрд▓ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдВрдЧреЗ?

рд╢реЗрд╖ 3 рдмрд┐рдВрджреБ рдЬрд┐рдирдХрд╛ рдЖрдк рд╡рд░реНрдгрди рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рд░рд╣реЗ, рддрд╛рдХрд┐ рдЙрдирдХреА рд╕реНрдкрд╖реНрдЯ рд╕рдордЭ рдЫреВрдЯрдиреЗ рд▓рдЧреЗред рдХреИрд╕реЗ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдиреЛрдЯ рдХрд┐рдпрд╛ @ polkovnikov-ph рдкрд╣рд▓реЗ рдФрд░ рджреВрд╕рд░реЗ рдорд╛рдорд▓реЗ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╡рд░рдг рдореЗрдВ рдХреНрдпреЛрдВ рдерд╛? рдХреЗрд╡рд▓ рджреЛ рд╕рд░рд▓ рдирд┐рдпрдореЛрдВ рдХреЛ рдХреНрд░рд┐рдпрд╛рдиреНрд╡рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:

  1. :: (рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ, рдореБрдЭреЗ рдЗрд╕ рдЪрд░рд┐рддреНрд░ рдХреА рдкрд╕рдВрдж рдкрд╕рдВрдж рдирд╣реАрдВ рд╣реИ, рдмрд╣реБрдд рд╢реЛрд░ рд╣реИ) рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдЗрд╕ рддрдереНрдп рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИ рдХрд┐ sequence рдиреЛрдб рддрддреНрд╡реЛрдВ рд╕реЗ рдЗрд╕ рдЪрд░рд┐рддреНрд░ рд╡рд╛рдкрд╕реА рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ
  2. рдпрджрд┐ рдЕрдиреБрдХреНрд░рдо рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рд╣реА рдРрд╕рд╛ рддрддреНрд╡ рд╣реИ, рддреЛ рдЗрд╕рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддрд╛ рд╣реИ, рдЕрдиреНрдпрдерд╛ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рд╕рд░рдгреА рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рддреА рд╣реИ

рдЙрджрд╛рд╣рд░рдг:

start =   'a' 'b'   'c'; // => ['a', 'b', 'c']
start = ::'a' 'b'   'c'; // => 'a'
start = ::'a' 'b' ::'c'; // => ['a', 'c']

рдмрдбрд╝рд╛ рдЙрджрд╛рд╣рд░рдг рдареАрдХ рд╡рд╣реА рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИ рдЬреЛ рдореИрдВ :: рд╕реЗ рджреЗрдЦрдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддрд╛ рд╣реВрдВ рдФрд░ рд╕рдВрджрд┐рдЧреНрдз рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ ( # , рдХрдИ :: ) рдХрд╛ рд╡рд░реНрдгрди рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИред

рдХреНрдпрд╛ рдпрд╣ рд╡рд╣реА рдмрд╛рдд рдирд╣реАрдВ рд╣реИ?

рдореИрдВ рддреЛ рдпрд╣реА рдкреВрдЫ рд░рд╣рд╛ рдерд╛ред рд╕рд╛рдорд╛рдиреНрдп рддрд░реАрдХреЗ рд╕реЗ рд╡рд┐рд╡рд░рдг рдЖрдорддреМрд░ рдкрд░ рдЕрдзрд┐рдХ рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдкрд╛рдардХ рдХреЛ рдпрд╣ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╡рд╣реА рдмрд╛рдд рд╣реИред рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред :)

рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, рдпрд╣ рдореЗрдердбрд╣реЗрдб рдЬреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЛ рдЖрд╕рд╛рди рдмрдирд╛ рджреЗрдЧрд╛

рд▓реЗрдХрд┐рди рдЗрд╕рдХреЗ рдмрдЬрд╛рдп рдСрдмреНрдЬреЗрдХреНрдЯ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдмрдирд╛рддреЗ? рдиреЛрдЯреЗрд╢рди рдореЗрдВ modifiers: рдФрд░ name: , рдкрд░рд┐рдгрд╛рдореА JS рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдЫреЛрдбрд╝ рджреЗрдВ, рдФрд░ рдпрд╣ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛ред

рдпрд╣ рдбреЗрд╡рд▓рдкрд░ рдХреА рдЧрд▓рддреА рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЛ рднреА рдЦреЛрд▓рддрд╛ рд╣реИ (рдпрд╛ рддреЛ рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╡реЗ рдЕрдкрдиреЗ рд╡реНрдпрд╛рдХрд░рдг рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреЗ рд╣реИрдВ, рдпрд╛ рдкрд░рд┐рдгрд╛рдо рдХреИрд╕реЗ рдХреНрд░рд┐рдпрд╛рдУрдВ рджреНрд╡рд╛рд░рд╛ рдирд┐рдпрдВрддреНрд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ)

рд╢реБрд░реВ рдореЗрдВ рдореИрдВ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд▓рд┐рдЦрдиреЗ рдЬрд╛ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ рдХрд┐ рдореЗрд░реЗ рдкрд╛рд╕ рдкрд░реНрдпрд╛рдкреНрдд рдХрдареЛрд░ рддрд░реНрдХ рдирд╣реАрдВ рд╣реИрдВред рдореИрдВ рдЕрдиреБрдХреНрд░рдо рдХреЗ рд╕рдорд╛рди рд╕реНрддрд░ рдкрд░ рдПрдХрд╛рдзрд┐рдХ :: рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреВрдВрдЧрд╛ (рдпрд╣рд╛рдВ рддрдХ тАЛтАЛтАЛтАЛрдХрд┐ рдзреНрд╡рдЬ рдХреЗ рд╕рд╛рде рднреА рдирд╣реАрдВ)ред

рдпрд╣ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдп рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рднреА рдорджрдж рдХрд░рддрд╛ рд╣реИ рдЬреИрд╕реЗ FunctionParameters рдЬрд╣рд╛рдВ рдпрд╣ рд▓рд┐рдЦрдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛:

рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд╣реА рдмрд╛рдд рд╣реИред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдЪреНрдЫрд╛ рд╕рд┐рдВрдЯреИрдХреНрд╕ рд╣реЛрдЧрд╛ inter(FunctionParam, "," __) , рд╕рд╛рде

inter a b = x:a xs:(b ::a)* { return xs.unshift(x), xs; }

рдирд┐рдпрдо < .., .. > = .. PEG.js рд╡реНрдпрд╛рдХрд░рдг рдореЗрдВ рдмрд╣реБрдд рдЕрдзрд┐рдХ рд╢реЛрд░ рдЬреЛрдбрд╝рдиреЗ рд▓рдЧрддрд╛ рд╣реИ

рд▓реЛрдЧ <...> рдкреНрд░рдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рдиреЗ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХрд░рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рддрд░реНрдХ рдкреНрд░рдХрд╛рд░ рдирд╣реАрдВ рд╣реИрдВред рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛ рд╣рд╛рд╕реНрдХреЗрд▓ рддрд░реАрдХрд╛ рд╣реИ рдмрд┐рдирд╛ рдХрд┐рд╕реА рдЕрддрд┐рд░рд┐рдХреНрдд рд╡рд░реНрдг рдХреЗ (рдКрдкрд░ inter )ред рдореБрдЭреЗ рдпрдХреАрди рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ ; рдЫреЛрдбрд╝реЗ рдЧрдП PEG.js рд╡реНрдпрд╛рдХрд░рдг рдореЗрдВ рдХреИрд╕реЗ рдЗрдВрдЯрд░реИрдХреНрдЯ рдХрд░рддрд╛ рд╣реИред рдРрд╕рд╛ рдХреЛрдИ рдорд╛рдорд▓рд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ рдЬрдм f a b = ... рдкрд┐рдЫрд▓реА рдкрдВрдХреНрддрд┐ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ (рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ)ред

рдХреБрдЫ рднрд╛рд╖рд╛рдУрдВ рдореЗрдВ рдПрдХ рд╡рд┐рд╕реНрддрд╛рд░ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬреЛ рдкреНрд░реАрдкреНрд░реЛрд╕реЗрд╕ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ

рд╣рд╛рдВ, рд▓реЗрдХрд┐рди рдореИрдВ рдЗрд╕реЗ рд╕реНрдорд╛рд░реНрдЯ рддрд░реАрдХреЗ рд╕реЗ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд░реВрдВрдЧрд╛ред рд╕рд░рдгрд┐рдпреЛрдВ рдкрд░ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд push рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рдмрдЬрд╛рдп, рдореИрдВ рдЗрд╕реЗ рд╡рд╕реНрддреБрдУрдВ рдкрд░ Object.assign рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛, рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рдРрд╕реА рдЪреАрдЬ рдЬреЛ рдПрдХ рдЦрд╛рд▓реА рд╕реНрдЯреНрд░рд┐рдВрдЧ ( eps ) рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рд╡рд╛рдкрд╕ рдЖрддреА рд╣реИ рдЗрд╕рдХрд╛ рддрд░реНрдХред рддрд╛рдХрд┐, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,

f = type:#"ident" name:$([a-z]i [a-z0-9_]i+)

рдЗрдирдкреБрдЯ рдХреЗ рд▓рд┐рдП {type: "ident", name: "abc"} рд▓реМрдЯрд╛рдПрдЧрд╛ "abc" ред

рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рдкрд╛рд░реНрд╕рд░ рджреНрд╡рд╛рд░рд╛ рдХреЛрдб рдмреНрд▓реЙрдХ рдХреА рдЕрдкреЗрдХреНрд╖рд╛ рдХреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рд╡рд╣ рдПрдХ рд╕рд░рдгреА-рдЬреИрд╕реА рд╡рд╕реНрддреБ рд▓реМрдЯрд╛рдП рдЬрд┐рд╕рдореЗрдВ рдПрдХ рдкреБрд╢ рд╡рд┐рдзрд┐ рд╣реЛ (рдЗрд╕рд▓рд┐рдП рдпрд╣ f = ::"a" {рд╡рд╛рдкрд╕реА [ "b" ] } рд░рд┐рдЯрд░реНрдирд┐рдВрдЧ [ "b", " рдП"] рдкрд░рд┐рдгрд╛рдо рдХреЗ рд░реВрдк рдореЗрдВ),

рдУ_рдУ

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рд┐рд░реНрдл рд╡рд░реАрдпрддрд╛ рдХрд╛ рдорд╛рдорд▓рд╛ рд╣реИ

рдЗрддрдирд╛ рд╣реА рдирд╣реАрдВ, рдкреНрд░рджрд░реНрд╢рди рднреАред рдпрджрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЯреЛрдХрди рдореЗрдВ рджреЛрдиреЛрдВ рддрд░рдл _ , рддреЛ рд╡реНрд╣рд╛рдЗрдЯрд╕реНрдкреЗрд╕ рд╡рд░реНрдг рдЕрдиреБрдХреНрд░рдо рдХреЗрд╡рд▓ рдкреАрдЫреЗ рд╡рд╛рд▓реЗ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВ, рдЬрдмрдХрд┐ _ рд╕реЗ рдкрд╣рд▓реЗ рдХреБрдЫ рднреА рдирд╣реАрдВ рдХреЗ рд╕рд╛рде рдореЗрд▓ рдЦрд╛рддреЗ рд╣реИрдВред parse$_ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЙрд▓ рдореЗрдВ рдереЛрдбрд╝рд╛ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рдордп рд▓рдЧрддрд╛ рд╣реИред рд╕рд╛рде рд╣реА рдХреЛрдб рд▓рдВрдмрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕рдореЗрдВ _ s рд╕реЗ рджреЛрдЧреБрдирд╛ рдЕрдзрд┐рдХ рд╣реИред

@Mingun рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ @futagoza рдбрд┐рдЬрд╝рд╛рдЗрди рд╕реНрдкреЗрд╕ рдХреА рдкрдбрд╝рддрд╛рд▓ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИ, рдЦрд╛рд╕рдХрд░ рдЕрдЧрд░ рдпрд╣ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╣реИ рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЕрд╕рд╣рдордд рд╣реЛрдиреЗ рдХрд╛ рдореМрдХрд╛ рд╣реИ :)

рдореБрдЦреНрдп рдмрд╛рдд "рдХреНрдпреЛрдВ" рдкреВрдЫрдирд╛ рдирд╣реАрдВ рд╣реИ, рдмрд▓реНрдХрд┐ рдпрд╣ рдХрд╣рдирд╛ рд╣реИ рдХрд┐ "рдирд╣реАрдВ! рдРрд╕рд╛ рдирд╣реАрдВ!"

image

f = type:#"ident" name:$([a-z]i [a-z0-9_]i+) рдЗрдирдкреБрдЯ "abc" рд▓рд┐рдП {type: "ident", name: "abc"} рд▓реМрдЯрд╛рдПрдЧрд╛ред

рдХреГрдкрдпрд╛ рдирд╣реАрдВ, рд╣рд╛рд╣рд╛ред рд╡рд╣ рд╡рд╛рдХреНрдп рд░рдЪрдирд╛ _wayyy_ рдмрд╣реБрдд рдЬрд╛рджреБрдИ рд╣реИред

рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореВрд▓ рд░реВрдк рд╕реЗ рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд @ рдСрдкрд░реЗрдЯрд░ рдмрд┐рд▓реНрдХреБрд▓ рд╕рд╣реА рд╣реИред рдЗрддрдиреЗ рд╕рд╛рд░реЗ, рдХрдИ рдмрд╛рд░ рдореИрдВ рдЕрдиреБрдХреНрд░рдо рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рднрд╛рдЧ рд▓реЗрддрд╛ рд╣реВрдВ:

sequence
    = first:element rest:(whitespace next:element {return next;})*
    {
        return [first].concat(rest);
    }
    ;

_рдРрд╕рд╛_ рдмрд╛рд░-рдмрд╛рд░ рдЯрд╛рдЗрдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рджрд░реНрдж, рдЦрд╛рд╕рдХрд░ рдЬрдм рд╡реЗ рдЗрд╕рд╕реЗ рдХрд╣реАрдВ рдЕрдзрд┐рдХ рдЬрдЯрд┐рд▓ рд╣реЛрдВред

рд╣рд╛рд▓рд╛рдВрдХрд┐, @ рдСрдкрд░реЗрдЯрд░ рдХреЗ рд╕рд╛рде, рдЙрдкрд░реЛрдХреНрдд рд╕рд░рд▓ рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:

sequence = first:element rest:(whitespace @element)* { return [first].concat(rest); };

рдФрд░ рдпрд╛ рддреЛ https://github.com/pegjs/pegjs/issues/235#issuecomment -66915879 рдпрд╛ https://github.com/pegjs/pegjs/issues/235#issuecomment -67544080 рдХреЗ рд╕рд╛рде рдЬреЛ рдФрд░ рдХрдо рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ:

sequence = first:element rest:(whitespace @element)* => [first].concat(rest);
/* or */
sequence = first:element rest:(whitespace @element)* {=[first].concat(rest)};

... рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкрд╣рд▓рд╛ рдореИрдВ рдмрд╣реБрдд рдЖрдВрд╢рд┐рдХ рд╣реВрдВред

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдПрдХ рдкрд┐рдЫрдбрд╝рд╛ рд╕рдВрдЧрдд рдкрд░рд┐рд╡рд░реНрддрди рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рд╣рд╛рд╕рд┐рд▓ рдХрд░рдирд╛ рдЖрд╕рд╛рди рд╣реЛрдЧрд╛ (рдРрд╕рд╛ рдкреНрд░рддреАрдд рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдХрд┐рд╕реА рдиреЗ рдЗрд╕реЗ рдкрд╣рд▓реЗ рд╣реА рдХрд░ рд▓рд┐рдпрд╛ рд╣реИ)ред

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЕрдЧрд░ рдореИрдВ рдЧрд▓рдд рдирд╣реАрдВ рд╣реВрдБ, рддреЛ рдпрд╣ рдПрдХ рдорд╛рдореВрд▓реА рдЯрдХреНрдХрд░ рд╣реЛ рд╕рдХрддреА рд╣реИред 0.11.0 @futagoza рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред

рдмрд╕ рдЗрд╕реЗ рдорд╛рд╕реНрдЯрд░ рдореЗрдВ рдЬреЛрдбрд╝рд╛ред рдорд▓реНрдЯреА рдкреНрд▓рдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП :: рдФрд░ рд╕рд┐рдВрдЧрд▓ рдкреНрд▓рдХрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП @ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рд▓реЗрдмрд▓ рдХреЗ рд╕рд╛рде :: рдХрд░рдирд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдмрджрд╕реВрд░рдд рдФрд░ рднреНрд░рдорд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рд▓рдЧ рд░рд╣рд╛ рдерд╛, рдЗрд╕рд▓рд┐рдП рдЙрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рд▓рдЯрдХрд╛ рджрд┐рдпрд╛

рдореИрдВрдиреЗ рдЗрд╕реЗ рдХреБрдЫ рд╕рдордп рдкрд╣рд▓реЗ рд╣реА рд▓рд╛рдЧреВ рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░ рджрд┐рдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди рдЗрд╕реЗ рдЕрдм рддрдХ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ (рдЬрдм рдореБрдЭреЗ рдЗрд╕рдХреЗ рдмрдЬрд╛рдп #579 рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП) рдФрд░ рдорд┐рдВрдЧреБрди рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдкрд░ рдмрд╛рдЗрдЯрдХреЛрдб рдЬрдирд░реЗрдЯрд░ рдЖрдзрд╛рд░рд┐рдд (https://github.com/Mingun/pegjs/commit/1c1c852bae91868eaa90d9bd9f7e4f722aa6435e )

рдЖрдк рдЗрд╕реЗ рдпрд╣рд╛рдВ рдЖрдЬрдорд╛ рд╕рдХрддреЗ рд╣реИрдВ: https://pegjs.org/Development/try (рдСрдирд▓рд╛рдЗрди рд╕рдВрдкрд╛рджрдХ, рд▓реЗрдХрд┐рди рдкреАрдИрдЬреА 0.11.0-рджреЗрд╡ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ)

рдкрд╡рд┐рддреНрд░ рдмрджрд▓рд╛рд╡ рдХрд╛ рд╕рдордп, рдмреИрдЯрдореИрдиред рдмрд╣реБрдд рдмрдврд╝рд┐рдпрд╛ рдХрд╛рдо @futagoza , рдЗрд╕рдиреЗ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд┐рдпрд╛ - рдмрд╣реБрдд рд╕рд░рд╛рд╣рдирд╛ рдХреАред рдХреНрдпрд╛ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА npm рдкрд░ dev рдЯреИрдЧ рдХреЗ рд▓рд┐рдП рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛? рдореБрдЭреЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдкрд░реАрдХреНрд╖рдг рд╢реБрд░реВ рдХрд░рдирд╛ рдЕрдЪреНрдЫрд╛ рд▓рдЧреЗрдЧрд╛ред

рдЬреЛ рдХреЛрдИ рднреА рдЗрд╕реЗ рдмреБрдирд┐рдпрд╛рджреА рд╡реНрдпрд╛рдХрд░рдг рдХреЗ рд╕рд╛рде рдЖрдЬрд╝рдорд╛рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реИ, рдЙрд╕рдХреЗ рд▓рд┐рдП рдЗрд╕ рдкрд┐рд▓реНрд▓рд╛ рдХреЛ рд╡рд╣рд╛рдБ рд░рдЦреЗрдВ рдФрд░ рдЗрд╕реЗ "abcd" рдЬреИрд╕рд╛ рдЗрдирдкреБрдЯ рджреЗрдВред

foo
    = '"' @$bar '"'
    ;

bar
    = [abcd]*
    ;

рдХреНрдпрд╛ рдпрд╣ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА npm рдкрд░ рджреЗрд╡ рдЯреИрдЧ рдХреЗ рд▓рд┐рдП рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛?

https://www.npmjs.com/package/pegjs/v/0.11.0-dev.325

рдирдорд╕реНрддреЗ, рдпрд╣ рдЙрди рдореБрджреНрджреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ es6 рд╣реЛрдиреЗ рдкрд░ рдЧрд╛рдпрдм рд╣реЛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рд╣рдореЗрдВ рдЕрдиреНрдп рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрди рдкрд╛рддреНрд░реЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ рдЬрд┐рдиреНрд╣реЗрдВ рддрдм рд╕реЗ es6 рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред рдЙрди рдЪреАрдЬреЛрдВ рдХреЗ рд▓рд┐рдП рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдЬреЛ рдЖрдк рдкрд╣рд▓реЗ рд╕реЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд╣реБрдд рдкреНрд░рддрд┐рдХреВрд▓ рд╣реИред

рдпрд╣ рдЯрд┐рдХрдЯ рдорд░реНрдЬ рдХрд┐рдпрд╛ рдЧрдпрд╛

pattern:Pattern init:(_ "=" _ <strong i="7">@a</strong>:AssignmentExpression)?

ES6 рдореЗрдВ рд╡рд╣реА рдмрд╛рдд, рдЬрд┐рд╕реЗ рд╣рд░ рдХреЛрдИ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рд╕рдордЭреЗрдЧрд╛, рдФрд░ рдЬреЛ рдкрд╛рд░реНрд╕рд░ рдХреЗ рдЕрдиреНрдп рднрд╛рдЧреЛрдВ рдХреЗ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░ рдореБрдлреНрдд рдореЗрдВ рдЖрддрд╛ рд╣реИ, рд╡рд╣ рд╣реИ

pattern:Pattern init:(_ "=" _ a:AssignmentExpression)? => a

рд╕рдорд╕реНрдпрд╛рдЧреНрд░рд╕реНрдд рд░реВрдк рд╕реЗ, рдЬрдм рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдкреНрд▓рдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЫреЛрдЯреА рдЧрд╛рдбрд╝реА рд▓рдЧрддрд╛ рд╣реИ, рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ, рдЗрд╕реЗ рдмрдВрдж рдХреЗ рд░реВрдк рдореЗрдВ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдПрдХ рд╢рд╛рдЦрд╛ рдореЗрдВ рддрдп рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдХрднреА рдЬрд╛рд░реА рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛

рдХреГрдкрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдлрд┐рд░ рд╕реЗ рдЦреЛрд▓реЗрдВ, @futagoza , рдЬрдм рддрдХ рдХрд┐ рдЗрд╕реЗ рдЬрд╛рд░реА рдХрд┐рдП рдЧрдП рд╕рдВрд╕реНрдХрд░рдг рдореЗрдВ рдареАрдХ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

StoneCypher picture StoneCypher  ┬╖  6рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

richb-hanover picture richb-hanover  ┬╖  7рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

alanmimms picture alanmimms  ┬╖  10рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

dmajda picture dmajda  ┬╖  7рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

audinue picture audinue  ┬╖  13рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ