A Bit of a Pickle
CJam, 63
q{"Slt 1:T;L ]',*'[\+']+ ]',*'(\+')+ [
0:T; C+"35/T=S/(C#=~}fC
Try it online
Explanation:
q read the input
{…}fC for each character C in the input
"…" push that long string, containing code to handle various cases
35/ split it into (two) parts of length 35
T= get the T'th part; T is 1 when parsing a string and 0 otherwise
(T is initially 0 by default)
S/ split by space into an array of strings
( take out the first item (containing special characters to check)
C# find the index of C in that string
= get the corresponding string from the array
(when C is not found, # returns -1 which gets the last array item)
~ execute that string
Now the long string with various pieces of code. Each part has a few characters to check and then a block for handling each one, and the default case.
First part: Slt 1:T;L ]',*'[\+']+ ]',*'(\+')+ [
Slt special characters to check
######## first block, corresponding to character 'S'
1:T; set T=1, causing the next characters to be processed with the 2nd part
L push an empty string/array, which will be used to collect the string
######## second block, corresponding to character 'l'
] end array
',* join with commas
'[\+ prepend a '['
']+ append a ']'
######## third block, corresponding to character 't'
] end array
',* join with commas
'(\+ prepend a '('
')+ append a ')'
######## last block, corresponding to other characters (practically, '(' and '.')
[ start array
Second part: (newline) 0:T; C+
newline special characters to check (only one)
######## first block, corresponding to newline
0:T; set T=0, switching back to the first part
######## last block, corresponding to any other character (including apostrophe)
C+ append the character to the collecting string
Perl, 149 bytes
I have a bad feeling that this is a poor attempt, but here goes:
$/=$,;$"=",";@s=[];/^\(/?$s[@s]=[]:{$p=/S(.*')/?$1:/l|t/?($l="@{pop@s}")|/l/?"[$l]":"($l)":0,push@{$s[-1]},$p}for<>=~/([(lt]|S.*?\n)/g;print$s[0][0];
The script has to be saved in a file and it takes input from STDIN.
Explanation:
# Set the input record separator to undef so that <> reads all lines at
# once
$/=$,;
# Ensure that elements of lists printed in quotes are separated by commas
$"=",";
# The stack. Initialise the bottom element with an empty array
@s=[];
# Tokens are extracted in the for loop a few lines below. Copied here for
# clarity: Read the entire input and iterate over all valid tokens of the
# pickle language
# for <>=~/([(lt]|S.*?\n)/g;
# the token is a mark - push an empty array to the stack
/^\(/ ? $s[@s]=[]
# token is a string, push it inside the stack top
: {$p=/S(.*')/ ? $1
# otherwise, remove the top and create list or tuple
# from it and push it inside the top element
: /l|t/ ? ($l="@{pop@s}") | /l/ ? "[$l]"
: "($l)"
: 0 # dummy value
# pushing of the string/list/tuple actually
# happens here
, push@{$s[-1]},$p}
# read the entire input at once and iterate over all valid tokens
for <>=~/([(lt]|S.*?\n)/g;
# in the end, the bottom element of the stack will be an array with just one
# element which is the string representation of the object
print$s[0][0];