Some Parsimmon combinations ported to regex

This commit is contained in:
barsdeveloper
2023-02-14 21:42:28 +01:00
parent d1ef250689
commit 45e5aedb09
5 changed files with 99 additions and 44 deletions

7
.vscode/launch.json vendored
View File

@@ -4,13 +4,6 @@
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch index.html",
"type": "firefox",
"request": "launch",
"reAttach": true,
"file": "${workspaceFolder}/index.html"
},
{
"name": "Launch localhost",
"type": "firefox",

64
dist/ueblueprint.js vendored
View File

@@ -3120,6 +3120,37 @@ class Grammar {
/* --- Factory --- */
/**
* @template T
* @param {RegExp} re
* @param {(execResult) => T} mapper
*/
static regexMap(re, mapper) {
const anchored = RegExp("^(?:" + re.source + ")", re.flags);
const expected = "" + re;
/** @param {Grammar} r */
return P((input, i) => {
const match = anchored.exec(input.slice(i));
if (match) {
return P.makeSuccess(i + match[0].length, mapper(match))
}
return P.makeFailure(i, expected)
})
}
/** @param {String} str */
static getStringParser(str) {
return P((input, i) => {
var j = i + str.length;
var head = input.slice(i, j);
if (head === str) {
return makeSuccess(j, head)
} else {
return makeFailure(i, expected)
}
})
}
/** @param {Grammar} r */
static getGrammarForType(r, attribute, defaultGrammar = r.AttributeAnyValue) {
if (attribute.constructor === Object) {
@@ -3301,8 +3332,7 @@ class Grammar {
Null = r => P.regex(new RegExp(String.raw`\(${Grammar.Regex.InlineOptWhitespace.source}\)`)).map(() => null).desc("null: ()")
/** @param {Grammar} r */
Boolean = r => P.regex(/true|false/i).map(v => v.toLocaleLowerCase() === "true" ? true : false)
.desc("either True or False")
Boolean = r => Grammar.regexMap(/(true)|false/i, v => v[1] ? true : false).desc("either True or False")
/** @param {Grammar} r */
Number = r => P.regex(Grammar.Regex.Number).map(Number).desc("a number")
@@ -3314,7 +3344,7 @@ class Grammar {
RealUnit = r => P.regex(Grammar.Regex.RealUnit).map(Number).desc("a number between 0 and 1")
/** @param {Grammar} r */
NaturalNumber = r => P.regex(/0|[1-9]\d*/).map(Number).desc("a natural number")
NaturalNumber = r => Grammar.regexMap(/\d+/, v => parseInt(v[0])).desc("a natural number")
/** @param {Grammar} r */
ColorNumber = r => P.regexp(Grammar.Regex.ByteInteger).desc("a number between 0 and 255")
@@ -3388,20 +3418,20 @@ class Grammar {
)
/** @param {Grammar} r */
LocalizedText = r => P.seqMap(
P.string(LocalizedTextEntity.lookbehind).skip(P.optWhitespace).skip(P.string("(")), // Goes into _0 (ignored)
r.String.trim(P.optWhitespace), // Goes into namespace
P.string(","), // Goes into _2 (ignored)
r.String.trim(P.optWhitespace), // Goes into key
P.string(","), // Goes into _4 (ignored)
r.String.trim(P.optWhitespace), // Goes into value
P.string(")"), // Goes into _6 (ignored)
(_0, namespace, _2, key, _4, value, _6) => new LocalizedTextEntity({
namespace: namespace,
key: key,
value: value
})
)
LocalizedText = r =>
Grammar.regexMap(
new RegExp(
String.raw`${LocalizedTextEntity.lookbehind}\s*\(`
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*\)`
),
matchResult => new LocalizedTextEntity({
namespace: matchResult[1],
key: matchResult[2],
value: matchResult[3]
}
))
/** @param {Grammar} r */
InvariantText = r => r.String.trim(P.optWhitespace).wrap(

File diff suppressed because one or more lines are too long

View File

@@ -56,6 +56,37 @@ export default class Grammar {
/* --- Factory --- */
/**
* @template T
* @param {RegExp} re
* @param {(execResult) => T} mapper
*/
static regexMap(re, mapper) {
const anchored = RegExp("^(?:" + re.source + ")", re.flags)
const expected = "" + re
/** @param {Grammar} r */
return P((input, i) => {
const match = anchored.exec(input.slice(i))
if (match) {
return P.makeSuccess(i + match[0].length, mapper(match))
}
return P.makeFailure(i, expected)
})
}
/** @param {String} str */
static getStringParser(str) {
return P((input, i) => {
var j = i + str.length
var head = input.slice(i, j)
if (head === str) {
return makeSuccess(j, head)
} else {
return makeFailure(i, expected)
}
})
}
/** @param {Grammar} r */
static getGrammarForType(r, attribute, defaultGrammar = r.AttributeAnyValue) {
if (attribute.constructor === Object) {
@@ -237,8 +268,7 @@ export default class Grammar {
Null = r => P.regex(new RegExp(String.raw`\(${Grammar.Regex.InlineOptWhitespace.source}\)`)).map(() => null).desc("null: ()")
/** @param {Grammar} r */
Boolean = r => P.regex(/true|false/i).map(v => v.toLocaleLowerCase() === "true" ? true : false)
.desc("either True or False")
Boolean = r => Grammar.regexMap(/(true)|false/i, v => v[1] ? true : false).desc("either True or False")
/** @param {Grammar} r */
Number = r => P.regex(Grammar.Regex.Number).map(Number).desc("a number")
@@ -250,7 +280,7 @@ export default class Grammar {
RealUnit = r => P.regex(Grammar.Regex.RealUnit).map(Number).desc("a number between 0 and 1")
/** @param {Grammar} r */
NaturalNumber = r => P.regex(/0|[1-9]\d*/).map(Number).desc("a natural number")
NaturalNumber = r => Grammar.regexMap(/\d+/, v => parseInt(v[0])).desc("a natural number")
/** @param {Grammar} r */
ColorNumber = r => P.regexp(Grammar.Regex.ByteInteger).desc("a number between 0 and 255")
@@ -324,20 +354,21 @@ export default class Grammar {
)
/** @param {Grammar} r */
LocalizedText = r => P.seqMap(
P.string(LocalizedTextEntity.lookbehind).skip(P.optWhitespace).skip(P.string("(")), // Goes into _0 (ignored)
r.String.trim(P.optWhitespace), // Goes into namespace
P.string(","), // Goes into _2 (ignored)
r.String.trim(P.optWhitespace), // Goes into key
P.string(","), // Goes into _4 (ignored)
r.String.trim(P.optWhitespace), // Goes into value
P.string(")"), // Goes into _6 (ignored)
(_0, namespace, _2, key, _4, value, _6) => new LocalizedTextEntity({
namespace: namespace,
key: key,
value: value
})
)
LocalizedText = r =>
Grammar.regexMap(
new RegExp(
String.raw`${LocalizedTextEntity.lookbehind}\s*\(`
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*,`
+ String.raw`\s*"(${Grammar.Regex.InsideString.source})"\s*\)`
),
matchResult => new LocalizedTextEntity({
namespace: matchResult[1],
key: matchResult[2],
value: matchResult[3]
}
)
)
/** @param {Grammar} r */
InvariantText = r => r.String.trim(P.optWhitespace).wrap(

View File

@@ -27,6 +27,7 @@
"@rollup/plugin-commonjs": "^21.1.0",
"@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-terser": "^0.1.0",
"@types/parsimmon": "^1.10.6",
"concurrently": "^7.6.0",
"cypress": "^12.1.0",
"http-server": "^14.1.1",