2

Does anyone know how to go about converting a string in the following format:

"I (get (it)) not"

can be converted to be represented as an array? For example, like this:

['I', ['get' , ['it']], 'not']

Basically, I want to use parentheses as "levels" in the array. I myself know me already a lot of JavaScript but I do not get how I should go about this. I've been trying for 3 hours, but I'm still stuck.

0

1 Answer 1

3

Because I'm feeling generous, here's a quick example I made up:

// takes a string and returns a array that represents the grouping symbols in the string
function parseString(str)
{  // remove leading and trailing whitespace -- whitespace not important
   str = str.trim();
   // split the string into an array of each of the individual characters
   var arr = str.split('');

   // an array to store the matched parts of the string
   var parsed = [];

   // the current level of the parentheses nesting
   var parentheses = 0;

   // represents the array for each of the parentheses levels
   var levels = [parsed];

   // a shortcut to the array for the current parentheses level
   var current = parsed;

   // parse out any operator that aren't meant to be in the checks
   var notOperators = /^[ ()]*(.*?)[ ()]*$/;

   // count the number of occurrances of a substring in the string
   function count(arg, substring) { return arg.split(substring).length; };

   // check there are the same number of parentheses
   if (count(str, '(') !== count(str, ')')) throw new SyntaxError('Unmatched parentheses');

   // adds the word before the operator/space, if any
   function addPart()
   {  // removes parts already parsed, gets the word
      var beginning = arr.splice(0, i).join('').trim();
      // strips off any operator tokens
      var str = beginning.match(notOperators)[1];
      if (str) current.push(str);
      // since we've removed the parts that we've parsed,
      // we need to reset the loop counter
      i = 0;
   }

   // loop through each of the characters
   for (var i = 0; i < arr.length; ++i)
   {  var token = arr[i];
      // separates words
      if (token === ' ') addPart();
       // opens a new grouping symbol
      else if (token === '(')
      {  addPart();
         // add a new level of hierarchy and keep reference to it
         current.push([]);
         current = levels[++parentheses] = current[current.length - 1];
      }
       // closes an open grouping symbol
      else if (token === ')')
      {  addPart();
         // move one level up the hierarchy of parentheses
         current = levels[--parentheses];
      }

      // make sure something like "a)(" is invalid
      if (parentheses < 0) throw new SyntaxError('Unexpected token )');
   }

   // add the final word before the end of string, if any
   addPart();

   // return the array that represents the string
   return parsed;
}

As you asked, something like:

parseString('The (quick) brown (fox (jumps)) (over the) lazy (dog)');

returns

["The", ["quick"], "brown", ["fox", ["jumps"]], ["over", "the"], "lazy", ["dog"]]
Sign up to request clarification or add additional context in comments.

1 Comment

Nice! Looks like a basic lisp parser! Love it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.