1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- 'use strict'
- exports.parse = function (source, transform) {
- return new ArrayParser(source, transform).parse()
- }
- class ArrayParser {
- constructor (source, transform) {
- this.source = source
- this.transform = transform || identity
- this.position = 0
- this.entries = []
- this.recorded = []
- this.dimension = 0
- }
- isEof () {
- return this.position >= this.source.length
- }
- nextCharacter () {
- var character = this.source[this.position++]
- if (character === '\\') {
- return {
- value: this.source[this.position++],
- escaped: true
- }
- }
- return {
- value: character,
- escaped: false
- }
- }
- record (character) {
- this.recorded.push(character)
- }
- newEntry (includeEmpty) {
- var entry
- if (this.recorded.length > 0 || includeEmpty) {
- entry = this.recorded.join('')
- if (entry === 'NULL' && !includeEmpty) {
- entry = null
- }
- if (entry !== null) entry = this.transform(entry)
- this.entries.push(entry)
- this.recorded = []
- }
- }
- consumeDimensions () {
- if (this.source[0] === '[') {
- while (!this.isEof()) {
- var char = this.nextCharacter()
- if (char.value === '=') break
- }
- }
- }
- parse (nested) {
- var character, parser, quote
- this.consumeDimensions()
- while (!this.isEof()) {
- character = this.nextCharacter()
- if (character.value === '{' && !quote) {
- this.dimension++
- if (this.dimension > 1) {
- parser = new ArrayParser(this.source.substr(this.position - 1), this.transform)
- this.entries.push(parser.parse(true))
- this.position += parser.position - 2
- }
- } else if (character.value === '}' && !quote) {
- this.dimension--
- if (!this.dimension) {
- this.newEntry()
- if (nested) return this.entries
- }
- } else if (character.value === '"' && !character.escaped) {
- if (quote) this.newEntry(true)
- quote = !quote
- } else if (character.value === ',' && !quote) {
- this.newEntry()
- } else {
- this.record(character.value)
- }
- }
- if (this.dimension !== 0) {
- throw new Error('array dimension not balanced')
- }
- return this.entries
- }
- }
- function identity (value) {
- return value
- }
|