Adding a Language
Adding a new language (also: frontend) to VerCors is a large task. To start, consider the following list:
- Add a language and extension mapping in
vct.main.stages.Parsing.Languageandvct.options.types.ReadLanguage - Add a grammar for your language.
- Our default stance is to parse languages ourselves with ANTLR v4. See if yours is available here.
- Place your lexer and parser as
LangXLexer.g4andLangXParser.g4insrc/parsers/antlr4. LangXLexer.g4should importSpecLexer.g4. Make sensible lexer rules to define specifications inside comments. See the bottom ofLangJavaLexerfor an example.- Make
XParser.g4which importsSpecParserandLangXParser. This should connect the specification and language by defining the missing grammar rules. SeeJavaParser.g4for an example. - Change
LangXParser.g4to include specification constructs like contracts,with/thenspecifications, and more. All specification rules start withval, so try searching forvalinLangJavaParser.g4.
- Implement a parser in
src/parsers/vct/parsers/parser/ColXParserthat extendsAntlrParser. - Implement a converter in
src/parser/vct/parsers/transform/XToColthat extendsToCol. The general process is to start with the root rule of your grammar, match its alternatives, and implement furtherconvertmethods as you encounter parse rules. Anything that is not supported can be put aside by calling??(rule). - Connect your
Parsing.LanguageandColXParserparser invct.main.stages.Parsing.run.
Congrats, you added a frontend! Most likely the real work only starts from here, though. Consider the following:
- If your language adds features that did not exist in VerCors before, consider adding them to the "core" of COL by adding a nice abstraction of your new language feature. For example, we started supporting GPU kernels, for which we added an abstract
ParBlock. - Your converter should contain no logic. Instead, implement any logic prefacing the normal rewriter chain in a language-specific rewriter. These rules are called in
LangSpecificToCol, then deferred to specific rewriters likeLangXToCol. - When possible, prefer simple logic in
LangSpecificToColconnecting to a nice abstraction in COL. It is helpful to future developers of VerCors that the rewriting logic occurs in the main rewriting chain when possible. - Nodes are cheap! Instead of bolting on new behaviour to existing nodes, just make your own.
- Add rewriters in
vct.rewritethat compile away your new features to existing features.- They should be added somewhere in the rewrite chain of
vct.main.stages.SilverTransformation. - Prefer writing rewriters that do not care where they are in the chain.
- They should be added somewhere in the rewrite chain of
- Unexpected results? Try using flags like
--output-after-pass,--trace-col,--backend-file-base. - Unacceptably slow parsing? See here.