Pegjs: рдореИрдВ рдЕрдкрдиреА рдбреАрдмреА рдХреНрд╡реЗрд░реА рдХреЗ рд▓рд┐рдП рдПрдХ рдкреАрдИрдЬреА.рдЬреЗрдПрд╕ рдкреИрдЯрд░реНрди рдХреИрд╕реЗ рдмрдирд╛ рд╕рдХрддрд╛ рд╣реВрдВ (рдПрдХреНрд╕ "рдФрд░" рд╡рд╛рдИ "рдФрд░" ...)

рдХреЛ рдирд┐рд░реНрдорд┐рдд 27 рдирд╡ре░ 2018  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: pegjs/pegjs

рд╡рд┐рд╖рдп рд╡рд░реНрдЧ

рд╕рд╡рд╛рд▓

рдЖрд╡рд╢реНрдпрдХ рд╢рд░реНрддреЗрдВ

  • рдХреНрдпрд╛ рдЖрдк рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рдкреБрди: рдкреЗрд╢ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ ?: рд╣рд╛рдБ
  • рдХреНрдпрд╛ рдЖрдкрдиреЗ рд░рд┐рдкреЛрдЬрд┐рдЯрд░реА рдореБрджреНрджреЛрдВ рдХреА рдЦреЛрдЬ рдХреА ?: рд╣рд╛рдБ
  • рдХреНрдпрд╛ рдЖрдкрдиреЗ рдордВрдЪреЛрдВ рдХреА рдЬрд╛рдБрдЪ рдХреА ?: рд╣рд╛рдБ
  • рдХреНрдпрд╛ рдЖрдкрдиреЗ рд╡реЗрдм рдЦреЛрдЬ рдХреА рдереА (рдЧреВрдЧрд▓, рдпрд╛рд╣реВ, рдЖрджрд┐) ?: рд╣рд╛рдБ

рд╡рд┐рд╡рд░рдг / рдЙрджрд╛рд╣рд░рдг рдХреЛрдб

рдЕрдм рддрдХ рдореЗрд░рд╛ рдкрд╛рд░реНрд╕рд░ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИред

const parser = peg.generate(`

eq
  = left:attribute "=" right:value { return left == right; }

and
  = left:eq "AND" right:eq { return left && right; }

рдпрд╣ id = 2 AND createdOn = 193242 рдЬреИрд╕реЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдкрдврд╝рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИред рдореИрдВ id = 2 AND secondId = 444 AND createdOn = 193242 рд╡рдЧреИрд░рд╣ рдкрдврд╝рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ... ("рдФрд░" рдХреА рдХреЛрдИ рднреА рд╕рдВрдЦреНрдпрд╛)ред рдореИрдВ рдЗрд╕реЗ PEG.js рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреИрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ?

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

рдпрд╣ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП:

and
  = left:eq right:and_eq+ {
      if ( right.length === 1 ) return left && right;
      // handle more then 1 'AND eq' here
    }

and_eq
  = "AND" e:eq { return e; }

рдХрд┐рд╕реА рднреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рд╡рд╛рд▓реЗ рдСрдкрд░реЗрдЯрд░реЛрдВ рдХреА рдХрд┐рд╕реА рднреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд▓рд┐рдП рд╕рд╛рдорд╛рдиреНрдп рд╕рдорд╛рдзрд╛рди (рдПрдПрд╕рдЯреА рдмрдирд╛рддрд╛ рд╣реИ):

{
function leftAssotiative(left, tail) {
  let r = left;
  for (let i = 0; i < tail.length; ++i) {
    r = { kind: tail[i][0], left: r, right: tail[i][1] };
  }
  return r;
}
function rightAssotiative(left, tail) {
  if (tail.length > 1) {
    let r = tail[tail.length-1][1];
    for (let i = tail.length-2; i >= 0; --i) {
      r = { kind: tail[i+1][0], left: tail[i][1], right: r };
    }
    return { kind: tail[0][0], left: left, right: r };
  }
  return left;
}
}

// Expressions
Expr// minimal priority
  = l:Expr0 t:(p0 Expr0)* { return rightAssotiative(l, t); };
Expr0
  = l:Expr1 t:(p1 Expr1)* { return leftAssotiative(l, t); };
...
ExprN// maximal priority
  = '(' <strong i="6">@Expr</strong> ')';

// Operators
p0 = [+-];
p1 = [*/];
...

@futagoza рд╕реЗрдХреНрд╕реА рджрд┐рдорд╛рдЧред рдзрдиреНрдпрд╡рд╛рдж!

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

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

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

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

brettz9 picture brettz9  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

ronjouch picture ronjouch  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

mattkanwisher picture mattkanwisher  ┬╖  5рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ