S-expressions: Difference between revisions
→JavaScript :: Functional: Adjusted type of parser, preferred indented JSON to tree diagram, added reserialization.
(→JavaScript :: Functional: Adjusted type of parser, preferred indented JSON to tree diagram, added reserialization.) |
|||
Line 3,760:
===Functional===
Showing the parse tree in and indented JSON format, and writing out a reserialization:
<lang JavaScript>(() => {
"use strict";
// ------------------ S-
const main = () => {
const expr = [
"((data \"quoted data\" 123 4.5)",
" (data (!@# (4.5) \"(more\" \"data)\")))"
].join("\n");
const [parse, residue] = parseExpr(
tokenized(expr)
);
return 0 < residue.length ? (
`Unparsed tokens: ${JSON.stringify(residue)}`
) : [
JSON.stringify(parse, null, 2),
"Reserialized from parse:",
parse.map(serialized).join(" ")
].join("\n\n");
};
// ---------------- EXPRESSION PARSER ----------------
// parseExpr [String] -> ([
const parseExpr = tokens => {
// A tuple of (parsed trees, residual tokens)
// derived from a list of tokens.
const
0 === tkns.length || ")" === tkns[0];
const
0 < tkns.length ? (() => {
const [t, ...ts] = tkns;
Line 3,783 ⟶ 3,800:
return "(" === t ? (
bimap(
xs =>
)(
)(
)
// and conclude where brackets close.
) : ")" === t ? (
Tuple(
// Other tokens are appended leaves.
) : Tuple(
)(ts);
})() : Tuple(
Tuple([])(
);
};
// ------------------- ATOM PARSER -------------------
// atom :: String -> Expr
Line 3,819 ⟶ 3,830:
"\"'".includes(s[0]) ? (
s.slice(1, -1)
) :
name: s
}
) : parseFloat(s, 10)
) : "";
Line 3,856 ⟶ 3,862:
);
// ------------------ SERIALIZATION ------------------
// serialized :: Expr -> String
const
const
)
`"${e}"`
`(${e.map(serialized).join(" ")})`
) : "?";
};
// --------------------- GENERIC ---------------------
// Tuple (,) :: a -> b -> (a, b)
Line 3,917 ⟶ 3,905:
// first and second values respectively.
g => ([a, b]) => Tuple(f(a))(g(b));
Line 3,968 ⟶ 3,911:
// True if 2 is a factor of n.
0 === n % 2;
Line 3,998 ⟶ 3,926:
return go;
};
// tail :: [a] -> [a]
const tail = xs =>
// A new list consisting of all
// items of xs except the first.
0 < xs.length ? (
xs.slice(1)
) : undefined;
return main();
})();</lang>
{{Out}}
<pre>
[
[
{
},
123,
4.5
[
{
"name": "data"
"name": "!@#"
]
]
Reserialized from parse:
((data "quoted data" 123 4.5) (data (!@# (4.5) "(more" "data)")))</pre>
=={{header|Julia}}==
|