me_util.tcl
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 namespace ::grammar::me::util {
00012 namespace export ast2tree ast2etree tree2ast
00013 }
00014
00015
00016
00017
00018
00019
00020
00021 ret ::grammar::me::util::ast2tree (type ast , type tree , optional root ={)} {
00022 # See grammar::me_ast for the specification of both value and tree
00023 # representations.
00024
00025 if {$root eq ""} {
00026 root = [$tree rootname]
00027 }
00028
00029
00030
00031 if {[llength $ast] < 3} {
00032 return -code error "Bad node \"$ast\", not enough elements"
00033 }
00034
00035 type = [lindex $ast 0]
00036 range = [lrange $ast 1 2]
00037 children = [lrange $ast 3 end]
00038
00039 if {($type eq "") && [llength $children]} {
00040 return -code error \
00041 "Terminal node \"[lrange $ast 0 2]\" has children"
00042 }
00043 foreach {s e} $range break
00044 if {
00045 ![string is integer -strict $s] || ($s < 0) ||
00046 ![string is integer -strict $e] || ($e < 0)
00047 } {
00048 return -code error "Bad range information \"$range\""
00049 }
00050
00051
00052
00053
00054
00055 new = [lindex [$tree insert $root end] 0]
00056
00057 if {$type eq ""} {
00058 $tree $new = type terminal
00059 } else {
00060 $tree $new = type nonterminal
00061 $tree $new = detail $type
00062 }
00063
00064 $tree $new = range $range
00065
00066 foreach child $children {
00067 ast2tree $child $tree $new
00068 }
00069 return
00070 }
00071
00072 ret ::grammar::me::util::ast2etree (type ast , type mcmd , type tree , optional root ={)} {
00073 # See grammar::me_ast for the specification of both value and tree
00074 # representations.
00075
00076 if {$root eq ""} {
00077 root = [$tree rootname]
00078 }
00079
00080
00081
00082 if {[llength $ast] < 3} {
00083 return -code error "Bad node \"$ast\", not enough elements"
00084 }
00085
00086 type = [lindex $ast 0]
00087 range = [lrange $ast 1 2]
00088 children = [lrange $ast 3 end]
00089
00090 if {($type eq "") && [llength $children]} {
00091 return -code error \
00092 "Terminal node \"[lrange $ast 0 2]\" has children"
00093 }
00094 foreach {s e} $range break
00095 if {
00096 ![string is integer -strict $s] || ($s < 0) ||
00097 ![string is integer -strict $e] || ($e < 0)
00098 } {
00099 return -code error "Bad range information \"$range\""
00100 }
00101
00102
00103
00104
00105
00106 new = [lindex [$tree insert $root end] 0]
00107
00108 if {$type eq ""} {
00109 cmd = $mcmd
00110 lappend cmd tok
00111 foreach loc $range {lappend cmd $loc}
00112
00113 $tree $new = type terminal
00114 $tree $new = detail [uplevel \
00115 } else {
00116 $tree $new = type nonterminal
00117 $tree $new = detail $type
00118 }
00119
00120 range = _lc {}
00121 foreach loc $range {
00122 lappend range_lc [uplevel \
00123 [linsert $mcmd end lc $loc]]
00124 }
00125
00126 $tree $new = range $range
00127 $tree $new = range_lc $range_lc
00128
00129 foreach child $children {
00130 ast2etree $child $mcmd $tree $new
00131 }
00132 return
00133 }
00134
00135 ret ::grammar::me::util::tree2ast (type tree , optional root ={)} {
00136 # See grammar::me_ast for the specification of both value and tree
00137 # representations.
00138
00139 if {$root eq ""} {
00140 root = [$tree rootname]
00141 }
00142
00143 value = {}
00144
00145 if {![$tree keyexists $root type]} {
00146 return -code error "Bad node \"$root\", type information is missing"
00147 }
00148 if {![$tree keyexists $root range]} {
00149 return -code error "Bad node \"$root\", range information is missing"
00150 }
00151
00152 range = [$tree get $root range]
00153 if {[llength $range] != 2} {
00154 return -code error "Bad node \"root\", bad range information \"$range\""
00155 }
00156
00157 foreach {s e} $range break
00158 if {
00159 ![string is integer -strict $s] || ($s < 0) ||
00160 ![string is integer -strict $e] || ($e < 0)
00161 } {
00162 return -code error "Bad node \"root\", bad range information \"$range\""
00163 }
00164
00165 if {[$tree get $root type] eq "terminal"} {
00166 lappend value {}
00167 } else {
00168 if {![$tree keyexists $root detail]} {
00169 return -code error "Bad node \"$root\", nonterminal detail is missing"
00170 }
00171
00172 lappend value [$tree get $root detail]
00173 }
00174
00175
00176 lappend value $s $e
00177
00178 foreach child [$tree children $root] {
00179 lappend value [tree2ast $tree $child]
00180 }
00181
00182 return $value
00183 }
00184
00185
00186
00187
00188 package provide grammar::me::util 0.1
00189