1

I'm trying to write a summarizer for my DSL in order to display error messages in the console. I've been following the example with the Pico language and was able to successfully create a parser and get syntax highlighting for my language. I tried to copy and simplify the Pico summarizer as much as possible in order to make it work for my language, but to no success so far.

Here's a small part of the grammar for my language:

start syntax Deployment = deployment: Hardware+ hardwares;
syntax Hardware = hardware: "hardware" String name "{" Service* services "}";

And here's the current state of the Language module:

set[LanguageService] depContributions() = {
 parsing(parser(#start[Deployment])),
 analysis(summarizer, providesDocumentation = false, providesDefinitions = false, providesReferences = false, providesImplementations = false)
};
int produceLSP() {
 registerLanguage(
 language(
 pathConfig(srcs=[|project://deployment-manager/src/main/rascal|]),
 "DeploymentManager",
 {"dep"},
 "Language",
 "depContributions"
 )
 );
 return 0;
}
Summary summarizer(loc l, start[Deployment] input) {
 rel[str, loc] result = {<"<var.name>", var.src> | /Hardware var := input};
 return summary(l,
 messages = {<src, error("<id> exists", src)> | <id, src> <- result}
 );
}

When I open a DSL program, I get the following error message:

Parsing failed: CallFailed
at: |project://deployment-manager/src/main/rascal/Language.rsc|(443,5,<19,139>,<19,144>)

The line the error message points to is the analysis line in depContributions().

I would greatly appreciate it if someone could help me out!

yannco
6102 silver badges9 bronze badges
asked May 21, 2025 at 14:55

1 Answer 1

1

Ah yes, this can be tricky at first. But later you might appreciate the extensible overloading feature of Rascal functions :-) For now, this overloading feature is messing up your code, as follows:

  1. The analysis function fails to apply, because one of its arguments does not fit the formal type parameter. When a function fails to apply in Rascal you get a CallFailed exception.

  2. The reason is that the first argument summarizer does not have a type that matches Summary (loc _origin, Tree _input)

  3. The reason for that is that the function summarizer is overloaded in the current context. There is your definition of type: Summary (loc l, start[Deployment] input) -which perfectly fits by the way. But there is also this other one, imported from util::LanguageServer: LanguageService summarizer(Summarizer summarizer, ...). Together these two functions with the same name are merged into one, with the type value (the "least upper bound type" of the two function types) because they do not have the same amount of parameters. value is not a subtype of Summary (loc, Tree) and so analysis fails to apply.

The fix for this is easy. Just rename summarizer to mySummarizer and supply that function to the analysis language service. That way it will not be overloaded anymore and keep its original type, and thus match with the first formal parameter of analysis.

answered May 21, 2025 at 18:23
Sign up to request clarification or add additional context in comments.

10 Comments

Syntax highlighting works again after I renamed the summarizer function. However, I still do not see any error messages. I would expect to see test_machine exists for example. Is the cause something in the definition of my syntax? Also is there a way of debugging the functions applied to registerLanguage?
Hi Ivo; right the functions you write and pass to registerLanguage can be called like any normal function in the REPL/Terminal for example, or in your own test code. First you parse a file (first import ParseTree;), d = parse(#start[Deployment], |file:///something.dep|), and you call mySummarizer(|file:///something.dep|, d)
You should get the summary and with mySummary.messages you can see what the messages are like. The location URI's are hyperlinks, so you can jump to the source of each error message to check if it's right.
I would separate this line rel[str, loc] result = {<"<var.name>", var.src> | /Hardware var := input}; into its own function, so you can test it separately. It looks good to me, BTW.
I managed to verify that mySummarizer works and I can see the error message that I expect in my REPL when I call mySummarizer from there. However, I still do not see them in VSCode. I'm expecting the error message to show up in the Problems section of the bottom panel. Is that what the expected outcome should be? I know that produceLSP() works because I see correct terminal output and syntax highlighting.
|

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.