📄 v8-earley-boyer.js
字号:
/* hexa-number */ var nb = 0; while (true) { var hexC = port.peekChar(); if (hexC >= '0' && hexC <= '9') { port.readChar(); nb = nb * 16 + hexC.charCodeAt(0) - '0'.charCodeAt(0); } else if (hexC >= 'a' && hexC <= 'f') { port.readChar(); nb = nb * 16 + hexC.charCodeAt(0) - 'a'.charCodeAt(0); } else if (hexC >= 'A' && hexC <= 'F') { port.readChar(); nb = nb * 16 + hexC.charCodeAt(0) - 'A'.charCodeAt(0); } else { // next char isn't part of hex. res += String.fromCharCode(nb); break; } } break; default: if (tmp === SC_EOF_OBJECT) { return new sc_Token(13/*ERROR*/, "unclosed string-literal" + res); } res += tmp; } break; default: if (c === SC_EOF_OBJECT) { return new sc_Token(13/*ERROR*/, "unclosed string-literal" + res); } res += c; } } }; function readIdOrNumber(firstChar) { var res = firstChar; while (isIdOrNumberChar(port.peekChar())) res += port.readChar(); if (isNaN(res)) return new sc_Token(9/*ID*/, res); else return new sc_Token(12/*NUMBER*/, res - 0); }; function skipWhitespaceAndComments() { var done = false; while (!done) { done = true; while (isWhitespace(port.peekChar())) port.readChar(); if (port.peekChar() === ';') { port.readChar(); done = false; while (true) { curChar = port.readChar(); if (curChar === SC_EOF_OBJECT || curChar === '\n') break; } } } }; function readDot() { if (isWhitespace(port.peekChar())) return new sc_Token(10/*DOT*/); else return readIdOrNumber("."); }; function readSharp() { var c = port.readChar(); if (isWhitespace(c)) return new sc_Token(13/*ERROR*/, "bad #-pattern0."); // reference if (isNumberChar(c)) { var nb = c - 0; while (isNumberChar(port.peekChar())) nb = nb*10 + (port.readChar() - 0); switch (port.readChar()) { case '#': return new sc_Token(18/*REFERENCE*/, nb); case '=': return new sc_Token(19/*STORE*/, nb); default: return new sc_Token(13/*ERROR*/, "bad #-pattern1." + nb); } } if (c === "(") return new sc_Token(14/*VECTOR_BEGIN*/); if (c === "\\") { // character var tmp = "" while (!isWhitespaceOrEOF(port.peekChar())) tmp += port.readChar(); switch (tmp.length) { case 0: // it's escaping a whitespace char: if (sc_isEOFObject(port.peekChar)) return new sc_Token(13/*ERROR*/, "bad #-pattern2."); else return new sc_Token(20/*CHAR*/, port.readChar()); case 1: return new sc_Token(20/*CHAR*/, tmp); default: var entry = sc_Char.readable2char[tmp.toLowerCase()]; if (entry) return new sc_Token(20/*CHAR*/, entry); else return new sc_Token(13/*ERROR*/, "unknown character description: #\\" + tmp); } } // some constants (#t, #f, #unspecified) var res; var needing; switch (c) { case 't': res = new sc_Token(15/*TRUE*/, true); needing = ""; break; case 'f': res = new sc_Token(16/*FALSE*/, false); needing = ""; break; case 'u': res = new sc_Token(17/*UNSPECIFIED*/, undefined); needing = "nspecified"; break; default: return new sc_Token(13/*ERROR*/, "bad #-pattern3: " + c); } while(true) { c = port.peekChar(); if ((isWhitespaceOrEOF(c) || c === ')') && needing == "") return res; else if (isWhitespace(c) || needing == "") return new sc_Token(13/*ERROR*/, "bad #-pattern4 " + c + " " + needing); else if (needing.charAt(0) == c) { port.readChar(); // consume needing = needing.slice(1); } else return new sc_Token(13/*ERROR*/, "bad #-pattern5"); } }; skipWhitespaceAndComments(); var curChar = port.readChar(); if (curChar === SC_EOF_OBJECT) return new sc_Token(0/*EOF*/, curChar); switch (curChar) { case " ": case "\n": case "\t": return readWhitespace(); case "(": return new sc_Token(1/*OPEN_PAR*/); case ")": return new sc_Token(2/*CLOSE_PAR*/); case "{": return new sc_Token(3/*OPEN_BRACE*/); case "}": return new sc_Token(4/*CLOSE_BRACE*/); case "[": return new sc_Token(5/*OPEN_BRACKET*/); case "]": return new sc_Token(6/*CLOSE_BRACKET*/); case "'": return new sc_Token(8/*QUOTE*/); case "#": return readSharp(); case ".": return readDot(); case '"': return readString(); default: if (isIdOrNumberChar(curChar)) return readIdOrNumber(curChar); throw "unexpected character: " + curChar; }};function sc_Reader(tokenizer) { this.tokenizer = tokenizer; this.backref = new Array();}sc_Reader.prototype.read = function() { function readList(listBeginType) { function matchesPeer(open, close) { return open === 1/*OPEN_PAR*/ && close === 2/*CLOSE_PAR*/ || open === 3/*OPEN_BRACE*/ && close === 4/*CLOSE_BRACE*/ || open === 5/*OPEN_BRACKET*/ && close === 6/*CLOSE_BRACKET*/; }; var res = null; while (true) { var token = tokenizer.peekToken(); switch (token.type) { case 2/*CLOSE_PAR*/: case 4/*CLOSE_BRACE*/: case 6/*CLOSE_BRACKET*/: if (matchesPeer(listBeginType, token.type)) { tokenizer.readToken(); // consume token return sc_reverseBang(res); } else throw "closing par doesn't match: " + listBeginType + " " + listEndType; case 0/*EOF*/: throw "unexpected end of file"; case 10/*DOT*/: tokenizer.readToken(); // consume token var cdr = this.read(); var par = tokenizer.readToken(); if (!matchesPeer(listBeginType, par.type)) throw "closing par doesn't match: " + listBeginType + " " + par.type; else return sc_reverseAppendBang(res, cdr); default: res = sc_cons(this.read(), res); } } }; function readQuote() { return sc_cons("quote", sc_cons(this.read(), null)); }; function readVector() { // opening-parenthesis is already consumed var a = new Array(); while (true) { var token = tokenizer.peekToken(); switch (token.type) { case 2/*CLOSE_PAR*/: tokenizer.readToken(); return a; default: a.push(this.read()); } } }; function storeRefence(nb) { var tmp = this.read(); this.backref[nb] = tmp; return tmp; }; function readReference(nb) { if (nb in this.backref) return this.backref[nb]; else throw "bad reference: " + nb; }; var tokenizer = this.tokenizer; var token = tokenizer.readToken(); // handle error if (token.type === 13/*ERROR*/) throw token.val; switch (token.type) { case 1/*OPEN_PAR*/: case 3/*OPEN_BRACE*/: case 5/*OPEN_BRACKET*/: return readList.call(this, token.type); case 8/*QUOTE*/: return readQuote.call(this); case 11/*STRING*/: return sc_jsstring2string(token.val); case 20/*CHAR*/: return new sc_Char(token.val); case 14/*VECTOR_BEGIN*/: return readVector.call(this); case 18/*REFERENCE*/: return readReference.call(this, token.val); case 19/*STORE*/: return storeRefence.call(this, token.val); case 9/*ID*/: return sc_jsstring2symbol(token.val); case 0/*EOF*/: case 12/*NUMBER*/: case 15/*TRUE*/: case 16/*FALSE*/: case 17/*UNSPECIFIED*/: return token.val; default: throw "unexpected token " + token.type + " " + token.val; }};/*** META ((export #t)) */function sc_read(port) { if (port === undefined) // we assume the port hasn't been given. port = SC_DEFAULT_IN; // THREAD: shared var... var reader = new sc_Reader(new sc_Tokenizer(port)); return reader.read();}/*** META ((export #t)) */function sc_readChar(port) { if (port === undefined) // we assume the port hasn't been given. port = SC_DEFAULT_IN; // THREAD: shared var... var t = port.readChar(); return t === SC_EOF_OBJECT? t: new sc_Char(t);}/*** META ((export #t)) */function sc_peekChar(port) { if (port === undefined) // we assume the port hasn't been given. port = SC_DEFAULT_IN; // THREAD: shared var... var t = port.peekChar(); return t === SC_EOF_OBJECT? t: new sc_Char(t);} /*** META ((export #t) (type bool))*/function sc_isCharReady(port) { if (port === undefined) // we assume the port hasn't been given. port = SC_DEFAULT_IN; // THREAD: shared var... return port.isCharReady();}/*** META ((export #t) (peephole (postfix ".close()")))*/function sc_closeInputPort(p) { return p.close();}/*** META ((export #t) (type bool) (peephole (postfix " instanceof sc_InputPort")))*/function sc_isInputPort(o) { return (o instanceof sc_InputPort);}/*** META ((export eof-object?) (type bool) (peephole (postfix " === SC_EOF_OBJECT")))*/function sc_isEOFObject(o) { return o === SC_EOF_OBJECT;}/*** META ((export #t) (peephole (hole 0 "SC_DEFAULT_IN")))*/function sc_currentInputPort() { return SC_DEFAULT_IN;}/* ------------ file operations are not supported -----------*//*** META ((export #t)) */function sc_callWithInputFile(s, proc) { throw "can't open " + s;}/*** META ((export #t)) */function sc_callWithOutputFile(s, proc) { throw "can't open " + s;}/*** META ((export #t)) */function sc_withInputFromFile(s, thunk) { throw "can't open " + s;}/*** META ((export #t)) */function sc_withOutputToFile(s, thunk) { throw "can't open " + s;}/*** META ((export #t)) */function sc_openInputFile(s) { throw "can't open " + s;}/*** META ((export #t)) */function sc_openOutputFile(s) { throw "can't open " + s;}/* ----------------------------------------------------------------------------*//*** META ((export #t)) */function sc_basename(p) { var i = p.lastIndexOf('/'); if(i >= 0) return p.substring(i + 1, p.length); else return '';}/*** META ((export #t)) */function sc_dirname(p) { var i = p.lastIndexOf('/'); if(i >= 0) return p.substring(0, i); else return '';}/* ----------------------------------------------------------------------------*//*** META ((export #t)) */function sc_withInputFromPort(p, thunk) { try { var tmp = SC_DEFAULT_IN; // THREAD: shared var. SC_DEFAULT_IN = p; return thunk(); } finally { SC_DEFAULT_IN = tmp; }}/*** META ((export #t)) */function sc_withInputFromString(s, thunk) { return sc_withInputFromPort(new sc_StringInputPort(sc_string2jsstring(s)), thunk);}/*** META ((export #t)) */function sc_withOutputToPort(p, thunk) { try { var tmp = SC_DEFAULT_OUT; // THREAD: shared var. SC_DEFAULT_OUT = p; return thunk(); } finally { SC_DEFAULT_OUT = tmp; }}/*** META ((export #t)) */function sc_withOutputToString(thunk) { var p = new sc_StringOutputPort(); sc_withOutputToPort(p, thunk); return p.close();}/*** META ((export #t)) */function sc_withOutputToProcedure(proc, thunk) { var t = function(s) { proc(sc_jsstring2string(s)); }; return sc_withOutputToPort(new sc_GenericOutputPort(t), thunk);}/*** META ((export #t) (peephole (hole 0 "new sc_StringOutputPort()")))*/function sc_openOutputString() { return new sc_StringOutputPort();}/*** META ((export #t)) */function sc_openInputString(str) { return new sc_StringInputPort(sc_string2jsstring(str));}/* ----------------------------------------------------------------------------*/function sc_OutputPort() {}sc_OutputPort.prototype = new sc_Port();sc_OutputPort.prototype.appendJSString = function(obj) { /* do nothing */}sc_OutputPort.prototype.close = function() { /* do nothing */}function sc_StringOutputPort() { this.res = "";}sc_StringOutputPort.prototype = new sc_OutputPort();sc_StringOutputPort.prototype.appendJSString = function(s) { this.res += s;}sc_StringOutputPort.prototype.close = function() { return sc_jsstring2string(this.res);}/*** META ((export #t)) */function sc_getOutputString(sp) { return sc_jsstring2string(sp.res);} function sc_ErrorOutputPort() {}sc_ErrorOutputPort.prototype = new sc_OutputPort();sc_ErrorOutputPort.prototype.appendJSString = function(s) { throw "don't write on ErrorPort!";}sc_ErrorOutputPort.prototype.close = function() { /* do nothing */}function sc_GenericOutputPort(appendJSString, close) { this.appendJSString = appendJSString; if (close) this.close = close;}sc_GenericOutputPort.prototype = new sc_OutputPort();/*** META ((export #t) (type bool) (peephole (postfix " instanceof sc_OutputPort")))*/function sc_isOutputPort(o) { return (o instanceof sc_OutputPort);}/*** META ((export #t) (peephole (postfix ".close()")))*/function sc_closeOutputPort(p) { return p.close();}/* ------------------ write ---------------------------------------------------*//*** META ((export #t)) */function sc_write(o, p) { if (p === undefined) // we assume not given p = SC_DEFAULT_OUT; p.appendJSString(sc_toWriteString(o));}function sc_toWriteString(o) { if (o === null) return "()"; else if (o === true) return "#t"; else if (o === false) return "#f"; else if (o === undefined) return "#unspecified"; else if (typeof o === 'function') return "#<procedure " + sc_hash(o) + ">"; else if (o.sc_toWriteString) return o.sc_toWriteString(); else return o.toString();}function sc_escapeWriteString(s) { var res = ""; var j = 0; for (i = 0; i < s.length; i++) { switch (s.charAt(i)) { case "\0": res += s.substring(j, i) + "\\0"; j = i + 1; break; case "\b": res += s.substring(j, i) + "\\b"; j = i + 1; break; case "\f": res += s.substring(j, i) + "\\f"; j = i + 1; break; case "\n": res += s.substring(j, i) + "\\n"; j = i + 1; break; case "\r": res += s.substring(j, i) + "\\r"; j = i + 1; break; case "\t": res += s.substring(j, i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -