1cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi#!lua 2cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi----------------------------------------------------------------------------- 3cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- lua script picoloadphones.lua --- creates pkb containing phones table. 4cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- 5cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- Copyright (C) 2009 SVOX AG. All rights reserved. 6cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi----------------------------------------------------------------------------- 7cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 8cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- load pico phones src file and create phones pkb file 9cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 10cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- accepted syntax: 11cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- - parses line of the following format: 12cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- :SYM "<sym>" :PROP mapval = <uint8> { , <propname> = <int> } 13cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- - initial '!' and trailing '!.*' are treated as comments, no '[]' 14cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 15cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 16cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi--- valid property names 17cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivipropnames = {mapval=0, vowel=0, diphth=0, glott=0, nonsyllvowel=0, syllcons=0} 18cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi--- valid property names (that may occur once only) 19cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviupropnames = {primstress=0, secstress=0, syllbound=0, wordbound=0, pause=0} 20cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 21cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 22cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- init 23cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviif #arg ~= 2 then 24cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("*** error: wrong number of arguments, must be 2"); return 25cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 26cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivilocal infile = io.open(arg[1], "r") 27cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviif not infile then 28cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("*** error: could not open input file: " .. arg[1]); return 29cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 30cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivilocal outfile = io.open(arg[2], "wb") 31cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviif not outfile then 32cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("*** error: could not open output file: " .. arg[2]); return 33cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 34cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 35cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 36cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- tables 37cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi--- table with symbol name keys (not really used currently) 38cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivilocal syms = {} 39cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi--- table with symbol name number keys (specified with property mapval) 40cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivilocal symnrs = {} 41cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi--- array of symbol name numer keys used (to check for unique mapvals) 42cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivilocal symnrsused = {} 43cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 44cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 45cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- parse input file, build up syms and symnrs tables 46cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifor line in infile:lines() do 47cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if string.match(line, "^%s*!.*$") or string.match(line, "^%s*$") then 48cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- discard comment-only lines 49cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else 50cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi cline = string.gsub(line, "^%s*", "") 51cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- get :SYM 52cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi sym = string.match(cline, "^:SYM%s+\"([^\"]-)\"%s+") 53cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if not sym then 54cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi sym = string.match(cline, "^:SYM%s+'([^']-)'%s+") 55cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 56cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if sym then 57cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi cline = string.gsub(cline, "^:SYM%s+['\"].-['\"]%s+", "") 58cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- get :PROP and mapval prop/propval 59cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi propval = string.match(cline, "^:PROP%s+mapval%s*=%s*(%d+)%s*") 60cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if propval then 61cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi cline = string.gsub(cline, "^:PROP%s+mapval%s*=%s*%d+%s*", "") 62cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- construct props table and add first mapval property 63cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi props = {mapval = tonumber(propval)} 64cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi symnr = tonumber(propval) 65cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if not symnrsused[symnr] then 66cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi symnrsused[symnr] = true 67cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else 68cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi io.write("*** error: mapval values must be unique, ", symnr, "\n") 69cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("line: ", line); return 70cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 71cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- check if remaining part are comments only 72cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi cline = string.gsub(cline, "^!.*", "") 73cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi while (#cline > 0) do 74cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- try to get next prop/propval and add to props 75cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi prop, propval = string.match(cline, "^,%s*(%w+)%s*=%s*(%d+)%s*") 76cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if prop and propval then 77cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi cline = string.gsub(cline, "^,%s*%w+%s*=%s*%d+%s*", "") 78cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi props[prop] = tonumber(propval) 79cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else 80cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("*** error: syntax error in property list") 81cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("line: ", line); return 82cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 83cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi -- cleanup if only comments remaining 84cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi cline = string.gsub(cline, "^!.*", "") 85cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 86cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else 87cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("*** error: no mapval property found") 88cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("line: ", line); return 89cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 90cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi syms[sym] = props 91cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi symnrs[symnr] = props 92cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else 93cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("*** error: no symbol found") 94cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi print("line: ", line) 95cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi return 96cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 97cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 98cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 99cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 100cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 101cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- check syms and symnrs 102cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 103cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifunction checksymtable (st) 104cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi for s in pairs(propnames) do propnames[s] = 0 end 105cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi for s in pairs(upropnames) do upropnames[s] = 0 end 106cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi for s, p in pairs(st) do 107cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi for prop, propval in pairs(p) do 108cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if not propnames[prop] and not upropnames[prop] then 109cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi io.write("*** error: invalid property name '", prop, "'\n") 110cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi return 111cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 112cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if propnames[prop] then 113cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi propnames[prop] = propnames[prop] + 1 114cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi elseif upropnames[prop] then 115cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi upropnames[prop] = upropnames[prop] + 1 116cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 117cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 118cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi for prop, propval in pairs(upropnames) do 119cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if propval > 1 then 120cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi io.write("*** error: property '", prop, "' must be unique\n"); return 121cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 122cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 123cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 124cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 125cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 126cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivichecksymtable(syms) 127cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivichecksymtable(symnrs) 128cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 129cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 130cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- get IDs of unique specids 131cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 132cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivispecid = {} 133cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifor i = 1, 8 do specid[i] = 0 end 134cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifor s, pl in pairs(symnrs) do 135cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl["primstress"] then specid[1] = pl["mapval"] 136cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi elseif pl["secstress"] then specid[2] = pl["mapval"] 137cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi elseif pl["syllbound"] then specid[3] = pl["mapval"] 138cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi elseif pl["pause"] then specid[4] = pl["mapval"] 139cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi elseif pl["wordbound"] then specid[5] = pl["mapval"] 140cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 141cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 142cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 143cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 144cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- write out Phones pkb 145cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 146cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifunction encodeprops (n) 147cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi rv = 0 148cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi pl = symnrs[n] 149cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl then 150cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl["vowel"] then rv = 1 end 151cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl["diphth"]then rv = rv + 2 end 152cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl["glott"] then rv = rv + 4 end 153cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl["nonsyllvowel"] then rv = rv + 8 end 154cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if pl["syllcons"] then rv = rv + 16 end 155cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 156cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi return rv 157cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 158cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 159cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifor i=1,8 do 160cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if specid[i] == 0 then outfile:write("\0") 161cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else outfile:write(string.format("%c", specid[i])) 162cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 163cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 164cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivifor i = 0, 255 do 165cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi nr = encodeprops(i) 166cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi if nr == 0 then outfile:write("\0") 167cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi else outfile:write(string.format("%c", nr)) 168cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi end 169cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviend 170cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 171cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 172cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- tini 173cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 174cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Triviinfile:close() 175cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivioutfile:close() 176cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi 177cb1b5f35225a63d1efdd595955e6455e718b1698Jean-Michel Trivi-- end 178