How to resolve the algorithm S-expressions step by step in the Pike programming language
How to resolve the algorithm S-expressions step by step in the Pike programming language
Table of Contents
Problem Statement
S-Expressions are one convenient way to parse and store data.
Write a simple reader and writer for S-Expressions that handles quoted and unquoted strings, integers and floats. The reader should read a single but nested S-Expression from a string and store it in a suitable datastructure (list, array, etc). Newlines and other whitespace may be ignored unless contained within a quoted string. “()” inside quoted strings are not interpreted, but treated as part of the string. Handling escaped quotes inside a string is optional; thus “(foo"bar)” maybe treated as a string “foo"bar”, or as an error. For this, the reader need not recognize “\” for escaping, but should, in addition, recognize numbers if the language has appropriate datatypes. Languages that support it may treat unquoted strings as symbols. Note that with the exception of “()"” (“\” if escaping is supported) and whitespace there are no special characters. Anything else is allowed without quotes. The reader should be able to read the following input and turn it into a native datastructure. (see the Pike, Python and Ruby implementations for examples of native data structures.) The writer should be able to take the produced list and turn it into a new S-Expression. Strings that don't contain whitespace or parentheses () don't need to be quoted in the resulting S-Expression, but as a simplification, any string may be quoted.
Let the writer produce pretty printed output with indenting and line-breaks.
Let's start with the solution:
Step by Step solution about How to resolve the algorithm S-expressions step by step in the Pike programming language
Source code in the pike programming language
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; i
{
switch(input[i])
{
case '(': output+= ({"("}); break;
case ')': output += ({")"}); break;
case '"': //"
output+=array_sscanf(input[++i..], "%s\"%[ \t\n]")[0..0];
i+=sizeof(output[-1]);
break;
case ' ':
case '\t':
case '\n': break;
default: string token = array_sscanf(input[i..], "%s%[) \t\n]")[0];
output+=({ value(token) });
i+=sizeof(token)-1;
break;
}
}
return output;
}
// this function is based on the logic in Parser.C.group() in the pike library;
array group(array tokens)
{
ADT.Stack stack=ADT.Stack();
array ret =({});
foreach(tokens;; string token)
{
switch(token)
{
case "(": stack->push(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);
You may also check:How to resolve the algorithm Unicode variable names step by step in the NetRexx programming language
You may also check:How to resolve the algorithm Own digits power sum step by step in the Phix programming language
You may also check:How to resolve the algorithm Price fraction step by step in the Kotlin programming language
You may also check:How to resolve the algorithm String comparison step by step in the J programming language
You may also check:How to resolve the algorithm Bioinformatics/base count step by step in the AWK programming language