class Symbol(string name) { string _sprintf(int type) { switch(type) { case 's': return name; case 'O': return sprintf("(Symbol: %s)", name||""); case 'q': return name; case 't': return "Symbol"; default: return sprintf("%"+int2char(type), name); } } mixed cast(string type) { switch(type) { case "string": return name; default: throw(sprintf("can not cast 'Symbol' to '%s'", type)); } } } mixed value(string token) { if ((string)(int)token==token) return (int)token; array result = array_sscanf(token, "%f%s"); if (sizeof(result) && floatp(result[0]) && ! sizeof(result[1])) return result[0]; else return Symbol(token); } array tokenizer(string input) { array output = ({}); for(int i=0; ipush(ret); ret=({}); break; case ")": if (!sizeof(ret) || !stack->ptr) { // Mismatch werror ("unmatched close parenthesis\n"); return ret; } ret=stack->pop()+({ ret }); break; default: ret+=({token}); break; } } return ret; } string sexp(array input) { array output = ({}); foreach(input;; mixed item) { if (arrayp(item)) output += ({ sexp(item) }); else if (intp(item)) output += ({ sprintf("%d", item) }); else if (floatp(item)) output += ({ sprintf("%f", item) }); else output += ({ sprintf("%q", item) }); } return "("+output*" "+")"; } string input = "((data \"quoted data\" 123 4.5)\n (data (!@# (4.5) \"(more\" \"data)\")))"; array data = group(tokenizer(input))[0]; string output = sexp(data);