Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use util::Monitor instead of println to report conversion progress #20

Merged
merged 2 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 24 additions & 13 deletions rascal-textmate-core/src/main/rascal/lang/textmate/Conversion.rsc
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
module lang::textmate::Conversion

import Grammar;
import IO;
import ParseTree;
import String;
import util::Maybe;
import util::Monitor;

import lang::oniguruma::Conversion;
import lang::oniguruma::RegExp;
Expand Down Expand Up @@ -45,8 +45,8 @@ alias RscGrammar = Grammar;
may contain additional meta-data needed during the transformation stage.
}

TmGrammar toTmGrammar(RscGrammar rsc, ScopeName scopeName, NameGeneration nameGeneration = long())
= transform(analyze(preprocess(rsc)), nameGeneration = nameGeneration) [scopeName = scopeName];
TmGrammar toTmGrammar(RscGrammar rsc, str name, NameGeneration nameGeneration = long())
= transform(analyze(preprocess(rsc), name), name, nameGeneration = nameGeneration);

@synopsis{
Preprocess Rascal grammar `rsc` to make it suitable for analysis and
Expand Down Expand Up @@ -103,7 +103,9 @@ RscGrammar preprocess(RscGrammar rsc) {
In stage 3, the set of all keywords that occur in `rsc` is created.
}

list[ConversionUnit] analyze(RscGrammar rsc) {
list[ConversionUnit] analyze(RscGrammar rsc, str name) {
str jobLabel = "Analyzing<name == "" ? "" : " (<name>)">";
jobStart(jobLabel, work = 4);

// Define auxiliary predicates
bool isCyclic(Production p, set[Production] ancestors, _)
Expand All @@ -114,26 +116,28 @@ list[ConversionUnit] analyze(RscGrammar rsc) {
= /\tag("category"(_)) := attributes;

// Analyze dependencies among productions
println("[LOG] Analyzing dependencies among productions");
jobStep(jobLabel, "Analyzing productions");
Graph[Production] graph = toGraph(rsc);
list[Production] prods = deps(graph).retainProds(isNonEmpty).retainProds(hasCategory).getProds();
list[Production] prodsNonRecursive = prods & deps(graph).removeProds(isCyclic, true).getProds();
list[Production] prodsRecursive = prods - prodsNonRecursive;

// Analyze delimiters
println("[LOG] Analyzing delimiters");
jobStep(jobLabel, "Analyzing delimiters");
set[Symbol] delimiters
= removeStrictPrefixes({s | /Symbol s := rsc, isDelimiter(delabel(s))})
- {s | p <- prods, /just(s) := getOuterDelimiterPair(rsc, p)}
- {s | p <- prods, /just(s) := getInnerDelimiterPair(rsc, p, getOnlyFirst = true)};
list[Production] prodsDelimiters = [prod(lex(DELIMITERS_PRODUCTION_NAME), [\alt(delimiters)], {})];

// Analyze keywords
println("[LOG] Analyzing keywords");
jobStep(jobLabel, "Analyzing keywords");
set[Symbol] keywords = {s | /Symbol s := rsc, isKeyword(delabel(s))};
list[Production] prodsKeywords = [prod(lex(KEYWORDS_PRODUCTION_NAME), [\alt(keywords)], {\tag("category"("keyword.control"))})];

// Return
// Prepare units
jobStep(jobLabel, "Preparing units");

bool isRecursive(Production p)
= p in prodsRecursive;
bool isEmptyProd(prod(_, [\alt(alternatives)], _))
Expand All @@ -142,7 +146,11 @@ list[ConversionUnit] analyze(RscGrammar rsc) {
set[ConversionUnit] units = {};
units += {unit(rsc, p, isRecursive(p), hasNewline(rsc, p), getOuterDelimiterPair(rsc, p), getInnerDelimiterPair(rsc, p, getOnlyFirst = true)) | p <- prods};
units += {unit(rsc, p, false, false, <nothing(), nothing()>, <nothing(), nothing()>) | p <- prodsDelimiters + prodsKeywords, !isEmptyProd(p)};
return sort([*removeStrictPrefixes(units)]);
list[ConversionUnit] ret = sort([*removeStrictPrefixes(units)]);

// Return
jobEnd(jobLabel);
return ret;
}

@synopsis{
Expand All @@ -156,24 +164,27 @@ list[ConversionUnit] analyze(RscGrammar rsc) {
2. composition of TextMate rules into a TextMate grammar.
}

TmGrammar transform(list[ConversionUnit] units, NameGeneration nameGeneration = long()) {
TmGrammar transform(list[ConversionUnit] units, str name, NameGeneration nameGeneration = long()) {
str jobLabel = "Transforming<name == "" ? "" : " (<name>)">";
jobStart(jobLabel, work = 2);

// Transform productions to rules
println("[LOG] Transforming productions to rules");
jobStep(jobLabel, "Transforming productions to rules");
units = addNames(units, nameGeneration);
units = addInnerRules(units);
units = addOuterRules(units);

// Transform rules to grammar
println("[LOG] Transforming rules to grammar");
jobStep(jobLabel, "Transforming rules to grammar");
set[TmRule] innerRules = {*u.innerRules | u <- units};
set[TmRule] outerRules = {*u.outerRules | u <- units};
Repository repository = ("<r.name>": r | TmRule r <- innerRules + outerRules);
list[TmRule] patterns = dupLast([include("#<r.name>") | u <- units, r <- getTopLevelRules(u)]);
TmGrammar tm = lang::textmate::Grammar::grammar(repository, "", patterns);

// Return
return tm;
jobEnd(jobLabel);
return tm[scopeName = name];
}

private list[ConversionUnit] addNames(list[ConversionUnit] units, NameGeneration nameGeneration) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ import lang::textmate::ConversionConstants;
import lang::textmate::ConversionUnit;
import lang::textmate::Grammar;

bool doAnalyzeTest(RscGrammar rsc, list[ConversionUnit] expect, bool printActual = false) {
list[ConversionUnit] actual = analyze(rsc);
bool doAnalyzeTest(RscGrammar rsc, list[ConversionUnit] expect, str name = "", bool printActual = false) {
list[ConversionUnit] actual = analyze(rsc, name);

if (printActual) {
str syntheticProductionNameVars(str s)
Expand Down Expand Up @@ -61,7 +61,7 @@ bool doAnalyzeTest(RscGrammar rsc, list[ConversionUnit] expect, bool printActual
}

bool doTransformTest(list[ConversionUnit] units, RepositoryStats expect, str name = "") {
TmGrammar tm = transform(units)[scopeName = "<name>"];
TmGrammar tm = transform(units, name);

loc lProject = |project://rascal-textmate-core|;
loc lGrammar = lProject + "/target/generated-test-grammars/<name>.tmLanguage.json";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex("Unit"),[lit("🌊")],{\tag("category"("constant.language"))}), false, false, <nothing(),nothing()>, <just(lit("🌊")),just(lit("🌊"))>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "Emoji");
test bool transformTest() = doTransformTest(units, <3, 0, 0>, name = "Emoji");
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("do"),lit("declare"),lit("fi"),lit("else"),lit("end"),lit("od"),lit("nil-type"),lit("begin"),lit("natural"),lit("then"),lit("if"),lit("while"),lit("string")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "Pico");
test bool transformTest() = doTransformTest(units, <4, 1, 0>, name = "Pico");
Original file line number Diff line number Diff line change
Expand Up @@ -86,5 +86,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("do"),lit("declare"),lit("fi"),lit("else"),lit("end"),lit("od"),lit("nil-type"),lit("begin"),lit("natural"),lit("then"),lit("if"),lit("while"),lit("string")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "PicoWithCategories");
test bool transformTest() = doTransformTest(units, <10, 3, 0>, name = "PicoWithCategories");
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("lexical"),lit("loc"),lit("test"),lit("lrel"),lit("throws"),lit("clear"),lit("top-down-break"),lit("module"),lit("any"),lit("int"),lit("quit"),lit("bottom-up-break"),lit("o"),lit("anno"),lit("true"),lit("public"),lit("keyword"),lit("for"),lit("tuple"),lit("bracket"),lit("bag"),lit("it"),lit("visit"),lit("do"),lit("data"),lit("layout"),lit("bool"),lit("edit"),lit("join"),lit("is"),lit("import"),lit("view"),lit("in"),lit("rat"),lit("modules"),lit("continue"),lit("left"),lit("num"),lit("assert"),lit("throw"),lit("one"),lit("help"),lit("default"),lit("all"),lit("global"),lit("syntax"),lit("false"),lit("finally"),lit("private"),lit("mod"),lit("java"),lit("node"),lit("start"),lit("set"),lit("if"),lit("bottom-up"),lit("right"),lit("variable"),lit("map"),lit("10"),lit("on"),lit("break"),lit("dynamic"),lit("solve"),lit("fail"),lit("unimport"),lit("outermost"),lit("real"),lit("list"),lit("insert"),lit("innermost"),lit("declarations"),lit("else"),lit("rel"),lit("function"),lit("notin"),lit("filter"),lit("datetime"),lit("catch"),lit("try"),lit("renaming"),lit("tag"),lit("has"),lit("top-down"),lit("Z"),lit("when"),lit("type"),lit("append"),lit("extend"),lit("non-assoc"),lit("assoc"),lit("switch"),lit("void"),lit("history"),lit("T"),lit("while"),lit("str"),lit("value"),lit("undeclare"),lit("case"),lit("alias"),lit("return"),lit("0")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "Rascal");
test bool transformTest() = doTransformTest(units, <20, 4, 0>, name = "Rascal");
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("10"),lit("0")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "RascalClass");
test bool transformTest() = doTransformTest(units, <5, 1, 0>, name = "RascalClass");
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex("Comment"),[lit("/*"),\iter-star(alt({\char-class([range(1,41),range(43,1114111)]),conditional(lit("*"),{\not-follow(lit("/"))})})),lit("*/")],{\tag("category"("Comment"))}), false, true, <nothing(),nothing()>, <just(lit("/*")),just(lit("*/"))>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "RascalComment");
test bool transformTest() = doTransformTest(units, <2, 1, 0>, name = "RascalComment");
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(label("text",lex("ConcretePart")),[conditional(iter(\char-class([range(1,9),range(11,59),range(61,61),range(63,91),range(93,95),range(97,1114111)])),{\not-follow(\char-class([range(1,9),range(11,59),range(61,61),range(63,91),range(93,95),range(97,1114111)]))})],{\tag("category"("MetaSkipped"))}), false, false, <just(lit("`")),just(lit("`"))>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "RascalConcrete");
test bool transformTest() = doTransformTest(units, <7, 1, 0>, name = "RascalConcrete");
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("10"),lit("0")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "RascalStringConstant");
test bool transformTest() = doTransformTest(units, <3, 1, 0>, name = "RascalStringConstant");
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("for"),lit("do"),lit("if"),lit("10"),lit("else"),lit("while"),lit("0")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "RascalStringLiteral");
test bool transformTest() = doTransformTest(units, <6, 0, 0>, name = "RascalStringLiteral");
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(label("expression",sort("Tag")),[lit("@"),layouts("LAYOUTLIST"),label("name",lex("Name")),layouts("LAYOUTLIST"),lit("="),layouts("LAYOUTLIST"),conditional(label("expression",sort("Expression")),{\not-follow(lit("@"))})],{\tag("Folded"()),\tag("category"("Comment"))}), false, true, <nothing(),nothing()>, <just(lit("@")),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "RascalTag");
test bool transformTest() = doTransformTest(units, <2, 1, 0>, name = "RascalTag");
Original file line number Diff line number Diff line change
Expand Up @@ -297,5 +297,5 @@ list[ConversionUnit] units = [
unit(rsc, prod(lex(KEYWORDS_PRODUCTION_NAME),[alt({lit("true"),lit("false")})],{\tag("category"("keyword.control"))}), false, false, <nothing(),nothing()>, <nothing(),nothing()>)
];

test bool analyzeTest() = doAnalyzeTest(rsc, units);
test bool analyzeTest() = doAnalyzeTest(rsc, units, name = "Walkthrough");
test bool transformTest() = doTransformTest(units, <7, 2, 0>, name = "Walkthrough");