Jump to content


Photo

Recursive String Parser


  • This topic is locked This topic is locked
2 replies to this topic

#1 chaosgames

chaosgames

    GMC Member

  • New Member
  • 26 posts

Posted 04 July 2012 - 10:05 PM

Hello all. I am trying to design a way to recursively parse a sentence using ds lists to manipulate the data. It's a little complex, but I believe that if I could get this to run correctly I could do some really fun things with it because it should be very fast.

If you don't know, parse means split a string into a data structure. I want this function to do that using 3 arguments: the current input string, the "parse-on" characters string, and the "organized" version of the string that can be read using the ds_list_read() function.

So the code is initialized in the create event of an object, and a function is used to parse the input string.
var my_list;
my_list = ds_list_create();
ds_list_add(my_list,"START");
my_input="Hello this is a test. I wonder if this thing will work at all.";
my_string = rParse(my_input," .",ds_list_write(my_list));
ds_list_read(my_list,my_string)

So then the main script is called rParse, I tried to comment it with as much detail as possible. Please see below:
//function rParse(in argument0 as string:TextToBeParsed, in argument1 as string:CharList,argument2 as string:Write_Ds_List_String)
//this function recursively parses a string into a data structure
//returns a string that can be read using the ds_list_read() function


//Establish two lists;
var wordList; var charOccur;

//list:charOccur, to determine where the first character in string:CharList
charOccur = ds_list_create();

//list:wordList, to add words to the parsed string
wordList = ds_list_create();


//Establish two temporary variables;
var tempString; var WordListStr;

//one for holding string:TextToBeParsed
tempString = argument0;

//another for holding the list written as a string 
WordListStr = argument2;

//pass argument2:Write_Ds_List_String to the wordList data structure
ds_grid_read(wordList,WordListStr);

//record all the values for the first occurance of char[i] in argument1
for (i = 1; i <= string_length(argument1); i += 1)
{
    ds_list_add(charOccur,string_pos(string_char_at(argument1,i),tempString));
}

//sort the list of charOccur position values in ascending order
ds_list_sort(charOccur,1);

//find the lowest position of where to split tempString
do
{
    //set the variable firstPos equal to the lowest value
    firstPos = ds_list_find_value(charOccur,0);
    
    //determine if the current item is the lowest
    if firstPos = 0 && ds_list_size(charOccur)>1
    {
        //if it is not last value, delete the entry
        ds_list_delete(charOccur,0);
    }
}

//until firstPos is not 0 or there is only one entry left
until (firstPos != 0 || ds_list_size(charOccur) = 1)

//if there are no more characters in the string
if firstPos = 0
{
    //add the last bit of the sentence to the data structure
    ds_list_add(wordList,tempString);
    
    //pass the list as a string
    WordListStr = ds_list_write(wordList);

    //free memory by destroying the lists
    ds_list_destroy(wordList);
    ds_list_destroy(charOccur);
    
    //return the data structure as a string 
    return WordListStr;
}
else
{
    //add the left bit of the sentence from position 1 to firstPos to the data structure
    ds_list_add(wordList,string_copy(tempString,1,firstPos));
    
    //pass the list as a string
    WordListStr = ds_list_write(wordList);
    
    //free memory by destroying the lists
    ds_list_destroy(wordList);
    ds_list_destroy(charOccur);
    
    //recursion
    WordListStr=rParse(string_copy(tempString,firstPos,string_length(tempString)),argument1,WordListStr);
}

So I get an error that says data structure does not exist, but I guess I'm failing to see what I'm overlooking. I tried to lay out the logic as neatly as possible, so if you follow or have a suggestion I would love the input.

Thanks Everyone
  • 0

#2 brac37

brac37

    GMC Member

  • GMC Member
  • 768 posts
  • Version:GM7

Posted 06 July 2012 - 06:17 PM

Replace the last "WordListStr=" by "return "?
  • 0

#3 torigara

torigara

    GMC Member

  • GMC Member
  • 6487 posts

Posted 07 July 2012 - 04:51 AM

So I get an error that says data structure does not exist

At this line? Then you've mixed up ds_grid with a list.

//pass argument2:Write_Ds_List_String to the wordList data structure
ds_grid_read(wordList,WordListStr);

By the way, I don't get why you're passing data structure as strings. Can't you simply pass the list index itself and manipulate it within the script? (I'm not sure why you copy the contents of list to another, add an item then copy it back to the original - instead of just adding the item to the original list. But if you want to copy lists, GM8.0 and later has ds_list_copy.)

Also, using a recursive function isn't a good idea; it isn't only unnecessarily complex but also consumes stacks that can lead into stack overflow errors. Usually, this sort of algorithm can be implemented simpler and more efficient with a loop. I think something like this is sufficient:
// argument0 = string to parse, argument1 = delimiter characters, argument2 = list index to store the result.
var word_len, i, c;
word_len = 0;
for (i = 1; i <= string_length(argument0); i += 1) {
    c = string_char_at(argument0, i);
    if (string_pos(c, argument1) > 0) { // If the letter is one of delimiters
        // Take the word in front of the delimiter and add it to the list
        if (word_len > 0) {
            ds_list_add(argument2, string_copy(argument0, i - word_len, word_len));
            word_len = 0;
        }
    }
    else {
        // Add the letter to the current word
        word_len += 1;
    }
}
// Add the last word to the list
if (word_len > 0) {
    ds_list_add(argument2, string_copy(argument0, string_length(argument0) - word_len + 1, word_len));
}

Edited by torigara, 07 July 2012 - 06:51 AM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users