# # KEHOME/src/convert.icn # Sep/29/2005 # Aug/31/2008 BSE(L,B,S,E) #=============================================================# # NOTE: # # get_string() destroys parse info., returns nest of strings # # unparse() destroys list, returns a string # # rhm Jun/23/2002 # #=============================================================# # string or nested list/set procedure get_string(x,option) #============================= # grammar change: "wp" now "nvnull" in nvlist context # convert symbols to nested lists of strings # option ::= # all # keep all characters # nv # keep nv; delete separators # other # delete separators # # type()=="null" => return "" # SYMBOL("null",[]) => return "" # SYMBOL("ppnull",[]) => return "" # use PHRASE list for subject,object,value # BSE(L,B,S,E) => return get_string(L,option) local y static warning initial { warning := "WARNING: get_string: " } #----------------------------# #return unparse(x) #----------------------------# /option := "all" # return all characters case type(x) of { default: { writes_type(mylog,x,warning||"unexpected type of x") return x } "null": { return "" } ("integer"|"real"): { return string(x) } "string": { case option of { "all": { return x } "nv": { return x } default: { return x } } # end case option } "list": { y := [] every put(y,get_string(!x,option)) case option of { "all": { return y } "nv": { return delete_separator(y) } default: { return delete_separator(y) } } # end case option } "set": { y := set() every insert(y,get_string(!x,option)) case option of { "all": { return y } "nv": { return delete_separator(y) } default: { return delete_separator(y) } } # end case option } "PHRASE": { return(get_string(x.pvalue,option)) } "NVPHRASE":{ return(get_string(x.novlist,option)) } "SYMBOL": { case option of { "all": { return get_string(x.svalue,option) } "nv": { case x.stype of { default: { return get_string(x.svalue,option) } "null": { return "" } "wp": { return x } "nv": { return x } "nvnull": { return SYMBOL("nv",[x.svalue,NVSEPARATOR,""]) } } # end case stype } # end "wp2nv" default: { # stip bracket, etc. case x.stype of { default: { writes_type(mylog,x,warning||"unexpected stype of x") return x } "null": { return "" } "wp": { return get_string(x.svalue,option) } "nv": { return get_string(x.svalue,option) } "nvnull": { return [get_string(x.svalue,option)] } # list like nv "bracket": { return get_string(x.svalue[2],option) } "paren": { return get_string(x.svalue[2],option) } "brace": { return get_string(x.svalue[2],option) } "angle": { return get_string(x.svalue[2],option) } } # end case stype } # end default } # end case option } # end "SYMBOL" "BSE": { return( get_string(bse_list(x),option) ) } # end "BSE" "PPOBJECT": { y := PPOBJECT() y.ppat := get_string(x.ppat,option) y.ppof := get_string(x.ppof,option) y.ppwith := get_string(x.ppwith,option) y.ppout := get_string(x.ppout,option) y.ppod := get_string(x.ppod,option) y.ppfrom := get_string(x.ppfrom,option) y.ppto := get_string(x.ppto,option) return y } } # end case type end # list or BSE procedure delete_separator(L,sep) #================================ # delete separator used in external representation of list local nosep,t,st,x local prep,nvlist static info,warning,ierror initial { info := "INFO: delete_separator: " warning := "WARNING: delete_separator: " ierror := "Internal ERROR: delete_separator: " } /sep := "," if DEBUG=="SEPARATOR" then { writes_type_all(L,info||"input L") } nosep := L case t := type(L) of { default: { writes_type(mylog,L,ierror||"unexpected type L") } "null": { writes_type(mylog,L,ierror||"unexpected null L") } "string": { if DEBUG==("NULL"|"EMPTY"|"LIST") then { # get lots of strings writes_type(mybug,L,warning||"unexpected type L") writes_type(mylog,L,warning||"unexpected type L") } } "integer": { writes_type(mylog,L,warning||"unexpected type L") } "real": { writes_type(mylog,L,warning||"unexpected type L") } "BSE": { nosep := bse_delete_separator(L,sep) } "SYMBOL": { case st := L.stype of { "null": { # get lots of null symbols if DEBUG==("NULL"|"EMPTY"|"LIST") then { writes_type(mybug,L,warning||"unexpected type L") writes_type(mylog,L,warning||"unexpected type L") } } "pp": { # SYMBOL("pp",[[prep],nvlist]) prep := L.svalue[1] nvlist := L.svalue[2] nvlist := delete_separator(nvlist) return SYMBOL("pp",[prep,nvlist]) } "nvobject": { # SYMBOL("nvobject",nvlist) nvlist := L.svalue nvlist := delete_separator(nvlist) return SYMBOL("nvobject",nvlist) } "subject": { # SYMBOL("subject",nvlist) nvlist := L.svalue nvlist := delete_separator(nvlist) return SYMBOL("subject",nvlist) } } # end case st } # end "SYMBOL" ("list"|"set"): { nosep := [] every x := !L do { if type(x)=="string" & x==sep then { } else { put(nosep,x) } } # end every x } # end "list"|"set" } if DEBUG=="SEPARATOR" then { writes_type_all(nosep,info||"output nosep") } return nosep end #=================================================================# # convert between string/list/nest/... # enquote/dequote strings with special characters # enbracket/parse_bracket symbols ([...] SYMBOLS representing lists/sets) # string procedure NullString(x) #====================== # ignore argument; return "" return "" end # string procedure NullValue(x) #===================== # ignore argument; return "[]" return "[]" end # list procedure NullList(x) #==================== # ignore argument; return [] return [] end #=================================================================# # string procedure echange2string(echange) #================================ local s if type(echange)=="null" then fail s := sym2string(echange) return s end # list procedure symbol2blist(symbol,listsep,wordsep,option) #==================================================== local blist /listsep := "" /wordsep := " " /option := "string" # or "value" if type(symbol)=="null" then fail blist := parse_list( sym2string(symbol,listsep,wordsep,option), listsep ) return blist end # string procedure sym2string(x,listsep,wordsep,option) #============================================= # get rid of extra blank at end of string /listsep := "," # original comma removed by map_symbol() /wordsep := " " /option := "string" # or "value" if type(x)=="null" then fail return trimws( symbol2string(x,listsep,wordsep,option) ) end # string procedure symbol2string(symbol,listsep,wordsep,option) #===================================================== # bracket all list/set # leaves extra wordsep at end # WARNING: use listsep="" before delete_separator(symbol,",") # WARNING: use listsep="," after delete_separator(symbol,",") local s,t,n,sym,i /wordsep := " " /option := "string" # or "value" case t := type(symbol) of { default: { writes_type(mylog,symbol,"Internal ERROR: symbol2string: "|| "unexpected type of symbol") return symbol } "SYMBOL": { return symbol2string(symbol.svalue,listsep,wordsep,option) } "string": { return symbol||wordsep } "integer": { return string(symbol)||wordsep } "real": { return string(symbol)||wordsep } ("list"|"set"): { case option of { default: { # "string" n := *symbol i := 0 s := "[" every sym := !symbol do { i +:= 1 s ||:= symbol2string(sym,listsep,wordsep,option) if i < n then s ||:= listsep } s ||:= "]" return s } # end default # "string" "value": { n := *symbol i := 0 s := "" #####if n > 1 then s ||:= "[" every sym := !symbol do { i +:= 1 s ||:= symbol2string(sym,listsep,wordsep,option) if i < n then s ||:= listsep } #####if n > 1 then s ||:= "]" return s } # end "value" } # end case option } # end "list"|"set" } # end case t end # list procedure symbol2vlist(symbol,listsep,wordsep) #============================================= local vlist,option /listsep := "," # original comma removed by map_symbol() /wordsep := " " option := "value" if type(symbol)=="null" then fail vlist := parse_list( sym2value(symbol,listsep,wordsep,option), listsep ) return vlist end # string procedure sym2value(x,listsep,wordsep) #===================================== # get rid of extra blank at end of string local value,option /listsep := "," # original comma removed by map_symbol() /wordsep := " " option := "value" if type(x)=="null" then fail value := trimws(symbol2value(x,listsep,wordsep,option)) return value end # value procedure symbol2value(symbol,listsep,wordsep) #============================================= # do NOT bracket list/set (of length 1) # leaves extra sep at end # WARNING: use listsep="" before delete_separator(symbol,",") # WARNING: use listsep="," after delete_separator(symbol,",") local value,option /listsep := "," # original comma removed by map_symbol() /wordsep := " " option := "value" if type(symbol)=="null" then fail value := symbol2string(symbol,listsep,wordsep,option) return value end procedure token2string(T,sep) #============================ local n,s,i /sep := " " if type(T)=="null" then fail n := *T s := "" every i := 1 to n do { s ||:= T[i].tvalue if i < n then s ||:= sep } return s # do NOT enquote() end # value procedure list2value(L,sep,bracket) #================================== # no bracket for list of length 1 # optional bracket for list of length > 1 /sep := "," /bracket := "" if type(L)=="null" then fail case *L of { 0: { return "" } 1: { return !L } default: { return list2string(L,sep,bracket) } } end # value procedure set2value(L,sep) #========================= # no bracket for list of length 1 if type(L)=="null" then fail return list2value(L,sep) end # string procedure list2string(L,sep,bracket) #=================================== local n,s,i,x /sep := "," /bracket := "[]" if type(L)=="null" then fail n := *L i := 0 s := bracket[1] | "" every x := !L do { i +:= 1 s ||:= x if i < n then s ||:= sep } s ||:= bracket[2] | "" return s end # string procedure set2string(L,sep) #========================== if type(L)=="null" then fail return list2string(L,sep) end procedure set2list(x) #==================== local L,y if type(x)=="null" then fail L := [] every y := ! x do put(L,y) return L end procedure string2list(s) #======================= local L static WordDef initial WordDef := &cset -- ',' if type(s)=="null" then fail L := [] s ? while tab(upto(WordDef)) do put(L,trimws(tab(many(WordDef)))) return L end #=================================================================# procedure forcequote(s,q) #======================== # make sure s is quoted -- for separator & comments local qsq static info initial { info := "INFO: forcequote: " } /q := "\"" #writes_type_all(s,info||"s") case type(s) of { default: { return s } "string": { qsq := q||dequote(s)||q #writes_type_all(qsq,info||"qsq") return qsq } } end procedure enquote(s,sep) #======================= # quote string containing separators # do not nest quote mark static dquote,squote initial { dquote := "\"" squote := "\'" } /sep := SEPARATOR # -- NVSEPARATOR case type(s) of { default: { return s } "null": { fail } "string": { } } s := trimws(s) # word.icn if *s = 0 then { return NullString(s) # "" } else if is_quote(s) then { # newword.icn return s # do NOT nest quote mark } else if is_bracket(s) then { # newword.icn return s # do NOT quote bracket } else if contains_separator(s,sep) then { # newword.icn return dquote||s||dquote # quote SEPARATOR } else if s==dquote then { return "dquote" # alias } else if s==squote then { return "squote" # alias } else { return s } end procedure dequote(s) #=================== return remove_quote(s) end procedure remove_quote(s) #======================== # remove quotes local t,x,y case t := type(s) of { default: { return s } "null": { fail } "string": { if is_quote(s) then return s[2:-1] else return s } # end "string" "PHRASE": { x := phrase_unparse(s) y := dequote(x) return PHRASE([y]) } # end "PHRASE" } # end case t end procedure remove_dquote(s) #========================= case type(s) of { default: { return s } "null": { fail } "string": { } } if is_dquote(s) then return s[2:-1] else return s end procedure remove_squote(s) #========================= case type(s) of { default: { return s } "null": { fail } "string": { } } if is_squote(s) then return s[2:-1] else return s end #=================================================================# # SYMBOL procedure enbracket(s) #===================== # [phrase,...] if type(s)=="null" then fail return SYMBOL("bracket",["[",s,"]"]) end # list or other procedure parse_bracket(s) #========================= # remove brackets from SYMBOL or list or string # parse string when brackets are removed # always return list for string input !!! local t if type(s)=="null" then fail case t := type(s) of { default: { writes_any(mylog,s,,"# Internal ERROR: parse_bracket: unexpected type <"|| t||"> of s <",">\n") return s # other } "SYMBOL": { return remove_bracket(s) } # list or SYMBOL "list": { return remove_bracket(s) } # list "string": { if *s >= 2 & s[1]=="[" & s[-1]=="]" then return parse_list( s[2:-1] ) # list else return [ s ] # list } } # end case type end # list or string or other procedure remove_bracket(s) #========================== # remove brackets from SYMBOL or list or string # do NOT parse string when brackets are removed # return list or string local x local t,stype,svalue static info,ierror,warning initial { info := "INFO: remove_bracket: " ierror := "Internal ERROR: remove_bracket: " warning := "WARNING: remove_bracket: " } if DEBUG==("BRACKET"|"BSE") then { writes_type_all(s,info||"input s") } x := s if type(s)=="null" then fail if *s = 0 then return s case t := type(s) of { default: { writes_type(mylog,s,ierror||"unexpected s") x := s # other } ("integer"|"real"): { return s } "SYMBOL": { stype := s.stype svalue := s.svalue case stype of { default: { writes_type(mylog,s,warning||"unexpected s") x := s # SYMBOL } "bracket": { # SYMBOL("bracket", ["[",[aa,bb,cc],"]"] ) x := svalue[2] # remove bracket } } # end case stype } "BSE": { if bse_begin(s)=="[" then { x := bse_list(s) } else { x := s } } "list": { if *s >= 2 & type(s[1])=="string" & s[1]=="[" & type(s[-1])=="string" & s[-1]=="]" then x := s[2] # remove bracket else x := s # list } "string": { if *s >= 2 & s[1]=="[" & s[-1]=="]" then x := trimws(s[2:-1]) # string else x := s # string } } # end case type if DEBUG==("BRACKET"|"BSE") then { writes_type_all(x,info||"output x") } return x end # list or string or other procedure remove_brace(s) #======================== # remove braces from SYMBOL or list or string # do NOT parse string when braces are removed # return list or string local x local t,stype,svalue static info,ierror initial { info := "INFO: remove_brace: " ierror := "Internal ERROR: remove_brace: " } if DEBUG==("BRACE"|"BSE") then { writes_type_all(s,info||"input s") } x := s if type(s)=="null" then fail if *s = 0 then return s case t := type(s) of { default: { writes_type(mylog,s,ierror||"unexpected s") x := s # other } ("integer"|"real"): { return s } "SYMBOL": { stype := s.stype svalue := s.svalue case stype of { default: { writes_type(mylog,s,ierror||"unexpected s") x := s # SYMBOL } "brace": { # SYMBOL("brace", ["{",[aa,bb,cc],"}"] ) x := svalue[2] # remove bracket } } # end case stype } "BSE": { if bse_begin(s)=="{" then { x := bse_list(s) } else { x := s } } "list": { if *s >= 2 & type(s[1])=="string" & s[1]=="{" & type(s[-1])=="string" & s[-1]=="}" then x := s[2] # remove bracket else x := s # list } "string": { if *s >= 2 & s[1]=="{" & s[-1]=="}" then x := trimws(s[2:-1]) # string else x := s # string } } # end case type if DEBUG==("BRACE"|"BSE") then { writes_type_all(x,info||"output x") } return x end # list or string or other procedure remove_paren(s) #======================== # remove parens from SYMBOL or list or string # do NOT parse string when parens are removed # return list or string local t,stype,svalue static ierror initial { ierror := "Internal ERROR: remove_paren: " } if type(s)=="null" then fail case t := type(s) of { default: { writes_type(mylog,s,ierror||"unexpected s") return s # other } "SYMBOL": { stype := s.stype svalue := s.svalue case stype of { default: { writes_type(mylog,s,ierror||"unexpected s") return s # SYMBOL } "paren": { # SYMBOL("paren", ["(",[aa,bb,cc],")"] ) return svalue[2] # remove paren } } # end case stype } "list": { if *s >= 2 & type(s[1])=="string" & s[1]=="(" & type(s[-1])=="string" & s[-1]==")" then return s[2] # remove paren else return s # list } "string": { if *s >= 2 & s[1]=="(" & s[-1]==")" then return trimws(s[2:-1]) # string else return s # string } } # end case type end #----------------------------------------# # list procedure string2charlist(x) #=========================== local y static warning initial warning := "WARNING: string2charlist: " case type(x) of { default: { writes_type_all(x,warning||"not string type: x") y := x } "string": { y := [] every put(y,!x) } } # end case type(x) return y end # list procedure bracket2list(label) #============================ # convert bracket to list # type(label) ::= SYMBOL | list | string local lab,lablist if is_quote(label) then { lab := dequote(label) } else if is_bracket(label) then { lab := remove_bracket(label) } else { lab := label } case type(lab) of { default: { } "list": { } "string": { lab := parse_list(lab,",") } } lablist := delete_separator(lab,",") return lablist end # list procedure brace2list(format) #=========================== # convert brace to list # type(format) ::= SYMBOL | list | string local fmt,flist if is_quote(format) then { fmt := dequote(format) } else if is_brace(format) then { fmt := remove_brace(format) } else { fmt := format } case type(fmt) of { default: { } "list": { } "string": { fmt := parse_list(fmt,",") } } flist := delete_separator(fmt,",") return flist end #----------------------------------------# # list or string procedure remove_angle(x) #======================== local y static info,ierror initial { info := "INFO: remove_angle: " ierror := "Internal ERROR: remove_angle: " } if DEBUG=="ANGLE" then writes_type_all(x,info||"x") case type(x) of { default: { writes_type(mylog,x,ierror||"unexpected type: x") y := x } "string": { if x[1]=="<" & x[-1]==">" then { y := x[2:-1] } else { y := x } y := trimws(y) } # end "string" "list": { if x[1]=="<" & x[-1]==">" then { y := x[2:-1] } else { y := x } } # end "list" } # end case type(x) if DEBUG=="ANGLE" then writes_type_all(y,info||"y") return y end #------------------------------------------------------- #------------------------------------------------------- #------------------------------------------------------- procedure value2set(v) #===================== if type(v)=="null" then fail return set(value2list(v)) end procedure value2list(v) #====================== # value includes external list "[...]" # value includes internal list [...] local t,w if DEBUG == "CONVERT" then write(mybug,"# INFO: value2list: value <",v,">") if type(v)=="null" then fail case t := type(v) of { default: { fail } "integer": { return [string(v)] } "real": { return [string(v)] } "list": { if *v = 1 then { return value2list(v[1]) } else { return v } } "string": { #####if is_bracket(v) then { return parse_bracket(v) #####} else { ##### return [v] #####} } } # end case t end #=================================================================# # list procedure phrase2list(phrase) #============================ if type(phrase)=="null" then fail return phrase_parse(phrase) # symbol.icn end # string procedure list2phrase(L,sep) #=========================== /sep := PSEPARATOR if type(L)=="null" then fail return list2string(L,sep) end #==================================================================== # list procedure get_plist(symbol) #========================== # get word list of a phrase local plist, t, st static head; initial { head := "# Internal ERROR: get_plist: unexpected " } if type(symbol)=="null" then fail plist := [] case t := type(symbol) of { default: { writes_any(mylog,symbol,,head||"type: symbol <",">\n") } "list": { symbol := delete_separator(symbol,",") every plist |||:= get_plist(!symbol) } "SYMBOL": { case st := symbol.stype of { default: { writes_any(mylog,symbol,,head||"subtype: symbol <",">\n") } "wp": { put(plist,symbol.svalue) } "nv": { put(plist,list2string(symbol.svalue,"")) } "bracket": { plist |||:= get_plist(symbol.svalue[2]) } "paren": { put(plist,sym2string(symbol.svalue," ")) } "conjunction": { put(plist,symbol.svalue[1]) } } } "string": { put(plist,symbol) } } return plist end # string procedure get_phrase(symbol) #=========================== local plist, phrase if type(symbol)=="null" then fail plist := get_plist(symbol) phrase := list2string(plist," ") return phrase end #==================================================================== # quote input/output phrase # string or list procedure kmap(x) #================ # quote x # called by interp_ho() in sentence.icn with x ::= string # called by do_relation() in relation.icn with x ::= list local y,z static squote,dquote,ierror initial { squote := "\'" dquote := "\"" ierror := "Internal ERROR: kmap: " } case type(x) of { default: { writes_type(mylog,x,ierror||"unexpected type: x") return x } "list": { z := [] every put(z,kmap(!x)) return z } "string": { } # continue below } # end case type() if is_quote(x) then return x y := x case KQUOTE of { default: { } "none": { } "squote": { if upto(squote,x) then y := dquote||x||dquote else y := squote||x||squote } "dquote": { if upto(dquote,x) then y := squote||x||squote else y := dquote||x||dquote } } # end case KQUOTE return y end # string or list procedure hmap(x) #================ # quote output x # called by xxx() in yyy.icn local y static squote,dquote initial { squote := "\'" dquote := "\"" } y := x case KQUOTE of { default: { } "none": { } "squote": { y := squote||x||squote } "dquote": { y := dquote||x||dquote } } # end case KQUOTE return x end #