summaryrefslogtreecommitdiff
path: root/genops.js
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-04 21:53:16 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-04 21:53:16 +0200
commite6bb770a52980ef3d85c2d4b93fb240c026ce7f7 (patch)
tree3fbfbad81222598292a6aaf70c7b7bd1f32272f8 /genops.js
parentf83ea28ae6a04f1121b8328f7bdc5dad94628328 (diff)
Advance parser
Diffstat (limited to 'genops.js')
-rwxr-xr-xgenops.js88
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);