cil-lexer
Version:
237 lines • 12.7 kB
JavaScript
;
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