diff options
Diffstat (limited to 'runtime/JavaScript/src/org/antlr/runtime/DFA.js')
-rwxr-xr-x | runtime/JavaScript/src/org/antlr/runtime/DFA.js | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/runtime/JavaScript/src/org/antlr/runtime/DFA.js b/runtime/JavaScript/src/org/antlr/runtime/DFA.js new file mode 100755 index 0000000..fb69996 --- /dev/null +++ b/runtime/JavaScript/src/org/antlr/runtime/DFA.js @@ -0,0 +1,149 @@ +/** A DFA implemented as a set of transition tables. + * + * Any state that has a semantic predicate edge is special; those states + * are generated with if-then-else structures in a specialStateTransition() + * which is generated by cyclicDFA template. + * + * There are at most 32767 states (16-bit signed short). + * Could get away with byte sometimes but would have to generate different + * types and the simulation code too. For a point of reference, the Java + * lexer's Tokens rule DFA has 326 states roughly. + */ +org.antlr.runtime.DFA = function() {}; + +org.antlr.runtime.DFA.prototype = { + /** From the input stream, predict what alternative will succeed + * using this DFA (representing the covering regular approximation + * to the underlying CFL). Return an alternative number 1..n. Throw + * an exception upon error. + */ + predict: function(input) { + var mark = input.mark(), // remember where decision started in input + s = 0, // we always start at s0 + specialState, + c, + snext; + + try { + while ( true ) { + specialState = this.special[s]; + if ( specialState>=0 ) { + s = this.specialStateTransition(specialState,input); + if (s===-1) { + this.noViableAlt(s, input); + return 0; + } + input.consume(); + continue; + } + if ( this.accept[s] >= 1 ) { + return this.accept[s]; + } + // look for a normal char transition + c = input.LA(1); // -1 == \uFFFF, all tokens fit in 65000 space + + if (c===org.antlr.runtime.Token.EOF) { + c = -1; + } else if (org.antlr.lang.isString(c)) { + c = c.charCodeAt(0); + } + + if (c>=this.min[s] && c<=this.max[s]) { + snext = this.transition[s][c-this.min[s]]; // move to next state + if ( snext < 0 ) { + // was in range but not a normal transition + // must check EOT, which is like the else clause. + // eot[s]>=0 indicates that an EOT edge goes to another + // state. + if ( this.eot[s]>=0 ) { // EOT Transition to accept state? + s = this.eot[s]; + input.consume(); + // TODO: I had this as return accept[eot[s]] + // which assumed here that the EOT edge always + // went to an accept...faster to do this, but + // what about predicated edges coming from EOT + // target? + continue; + } + this.noViableAlt(s,input); + return 0; + } + s = snext; + input.consume(); + continue; + } + if ( this.eot[s]>=0 ) { // EOT Transition? + s = this.eot[s]; + input.consume(); + continue; + } + if ( c==org.antlr.runtime.Token.EOF && this.eof[s]>=0 ) { // EOF Transition to accept state? + return this.accept[this.eof[s]]; + } + // not in range and not EOF/EOT, must be invalid symbol + this.noViableAlt(s,input); + return 0; + } + } + finally { + input.rewind(mark); + } + }, + + noViableAlt: function(s, input) { + if (this.recognizer.state.backtracking>0) { + this.recognizer.state.failed=true; + return; + } + var nvae = + new org.antlr.runtime.NoViableAltException(this.getDescription(), + this.decisionNumber, + s, + input); + this.error(nvae); + throw nvae; + }, + + /** A hook for debugging interface */ + error: function(nvae) { }, + + specialStateTransition: function(s, input) { + return -1; + }, + + getDescription: function() { + return "n/a"; + } +}; + +org.antlr.lang.augmentObject(org.antlr.runtime.DFA, { + /** Given a String that has a run-length-encoding of some unsigned shorts + * like "\1\2\3\9", convert to short[] {2,9,9,9}. + */ + unpackEncodedString: function(encodedString) { + // walk first to find how big it is. + var i, + data = [], + di = 0, + n, + v, + j; + for (i=0; i<encodedString.length; i+=2) { + n = encodedString.charCodeAt(i); + v = encodedString.charCodeAt(i+1); + if (v===0xffff) { + v = -1; // overflow at 16 bits + } + // add v n times to data + for (j=1; j<=n; j++) { + data[di++] = v; + } + } + return data; + }, + + // alias + unpackEncodedStringToUnsignedChars: function(encodedString) { + return org.antlr.runtime.DFA.unpackEncodedString(encodedString); + } +}); |