colorful rat Ratfactor.com > Dave's Repos

hoot

Silly HTML game building engine
git clone http://ratfactor.com/repos/hoot/hoot.git

hoot/js/hoot-grammar.js

Download raw file: js/hoot-grammar.js

1 2 /* 3 4 This is the grammar for Hootscript. This script also makes some transformations 5 to the grammar so that it contains predictions (instead of a separate prediction 6 table as you might expect). 7 8 This grammar is used by the Hoot parser to transform scripts into games. 9 10 */ 11 12 13 function getGrammar(){ 14 15 // the grammar 16 // ===================================================================== 17 18 19 var grammar = { 20 "script": { rules: "+func", keep:true }, 21 "func": { rules: "name colon +expr", keep:true }, 22 "expr": { rules: "print | assign | ifseq | runme | incr | decr" }, 23 "print": { rules: "qopen *qinnards qclose", keep:true }, 24 "assign": { rules: "set name to num", keep:true }, 25 "qinnards": { rules: "strname | upname | break | link | string" }, 26 "ifseq": { rules: "if value test value then +expr *elseseq end", keep:true }, 27 "elseseq": { rules: "else +expr", keep:true }, 28 "test": { rules: "eq | lt | gt | de" }, 29 "value": { rules: "name | num" }, 30 "cond": { rules: "if value test value then +expr", keep:true }, 31 "runme": { rules: "run name", keep:true }, 32 "incr": { rules: "increase name", keep:true }, 33 "decr": { rules: "decrease name", keep:true }, 34 "colon": { lookahead: /^:/, extract: /^(:)\s*/ }, 35 "name": { lookahead: /^\[/, extract: /^\[([^[_]+?)\]\s*/, keep:true }, 36 "num": { lookahead: /^\d/, extract: /^(\d+)\s*/, keep:true }, 37 "eq": { lookahead: /^e/, extract: /^(equals)\s*/, keep:true }, 38 "lt": { lookahead: /^l/, extract: /^(less than)\s*/, keep:true }, 39 "gt": { lookahead: /^g/, extract: /^(greater than)\s*/, keep:true }, 40 "de": { lookahead: /^d/, extract: /^(doesn't equal)\s*/, keep:true }, 41 "set": { lookahead: /^s/, extract: /^(set)\s*/ }, 42 "to": { lookahead: /^t/, extract: /^(to)\s*/ }, 43 "if": { lookahead: /^if/, extract: /^(if)\s*/ }, 44 "then": { lookahead: /^t/, extract: /^(then)\s*/ }, 45 "else": { lookahead: /^el/, extract: /^(else)\s*/ }, 46 "end": { lookahead: /^en/, extract: /^(end)\s*/ }, 47 "run": { lookahead: /^r/, extract: /^(run)\s*/ }, 48 "increase": { lookahead: /^in/, extract: /^(increase)\s*/ }, 49 "decrease": { lookahead: /^de/, extract: /^(decrease)\s*/ }, 50 "qopen": { lookahead: /^\//, extract: /^(\/)/ }, 51 "qclose": { lookahead: /^\//, extract: /^(\/)\s*/ }, 52 "string": { lookahead: /^[^\/^[_]/, extract: /^((?:\\.|[^\/[_^])+)/, keep:true }, 53 "link": { lookahead: /^_/, extract: /^_([^_]+?)_/, keep:true }, 54 "break": { lookahead: /^__/, extract: /^(__)/, keep:true }, 55 "strname": { lookahead: /^\[/, extract: /^\[([^[]+?)\]/, keep:true }, 56 "upname": { lookahead: /^\^\[/, extract: /^\^\[(.+?)\]/, keep:true } 57 }; 58 59 60 61 62 // massage the grammar 63 // ===================================================================== 64 65 for(var g in grammar){ 66 atom = grammar[g]; 67 atom.name = g; // store its name inside itself 68 atom.operator = ""; // default 69 70 if(atom.rules){ 71 // split alternative rules 72 atom.rules = atom.rules.split(" | "); 73 for(r in atom.rules){ 74 // split rule into atoms 75 atom.rules[r] = atom.rules[r].split(" "); 76 for(x in atom.rules[r]){ 77 // look for + and * operators on atoms 78 ratom = atom.rules[r][x]; 79 firstchar = ratom[0]; 80 if(firstchar == "+" || firstchar == "*"){ 81 ratom = ratom.slice(1); 82 } 83 else{ 84 firstchar = ""; 85 } 86 atom.rules[r][x] = { 87 "name": ratom, 88 "operator":firstchar 89 } 90 } 91 } 92 } 93 } 94 95 96 // now go through again and make predictions 97 for(var g in grammar){ 98 atom = grammar[g]; 99 100 if(atom.rules){ 101 atom.predictions = []; 102 for(r in atom.rules){ 103 atom.predictions.push(getprediction(atom.rules[r][0].name)); 104 } 105 } 106 } 107 108 function getprediction(atom){ 109 if(!grammar[atom]){ alert("Bad Grammar! Couldn't find '"+atom+"'."); } 110 if(grammar[atom].rules){ 111 return getprediction(grammar[atom].rules[0][0].name); 112 } 113 return grammar[atom].lookahead; 114 } 115 116 117 118 119 return grammar; 120 }