(: Abstract syntax tree @author Andy Bunce :) module namespace ast="lsp/ast"; (: import module namespace p="xq4" at "xq4.xqm"; :) import module namespace xq4="java:quodatum.parser.xq4"; (:~ build :) declare function ast:build($text as xs:string,$uri as xs:string:="") as element(*){ let $xml:= xq4:parseModule($text)=>prof:time("⏱️ p:parse-Module " || $uri) return ($xml, message(ast:report($xml),"REP"), message(ast:report(ast:flatten($xml)),"flat") ) }; (:~ :concrete to abstract: simplify by omitting elements with only one child :) declare function ast:flatten($input as element()) as element() { if (1=count($input/*)) then ast:flatten($input/*) else element {node-name($input) } {$input/@*, for $child in $input/node() return if ($child instance of element()) then ast:flatten($child) else $child } }; (:-------------------------------------------:) declare function ast:report($el as element(*)) { { "total-elements": count($el//element()), "max-depth": ast:max-node-depth($el), "char-count": string-length($el) } }; declare function ast:max-depth($nodes as node()*) as xs:integer { if (empty($nodes)) then 0 else max(( for $node in $nodes return if ($node instance of element()) then ast:max-depth($node/node()) + 1 else ast:max-depth($node/node()) )) }; declare function ast:max-node-depth($root as node()) as xs:integer { ast:max-depth($root) };