123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- export default parseString;
- var NEUTRAL = 1;
- var KEYWORD = 2;
- var NUMBER = 3;
- var QUOTED = 4;
- var AFTERQUOTE = 5;
- var ENDED = -1;
- var whitespace = /\s/;
- var latin = /[A-Za-z]/;
- var keyword = /[A-Za-z84_]/;
- var endThings = /[,\]]/;
- var digets = /[\d\.E\-\+]/;
- // const ignoredChar = /[\s_\-\/\(\)]/g;
- function Parser(text) {
- if (typeof text !== 'string') {
- throw new Error('not a string');
- }
- this.text = text.trim();
- this.level = 0;
- this.place = 0;
- this.root = null;
- this.stack = [];
- this.currentObject = null;
- this.state = NEUTRAL;
- }
- Parser.prototype.readCharicter = function() {
- var char = this.text[this.place++];
- if (this.state !== QUOTED) {
- while (whitespace.test(char)) {
- if (this.place >= this.text.length) {
- return;
- }
- char = this.text[this.place++];
- }
- }
- switch (this.state) {
- case NEUTRAL:
- return this.neutral(char);
- case KEYWORD:
- return this.keyword(char)
- case QUOTED:
- return this.quoted(char);
- case AFTERQUOTE:
- return this.afterquote(char);
- case NUMBER:
- return this.number(char);
- case ENDED:
- return;
- }
- };
- Parser.prototype.afterquote = function(char) {
- if (char === '"') {
- this.word += '"';
- this.state = QUOTED;
- return;
- }
- if (endThings.test(char)) {
- this.word = this.word.trim();
- this.afterItem(char);
- return;
- }
- throw new Error('havn\'t handled "' +char + '" in afterquote yet, index ' + this.place);
- };
- Parser.prototype.afterItem = function(char) {
- if (char === ',') {
- if (this.word !== null) {
- this.currentObject.push(this.word);
- }
- this.word = null;
- this.state = NEUTRAL;
- return;
- }
- if (char === ']') {
- this.level--;
- if (this.word !== null) {
- this.currentObject.push(this.word);
- this.word = null;
- }
- this.state = NEUTRAL;
- this.currentObject = this.stack.pop();
- if (!this.currentObject) {
- this.state = ENDED;
- }
- return;
- }
- };
- Parser.prototype.number = function(char) {
- if (digets.test(char)) {
- this.word += char;
- return;
- }
- if (endThings.test(char)) {
- this.word = parseFloat(this.word);
- this.afterItem(char);
- return;
- }
- throw new Error('havn\'t handled "' +char + '" in number yet, index ' + this.place);
- };
- Parser.prototype.quoted = function(char) {
- if (char === '"') {
- this.state = AFTERQUOTE;
- return;
- }
- this.word += char;
- return;
- };
- Parser.prototype.keyword = function(char) {
- if (keyword.test(char)) {
- this.word += char;
- return;
- }
- if (char === '[') {
- var newObjects = [];
- newObjects.push(this.word);
- this.level++;
- if (this.root === null) {
- this.root = newObjects;
- } else {
- this.currentObject.push(newObjects);
- }
- this.stack.push(this.currentObject);
- this.currentObject = newObjects;
- this.state = NEUTRAL;
- return;
- }
- if (endThings.test(char)) {
- this.afterItem(char);
- return;
- }
- throw new Error('havn\'t handled "' +char + '" in keyword yet, index ' + this.place);
- };
- Parser.prototype.neutral = function(char) {
- if (latin.test(char)) {
- this.word = char;
- this.state = KEYWORD;
- return;
- }
- if (char === '"') {
- this.word = '';
- this.state = QUOTED;
- return;
- }
- if (digets.test(char)) {
- this.word = char;
- this.state = NUMBER;
- return;
- }
- if (endThings.test(char)) {
- this.afterItem(char);
- return;
- }
- throw new Error('havn\'t handled "' +char + '" in neutral yet, index ' + this.place);
- };
- Parser.prototype.output = function() {
- while (this.place < this.text.length) {
- this.readCharicter();
- }
- if (this.state === ENDED) {
- return this.root;
- }
- throw new Error('unable to parse string "' +this.text + '". State is ' + this.state);
- };
- function parseString(txt) {
- var parser = new Parser(txt);
- return parser.output();
- }
|