diff options
Diffstat (limited to 'genops.js')
-rwxr-xr-x | genops.js | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/genops.js b/genops.js new file mode 100755 index 0000000..33b688d --- /dev/null +++ b/genops.js @@ -0,0 +1,88 @@ +#!/usr/bin/env node +const fs=require("fs"); + + +function print(/*arguments*/){ + //console.log.apply(console,arguments); + process.stdout.write.apply(process.stdout,arguments); +} + +function pad(s,w,c){ + s=s+""; + if(s.length>=Math.abs(w))return s; + if(w<0)return s+Array(-w-s.length+1).join(c?c:" "); + else return Array(w-s.length+1).join(c?c:" ")+s; +} + + +function readopmap(fname){ + let table=String(fs.readFileSync(fname)).split("\n"); + let i; + for(i=0;i<table.length;i++){ + if(/Oper.*Prec.*Assoc/.test(table[i]))break; + } + let header=table[i]; + table=table.slice(i+1); + for(i=0;i<table.length;i++){ + if(table[i].length==0)break; + } + table=table.slice(0,i); + + let opsidx=header.indexOf("Oper"), + precidx=header.indexOf("Prec"), + associdx=header.indexOf("Assoc"); + + let opmap={}; + + for(let row of table){ + let ops=row.slice(opsidx,precidx).trim().split(" "), + prec=parseInt(row.slice(precidx,associdx).trim(),10), + assoc=row.slice(associdx).replace(/ *([^ ]+).*/,"$1"); + for(let op of ops){ + opmap[op]={prec,assoc}; + } + } + return opmap; +} + +function outputfunc(opmap,name,gen,padw){ + print("int "+name+"(const char *op){\n"); + print("\tswitch(op[0]){\n"); + + let firstchars={}; + for(let k in opmap){ + if(firstchars[k[0]])firstchars[k[0]].push(k); + else firstchars[k[0]]=[k]; + } + let arr=[]; + for(k in firstchars){ + arr.push([k,firstchars[k].sort()]); + } + arr=arr.sort(); + for(let tup of arr){ + let k=tup[0],ops=tup[1]; + print("\t\tcase '"+k+"': return "); + for(let op of ops){ + let cond=""; + for(j=1;j<op.length;j++)cond+="op["+j+"]=='"+op[j]+"'&&"; + cond+="op["+j+"]=='\\0'"; + print(cond+" ? "+pad(gen(opmap[op]),padw)+" : "); + } + print("-1;\n"); + } + + print("\t\tdefault: return -1;\n"); + print("\t}\n"); + print("}\n"); +} + + +const opmap=readopmap("LANGUAGE.txt"); +outputfunc(opmap,"precedence",o=>o.prec,2); +print("\n"); +const assocenum={ + "Prefix": "AS_PREFIX", "Suffix": "AS_SUFFIX", + "Left": "AS_LEFT", "Right": "AS_RIGHT", + "Nonassociative": "AS_NONASSOC" +}; +outputfunc(opmap,"associativity",o=>assocenum[o.assoc],-11); |