Nolan,
You can use the GCC for that. Recent versions (>3.0) support the
-fdump-translation-unit options which will just dump the parse tree
in an easily parseable format. I have an AWK script that parses that
one in (see attachment) at a reasonable speed. Always wanted to convert it to Icon, however, never got around to that...
Pjotr
Nolan Clayton wrote:
I am almost finished with the new ui (gui2). I was wondering if anyone had some unicon code (small <- one file) that can parse a c/c++ or java file. The parser would be used for the ui class browser. Any other languages perl, tcl/tk, ada, fortran, lisp, pascal, c# or makefiles. Whatever! Any help would be greatly appreciated.
Thanks, Nolan Clayton
------------------------------------------------------- SF email is sponsored by - The IT Product Guide Read honest & candid reviews on hundreds of IT Products from real users. Discover which products truly live up to the hype. Start reading now. http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click _______________________________________________ Unicon-group mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/unicon-group
func name(x) {
if (Name[x] ~ /^[0-9]/ && Name[Name[x]])
Name[x]=Name[Name[x]]
return Name[x]
}
func __type(t,des) {
if (tag[name(t)]=="type_decl") return name(name(t))
if (unql[t]) return name(t)
return sprintf("%s%s%s",des,des ? " " : "",name(t))
}
func _type(t) {
m=(modi[t] ? modi[t] " " : "")
if (tag[t]=="pointer_type") return m _type(ptrd[t]) "*"
else if (tag[t]=="reference_type") return m _type(refd[t]) "&"
else if (tag[t]=="record_type") return __type(t,"struct")
else if (tag[t]=="enumeral_type") return __type(t,"enum")
else if (tag[t]=="union_type") return __type(t,"union")
else if (tag[t]=="void_type") return m "void"
else if (tag[t]=="real_type") return m "float"
else if (tag[t]=="integer_type") return __type(t,m)
else if (tag[t]=="array_type")
return m _type(domn[t]) "[" _expr(elts[t]) "]"
else if (tag[t]=="function_type")
return m _type(retn[t]) "(*)(" _params(prms[t]) ")"
else printf "Unknown type: %s %s\n",t,tag[t] >STDERR
}
func _return_type(t) {
if (tag[t]=="function_type")
return _type(retn[t])
}
func _const(c) {
#t=( type[c] ? "(" _type(type[c]) ")" : "")
if (tag[c]=="integer_cst") return t low[c]
else if (tag[c]=="string_cst") return t name(c)
else if (tag[c]=="real_cst") return t "0"
else printf "Unknown const: %s %s\n",c,tag[c] >STDERR
}
func _decl(t) {
i=init[t]
if (i) return (modi[t] ? modi[t] " " : "")\
sprintf("%s %s = %s",_type(type[t]),
name(t),
_expr(i))
return sprintf("%s %s",_type(type[t]),name(t))
}
func _params(t) { r=""
for (first=1; t; t=chan[t]) {
r=r sprintf("%s%s %s",
(first ? "" : ", "),
_type(type[t]),name(t))
first=0
}
return r
}
func _elems(t) { r=""
for (first=1; t; t=chan[t]) {
r=r sprintf("%s%s",(first ? "" : ", "),
_expr(valu[t]))
first=0
}
return r
}
func _cons(t) { r=""
for (first=1; t; t=chan[t]) {
r=r (first ? "" : ", ")
if (purp[t]) r=r name(purp[t]) ": "
r=r _expr(valu[t])
first=0
}
return r
}
func escape(s) {
gsub(/\n/,"\\n",s)
gsub(/\t/,"\\t",s)
gsub(/\r/,"\\r",s)
gsub(/\a/,"\\a",s)
gsub(/\b/,"\\b",s)
return s
}
func _expr(c) {
if (!c) return ""
#t=( type[c] ? "(" _type(type[c]) ")" : "")
if (0) {}
else if (tag[c]=="bit_not_expr")
return sprintf(t "( !%s )",_expr(op[c,0]))
else if (tag[c]=="negate_expr")
return sprintf(t "( ~%s )",_expr(op[c,0]))
else if (tag[c]=="ne_expr")
return sprintf(t "( %s != %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="eq_expr")
return sprintf(t "( %s == %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="le_expr")
return sprintf(t "( %s <= %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="ge_expr")
return sprintf(t "( %s >= %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="lt_expr")
return sprintf(t "( %s < %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="gt_expr")
return sprintf(t "( %s > %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="preincrement_expr")
return sprintf(t "( +%s = %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="predecrement_expr")
return sprintf(t "( -%s = %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="postincrement_expr")
return sprintf(t "( %s += %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="postdecrement_expr")
return sprintf(t "( %s -= %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="rshift_expr")
return sprintf(t "( %s >> %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="lshift_expr")
return sprintf(t "( %s @<< %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="truth_andif_expr")
return sprintf(t "( %s && %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="truth_orif_expr")
return sprintf(t "( %s || %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="bit_ior_expr")
return sprintf(t "( %s | %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="bit_and_expr")
return sprintf(t "( %s & %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="bit_xor_expr")
return sprintf(t "( %s ^ %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="mult_expr")
return sprintf(t "( %s * %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="plus_expr")
return sprintf(t "( %s + %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="minus_expr")
return sprintf(t "( %s - %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="trunc_div_expr")
return sprintf(t "( %s / %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="exact_div_expr")
return sprintf(t "( %s / %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="trunc_mod_expr")
return sprintf(t "( %s %% %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="compound_expr")
return sprintf(t "( %s , %s )",_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="cond_expr")
return sprintf(t "( %s ? %s : %s )",
_expr(op[c,0]),
_expr(op[c,1]),_expr(op[c,2]))
else if (tag[c]=="min_expr")
return sprintf(t "( %s < %s ? %s : %s )",
_expr(op[c,0]),_expr(op[c,1]),
_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="max_expr")
return sprintf(t "( %s > %s ? %s : %s )",
_expr(op[c,0]),_expr(op[c,1]),
_expr(op[c,0]),_expr(op[c,1]))
else if (tag[c]=="modify_expr") {
if (tag[op[c,0]]=="result_decl")
return sprintf(t "( %s )",_expr(op[c,1]))
else
return sprintf(t "%s = %s",_expr(op[c,0]),
_expr(op[c,1]))
}
else if (tag[c]=="addr_expr") {
if (DEBUG) print "!!",c,tag[c],tag[op[c,0]]
if (tag[op[c,0]]=="function_decl")
return sprintf("%s",name(op[c,0]))
else if (tag[op[c,0]]=="string_cst")
return sprintf("\"%s\"",escape(name(op[c,0])))
else
return sprintf("&%s",name(op[c,0]))
}
else if (tag[c]=="call_expr") return sprintf(t "%s ( %s )",
_expr(Func[c]),_elems(args[c]))
else if (tag[c]=="float_expr")
return sprintf(t "( %s )",_expr(op[c,0]))
else if (tag[c]=="convert_expr")
return sprintf(t "%s",_expr(op[c,0]))
else if (tag[c]=="nop_expr")
return sprintf(t "( %s )",_expr(op[c,0]))
else if (tag[c]=="expr_stmt") return t _expr(expr[c])
else if (tag[c]=="expr_with_file_location")
return t _expr(op[c,0])
else if (tag[c]=="save_expr") return t _expr(op[c,0])
else if (tag[c]=="non_lvalue_expr") return t _expr(expr[c])
else if (tag[c]=="integer_type") return "(" name(c) ")"
else if (tag[c]=="compound_literal_expr") return t
else if (tag[c]=="constructor") {
level++
bb=_cons(elts[c])
level--
return "{" bb "}"
}
else if (tag[c]=="stmt_expr") {
level++
bb=esrap(stmt[c])
level--
return t bb
}
else if (tag[c]=="array_ref")
return _expr(op[c,0]) "[" _expr(op[c,1]) "]"
else if (tag[c]=="indirect_ref") return name(op[c,0])
else if (tag[c]=="component_ref") return _expr(op[c,0])\
(tag[op[c,0]]=="indirect_ref" ? "->" : ".")\
_expr(op[c,1])
else if (tag[c] ~ /_decl/) return name(c)
else if (tag[c] ~ /_cst/) return _const(c)
else if (tag[c]=="bit_field_ref") return "/*bit_field_ref*/"
else if (tag[c]=="error_mark") return "ERROR"
else printf "Unknown expr: %s %s\n",c,tag[c] >STDERR
}
func esrap(b) {
o=""
for (; b; b=Next[b])
{
if (DEBUG) print "!!",b,tag[b]
if (LINE_NO && tag[b] != "compound_stmt" &&\
(line[b] || file[b]))
o=o put(sprintf("#line %d \"%s\"",
line[b],file[b]))
if (0) {}
else if (tag[b]=="function_decl") {
o=o put(sprintf("%s %s %s(%s)",
modi[b],
_return_type(type[b]),
name(b),
_params(args[b])))
o=o esrap(body[b])
}
else if (tag[b]=="label_stmt")
o=o put(sprintf("%s:",name(labl[b])),-1)
else if (tag[b]=="goto_stmt")
o=o put(sprintf("goto %s;",name(dest[b])))
else if (tag[b]=="asm_stmt")
o=o put(sprintf("__asm__ %s (%s)\n",
name(strg[b]),_cons(ins[b])))
else if (tag[b]=="compound_stmt") {
#o=o put(sprintf("/* compound till %d */", line[b]))
if (body[b]) o=o esrap(body[b])
else o=o put(";")
}
else if (tag[b]=="scope_stmt") {
if(modi[b] ~ /begn/) {
o=o put("{")
level++
} else {
level--
o=o put("}")
}
}
else if (tag[b]=="decl_stmt") {
o=o put(sprintf("%s;",_decl(decl[b])))
}
else if (tag[b]=="if_stmt") {
o=o put(sprintf("if %s",_expr(cond[b])))
level++
o=o esrap(then[b])
level--
if (Else[b]) {
o=o put("else")
level++
o=o esrap(Else[b])
level--
}
}
else if (tag[b]=="expr_stmt") {
o=o put(sprintf("%s;",_expr(expr[b])))
}
else if (tag[b]=="return_stmt") {
o=o put(sprintf("return %s;",_expr(expr[b])))
}
else if (tag[b]=="for_stmt") {
o=o put(sprintf("for (%s; %s; %s)",
_expr(init[b]),
_expr(cond[b]),
_expr(expr[b])))
level++
if (body[b]) o=o esrap(body[b])
else o=o put(";")
level--
}
else if (tag[b]=="switch_stmt") {
o=o put(sprintf("switch (%s)",_expr(cond[b])))
level++
if (body[b]) o=o esrap(body[b])
else o=o put(";")
level--
}
else if (tag[b]=="case_label") {
if (low[b]) o=o put(sprintf("case %s:",
_const(substr(low[b],2))),
-1)
else o=o put("default:",-1)
}
else if (tag[b]=="do_stmt") {
o=o put("do")
level++
if (body[b]) o=o esrap(body[b])
else o=o put(";")
level--
o=o put(sprintf("while (%s);",_expr(cond[b])))
}
else if (tag[b]=="while_stmt") {
o=o put(sprintf("while (%s)",_expr(cond[b])))
level++
if (body[b]) o=o esrap(body[b])
else o=o put(";")
level--
}
else if (tag[b]=="continue_stmt")
o=o put("continue;")
else if (tag[b]=="break_stmt")
o=o put("break;")
else if (tag[b]=="namespace_decl") {
o=o put(sprintf("namespace %s {",name(b)))
level++
if (dcls[b]) o=o esrap(dcls[b])
o=o put("}")
level--
}
else
printf "Unexpected tag: %s %s\n",b,tag[b] >STDERR
}
level-=inc
return o
}
func quote(s) {
return gensub(/"/,"\\\\\"","g",s)
}
func pexpr(e) {
return quote(_expr(e))
}
func gendot(b,old,exits,edge_label) {
print "node [peripheries=2]"
for (;b;b=Next[b])
{
print tag[b],tag[old] >STDERR
emit_edge=1
if (tag[b]=="function_decl") {
printf "label=\"%s %s %s(%s)\"\n" \
"color=blue\n",
modi[b],
_return_type(type[b]),
name(b),
_params(args[b])
gendot(body[b])
}
else if (tag[b]=="label_stmt") {
#printf "%i [label=\"%s\"]\n",b,name(labl[b])
emit_edge=0
}
else if (tag[b]=="goto_stmt") {
if (!old) {
printf "%i [shape=none label=\"goto %s\"]\n",b,dest[b]
old=b
}
goto_dest=0
for (i in labl) if (labl[i]==dest[b]) {
goto_dest=i
break
}
printf "%i -> %i [label=\"goto
%s\"]\n",old,Next[goto_dest],name(dest[b])
emit_edge=0
}
else if (tag[b]=="compound_stmt") {
old=gendot(body[b])
emit_edge=0
}
else if (tag[b]=="scope_stmt") {
if(modi[b] ~ /begn/) {
print "subgraph cluster_" b " {\n" \
" label=\"" name(b) "\"\n" \
" color=blue"
#printf "%i [shape=point label=\"{\"]\n",b
emit_edge=0
} else {
for (i in exits) printf "%i -> %i\n",i,b
printf "%i [shape=point label=\"}\"]\n",b
print "}"
}
}
else if (tag[b]=="decl_stmt") {
printf "%i [shape=box label=\"%s\"]\n",b,
_decl(decl[b])
}
else if (tag[b]=="if_stmt") {
printf "%i [shape=triangle label=\"%s\"]\n",b,
pexpr(cond[b])
if (Else[b]) {
printf "%i -> %i [label=else]\n",b,Else[b]
gendot(Else[b])
}
if (then[b]) {
printf "%i -> %i [label=then]\n",b,then[b]
gendot(then[b])
}
}
else if (tag[b]=="expr_stmt") {
printf "%i [shape=box label=\"%s\"]\n",b,
pexpr(expr[b])
}
else if (tag[b]=="return_stmt") {
printf "%i [shape=box peripheries=2 style=filled label=\"%s\"]\n",b,
pexpr(expr[b])
}
else if (tag[b]=="switch_stmt") {
if (old) printf "%i -> %i\n",old,b
printf "%i [shape=house label=\"%s\"]\n",b,
pexpr(cond[b])
switch_node=b
old=gendot(body[b])
}
else if (tag[b]=="case_label") {
if (low[b])
lab= _const(substr(low[b],2))
else
lab="default";
printf "%i -> %i [label=\"%s\"]", switch_node, Next[b], lab
emit_edge=0
old=0
}
else if (tag[b]=="for_stmt") {
if (old) printf "%i -> %i\n",old,init[b]
printf "%i [shape=box label=\"%s\"]\n",init[b],
pexpr(init[b])
printf "%i [shape=triangle label=\"%s\"]\n",cond[b],
pexpr(cond[b])
printf "%i -> %i\n",init[b],cond[b]
bb=gendot(body[b])
printf "%i -> %i [label=true]\n",cond[b],bb
#printf "%i -> %i [label=false]\n",cond[b],b
printf "%i [shape=box label=\"%s\"]\n",expr[b],
pexpr(expr[b])
printf "%i -> %i\n",bb,expr[b]
printf "%i -> %i\n",expr[b],cond[b]
emit_edge=0
edge_label="false"
old=cond[b]
}
else if (tag[b]=="do_stmt") {
bb=gendot(body[b])
if (old) printf "%i -> %i\n",old,bb
printf "%i [shape=triangle label=\"%s\"]\n",cond[b],
pexpr(cond[b])
printf "%i -> %i\n",bb,cond[b]
printf "%i -> %i [label=true]\n",cond[b],bb
emit_edge=0
edge_label="false"
old=cond[b]
}
else if (tag[b]=="while_stmt") {
if (old) printf "%i -> %i\n",old,cond[b]
printf "%i [shape=triangle label=\"%s\"]\n",cond[b],
pexpr(cond[b])
bb=gendot(body[b])
printf "%i -> %i [label=true]\n",cond[b],bb
printf "%i -> %i\n",bb,cond[b]
emit_edge=0
edge_label="false"
old=cond[b]
}
else if (tag[b]=="continue_stmt") {
#printf "%i [shape=none label=\"continue\"]\n",b
exits[old]=1
emit_edge=0
}
else if (tag[b]=="break_stmt") {
#printf "%i [shape=none label=\"break\"]\n",b
exits[old]=1
emit_edge=0
}
if (emit_edge) {
if (old) {
printf "%i -> %i",old,b
if (edge_label) {
printf "[label=\"%s\"]",edge_label
edge_label=""
}
printf "\n"
}
old=b
print "node [peripheries=1]"
}
}
return old
}
func put(x,incr) {
y=""
for (i=0; i<level+incr; i++) y=y "\t"
y=y x "\n"
return y
}
func append(_a,_b) { return _a=_a (_a ? " " : "") _b }
BEGIN { node=0
STDERR="/dev/stderr"
FS="[ \t:]+"
modifiers["undefined"]=modifiers["volatile"]=\
modifiers["static"]=modifiers["extern"]=\
modifiers["struct"]=modifiers["union"]=\
modifiers["begn"]=modifiers["clnp"]=modifiers["end"]=\
modifiers["null"]=modifiers["register"]=\
modifiers["unsigned"]=modifiers["int"]=modifiers["char"]=\
modifiers["float"]=modifiers["double"]=modifiers["long"]=\
modifiers["short"]=modifiers["bitfield"]=1
modifiers["artificial"]=modifiers["C"]=modifiers["operator"]=\
modifiers["new"]=modifiers["delete"]=\
modifiers["vecnew"]=modifiers["vecdelete"]=1
MODE=""
}
MODE=="" { start=1 }
MODE=="" && /^@/ { if (node) {
if (cur=="identifier_node")
{
identifiers[num]=cur
if (0) if (name(num)) for (n in Name)
if (name(n)==num)
Name[n]=name(num)
}
tag[num]=cur
}
node=1
num=substr($1,2)
cur=$2
start=3
}
MODE=="" {
if (DEBUG>1) printf "loop:"
for (i=start; i<=NF; i++)
{
if (DEBUG>1) printf " %s",$i
if (0) {}
else if ($i=="name") {
ref=substr($(++i),2)
if (ref in Name) Name[num]=name(ref)
else Name[num]=ref
}
else if ($i=="srcp") {
file[num]=$(++i)
line[num]=$(++i)
}
else if ($i=="op") {
opno=$(++i)
op[num,opno]=substr($(++i),2)
}
else if ($i=="scpe") scpe[num]=substr($(++i),2)
else if ($i=="fn") Func[num]=substr($(++i),2)
else if ($i=="init") init[num]=substr($(++i),2)
else if ($i=="decl") decl[num]=substr($(++i),2)
else if ($i=="args") args[num]=substr($(++i),2)
else if ($i=="valu") valu[num]=substr($(++i),2)
else if ($i=="expr") expr[num]=substr($(++i),2)
else if ($i=="cond") cond[num]=substr($(++i),2)
else if ($i=="then") then[num]=substr($(++i),2)
else if ($i=="else") Else[num]=substr($(++i),2)
else if ($i=="next") Next[num]=substr($(++i),2)
else if ($i=="chan") chan[num]=substr($(++i),2)
else if ($i=="body") body[num]=substr($(++i),2)
else if ($i=="type") type[num]=substr($(++i),2)
else if ($i=="retn") retn[num]=substr($(++i),2)
else if ($i=="size") size[num]=substr($(++i),2)
else if ($i=="prms") prms[num]=substr($(++i),2)
else if ($i=="mngl") mngl[num]=substr($(++i),2)
else if ($i=="unql") unql[num]=substr($(++i),2)
else if ($i=="refd") refd[num]=substr($(++i),2)
else if ($i=="elts") elts[num]=substr($(++i),2)
else if ($i=="bpos") bpos[num]=substr($(++i),2)
else if ($i=="flds") flds[num]=substr($(++i),2)
else if ($i=="domn") domn[num]=substr($(++i),2)
else if ($i=="argt") argt[num]=substr($(++i),2)
else if ($i=="dest") dest[num]=substr($(++i),2)
else if ($i=="labl") labl[num]=substr($(++i),2)
else if ($i=="ptd") ptrd[num]=substr($(++i),2)
else if ($i=="min") mini[num]=substr($(++i),2)
else if ($i=="max") maxi[num]=substr($(++i),2)
else if ($i=="cnst") cnst[num]=substr($(++i),2)
else if ($i=="clbr") clbr[num]=substr($(++i),2)
else if ($i=="csts") csts[num]=substr($(++i),2)
else if ($i=="outs") outs[num]=substr($(++i),2)
else if ($i=="purp") purp[num]=substr($(++i),2)
else if ($i=="stmt") stmt[num]=substr($(++i),2)
else if ($i=="ins") ins[num]=substr($(++i),2)
else if ($i=="dcls") dcls[num]=substr($(++i),2)
else if ($i=="strg" && cur=="asm_stmt") {
strg[num]=substr($(++i),2)
}
else if ($i=="strg" && cur=="identifier_node") {
IN_STRG=1
Name[num]=append(name(num),$(++i))
}
else if ($i=="lngt") { IN_STRG=0
lngt[num]=$(++i)
if (lngt[num]!=length(name(num)) && 0)
printf "Consistency '%s' %d!=%d\n",
name(num),lngt[num],
length(name(num)) > STDERR
}
else if ($i=="strg") {
if (match($0,
/strg: (.*) lngt: [0-9]+[:space:]*$/,
a))
Name[num]=a[1]
else {
MODE="string"
string=""
$0=substr($0,index($0,"strg: ")+6)
}
break
}
else if ($i=="line") line[num]=$(++i)
else if ($i=="high") high[num]=$(++i)
else if ($i=="algn") algn[num]=$(++i)
else if ($i=="prec") prec[num]=$(++i)
else if ($i=="qual") qual[num]=$(++i)
else if ($i=="used") used[num]=$(++i)
else if ($i=="packet") pack[num]=$(++i)
else if ($i=="low") low[num]=$(++i)
else if ($i=="segment") seg[num]=$(++i)
else if ($i ~ /^@/)
printf "Unknown ref: %s\n",$i > STDERR
else if ($i in modifiers) {
if (IN_STRG)
Name[num]=append(name(num),$i)
else
modi[num]=append(modi[num],$i)
}
else if ($i)
printf "Unknown tag: '%s'\n",$i > STDERR }
if (DEBUG>1) printf "\n"
}
MODE=="string" && match($0,/[ \t]*lngt: ([0-9]+)[ \t]*$/,a) {
string=string substr($0,1,RSTART-1)
if (0 && a[1]!=length(string)+1)
printf "Consistency '%s' %d!=%d\n",
string,a[1],length(string) > STDERR
Name[num]=string
lngt[num]=a[1]
MODE=""
}
MODE=="string" { string=string $0 "\n" }
END { if (!OP) OP="cutpoints"
for (i in Name) un[name(i)]=append(un[name(i)],i)
delete cnt
nname=asort(Name,sorted)
if (OP=="idents") for (ix=1; ix<=nname; ix++)
{
split(un[sorted[ix]],el," ")
n=el[++cnt[un[sorted[ix]]]]
if (tag[n] ~ /.*_decl/) {}
else continue
if (modi[n] ~ /undefined/) continue
if (file[n] ~ /<built-in>/) continue
if (file[n] ~ /<internal>/) continue
printf "%s:%05d %s %s%s\n",
file[n],line[n],name(n),
(scpe[n] ? "scoped " : ""),modi[n]
}
if (OP=="esrap") for (ix=1; ix<=nname; ix++)
{
split(un[sorted[ix]],el," ")
n=el[++cnt[un[sorted[ix]]]]
if (tag[n] ~ /function_decl/ &&\
(!FUNCTION || name(n)==FUNCTION))
{
if (modi[n] ~ /undefined/) continue
level=0
printf "%s",esrap(n)
}
}
if (OP=="gendot")
{
printf "digraph tree_directed {\n" \
"label=\"%s\"\n" \
"overlap=false\n","top-level"
for (ix=1; ix<=nname; ix++)
{
split(un[sorted[ix]],el," ")
n=el[++cnt[un[sorted[ix]]]]
if (tag[n] ~ /function_decl/ &&\
(!FUNCTION || name(n)==FUNCTION))
{
if (modi[n] ~ /undefined/) continue
level=0
printf "subgraph cluster_%i {\n",n
gendot(n)
print "}"
}
}
print "}"
}
}
