All files tree_regexp.js

100% Statements 45/45
100% Branches 34/34
100% Functions 6/6
100% Lines 43/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 641x 1x       98x 98x   98x 98x 98x 98x 98x 98x 98x 3804x 67x 3737x 69x 3668x 281x 281x 281x 3387x 281x 281x 281x 190x 190x   91x   281x 3106x 91x 3015x 91x 91x   3804x 3804x   98x       6x       22x       92x 92x 86x 263x 86x       1x  
const Regex = require('becke-ch--regex--s0-0-v1--base--pl--lib')
const GroupBuilder = require('./group_builder')
 
class TreeRegexp {
  constructor(regexp) {
    this._re = 'string' === typeof regexp ? new RegExp(regexp) : regexp
    this._regex = new Regex(this._re.source, this._re.flags)
 
    const stack = [new GroupBuilder()]
    const groupStartStack = []
    let last = null
    let escaping = false
    let nonCapturingMaybe = false
    let charClass = false
    this._re.source.split('').forEach((c, n) => {
      if (c == '[' && !escaping) {
        charClass = true
      } else if (c == ']' && !escaping) {
        charClass = false
      } else if (c === '(' && !escaping && !charClass) {
        stack.push(new GroupBuilder())
        groupStartStack.push(n + 1)
        nonCapturingMaybe = false
      } else if (c === ')' && !escaping && !charClass) {
        const gb = stack.pop()
        const groupStart = groupStartStack.pop()
        if (gb.capturing) {
          gb.source = this._re.source.substring(groupStart, n)
          stack[stack.length - 1].add(gb)
        } else {
          gb.moveChildrenTo(stack[stack.length - 1])
        }
        nonCapturingMaybe = false
      } else if (c === '?' && last === '(') {
        nonCapturingMaybe = true
      } else if (c === ':' && nonCapturingMaybe) {
        stack[stack.length - 1].setNonCapturing()
        nonCapturingMaybe = false
      }
      escaping = c === '\\' && !escaping
      last = c
    })
    this._groupBuilder = stack.pop()
  }
 
  get regexp() {
    return this._re
  }
 
  get groupBuilder() {
    return this._groupBuilder
  }
 
  match(s) {
    const match = this._regex.exec(s)
    if (!match) return null
    let groupIndex = 0
    const nextGroupIndex = () => groupIndex++
    return this._groupBuilder.build(match, nextGroupIndex)
  }
}
 
module.exports = TreeRegexp