Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

file 92 lines (85 sloc) 4.53 kb
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
// TODO: turn off the "seq" inliner when G.seq !== OMeta.seq (will require some refactoring)
// TODO: add a factorizing optimization (will make jumptables more useful)

ometa BSNullOptimization {
  setHelped = !(this._didSomething = true),
  helped = ?this._didSomething,
  trans = [:t ?(this[t] != undefined) apply(t):ans] -> ans,
  optimize = trans:x helped -> x,

  App :rule anything*:args -> ['App', rule].concat(args),
  Act :expr -> ['Act', expr],
  Pred :expr -> ['Pred', expr],
  Or trans*:xs -> ['Or'].concat(xs),
  XOr trans*:xs -> ['XOr'].concat(xs),
  And trans*:xs -> ['And'].concat(xs),
  Opt trans:x -> ['Opt', x],
  Many trans:x -> ['Many', x],
  Many1 trans:x -> ['Many1', x],
  Set :n trans:v -> ['Set', n, v],
  Not trans:x -> ['Not', x],
  Lookahead trans:x -> ['Lookahead', x],
  Form trans:x -> ['Form', x],
  ConsBy trans:x -> ['ConsBy', x],
  IdxConsBy trans:x -> ['IdxConsBy', x],
  JumpTable ([:c trans:e] -> [c, e])*:ces -> ['JumpTable'].concat(ces),
  Interleave ([:m trans:p] -> [m, p])*:xs -> ['Interleave'].concat(xs),
  Rule :name :ls trans:body -> ['Rule', name, ls, body]
}
BSNullOptimization.initialize = function() { this._didSomething = false }

ometa BSAssociativeOptimization <: BSNullOptimization {
  And trans:x end setHelped -> x,
  And transInside('And'):xs -> ['And'].concat(xs),
  Or trans:x end setHelped -> x,
  Or transInside('Or'):xs -> ['Or'].concat(xs),
  XOr trans:x end setHelped -> x,
  XOr transInside('XOr'):xs -> ['XOr'].concat(xs),

  transInside :t = [exactly(t) transInside(t):xs] transInside(t):ys setHelped -> xs.concat(ys)
                 | trans:x transInside(t):xs -> [x].concat(xs)
                 | -> []
}

ometa BSSeqInliner <: BSNullOptimization {
  App = 'seq' :s end seqString(s):cs setHelped -> ['And'].concat(cs).concat([['Act', s]])
             | :rule anything*:args -> ['App', rule].concat(args),
  inlineChar = BSOMetaParser.eChar:c ~end -> ['App', 'exactly', c.toProgramString()],
  seqString = &(:s ?(typeof s === 'string'))
                 ( ['"' inlineChar*:cs '"' ] -> cs
                 | ['\'' inlineChar*:cs '\''] -> cs
                 )
}

JumpTable = function(choiceOp, choice) {
  this.choiceOp = choiceOp
  this.choices = {}
  this.add(choice)
}
JumpTable.prototype.add = function(choice) {
  var c = choice[0], t = choice[1]
  if (this.choices[c]) {
    if (this.choices[c][0] == this.choiceOp)
      this.choices[c].push(t)
    else
      this.choices[c] = [this.choiceOp, this.choices[c], t]
  }
  else
    this.choices[c] = t
}
JumpTable.prototype.toTree = function() {
  var r = ['JumpTable'], choiceKeys = ownPropertyNames(this.choices)
  for (var i = 0; i < choiceKeys.length; i += 1)
    r.push([choiceKeys[i], this.choices[choiceKeys[i]]])
  return r
}
ometa BSJumpTableOptimization <: BSNullOptimization {
  Or (jtChoices('Or') | trans)*:cs -> ['Or'].concat(cs),
  XOr (jtChoices('XOr') | trans)*:cs -> ['XOr'].concat(cs),
  quotedString = &string [ '"' (BSOMetaParser.eChar:c ~end -> c)*:cs '"'
                          | '\'' (BSOMetaParser.eChar:c ~end -> c)*:cs '\''] -> cs.join(''),
  jtChoice = ['And' ['App' 'exactly' quotedString:x] anything*:rest] -> [x, ['And'].concat(rest)]
                | ['App' 'exactly' quotedString:x] -> [x, ['Act', x.toProgramString()]],
  jtChoices :op = jtChoice:c {new JumpTable(op, c)}:jt (jtChoice:c {jt.add(c)})* setHelped -> jt.toTree()
}

ometa BSOMetaOptimizer {
  optimizeGrammar = ['Grammar' :n :sn optimizeRule*:rs] -> ['Grammar', n, sn].concat(rs),
  optimizeRule = :r (BSSeqInliner.optimize(r):r | empty)
                       ( BSAssociativeOptimization.optimize(r):r
                       | BSJumpTableOptimization.optimize(r):r
                       )* -> r
}
Something went wrong with that request. Please try again.