graphviz: done parsing directed graphs

This is mostly what I want since I'm interested in parsing the output of
debtree.
This commit is contained in:
Kartik K. Agaram 2022-03-18 17:09:47 -07:00
parent 7dc0928f52
commit 06615231ae
1 changed files with 83 additions and 1 deletions

View File

@ -564,10 +564,18 @@
> return self:string()
> elseif c == '<' then
> error('html strings are not implemented yet')
> elseif string.pos('-.0123456789', c) then
> elseif c == '-' then
> if self.chars.peek2 == '-' or self.chars.peek2 == '>' then
> return self:edgeop()
> else
> return self:numeral()
> end
> elseif string.pos('.0123456789', c) then
> return self:numeral()
> elseif string.match(c, '[%a_]') then
> return self:identifier()
> else
> error('unexpected character '..str(c))
> end
> end,
> skip_whitespace_and_comments = function(self)
@ -654,6 +662,9 @@
> end
> return result
> end,
> edgeop = function(self)
> return self.chars:read()..self.chars:read()
> end,
> }
>end
>
@ -673,3 +684,74 @@
> check_tokenizer('"abc def" 124', '"abc def"', 'tokenizer: string')
> check_tokenizer('', nil, 'tokenizer: eof')
>end
- __teliva_timestamp: original
parse_graph:
>-- https://graphviz.org/doc/info/lang.html
>function parse_graph(tokens, graph)
> local t = tokens:read()
> if t == 'strict' then
> t = tokens:read()
> end
> if t == 'graph' then
> error('undirected graphs not supported just yet')
> elseif t == 'digraph' then
> return parse_directed_graph(tokens, graph)
> else
> error('parse_graph: unexpected token '..t)
> end
>end
- __teliva_timestamp:
>Fri Mar 18 16:52:39 2022
skip_attr_list:
>function skip_attr_list(tokens)
> while true do
> local tok = tokens:read()
> if tok == nil then
> error('unterminated attr list; looked for "]" in vain')
> end
> if tok == ']' then break end
> end
>end
- __teliva_timestamp:
>Fri Mar 18 17:01:49 2022
parse_directed_graph:
>function parse_directed_graph(tokens, graph)
> tokens:read() -- skip name
> assert(tokens:read() == '{')
> while true do
> if tokens:peek() == nil then
> error('file not terminated with "}"')
> end
> if tokens:peek() == '}' then break end
> local tok1 = tokens:read()
> if tok1 == '[' then
> skip_attr_list(tokens)
> else
> local tok2 = tokens:read()
> if tok2 == '[' then
> -- node_stmt
> skip_attr_list(tokens)
> -- otherwise ignore node declarations;
> -- we'll assume the graph is fully connected
> -- and we can focus on just edges
> elseif tok2 == '->' then
> -- edge_stmt
> local tok3 = tokens:read()
> if graph[tok1] == nil then
> graph[tok1] = {tok3}
> else
> append(graph[tok1], {tok3})
> end
> elseif tok2 == '--' then
> error('unexpected token "--" in digraph; edges should be directed using "->"')
> elseif tok2 == '=' then
> -- id '=' id
> -- skip
> tokens:read()
> else
> error('unexpected token '..tok2)
> end
> end
> end
> assert(tokens:read() == '}')
>end