UNPKG

cil-lexer

Version:
237 lines 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tsparsec_1 = require("tsparsec"); const tag_g_1 = require("./tag.g"); const bigint = require("big-integer"); var Token; (function (Token) { function delimiter(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "Delimiter", tag: value, source, startLine, startColumn, endLine, endColumn, trailingTrivia }; } Token.delimiter = delimiter; function instr(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "Instr", tag: value, source, startLine, startColumn, endLine, endColumn, trailingTrivia }; } Token.instr = instr; function keyword(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "Keyword", tag: value, source, startLine, startColumn, endLine, endColumn, trailingTrivia }; } Token.keyword = keyword; function directive(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "Directive", tag: value, source, startLine, startColumn, endLine, endColumn, trailingTrivia }; } Token.directive = directive; function id(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "Id", tag: 0 /* Id */, source, startLine, startColumn, value, endLine, endColumn, trailingTrivia }; } Token.id = id; function dottedName(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "DottedName", tag: 1 /* DottedName */, source, startLine, startColumn, value, endLine, endColumn, trailingTrivia }; } Token.dottedName = dottedName; function qstring(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "QString", tag: 5 /* QString */, source, startLine, startColumn, value, endLine, endColumn, trailingTrivia }; } Token.qstring = qstring; function sqstring(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "SQString", tag: 6 /* SQString */, source, startLine, startColumn, value, endLine, endColumn, trailingTrivia }; } Token.sqstring = sqstring; function int32(source, startLine, startColumn, value, style, raw, endLine, endColumn, trailingTrivia) { return { type: "Int32", tag: 2 /* Int32 */, source, startLine, startColumn, value, style, raw, endLine, endColumn, trailingTrivia }; } Token.int32 = int32; function int64(source, startLine, startColumn, value, style, raw, endLine, endColumn, trailingTrivia) { return { type: "Int64", tag: 3 /* Int64 */, source, startLine, startColumn, value, style, raw, endLine, endColumn, trailingTrivia }; } Token.int64 = int64; function float64(source, startLine, startColumn, value, endLine, endColumn, trailingTrivia) { return { type: "Float64", tag: 4 /* Float64 */, source, startLine, startColumn, value, endLine, endColumn, trailingTrivia }; } Token.float64 = float64; function hexbyte(source, startLine, startColumn, value, raw, endLine, endColumn, trailingTrivia) { return { type: "HexByte", tag: 7 /* HexByte */, source, startLine, startColumn, value, raw, endLine, endColumn, trailingTrivia }; } Token.hexbyte = hexbyte; })(Token = exports.Token || (exports.Token = {})); // /[ \t\n\f\r]/ function isWhitespace(char) { switch (char) { case 32 /* " " */: case 9 /* "\t" */: case 10 /* "\n" */: case 12 /* "\f" */: case 13 /* "\r" */: case 65279 /* ZERO_WIDTH_NO_BREAK_SPACE */:// \uFEFF return true; default: return false; } } const spaces1 = tsparsec_1.skipMany1(tsparsec_1.satisfy(isWhitespace, "[ \\t\\n\\f\\r\\uFEFF]")); // /(//)[^\n]*/ const singleComment = tsparsec_1.string("//").left(tsparsec_1.skipMany0(tsparsec_1.noneof("\n"))); // /(/\*)((?!\*/).)*(\*/)/ const blockComment = tsparsec_1.string("/*").left(tsparsec_1.skipMany0(tsparsec_1.notFollowedBy(tsparsec_1.string("*/")).left(tsparsec_1.anyChar))).left(tsparsec_1.string("*/")); const trivias0 = tsparsec_1.skipped(tsparsec_1.skipMany0(tsparsec_1.choice(spaces1, singleComment, blockComment))); const trivias = trivias0.parser; const idOthers = tsparsec_1.anyof("_$@`?"); const idStart = tsparsec_1.choice(tsparsec_1.asciiLetter, idOthers); const idContinue = tsparsec_1.choice(tsparsec_1.asciiLetter, tsparsec_1.asciiDigit, idOthers); // /([a-zA-Z_$@`?][a-zA-Z0-9_$@`?]*)/ const id = idStart.right(tsparsec_1.skipMany0(idContinue)); // \a\b\f\n\r\t\v const simpleEscape = tsparsec_1.anyChar.map((char) => { switch (char) { case 97 /* a */: return 97 /* "\a" */; case 98 /* b */: return 8 /* "\b" */; case 102 /* f */: return 12 /* "\f" */; case 110 /* n */: return 10 /* "\n" */; case 114 /* r */: return 13 /* "\r" */; case 116 /* t */: return 9 /* "\t" */; case 118 /* v */: return 11 /* "\v" */; default: return char; } }); const escape = tsparsec_1.char(92 /* "\\" */).right(simpleEscape); const qstringChar = tsparsec_1.choice(tsparsec_1.noneof(`"\\`), escape); const qMark = tsparsec_1.char(34 /* '"' */); /** /"(\\.|[^\\"])*"/ */ const qstring = tsparsec_1.pipe(qMark, tsparsec_1.manyChars0(qstringChar), qMark, (_, v) => v).parser; /** /'(\\.|[^\\'])*'/ */ const sqstringChar = tsparsec_1.choice(tsparsec_1.noneof(`'\\`), escape); const sqMark = tsparsec_1.char(39 /* "'" */); const sqstring = tsparsec_1.pipe(sqMark, tsparsec_1.manyChars0(sqstringChar), sqMark, (_, v) => v).parser; const int32Min = bigint(-2147483648), int32Max = bigint(2147483647), int64Min = bigint("-9223372036854775808"), int64Max = bigint("9223372036854775807"); const hexDigits = tsparsec_1.skipMany1(tsparsec_1.asciiHex); const hexInteger = tsparsec_1.skipPipe(tsparsec_1.char(48 /* _0 */), tsparsec_1.anyof("xX"), hexDigits); const decimalDigits = tsparsec_1.skipMany1(tsparsec_1.asciiDigit); const decimalInteger = tsparsec_1.opt(tsparsec_1.anyof("-+")).right(decimalDigits); /** /0[xX][a-fA-F0-9]+|[-+]?[0-9]+/ */ const integer = tsparsec_1.skipped(tsparsec_1.choice(hexInteger, decimalInteger)) .parser; const optE = tsparsec_1.opt(tsparsec_1.skipPipe(tsparsec_1.anyof("eE"), tsparsec_1.opt(tsparsec_1.anyof("-+")), tsparsec_1.skipMany1(tsparsec_1.asciiDigit))); const float64 = tsparsec_1.skipped(tsparsec_1.choice( // /[0-9]+[eE][-+]?[0-9]+/ tsparsec_1.skipPipe(tsparsec_1.skipMany1(tsparsec_1.asciiDigit), tsparsec_1.anyof("eE"), tsparsec_1.opt(tsparsec_1.anyof("-+")), tsparsec_1.skipMany1(tsparsec_1.asciiDigit)), // /[0-9]*\.[0-9]+([Ee][-+]?[0-9]+)?/ tsparsec_1.skipPipe(tsparsec_1.skipMany0(tsparsec_1.asciiDigit), tsparsec_1.char(46 /* "." */), tsparsec_1.skipMany1(tsparsec_1.asciiDigit), optE), // /[0-9]+\.[0-9]*([Ee][-+]?[0-9]+)?/ tsparsec_1.skipPipe(tsparsec_1.skipMany1(tsparsec_1.asciiDigit), tsparsec_1.char(46 /* "." */), tsparsec_1.skipMany0(tsparsec_1.asciiDigit), optE))) .map(parseFloat) .parser; const hexbyte = tsparsec_1.skipped(tsparsec_1.asciiHex.right(tsparsec_1.opt(tsparsec_1.asciiHex))).parser; const delimiter1 = tsparsec_1.anyof(Array .from(tag_g_1.delimiterToTag.keys()) .filter(k => k.length === 1) .join("")) .map(k => tag_g_1.delimiterToTag.get(String.fromCodePoint(k))); const delimiter2 = tsparsec_1.choice(...Array .from(tag_g_1.delimiterToTag.entries()) .filter(([{ length }]) => length !== 1) .map(([k, v]) => tsparsec_1.string(k).return(v))); const delimiter = tsparsec_1.choice(delimiter2, delimiter1).parser; const dot = tsparsec_1.char(46 /* "." */); // /@id(\.@id)*/ const idOrDottedName = tsparsec_1.skipped(tsparsec_1.skipSepBy1(id, dot)).parser; // /@id\.(?!@id)/ const idDot = tsparsec_1.skipped(id.right(dot).right(tsparsec_1.notFollowedBy(id))).parser; // /\.@id/ const dotId = tsparsec_1.skipped(dot.right(id)).parser; // /#@id/ const hashId = tsparsec_1.skipped(tsparsec_1.char(35 /* "#" */).right(id)).parser; function tryToReserved(source, line, column, value, endLine, endColumn, trailingTrivia) { const keywordTag = tag_g_1.keywordToTag.get(value); if (keywordTag !== void 0) { return Token.keyword(source, line, column, keywordTag, endLine, endColumn, trailingTrivia); } const instrTag = tag_g_1.instrToTag.get(value); if (instrTag !== void 0) { return Token.instr(source, line, column, instrTag, endLine, endColumn, trailingTrivia); } const directiveTag = tag_g_1.directiveToTag.get(value); if (directiveTag !== void 0) { return Token.directive(source, line, column, directiveTag, endLine, endColumn, trailingTrivia); } return void 0; } // function hex2int(c: CodePoint) { return (c & 15) + (c >> 6) * 9 } exports.hexbyteAndTrailingTrivias0 = tsparsec_1.extend((stream) => { const { line, column } = stream; const raw = hexbyte(stream); return Token.hexbyte(stream.source, line, column, parseInt(raw, 16), raw, stream.line, stream.column, trivias(stream)); }); const tokenAndTrailingTrivias0 = tsparsec_1.choice( // keyword /\w+\./ tsparsec_1.extend((stream) => { const { line, column } = stream; const result = tryToReserved(stream.source, line, column, idDot(stream), stream.line, stream.column, trivias(stream)); if (result !== void 0) { return result; } throw "keyword /\w+\./"; }), // id | dottedname | keyword /\w+/ | keyword /\w+(\.\w+)+/ tsparsec_1.extend((stream) => { const { line, column } = stream; const value = idOrDottedName(stream); const { line: endLine, column: endColumn } = stream; const trailingTrivia = trivias(stream); const result = tryToReserved(stream.source, line, column, value, endLine, endColumn, trailingTrivia); if (result !== void 0) { return result; } if (value.includes(".")) { return Token.dottedName(stream.source, line, column, value.split("."), endLine, endColumn, trailingTrivia); } return Token.id(stream.source, line, column, value, endLine, endColumn, trailingTrivia); }), // keyword /\.\w+/ tsparsec_1.extend((stream) => { const { line, column } = stream; const result = tryToReserved(stream.source, line, column, dotId(stream), stream.line, stream.column, trivias(stream)); if (result !== void 0) { return result; } throw "keyword /\.\w+/"; }), // keyword /#\w+/ tsparsec_1.extend((stream) => { const { line, column } = stream; const result = tryToReserved(stream.source, line, column, hashId(stream), stream.line, stream.column, trivias(stream)); if (result !== void 0) { return result; } throw "keyword /#\w+/"; }), // delimiter tsparsec_1.extend((stream) => Token.delimiter(stream.source, stream.line, stream.column, delimiter(stream), stream.line, stream.column, trivias(stream))), // qstring tsparsec_1.extend((stream) => Token.qstring(stream.source, stream.line, stream.column, qstring(stream), stream.line, stream.column, trivias(stream))), // sqstring tsparsec_1.extend((stream) => Token.sqstring(stream.source, stream.line, stream.column, sqstring(stream), stream.line, stream.column, trivias(stream))), // float64 tsparsec_1.extend((stream) => Token.float64(stream.source, stream.line, stream.column, float64(stream), stream.line, stream.column, trivias(stream))), // int32 | int64 tsparsec_1.extend((stream) => { const { line, column } = stream; const raw = integer(stream); const { line: endLine, column: endColumn } = stream; const trailingTrivia = trivias(stream); const c1 = raw.codePointAt(1); const style = (c1 === 120 /* x */ || c1 === 88 /* X */) ? 1 /* Hex */ : 0 /* Decimal */; const value = bigint(raw); if (int32Min.leq(value) && value.leq(int32Max)) { return Token.int32(stream.source, line, column, value.toJSNumber(), style, raw, endLine, endColumn, trailingTrivia); } else if (int64Min.leq(value) && value.leq(int64Max)) { return Token.int64(stream.source, line, column, value, style, raw, endLine, endColumn, trailingTrivia); } throw `int64 overflow (${raw})`; }), exports.hexbyteAndTrailingTrivias0); const start = trivias0.right(tsparsec_1.many0(tokenAndTrailingTrivias0)).left(tsparsec_1.eos); function parse(string, source = null) { return start.parse(string, source); } exports.parse = parse; //# sourceMappingURL=lexer.js.map