# # KEHOME/parser/nvlist.icn # Richard H. McCullough Aug/26/2005 Jul/20/2009 Aug/22/2014 link unparse # see grammar in symbol.icn # NOTE: for convenience, question.icn calls nv2nov for # qphrase,wphrase,bphrase,partphrase # # subject is object; # subject is object pplist; # subject has object; # subject hasp object; # subject do object pplist done; # subject rel object pplist; # # subject ::= phraselist; # SYMBOL("subject", phraselist) # object ::= csnvlist; # SYMBOL("object", csnvlist) # # phraselist ::= csvlist or CSV(csvlist) # phrase ::= list or PHRASE(list) # # nvlist ::= list or CSV(list) # # nov ::= # [name,op,value] # op ::= # "=" # "+=" # "-=" # "*=" record NVPHRASE ( nv_list # [name,op,value] ) # procedures #==========# # parse_nv(line) # new_nv(novlist) # nv_name(x) # nv_op(x) # nv_value(x) # nv_list(x) # nv_badtype(t,x,ierror) # error message # nv_writes(fd,x) # nv_unparse(x) # nv2nov(nvphrase) # nov2nv(novlist) # symbol2nv(symbol) # list of NVPHRASE | PHRASE procedure parse_nv(line) #======================= local t,name,op,value,nv local i,nvlist,novlist,word local nov,csvlist,csnvlist local x,y static prog,b,c,colon,yyprefix static ws,OpDef initial { prog := "parse_nv: " b := " " c := "," ws := ' \t\v\r\n\f' OpDef := '=+-*' } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(line) of { default: { write(&errout,yyprefix,"unexpected input type (",t,") line = (",showparse(line),")"); fail } ("string"|"integer"|"real"): { line ? if i := upto(OpDef) then { name := tab(i) op := tab(many(OpDef)) value := tab(0) name := trim(name,ws,0) value := trim(value,ws,0) nov := NVPHRASE(name,op,value) } else { name := line nov := PHRASE([name]) } # end if return nov } "CSV": { # list of string or list csvlist := line.csv_list csnvlist := [] every x := !csvlist do { y := parse_nv(x) put(csnvlist,new_nv(y)) } # end every do return csnvlist } "list": { nvlist := line } # continue below "PHRASE": { nvlist := line.csv_list } # continue below } # end case nov := PHRASE(nvlist) # default every i := key(nvlist) do { word := nvlist[i] if member(OpDef,cset(word)) then { name := PHRASE(nvlist[1:i]) op := unparse(nvlist[i],b) value := PHRASE(nvlist[i+1:0]) nov := NVPHRASE(name,op,value) break } # end if } # end every i return nov end # procedure # NVPHRASE or PHRASE procedure new_nv(nvlist) #======================== local t,n local name,op,value static prog,b,colon,yyprefix static OpDef initial { prog := "new_nv: " b := " " colon := ":" OpDef := '=+-*' } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog t := type(nvlist) n := *nvlist case t of { default: { write(mylog,yyprefix,"unexpected input type (",t,") nvlist = (",showparse(nvlist),")"); fail } "list": { case n of { 3: { name := nvlist[1] op := unparse(nvlist[2]) value := nvlist[3] if member(OpDef,cset(op)) then { return NVPHRASE([name,op,value]) } else { write(&errout,yyprefix,"unexpected input operator ("||op||")") return PHRASE(nvlist) } # end if } default : { return PHRASE(nvlist) } } # end case n } "NVPHRASE": { return nvlist } "PHRASE": { return nvlist } } # end case t end # procedure # list procedure nv_list(x) #====================== local t,y static prog,b,colon,yyprefix initial { prog := "nv_list: " b := " " colon := ":" } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(x) of { default: { write(mylog,yyprefix,"unexpected input type (",t,") x = (",showparse(x),")"); fail } "NVPHRASE": { y := x.nv_list } } return y end # string procedure nv_name(x) #=================== local t,y static prog,b,colon,yyprefix initial { prog := "nv_name: " b := " " colon := ":" } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(x) of { default: { write(mylog,yyprefix,"unexpected input type (",t,") x = (",showparse(x),")"); fail } "NVPHRASE": { y := x.nv_list[1] } } return y end # string procedure nv_op(x) #================= local t,y static prog,b,colon,yyprefix initial { prog := "nv_op: " b := " " colon := ":" } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(x) of { default: { write(mylog,yyprefix,"unexpected input type (",t,") x = (",showparse(x),")"); fail } "NVPHRASE": { y := x.nv_list[2] } } return y end # string procedure nv_value(x) #==================== local t,y static prog,b,colon,yyprefix initial { prog := "nv_value: " b := " " colon := ":" } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(x) of { default: { write(mylog,yyprefix,"unexpected input type (",t,") x = (",showparse(x),")"); fail } "NVPHRASE": { y := x.nv_list[3] } } return y end procedure nv_writes(fd,x) #======================== local t,nvlist static prog,b,colon,yyprefix static ierror initial { prog := "nv_writes: " b := " " colon := ":" ierror := "Internal ERROR: "||prog } /fd := &output yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(x) of { default: { write(&errout,yyprefix,"unexpected input type (",t,")"); fail } "NVPHRASE": { write(fd,showparse(x)) } } # end case t end # string procedure nv_unparse(x) #====================== local t static prog,b,colon,yyprefix initial { prog := "nv_unparse: " b := " " colon := ":" } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog case t := type(x) of { default: { write(&errout,yyprefix,"unexpected input type (",t,")"); fail } "NVPHRASE": { return unparse(x) } } # end case t end # novlist or list of novlist procedure nv2nov(nvphrase) #========================= # called by set_charnest() in char.icn # called by qsubject() in question.icn # called by qverb() in question.icn # called by qobject() in question.icn # called by qvalue() in question.icn local t,st,nov static prog,b static ierror,warning,notimp,utype,ustype initial { prog := "nv2nov: " b := " " ierror := "Internal ERROR: "||prog warning := "WARNING: "||prog notimp := "Not Implemented: "||prog utype := warning||"unexpected type(" ustype := warning||"unexpected stype(" } nov := [] case t := type(nvphrase) of { "NVPHRASE": { nov := nv_list(nvphrase) } "PHRASE": { nov := phrase_list(nvphrase) } "CSV": { nov := csv_list(nvphrase) } "SYMBOL": { case st := nvphrase.stype of { "nvobject": { nov := nv2nov(nvphrase.svalue) } "object": { nov := nv2nov(nvphrase.svalue) } default: { write_type(mylog,nvphrase,ustype||st||") nvphrase") write_type(&errout,nvphrase,ustype||st||") nvphrase") nov := [nvphrase] } } # end case st } # end "SYMBOL" "list": { # novlist or nvlist case *nvphrase of { 0: { if DEBUG==("NULL"|"EMPTY"|"LIST") then { write_type(mylog,nvphrase,utype||t||") nvphrase") write_type(mylog,nvphrase,utype||t||") nvphrase") } } default: { #####write_type(&errout,nvphrase,utype) #####write_type(mylog,nvphrase,utype) } } # end case *nvphrase nov := [] every put(nov,nv2nov(!nvphrase)) } # end "list" "string": { case nvphrase of { "?": { # get lots of "?" } default: { ###write_type(&errout,nvphrase,utype) ###write_type(mylog,nvphrase,utype) } } nov := [nvphrase] } default: { write_type(&errout,nvphrase,utype) write_type(mylog,nvphrase,utype) nov := [nvphrase] } } return nov end # NVPHRASE procedure nov2nv(novlist) #======================== local nv static prog static ierror,utype,usize initial { prog := "nov2nv: " ierror := "Internal ERROR: "||prog utype := ierror||"unexpected type: novlist" usize := ierror||"unexpected size: novlist" } return new_nv(novlist) end #======================================================# # list procedure symbol2nov(symbol) #=========================== # called by set_charnest() in char.icn # called by do_action() in action.icn # output ::= # [name] # [name,op,value] local t,nvnest static prog,b,colon,yyprefix static info,ierror initial { prog := "symbol2nov: " b := " " colon := ":" info := "INFO: "||prog ierror := "Internal ERROR: "||prog } yyprefix := yylineno||colon||yywordno||b||KFORMAT||b||prog if DEBUG==("ACTION"|"EVENT") then { write_type(mylog,symbol,info||"symbol") write_type(mylog,symbol,info||"symbol") } nvnest := [] case t := type(symbol) of { default: { write(&errout,yyprefix,"unexpected input type (",t,") symbol = (",showparse(symbol),")") write(mylog,yyprefix,"unexpected input type (",t,") symbol = (",showparse(symbol),")") fail } "list": { every put(nvnest,symbol2nov(!symbol)) } "set": { every put(nvnest,symbol2nov(!symbol)) } "CSV": { nvnest := symbol2nov(csv_list(symbol)) } ("string"|"integer"|"real"): { nvnest := [string(symbol)] } "SYMBOL": { nvnest := nv2nov(symbol) } "NVPHRASE": { nvnest := nv2nov(symbol) } "PHRASE": { nvnest := nv2nov(symbol) } } # end case type if DEBUG==("ACTION"|"EVENT") then { write_type(mylog,nvnest,info||"nvnest") write_type(mylog,nvnest,info||"nvnest") } return nvnest end #