Created
July 15, 2011 03:04
-
-
Save bluegraybox/1083971 to your computer and use it in GitHub Desktop.
This is the core functionality from the indent parser (sequential Erlang version)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-record(line, {content, indent}). | |
-record(node, {content, children}). | |
parse_text_line(Text) -> | |
%% converts " text" to (:content "text" :indent 4) | |
Content = string:strip(string:strip(Text, left), left, $\t), | |
Indent = length(Text) - length(Content), | |
#line{content=string:strip(Content, right, $\n), indent=Indent}. | |
%% Split a list of lines in two, breaking on the first line whose indent is =< the minimum. | |
split_list(_MinIndent, List1, []) -> [lists:reverse(List1), []]; | |
split_list(MinIndent, List1, [First|Rest]) when First#line.indent =< MinIndent -> | |
[lists:reverse(List1), [First|Rest]]; | |
split_list(MinIndent, List1, [First|Rest]) -> | |
split_list(MinIndent, [First|List1], Rest). | |
%% Parse a list of 'line' record into a tree structure, based on indent | |
build_nodes([]) -> []; | |
build_nodes([First|Rest]) -> | |
[ChildLines, SiblingLines] = split_list(First#line.indent, [], Rest), | |
Children = build_nodes(ChildLines), | |
Siblings = build_nodes(SiblingLines), | |
Node = #node{content=First#line.content, children=Children}, | |
[Node|Siblings]. |
Here's the full code for the sequential Erlang version of the indent parser. There's also a concurrent Erlang version and a Lisp version.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I eventually discovered lists:splitwith/2, which obsolesces my split_list/3. So you can throw that out and replace line 20 with: