From adc66aefb3deba21025e16e32e5f81cff8facee5 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Thu, 4 Apr 2024 16:56:52 +0200 Subject: [PATCH 01/19] Add new documentation structure --- hugo/content/docs/0_introduction/_index.md | 4 + hugo/content/docs/0_introduction/features.md | 4 + .../content/docs/0_introduction/playground.md | 4 + hugo/content/docs/0_introduction/showcases.md | 4 + .../docs/0_introduction/what-is-langium.md | 6 ++ hugo/content/docs/1_learn/_index.md | 4 + .../docs/1_learn/create_validations.md | 6 ++ hugo/content/docs/1_learn/generate_ast.md | 6 ++ .../docs/1_learn/generate_everything.md | 6 ++ hugo/content/docs/1_learn/install.md | 16 ++++ hugo/content/docs/1_learn/overview.md | 28 +++++++ .../docs/1_learn/resolve_cross_references.md | 6 ++ hugo/content/docs/1_learn/scaffold.md | 71 ++++++++++++++++++ hugo/content/docs/1_learn/write_grammar.md | 6 ++ hugo/content/docs/2_recipes/_index.md | 6 ++ hugo/content/docs/_index.md | 14 +--- hugo/content/old/_index.md | 4 + hugo/content/old/docs/_index.md | 12 +++ .../{ => old}/docs/configuration-services.md | 0 .../{ => old}/docs/document-lifecycle.md | 0 .../content/{ => old}/docs/getting-started.md | 0 .../{ => old}/docs/grammar-language.md | 0 .../{ => old}/docs/langium-overview.md | 0 hugo/content/{ => old}/docs/sematic-model.md | 0 hugo/content/{ => old}/guides/_index.md | 0 .../{ => old}/guides/builtin-library.md | 0 .../content/{ => old}/guides/code-bundling.md | 0 hugo/content/{ => old}/guides/formatting.md | 0 .../{ => old}/guides/multiple-languages.md | 0 .../{ => old}/guides/scoping/_index.md | 0 .../{ => old}/guides/scoping/class-member.md | 0 .../guides/scoping/qualified-name.md | 0 hugo/content/{ => old}/tutorials/_index.md | 0 .../tutorials/building_an_extension/icon.png | Bin .../tutorials/building_an_extension/index.md | 0 .../installed-extension.jpg | Bin .../building_an_extension/minilogo-vsix.jpg | Bin .../minilogo-with-icon.png | Bin .../building_an_extension/vsix-install.jpg | Bin .../building_an_extension/vsix-installed.jpg | Bin .../{ => old}/tutorials/customizing_cli.md | 0 .../content/{ => old}/tutorials/generation.md | 0 .../tutorials/generation_in_the_web.md | 0 .../{ => old}/tutorials/langium_and_monaco.md | 0 .../content/{ => old}/tutorials/validation.md | 0 .../{ => old}/tutorials/writing_a_grammar.md | 0 hugo/content/playground/_index.html | 2 +- 47 files changed, 197 insertions(+), 12 deletions(-) create mode 100644 hugo/content/docs/0_introduction/_index.md create mode 100644 hugo/content/docs/0_introduction/features.md create mode 100644 hugo/content/docs/0_introduction/playground.md create mode 100644 hugo/content/docs/0_introduction/showcases.md create mode 100644 hugo/content/docs/0_introduction/what-is-langium.md create mode 100644 hugo/content/docs/1_learn/_index.md create mode 100644 hugo/content/docs/1_learn/create_validations.md create mode 100644 hugo/content/docs/1_learn/generate_ast.md create mode 100644 hugo/content/docs/1_learn/generate_everything.md create mode 100644 hugo/content/docs/1_learn/install.md create mode 100644 hugo/content/docs/1_learn/overview.md create mode 100644 hugo/content/docs/1_learn/resolve_cross_references.md create mode 100644 hugo/content/docs/1_learn/scaffold.md create mode 100644 hugo/content/docs/1_learn/write_grammar.md create mode 100644 hugo/content/docs/2_recipes/_index.md create mode 100644 hugo/content/old/_index.md create mode 100644 hugo/content/old/docs/_index.md rename hugo/content/{ => old}/docs/configuration-services.md (100%) rename hugo/content/{ => old}/docs/document-lifecycle.md (100%) rename hugo/content/{ => old}/docs/getting-started.md (100%) rename hugo/content/{ => old}/docs/grammar-language.md (100%) rename hugo/content/{ => old}/docs/langium-overview.md (100%) rename hugo/content/{ => old}/docs/sematic-model.md (100%) rename hugo/content/{ => old}/guides/_index.md (100%) rename hugo/content/{ => old}/guides/builtin-library.md (100%) rename hugo/content/{ => old}/guides/code-bundling.md (100%) rename hugo/content/{ => old}/guides/formatting.md (100%) rename hugo/content/{ => old}/guides/multiple-languages.md (100%) rename hugo/content/{ => old}/guides/scoping/_index.md (100%) rename hugo/content/{ => old}/guides/scoping/class-member.md (100%) rename hugo/content/{ => old}/guides/scoping/qualified-name.md (100%) rename hugo/content/{ => old}/tutorials/_index.md (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/icon.png (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/index.md (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/installed-extension.jpg (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/minilogo-vsix.jpg (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/minilogo-with-icon.png (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/vsix-install.jpg (100%) rename hugo/content/{ => old}/tutorials/building_an_extension/vsix-installed.jpg (100%) rename hugo/content/{ => old}/tutorials/customizing_cli.md (100%) rename hugo/content/{ => old}/tutorials/generation.md (100%) rename hugo/content/{ => old}/tutorials/generation_in_the_web.md (100%) rename hugo/content/{ => old}/tutorials/langium_and_monaco.md (100%) rename hugo/content/{ => old}/tutorials/validation.md (100%) rename hugo/content/{ => old}/tutorials/writing_a_grammar.md (100%) diff --git a/hugo/content/docs/0_introduction/_index.md b/hugo/content/docs/0_introduction/_index.md new file mode 100644 index 00000000..eaac07d3 --- /dev/null +++ b/hugo/content/docs/0_introduction/_index.md @@ -0,0 +1,4 @@ +--- +title: "Introduction" +weight: 0 +--- \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/features.md b/hugo/content/docs/0_introduction/features.md new file mode 100644 index 00000000..ef358ba5 --- /dev/null +++ b/hugo/content/docs/0_introduction/features.md @@ -0,0 +1,4 @@ +--- +title: "Features" +weight: 200 +--- \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/playground.md b/hugo/content/docs/0_introduction/playground.md new file mode 100644 index 00000000..ed1e5ea4 --- /dev/null +++ b/hugo/content/docs/0_introduction/playground.md @@ -0,0 +1,4 @@ +--- +title: "Try it out!" +weight: 400 +--- \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/showcases.md b/hugo/content/docs/0_introduction/showcases.md new file mode 100644 index 00000000..0784e7fc --- /dev/null +++ b/hugo/content/docs/0_introduction/showcases.md @@ -0,0 +1,4 @@ +--- +title: "Showcases" +weight: 300 +--- \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/what-is-langium.md b/hugo/content/docs/0_introduction/what-is-langium.md new file mode 100644 index 00000000..776b83be --- /dev/null +++ b/hugo/content/docs/0_introduction/what-is-langium.md @@ -0,0 +1,6 @@ +--- +title: "What is Langium?" +weight: 100 +--- + +Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. diff --git a/hugo/content/docs/1_learn/_index.md b/hugo/content/docs/1_learn/_index.md new file mode 100644 index 00000000..2da00312 --- /dev/null +++ b/hugo/content/docs/1_learn/_index.md @@ -0,0 +1,4 @@ +--- +title: "Learn Langium" +weight: 200 +--- \ No newline at end of file diff --git a/hugo/content/docs/1_learn/create_validations.md b/hugo/content/docs/1_learn/create_validations.md new file mode 100644 index 00000000..6dcd5d19 --- /dev/null +++ b/hugo/content/docs/1_learn/create_validations.md @@ -0,0 +1,6 @@ +--- +title: "Create validations" +weight: 700 +url: /docs/learn/create_validations +--- +TODO diff --git a/hugo/content/docs/1_learn/generate_ast.md b/hugo/content/docs/1_learn/generate_ast.md new file mode 100644 index 00000000..f78bd305 --- /dev/null +++ b/hugo/content/docs/1_learn/generate_ast.md @@ -0,0 +1,6 @@ +--- +title: "Generate the AST" +weight: 500 +url: /docs/learn/generate_ast +--- +TODO diff --git a/hugo/content/docs/1_learn/generate_everything.md b/hugo/content/docs/1_learn/generate_everything.md new file mode 100644 index 00000000..a7bc8fa2 --- /dev/null +++ b/hugo/content/docs/1_learn/generate_everything.md @@ -0,0 +1,6 @@ +--- +title: "Generate your artifacts" +weight: 800 +url: /docs/learn/generate_everything +--- +TODO diff --git a/hugo/content/docs/1_learn/install.md b/hugo/content/docs/1_learn/install.md new file mode 100644 index 00000000..58302ab5 --- /dev/null +++ b/hugo/content/docs/1_learn/install.md @@ -0,0 +1,16 @@ +--- +title: "Install Yeoman" +weight: 200 +url: /docs/learn/install +--- + +Before diving into Langium itself, let's get your environment ready for development: + +1. You have a working [Node environment](https://nodejs.org/en/download/) with version 16 or higher. +2. Install Yeoman and the Langium extension generator. + +```bash +npm i -g yo generator-langium +``` + +For our getting started example, we would also recommend you to install the latest version of [vscode](https://code.visualstudio.com/). diff --git a/hugo/content/docs/1_learn/overview.md b/hugo/content/docs/1_learn/overview.md new file mode 100644 index 00000000..4e8dfcd6 --- /dev/null +++ b/hugo/content/docs/1_learn/overview.md @@ -0,0 +1,28 @@ +--- +title: "Overview" +weight: 100 +url: /docs/learn +--- + +{{}} +flowchart TD + A(["1. Install Yeoman generator"]); + B(["2. Scaffold a Langium project"]); + C(["3. Write the grammar"]); + D(["4. Generate AST files"]); + E(["5. Resolve cross-references"]); + F(["6. Create validations"]); + G(["7. Generate what you want"]); + H(["8. Find advanced topics"]); + A --> B --> C --> D --> E --> F --> G --> H; + G -- reiterate --> C; + + click A "/docs/learn/install" + click B "/docs/learn/scaffold" + click C "/docs/learn/write_grammar" + click D "/docs/learn/generate_ast" + click E "/docs/learn/resolve_cross_references" + click F "/docs/learn/create_validations" + click G "/docs/learn/generate_everything" + click H "/docs/recipes" +{{}} diff --git a/hugo/content/docs/1_learn/resolve_cross_references.md b/hugo/content/docs/1_learn/resolve_cross_references.md new file mode 100644 index 00000000..21e2b319 --- /dev/null +++ b/hugo/content/docs/1_learn/resolve_cross_references.md @@ -0,0 +1,6 @@ +--- +title: "Resolve cross-references" +weight: 600 +url: /docs/learn/resolve_cross_references +--- +TODO diff --git a/hugo/content/docs/1_learn/scaffold.md b/hugo/content/docs/1_learn/scaffold.md new file mode 100644 index 00000000..5c8f7996 --- /dev/null +++ b/hugo/content/docs/1_learn/scaffold.md @@ -0,0 +1,71 @@ +--- +title: "Scaffold a Langium project" +weight: 300 +url: /docs/learn/scaffold +--- + +To create your first working DSL, execute the Yeoman generator: + +```bash +> yo langium +┌─────┐ ─┐ +┌───┐ │ ╶─╮ ┌─╮ ╭─╮ ╷ ╷ ╷ ┌─┬─╮ +│ ,´ │ ╭─┤ │ │ │ │ │ │ │ │ │ │ +│╱ ╰─ ╰─┘ ╵ ╵ ╰─┤ ╵ ╰─╯ ╵ ╵ ╵ +` ╶─╯ + +Welcome to Langium! This tool generates a VS Code extension with a "Hello World" language + to get started quickly. The extension name is an identifier used in the extension +marketplace or package registry. +❓ Your extension name: hello-world +The language name is used to identify your language in VS Code. Please provide a name to +be shown in the UI. CamelCase and kebab-case variants will be created and used in +different parts of the extension and language server. +❓ Your language name: Hello World +Source files of your language are identified by their file name extension. You can +specify multiple file extensions separated by commas. +❓ File extensions: .hello +Your language can be run inside of a VSCode extension. +❓ Include VSCode extension? Yes +You can add CLI to your language. +❓ Include CLI? Yes +You can run the language server in your web browser. +❓ Include Web worker? Yes +You can add the setup for language tests using Vitest. +❓ Include language tests? Yes +``` + +Yeoman will prompt you with a few basic questions about your DSL: + +1. _Extension name_: Will be used as the folder name of your extension and its `package.json`. +2. _Language name_: Will be used as the name of the grammar and as a prefix for some generated files and service classes. +3. _File extensions_: A comma separated list of file extensions for your DSL. + +The following questions are about the project parts you want to include in your project: + +* _VS Code extension_: will be used to run your language inside of a VS Code extension. +* _CLI_: will add a CLI to your language. +* _Web worker_: will add the setup for running the language server in your web browser. +* _Language tests_: will add the setup for language tests. + +Afterwards, it will generate a new project and start installing all dependencies, including the `langium` framework as well as the `langium-cli` command line tool required for generating code based on your grammar definition. + +After everything has successfully finished running, open your newly created Langium project with vscode via the UI (File > Open Folder...) or execute the following command, replacing `hello-world` with your chosen project name: + +```bash +code hello-world +``` + +## Sneak peek using the VS Code extension + +Press `F5` or open the debug view and start the available debug configuration to launch the extension in a new _Extension Development Host_ window. Open a folder and create a file with your chosen file extension (`.hello` is the default). The `hello-world` language accepts two kinds of entities: The `person` and `Hello` entity. Here's a quick example on how to use them both: + +```text +person Alice +Hello Alice! + +person Bob +Hello Bob! +``` + +The file `src/language/hello-world.langium` in your newly created project contains your grammar. diff --git a/hugo/content/docs/1_learn/write_grammar.md b/hugo/content/docs/1_learn/write_grammar.md new file mode 100644 index 00000000..579c77fc --- /dev/null +++ b/hugo/content/docs/1_learn/write_grammar.md @@ -0,0 +1,6 @@ +--- +title: "Write the grammar" +weight: 400 +url: /docs/learn/write_grammar +--- +TODO diff --git a/hugo/content/docs/2_recipes/_index.md b/hugo/content/docs/2_recipes/_index.md new file mode 100644 index 00000000..de287afb --- /dev/null +++ b/hugo/content/docs/2_recipes/_index.md @@ -0,0 +1,6 @@ +--- +title: "Recipes" +weight: 300 +url: "/docs/recipes" +--- +TODO \ No newline at end of file diff --git a/hugo/content/docs/_index.md b/hugo/content/docs/_index.md index 9ab17e51..42656038 100644 --- a/hugo/content/docs/_index.md +++ b/hugo/content/docs/_index.md @@ -1,12 +1,4 @@ --- -title: "Documentation" -weight: 100 ---- - -Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. - -This reference documentation provides [an overview](/docs/langium-overview), a [getting started guide](/docs/getting-started) and a deep dive into several aspects of Langium. Additional topics are covered in [the Guides section](/guides/) and step-by-step walkthroughs are available in [the tutorials section](/tutorials/). - -## Want to contribute? - -Visit the [Langium repository](https://github.com/eclipse-langium/langium) to take part in improving Langium. +title: "New documentation" +weight: 0 +--- \ No newline at end of file diff --git a/hugo/content/old/_index.md b/hugo/content/old/_index.md new file mode 100644 index 00000000..9b2501dc --- /dev/null +++ b/hugo/content/old/_index.md @@ -0,0 +1,4 @@ +--- +title: "Old documentation" +weight: 100 +--- diff --git a/hugo/content/old/docs/_index.md b/hugo/content/old/docs/_index.md new file mode 100644 index 00000000..9ab17e51 --- /dev/null +++ b/hugo/content/old/docs/_index.md @@ -0,0 +1,12 @@ +--- +title: "Documentation" +weight: 100 +--- + +Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. + +This reference documentation provides [an overview](/docs/langium-overview), a [getting started guide](/docs/getting-started) and a deep dive into several aspects of Langium. Additional topics are covered in [the Guides section](/guides/) and step-by-step walkthroughs are available in [the tutorials section](/tutorials/). + +## Want to contribute? + +Visit the [Langium repository](https://github.com/eclipse-langium/langium) to take part in improving Langium. diff --git a/hugo/content/docs/configuration-services.md b/hugo/content/old/docs/configuration-services.md similarity index 100% rename from hugo/content/docs/configuration-services.md rename to hugo/content/old/docs/configuration-services.md diff --git a/hugo/content/docs/document-lifecycle.md b/hugo/content/old/docs/document-lifecycle.md similarity index 100% rename from hugo/content/docs/document-lifecycle.md rename to hugo/content/old/docs/document-lifecycle.md diff --git a/hugo/content/docs/getting-started.md b/hugo/content/old/docs/getting-started.md similarity index 100% rename from hugo/content/docs/getting-started.md rename to hugo/content/old/docs/getting-started.md diff --git a/hugo/content/docs/grammar-language.md b/hugo/content/old/docs/grammar-language.md similarity index 100% rename from hugo/content/docs/grammar-language.md rename to hugo/content/old/docs/grammar-language.md diff --git a/hugo/content/docs/langium-overview.md b/hugo/content/old/docs/langium-overview.md similarity index 100% rename from hugo/content/docs/langium-overview.md rename to hugo/content/old/docs/langium-overview.md diff --git a/hugo/content/docs/sematic-model.md b/hugo/content/old/docs/sematic-model.md similarity index 100% rename from hugo/content/docs/sematic-model.md rename to hugo/content/old/docs/sematic-model.md diff --git a/hugo/content/guides/_index.md b/hugo/content/old/guides/_index.md similarity index 100% rename from hugo/content/guides/_index.md rename to hugo/content/old/guides/_index.md diff --git a/hugo/content/guides/builtin-library.md b/hugo/content/old/guides/builtin-library.md similarity index 100% rename from hugo/content/guides/builtin-library.md rename to hugo/content/old/guides/builtin-library.md diff --git a/hugo/content/guides/code-bundling.md b/hugo/content/old/guides/code-bundling.md similarity index 100% rename from hugo/content/guides/code-bundling.md rename to hugo/content/old/guides/code-bundling.md diff --git a/hugo/content/guides/formatting.md b/hugo/content/old/guides/formatting.md similarity index 100% rename from hugo/content/guides/formatting.md rename to hugo/content/old/guides/formatting.md diff --git a/hugo/content/guides/multiple-languages.md b/hugo/content/old/guides/multiple-languages.md similarity index 100% rename from hugo/content/guides/multiple-languages.md rename to hugo/content/old/guides/multiple-languages.md diff --git a/hugo/content/guides/scoping/_index.md b/hugo/content/old/guides/scoping/_index.md similarity index 100% rename from hugo/content/guides/scoping/_index.md rename to hugo/content/old/guides/scoping/_index.md diff --git a/hugo/content/guides/scoping/class-member.md b/hugo/content/old/guides/scoping/class-member.md similarity index 100% rename from hugo/content/guides/scoping/class-member.md rename to hugo/content/old/guides/scoping/class-member.md diff --git a/hugo/content/guides/scoping/qualified-name.md b/hugo/content/old/guides/scoping/qualified-name.md similarity index 100% rename from hugo/content/guides/scoping/qualified-name.md rename to hugo/content/old/guides/scoping/qualified-name.md diff --git a/hugo/content/tutorials/_index.md b/hugo/content/old/tutorials/_index.md similarity index 100% rename from hugo/content/tutorials/_index.md rename to hugo/content/old/tutorials/_index.md diff --git a/hugo/content/tutorials/building_an_extension/icon.png b/hugo/content/old/tutorials/building_an_extension/icon.png similarity index 100% rename from hugo/content/tutorials/building_an_extension/icon.png rename to hugo/content/old/tutorials/building_an_extension/icon.png diff --git a/hugo/content/tutorials/building_an_extension/index.md b/hugo/content/old/tutorials/building_an_extension/index.md similarity index 100% rename from hugo/content/tutorials/building_an_extension/index.md rename to hugo/content/old/tutorials/building_an_extension/index.md diff --git a/hugo/content/tutorials/building_an_extension/installed-extension.jpg b/hugo/content/old/tutorials/building_an_extension/installed-extension.jpg similarity index 100% rename from hugo/content/tutorials/building_an_extension/installed-extension.jpg rename to hugo/content/old/tutorials/building_an_extension/installed-extension.jpg diff --git a/hugo/content/tutorials/building_an_extension/minilogo-vsix.jpg b/hugo/content/old/tutorials/building_an_extension/minilogo-vsix.jpg similarity index 100% rename from hugo/content/tutorials/building_an_extension/minilogo-vsix.jpg rename to hugo/content/old/tutorials/building_an_extension/minilogo-vsix.jpg diff --git a/hugo/content/tutorials/building_an_extension/minilogo-with-icon.png b/hugo/content/old/tutorials/building_an_extension/minilogo-with-icon.png similarity index 100% rename from hugo/content/tutorials/building_an_extension/minilogo-with-icon.png rename to hugo/content/old/tutorials/building_an_extension/minilogo-with-icon.png diff --git a/hugo/content/tutorials/building_an_extension/vsix-install.jpg b/hugo/content/old/tutorials/building_an_extension/vsix-install.jpg similarity index 100% rename from hugo/content/tutorials/building_an_extension/vsix-install.jpg rename to hugo/content/old/tutorials/building_an_extension/vsix-install.jpg diff --git a/hugo/content/tutorials/building_an_extension/vsix-installed.jpg b/hugo/content/old/tutorials/building_an_extension/vsix-installed.jpg similarity index 100% rename from hugo/content/tutorials/building_an_extension/vsix-installed.jpg rename to hugo/content/old/tutorials/building_an_extension/vsix-installed.jpg diff --git a/hugo/content/tutorials/customizing_cli.md b/hugo/content/old/tutorials/customizing_cli.md similarity index 100% rename from hugo/content/tutorials/customizing_cli.md rename to hugo/content/old/tutorials/customizing_cli.md diff --git a/hugo/content/tutorials/generation.md b/hugo/content/old/tutorials/generation.md similarity index 100% rename from hugo/content/tutorials/generation.md rename to hugo/content/old/tutorials/generation.md diff --git a/hugo/content/tutorials/generation_in_the_web.md b/hugo/content/old/tutorials/generation_in_the_web.md similarity index 100% rename from hugo/content/tutorials/generation_in_the_web.md rename to hugo/content/old/tutorials/generation_in_the_web.md diff --git a/hugo/content/tutorials/langium_and_monaco.md b/hugo/content/old/tutorials/langium_and_monaco.md similarity index 100% rename from hugo/content/tutorials/langium_and_monaco.md rename to hugo/content/old/tutorials/langium_and_monaco.md diff --git a/hugo/content/tutorials/validation.md b/hugo/content/old/tutorials/validation.md similarity index 100% rename from hugo/content/tutorials/validation.md rename to hugo/content/old/tutorials/validation.md diff --git a/hugo/content/tutorials/writing_a_grammar.md b/hugo/content/old/tutorials/writing_a_grammar.md similarity index 100% rename from hugo/content/tutorials/writing_a_grammar.md rename to hugo/content/old/tutorials/writing_a_grammar.md diff --git a/hugo/content/playground/_index.html b/hugo/content/playground/_index.html index d005d41b..8ea1d026 100644 --- a/hugo/content/playground/_index.html +++ b/hugo/content/playground/_index.html @@ -1,6 +1,6 @@ --- title: "Playground" -weight: 0 +weight: 400 type: playground layout: index url: "/playground" From 17cb76bc8363eec8fdbe210751017746008f3031 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Fri, 5 Apr 2024 09:45:48 +0200 Subject: [PATCH 02/19] Fill out what is already there --- hugo/content/docs/0_introduction/_index.md | 7 +- hugo/content/docs/0_introduction/features.md | 3 +- .../content/docs/0_introduction/playground.md | 3 +- hugo/content/docs/0_introduction/showcases.md | 3 +- .../docs/0_introduction/what-is-langium.md | 6 - hugo/content/docs/1_learn/_index.md | 6 +- hugo/content/docs/1_learn/minilogo/_index.md | 22 + .../minilogo/building_an_extension/icon.png | Bin 0 -> 163818 bytes .../minilogo/building_an_extension/index.md | 90 +++ .../installed-extension.jpg | Bin 0 -> 119541 bytes .../building_an_extension/minilogo-vsix.jpg | Bin 0 -> 33381 bytes .../minilogo-with-icon.png | Bin 0 -> 121740 bytes .../building_an_extension/vsix-install.jpg | Bin 0 -> 114994 bytes .../building_an_extension/vsix-installed.jpg | Bin 0 -> 23871 bytes .../docs/1_learn/minilogo/customizing_cli.md | 151 +++++ .../docs/1_learn/minilogo/generation.md | 378 +++++++++++ .../1_learn/minilogo/generation_in_the_web.md | 331 ++++++++++ .../1_learn/minilogo/langium_and_monaco.md | 619 ++++++++++++++++++ .../docs/1_learn/minilogo/validation.md | 153 +++++ .../1_learn/minilogo/writing_a_grammar.md | 312 +++++++++ .../{overview.md => workflow/_index.md} | 7 +- .../{ => workflow}/create_validations.md | 2 +- .../1_learn/{ => workflow}/generate_ast.md | 2 +- .../{ => workflow}/generate_everything.md | 2 +- .../docs/1_learn/{ => workflow}/install.md | 2 +- .../resolve_cross_references.md | 2 +- .../docs/1_learn/{ => workflow}/scaffold.md | 2 +- .../1_learn/{ => workflow}/write_grammar.md | 2 +- .../content/docs/2_recipes/builtin-library.md | 164 +++++ hugo/content/docs/2_recipes/code-bundling.md | 119 ++++ hugo/content/docs/2_recipes/formatting.md | 112 ++++ .../docs/2_recipes/multiple-languages.md | 447 +++++++++++++ hugo/content/docs/2_recipes/scoping/_index.md | 31 + .../docs/2_recipes/scoping/class-member.md | 148 +++++ .../docs/2_recipes/scoping/qualified-name.md | 238 +++++++ hugo/content/old/guides/multiple-languages.md | 33 +- 36 files changed, 3360 insertions(+), 37 deletions(-) delete mode 100644 hugo/content/docs/0_introduction/what-is-langium.md create mode 100644 hugo/content/docs/1_learn/minilogo/_index.md create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/icon.png create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/index.md create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/installed-extension.jpg create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-vsix.jpg create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-with-icon.png create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-install.jpg create mode 100644 hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-installed.jpg create mode 100644 hugo/content/docs/1_learn/minilogo/customizing_cli.md create mode 100644 hugo/content/docs/1_learn/minilogo/generation.md create mode 100644 hugo/content/docs/1_learn/minilogo/generation_in_the_web.md create mode 100644 hugo/content/docs/1_learn/minilogo/langium_and_monaco.md create mode 100644 hugo/content/docs/1_learn/minilogo/validation.md create mode 100644 hugo/content/docs/1_learn/minilogo/writing_a_grammar.md rename hugo/content/docs/1_learn/{overview.md => workflow/_index.md} (92%) rename hugo/content/docs/1_learn/{ => workflow}/create_validations.md (54%) rename hugo/content/docs/1_learn/{ => workflow}/generate_ast.md (57%) rename hugo/content/docs/1_learn/{ => workflow}/generate_everything.md (56%) rename hugo/content/docs/1_learn/{ => workflow}/install.md (93%) rename hugo/content/docs/1_learn/{ => workflow}/resolve_cross_references.md (54%) rename hugo/content/docs/1_learn/{ => workflow}/scaffold.md (98%) rename hugo/content/docs/1_learn/{ => workflow}/write_grammar.md (57%) create mode 100644 hugo/content/docs/2_recipes/builtin-library.md create mode 100644 hugo/content/docs/2_recipes/code-bundling.md create mode 100644 hugo/content/docs/2_recipes/formatting.md create mode 100644 hugo/content/docs/2_recipes/multiple-languages.md create mode 100644 hugo/content/docs/2_recipes/scoping/_index.md create mode 100644 hugo/content/docs/2_recipes/scoping/class-member.md create mode 100644 hugo/content/docs/2_recipes/scoping/qualified-name.md diff --git a/hugo/content/docs/0_introduction/_index.md b/hugo/content/docs/0_introduction/_index.md index eaac07d3..06bc2e11 100644 --- a/hugo/content/docs/0_introduction/_index.md +++ b/hugo/content/docs/0_introduction/_index.md @@ -1,4 +1,5 @@ --- -title: "Introduction" -weight: 0 ---- \ No newline at end of file +title: "What is Langium?" +weight: -100 +--- +Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. diff --git a/hugo/content/docs/0_introduction/features.md b/hugo/content/docs/0_introduction/features.md index ef358ba5..e37c7106 100644 --- a/hugo/content/docs/0_introduction/features.md +++ b/hugo/content/docs/0_introduction/features.md @@ -1,4 +1,5 @@ --- title: "Features" weight: 200 ---- \ No newline at end of file +--- +TODO \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/playground.md b/hugo/content/docs/0_introduction/playground.md index ed1e5ea4..c39edb55 100644 --- a/hugo/content/docs/0_introduction/playground.md +++ b/hugo/content/docs/0_introduction/playground.md @@ -1,4 +1,5 @@ --- title: "Try it out!" weight: 400 ---- \ No newline at end of file +--- + \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/showcases.md b/hugo/content/docs/0_introduction/showcases.md index 0784e7fc..5b166c72 100644 --- a/hugo/content/docs/0_introduction/showcases.md +++ b/hugo/content/docs/0_introduction/showcases.md @@ -1,4 +1,5 @@ --- title: "Showcases" weight: 300 ---- \ No newline at end of file +--- + \ No newline at end of file diff --git a/hugo/content/docs/0_introduction/what-is-langium.md b/hugo/content/docs/0_introduction/what-is-langium.md deleted file mode 100644 index 776b83be..00000000 --- a/hugo/content/docs/0_introduction/what-is-langium.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "What is Langium?" -weight: 100 ---- - -Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. diff --git a/hugo/content/docs/1_learn/_index.md b/hugo/content/docs/1_learn/_index.md index 2da00312..77cb5f19 100644 --- a/hugo/content/docs/1_learn/_index.md +++ b/hugo/content/docs/1_learn/_index.md @@ -1,4 +1,6 @@ --- title: "Learn Langium" -weight: 200 ---- \ No newline at end of file +weight: 0 +url: /docs/learn +--- +TODO \ No newline at end of file diff --git a/hugo/content/docs/1_learn/minilogo/_index.md b/hugo/content/docs/1_learn/minilogo/_index.md new file mode 100644 index 00000000..cff9ad83 --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/_index.md @@ -0,0 +1,22 @@ +--- +title: "Minilogo tutorial" +weight: 200 +--- + +In this section you'll find helpful tutorials aimed at teaching you how to implement Langium for concrete applications. + +These tutorials revolve around the MiniLogo language, implemented in Langium. They describe how to implement MiniLogo from the ground up, and how to customize the various features of MiniLogo. + +By working through each of these tutorials, you'll be learning about: + +- writing a grammar in Langium +- implementing validation for your language +- customizing a CLI for your tooling +- writing up a simple generator +- building a VSCode extension +- running Langium in the web with the Monaco editor +- implementing generation in the web + +By the end of this series, you should be equipped to start working on your own language, and also have a pretty good idea for how you can integrate Langium into other projects as well. + +With that being said, hop on in to the first guide on [Writing a Grammar in Langium](writing_a_grammar)! diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/icon.png b/hugo/content/docs/1_learn/minilogo/building_an_extension/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9beea261318ced153fafd3d82823f4ed8d22a723 GIT binary patch literal 163818 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 literal 0 HcmV?d00001 diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/index.md b/hugo/content/docs/1_learn/minilogo/building_an_extension/index.md new file mode 100644 index 00000000..a6d460ea --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/building_an_extension/index.md @@ -0,0 +1,90 @@ +--- +title: "Building an Extension" +weight: 5 +--- + +{{< toc format=html >}} + +In this tutorial we'll be going over how to build a VSIX extension (VSCode extension) for your Langium-based language. This will allow providing LSP support in VSCode for your language. We'll assume that you've already looked at the previous tutorial, and have had time to read the [guide on bundling](/guides/code-bundling/), so that you're ready to build an extension. At this point we assume that your language is also working, and there are no issues running `npm run langium:generate` or `npm run build`. If there are, you'll want to correct those first. + +## Setting up the Scripts + +To get started, you'll want to have a language expressed in Langium, such as [Lox](https://github.com/langium/langium-lox) or [MiniLogo](https://github.com/langium/langium-minilogo). If you have been following along with these tutorials, you should already have something ready. If you don't you can also use the default language generated by the yeoman generator for Langium, presented in the [getting started](/docs/getting-started/) section. + +Regardless of what you're working with, you'll want to make sure you have the following scripts in your **package.json**. + +```json +{ + ... + "vscode:prepublish": "npm run esbuild-base -- --minify && npm run lint", + "esbuild-base": "esbuild ./src/extension/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node", + ... +} +``` + +The `esbuild-base` script is particularly important, as it will be constructing the extension itself. + +You'll also need to install `esbuild` if you haven't already. + +```bash +npm i --save-dev esbuild +``` + +## Generate an Extension + +At this point we're ready to generate an extension. We need the VS Code Extension Manager (`vsce`) to do this, so make sure to download this from npm via `npm install -g @vscode/vsce` (or install locally, as per your preference). Once you have that installed, you can invoke it like so from the root of your project. + +```bash +vsce package +``` + +You should now see a VSIX extension file in the root of your project. The name of this file will correspond with the **name** and **version** properties listed in your **package.json**. For MiniLogo, this produced **minilogo-0.1.0.vsix**. + +{{< figure src="minilogo-vsix.jpg" height="225" >}} + +## Installing + +For installing the extension, you can right click the extension file, and select "Install VSIX Extension" at the bottom of the list. + +{{< figure src="vsix-install.jpg" title="Indication that VSIX extension has been installed" height="400" >}} + +You should see a small indication at the bottom right of your screen that your VSIX extension has been successfully installed, like so: + +![Indication that VSIX extension has been installed](vsix-installed.jpg) + +You can verify this by going to your extensions tab and looking at the enabled extensions, where you should find the name of your language (again corresponding to the **name** property in your package.json). + +{{< figure src="installed-extension.jpg" height="400" >}} + +Assuming the extension is enabled and working correctly, you can open any file that ends in the extensions registered for your language, and you should immediately observe the syntax highlighting kicking in. Interaction with your language should show that syntax errors are recognized, and other LSP functionalities are working as intended (such as renaming of symbols). + +## Adding an Icon + +You may notice that your extension may not have an icon to start with. This is a small thing that we can quickly fix. This is as simple as adding a small PNG icon somewhere in your project repo, such as the root. You'll also want to set the **icon** property in your package.json with the relative path to this icon. + +```json +{ + ... + "name": "minilogo", + "displayName": "minilogo", + "icon": "icon.png", + "publisher": "TypeFox", + ... +} +``` + +In our example, we're using a simple turtle icon from [onlinewebfonts](https://www.onlinewebfonts.com/icon/74548) as a placeholder. + +{{< figure src="icon.png" height="200" >}} + +When you regenerate your extension & reinstall it, you should get an icon that is the same as the one that you packaged it with. + +{{< figure src="minilogo-with-icon.png" height="300" >}} + +## Conclusion + +And that's it, at this point you have an extension for your language that you can use for development. After some testing, and improvements, you could even publish it! + +As a quick aside, it's important to keep the extensions that your language recognizes synchronized in both your **package.json** and your **langium-config.json**. If you do make changes to your extensions, it's a good idea to double check that these are both synced up, and to do a full rebuild to get those changes into your extension. + +And that's it for building an extension. In the next tutorial, we'll be setting up [Langium + Monaco in the web](/tutorials/langium_and_monaco/). diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/installed-extension.jpg b/hugo/content/docs/1_learn/minilogo/building_an_extension/installed-extension.jpg new file mode 100644 index 0000000000000000000000000000000000000000..235b1aa0b4a26de9c1e28ca960d7958d174614de GIT binary patch literal 119541 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 H=P~~;OUy3< literal 0 HcmV?d00001 diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-vsix.jpg b/hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-vsix.jpg new file mode 100644 index 0000000000000000000000000000000000000000..4407ebdc7e78428120fe9c05edcd57265dc5a11e GIT binary patch literal 33381 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 literal 0 HcmV?d00001 diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-with-icon.png b/hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-with-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..71a1d684735699512d09b069207697183fcd9dbc GIT binary patch literal 121740 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 z%0D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 literal 0 HcmV?d00001 diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-install.jpg b/hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-install.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc832f4cbdeec2ca1cc02e870e558a830ba72df9 GIT binary patch literal 114994 zcmeFY2|SeF`!IYncFDf)y9i~CFqV)cg%D|y>{+raOex7;DoQbhtV#9~CVM4h-@+hE zmdsd(88gq(w{P|PJ-`3*dEWo~c|V```Q6Oi*M07Du5)eYoan1H*blb^G* zx4)ZD0C|F5)GZ*uS5r~Z+h4))qR$0q1t%Xb#Slkd#e)h56d^5mh_9oQr*nYF1!q@x zZ*8&Vw`egD_lw$MHmYU^%zO=;-Q15}@pHDka>B~#il>vtMKQRJh*pSZh?lRIbAY2r zh}R`=f6WkWu^-4a0lZtRC?@iwN`R-fn624K5d$ATXAw1p0}2PkKx@B?E}9lcjDEHS zPugNXi3|=7RtQ#B@bPn1JgA|ep?E+^QAtT2)R6ZN^$u_hk@xl&{~N;*XMZO@ci#Ya zA8(OejE)z40t2+g#1ugfia)#91%J`1Bl7R--xBz@1pY07e@o!s68N_S{_m5(Z*Rxh z8@M>Zz?Xr@OVFW{z*X`A{*teVvcduAkiLl-)vikht{<@E50Ir-Fn%ZrDy8~%jsD>x zUO$37$^6;GzyNX5!raK@xZw}4koldXukR&F76|h44)C)u))%ooV<$p81JOfF5IZCR z$vZmv`|6!Md3+b=-}fK*e|>HA|8V}G9{F8dzl#5R0P98I76I?^B&dGjqQ8?DfXg9> z>WP!DUjPKr?3RlM2l(#7-~(~^0RjPhdlz>73x2W-U-%1t^`nlJg#oD31pM1Qj*fn= z5VZF*C>IHGas@c{VgY=>`=Yxy1Tl*MSjWrD=OTd516T&s@dfZM{zDi3z~lM{?C5ym z7fwe<*I)2oynvRV<0J0=zLy+Be?0t8etBIA1oHZENrCS@Zhl8Cz?}ogZP3%lbQj(O z;6?8XC(Hp1oNx-fJK*jwn3BOQ@aSm(gZh*LPW}eFE<6{24_tISVhUgZ02_H5V7L579lt<} zUHT<?4#nN(xEy`bsT)_ zf{zl_Au5f(`S@L*dWO1-dXl=28bdvVaF6u+CmESR7{JkAGIR#={X-U1QUIqal|Gd= zzz#4|aZ&L>@>D9IA3Z8K=vft%8vNvNS1NyNfAjl8)_+R!FIq4BlK0;f{O|q$e&Y^Z1azAI(#B5;V7FmquvS<->;tR@Rt1T` z(6HCAPq5lu_-Fq{KeX%mt2c`u^mqcjxc{p2H@|;teAhnw4-_8wc7XU7mH_9F0ASCM zfsb#fpS!DDfQTMg5u8O#yqy&GizppXQi7n}^<}pX1g)O>v2IXsefnK?V;q9C(PT3D z?eDTKwxErp!aW_0{w#i!bi1xqXx4CGZ<;SkPsve$pC(oAT{VP zqzf5B#~^da3OWOw1NQ0$?A#9uhQgrh&@Ctqgf1RHX%Gs^g7Tmus1&M#YM^?k1!{vn zLw(Q)u%2mX0m4EX5P^b%f|i1bf}MhwLYP95LXJX-;t+)ng(1ap3JZ!e6z3^iDZD8H zDZ(gjP{dIrQ>0NmqsXTyp?E`4Pw|1Gi(-gkg5n#+3dJ@hjB*bp2c;mT6s02NAxb?; zQ%WmJ2TE7U%am6rZ&D^wKBUZ~d_h@BSx?zU*++??T%cTsK`=%b7fci;4?6@ifSJSW zU@kB}SOhE#cutnGw6%7?Tl?atQu;8Oqr>UH%E>lHN#Z#qGb&OE2x{nSemBZprN7RqLHRi2V?OJ zjR(zDns}OYnqr!FG+i`PH0!jqw7j%(wA!@hw2rg^w6|y<(Y~NX({|HN)8gqE>4fQ& z=#1#>=)CD7=~Czl=<4XY>1OE&^eps}^qTbM^cU$v>67TQ>8t5G>8I%l46F>&4B8A< z3?2;E86GmcWN2pi!m!H7$SB6B!FY<%o$(suL&jH(?-?f;xAw5@k=b4VHD?It zW6oMm3>S<`ipzxS5?2yeDOW$&Hn$+R9=9`h4EIa!ZthJUejZ&OXP#J|VxB&pZC(*x zLtanbyS!DrqkL3+vV5obg84G|n)w#_IrtCrJMqWzm+}t_PzuNjSO{Dd$P)M@ur4Sh zXe{U}_(-r(a8Za$NLR>1=)O>$&^KXrVI5(2;rqg9;dv2G5j~MhA`eBHM6jX)qDMso zMW2awh!Vu4#ZHSwiWQ5EiZh5G5_b{5FWw-Il@OLNlL(V2lo*zzmpmltCYdVPD!C~o zEoCDWEmb8oC(R>mB7H@=Q2L7ulMGzuvP`B-?>?G+hxU2yOW*fdmQq$#)=l=YY^NNh zoSK}wT)JG>e(L=i`@Q#P?jMlfBd;ePBwr{$p}?hZTp?1SO5wYrgrc3|UBy;K(gD>2 zmkwkf7&*vx@Yun~gVhIDlw_5hlpZVfDl;h?DI=9%E8|q;RGd{ZR0dVqRn1hRRU1@y z)YR4d)LyE6Q}%*fTK&EaukC2n+a^cAZtdoILs?)+n-HZ1xesk7#PIjJk(RN98nRC^4z32MP z4eplWw&-r)p5~78IO>7&*z`2_%=IK+vbj|3Mdx+i>y0;?x2JcLkC0D@PnWNp?=4@< zWzEYEE@S;n{c`*%{2lyX2XFvK{!^e#U{v5lkWSF!AbhZOa9Idzh8LoR?Z;w0>nH;%x!{$cy zO~ISjZcarRM-|@Md&}?EK=k2g)NQKU?zcN)lw%&nkYX>!evCU1ml8*ecZ&a*a4_Lv z0y)tou_H+>DdP^!9q&8+cj0&Ql3A0lBv0KlyH|N%5fvK2> z#~;3aB=P9ZBVw9cTHj;+$Hh+sp2R%aOuv}kouQlY5+#U=Lv25Ge>(Wg_*rG9RAx#R zO;%9WOty7)>+?g;^Kl^n7I{ti>iPKv0tHEhl!bwX-(H-3@wwC|^-~RqhLJ|w#@?n=O&!gq&F@=` zS{hsRTG8*d-`9N5{P5=Ep^sHt zbEK!G*QB?t??hi$|LOk0fwKdc!Ha`)Lzjkd!$HG@k!xS5zr>ERjHZkUjAf4R8!yJF zVQMFiOnjQOoE({Qnp*hk|CKm>bB1XqWmb4Le@4(+j=}gvDD+tV>V6 z%X}|i)?NODwZ%^3{BY!z_*LH3+%=W8hV_%{V;f!@gw0qyFFtSU&{pfV&GsxIm`F=} zxU+Aknq*4)LiQq)eI5NAfA|8s2O5+v;Fx127lN41KoI+9;6K>^wg3B3Avk-KW34*LNAWCKBU!R}o{@PdW zKG1+Y#M6^I7rZX~eDx2vzxJG<=x@6J`3|^IR#w?<^AC6OJBXDII076n3NeV1l>){} zL2iPC0Uy-BNded2y--lXsHkaZ>F604L4^tyh>`*ZqojgSQ||^2D8j*eh>De(P4u81 z4f`oaTCvLmf0t(qN=8TNJG=$h@p}3 zQIlhqR;R6PfP3b2(b>h-&E3O4ATTI6B=pLSn^Cu-Z^y(Y-@E@HCH3K>w9KsR=Q+7~ z`30qAg)8(?A*6`+{)_O`o<=HYkQY3 z3JCTWTfaE_C%#w#UzAi-Fe=(zz9=Yz!3V}lMJ;-ehE4Ajt>a~OF{SHt9Qt>kmDJOV zD_dYWFZgvaa7n04NaA)``@z|NkFm)ABhG#?_M5K}u(kM$D@qDLEhQyT6%1U!d)vKe zXn_L;F5qbWxafXd^t%`Ei+)~YfP`YVB@9Ll{u$|L=>C57-@lVb!Ree5c^KLQqX5PP zV};-l$z-m$3_c;c^Mnk|rIDd&mj$8>8M+z0;ZKG#J;~66$Hmy++fwMQGu32>0p7cfTH`bY?a0u|)Bhj!UAMH8LxwP!WT-r8 z$sXI;NQP)gqUO1SA@+@tFrS=n)@YYl6R)X*#u8DFMjxGg#lRzVB50Op7X4o+>^UhH z2={3LV#@|-kaoMzlyrR_ISnV-`XL06p2%2qxp2dHG=i=sEJgen-qBIvaaP3(d4cvl zZ4AO1aj$|Hy|1wpj=%JrVfa5+O~kHEVP3&2X%{E3AA2wxsZvRkC}#IO@sbK0(_@F7 z6iGr!3$BgvJ_2L2pXIy)2c+Y^^8)FG9v0r{!5N}rbTsA{0=XV02;M?@@>G?U+q6sx z=%OCIQa_yH2T{K&plKyaz{^lO>FX=42>En70ezf^0A#Xpo^URbYhe1Nc*9h@N?ImJA&kAVYHMhzaxm_YAhQ z^Y)+SZ7>P{!}Qm6a(Ac!u^-XIJa~TrVvX673`qbUqFZiGKD6iDIE52l{Pvs9lU29L zkSk(aYW%Okf|w6C-)49Y)DGV|g;+3zZ_|Q-myBF-ZKdilr9jvtLK-)GN~+Y=h4=bq zC91|{nrJ~ZN+yePep3x7=I<}2>UzV3pNHs4QY32|k+w;5`QJYq>_4nLckzoR3)AJv z*P)IB=-AwdwqXPrGE29;v^j$IXFeRfDNlx;qc~GJy4Tmcu&E8mE#hY+*1izA(vcP> zihT%XitkZmD00*usNnQ0($$!RZ2gWRLn6W9p=78tANdtcyt|^|Z&EYR-`aqnN6v2Q zk)e8*BG6LShbV@izY^EZNQS7ZtH{v)JW@vzkqjk`!b!S1HDqYE7rlZY9osXkWcfgNsEZ7ta0D=ay{8>O5w}xGV1D@^ zEVY~!TKvL1DuT@k?)4dsJ+s^TVVE-Zj*y~?B9Uu;oLHJg(1fp&-~nW4iy}PyH|0r> zjJCJml2}nU(~JMEn}cE^N(lP={rE>yXqx~i0E+&A+!CMGUh`31KZBiZfCH(ae@N|P z65d#cb))9*N7P0Da&|2OsD6cFeUl97039cT2jh~6ogW#^30Weo!lZaw~o1udCKN4=g2_>9s19X;jijggWmov^#6?MA7VFOgx@rHKJ&}4t&omH@qZK~ zsU5Mp4c~$TOBY5USLYF1ieN;CRn;ZT)Mb$x@PBK+o5@utJe|597CyGDMGz&ye7E%djH2a$9@E33cN2QRZBl9EVZwgtm${MYc3 z-yL3gWC+L@+4(1zj$vX;!N2hh{RcWr)%vJD(2D}yMVtO%s-#9d&@ephKera2aQ^mi z;~gMiQp9gQ87H_sYyX&4{q2tadmFYa~{5^coVU@ z`I}2%dT$-({%du0DkZG1OK%7_h<5)e;#VYAF!}sxdjHy1?8l8(5nz1-G6n|mC$GTv zhW{9I|AEpJLht(&=fgpFdsBalI2xNoLjImz{)53iwmZ0!2tdfho!^}PduW3t&m9sJ5Mp=>~^O4i$BrC9s zDdGTI8=+hh@T0zVCdw3-lA#H)f8OuJZGiPW)BVSOha`pi8v}x5CA?s!_``>~59U!v z@@JCMTxRT!FR@0>z@)oEKG>?VOT|`ber3fflJ0^@8qi3p^b*7-84p3Sa# z%1q3D$=ZQ|y0%Km<78n?iigD6jyT@EcA~4-vJZ+Ux@+I6(gD75^wo$_;kBd0Gr&tK zOd^Tp%_Co#FBNBgtK#b@#uhfK^{3p`>M@f_)y%%!!l-<3-!+Kp-Zw-Z3Y$WNk)iAx zAq&7e5)uV`#uA_7q?e)yHluCGr>MBP1HEfQ$1Ar|?dpau!<-}BhMgLVPdk3b45S;? ziDd;Ub7`bJCAOYPHz?we9$Sg6UO!MA1J6Yw-Tp_ub;G4@ernz{oMuNFR zT9;K(ddXe`wHfM1H@#1@D8DiiJ!+YR^4ydr(SIWxis-BMY4jOhHo-DC%PmJ$2{RJ+ zA;F&E++BB0X{ej%R#| zwAq`UnMadRrs8elY|d#1x-^Z&_Lsccd-GNEPE{QzsjF@;Fiw|<_6#`wF3yh(wSfM# zY>F~NEUt=DY4TK2=yFrKdOnfkNV=kU|B+S06HD7cv&NxXe)rMCbC0X;ta~Paor`dZ_$*u&+^RU_)OuqgdWm-8Z84)~yQkp%(3sbl*UWy_dLw6%2aW@I zVm12cykh(zS1>1_h80PS6cfym!gMMFeMFN<1fx4wkXoMp_n-`Hii?(*SmgIb{mgwA zbZJUQNOXz>F?S@J$j$?zIl*pD4aMh8<-QYHeQqJJ=B`yy?!y6(@Tyuc zRyrJX1l3#kwvre|`FzCFZz!x@=aA_ny4i3C z1$P-AZq&t@CzZc_kLeG1q*Bj*o6W4sZ}`Dm=L}QZ#>2WVhhz;*gzbi3I!5Po->*g- z8A~56zUX8QI~P2iWbe^EQ27@1sg`rQ%asf=4DjeF1b!d#HXQRrm^LtEoq*o+Wd_&< z`v|}3)o^V#?v(GgNA7W2Da*>z^Smw16Au;+X$B3YcTywdM?-E*NG~D@7IO%e2)PjN z{z(_?s;&GBo9_C}tjNp3V)4Qc(zT{7H$TSTF+bSYFp%<1JEPNOt!L)YdAW}pi5(+F z1BNfr;#)bHRm9U1KCB`9&3vhmHIB{->4k2ambPQVC*Dd%&WwKYGnxpjHunrrk9bInR+FN@MV{@&>aLTYJXs4)LUSakW3pZ8Xoskv-<9Upla-v*2(HS$& z6Q+$*osFyse}2yGN=v%*gFweT-Hm|*I?9ztvl-@m^%^11?M7gy&m#KKJV;EkFb#{|K4i^RE|+8?(WLcCs7B~KfUcsp3J7=~JvtV>L2 z=v~!#D;<7im{h5K>>-cg3E6YR(_?7?wY3V!1M!0|#}H9)PWFj8eB~H#pK%nQPg#Q7 zQ2S1XOUL;Bvr8*gU!A-cXJa>f1_zpi%Z#Jo?rK5JBuyZZ1l&Lt#F#Y5lEugs*p7H+Vm zfcNtBRF5qto{osLtx>#?dfDhpQpK0I#*D0=7YDyyQKS269k{+emK(G=&~Y)vAjQds zB=m+)Jqg4mQ1a|#=$N-B?32$b8JaJC@X15tg3I_-VUuf-i9%eG*%EszSc6oCr)D%4 z_kI0paq6fogGP*-(b?ErIb#+42fXj^V`wzjvZ6XanVVC0uwCc8Xx_N0B$aEd`yj)b z#jE=4f*FeE*A`4>6t~FGy5()!8>cwMqC{AxDkM29t0kLca+IB}pZe}}oJ~qx%Tg_G z`PA2p@{@-}zbY0f#mZDOie!RsZkbbt94~J?h~hY9_}TB(ZqZ(A0CVeoY>1V~oYSxc z?;U967-TZzo=!U&a-0efcp;M+tMEVDdsI&wcXlawoQ+?YC(MqPNE$(YV=B55 zdVJ}2>HMQvmpiqLbqTyOUtC_mnoq`W7RGumSn9Zytdp!RlMD}7kfDs;cjT_$UQGqw zYj2T1j$60tv&usF1(KOjpVte8KD)7bC)t~~PBvR*Cq$jMrKJDB*=*T0Ce3Datn^9b zA(2=!2V3`{FQn(l39#?3Hv&G_2NDyAw}42)^n)-P!f8^MFh9~|3prs+M1l#2CB)bQ zN0YukrPJ$~y{V>w)LhNn*Q)AAr~0lBo4gkhu$deuO4fmp@6+`09TF1vqHW3aRPR@| zc^kH~O7SqcRFNzG=bZP~=AR4l{9uAy>Ri!gc=&b7%>k~4A`Qo$CIo_L>LT)^U4#G` z8pwG|hH}~ph=#@9JLzb*@%ZslWOJ?hRPH+_R|2frPQN2173~_i&}RQIjhFU;zd(uF z+-T~ILHyVA*F38@P5QDlFOTNbt@%w96a+rAu$Ov7K!7n;^!80H8M+a(=;I^d?((>~ z?og;;;+aP;D)ddXKWKXzZ$KIDaLm`O+~5n#IL21$hZ!br6Fb7JUWh$%HOaL#pz@Tl$=$+t71;E%H~e9C&XdsBpsD0matKR2hp0c zjbwPm__cMgl@2?i8MRRm=uPx{5x{IIAXXdQ(!Rm3PUDM zLb$=h>n!)3h*&<>?!2zi`?5|3O{7r^*O@X-jFz)T?nxb&LsbgDiceA`ve0f+mf!y# zqna+*XD)Iuty6*-aX&);9*F_?@G|y0ab##=92nw|9M0e!5=@G;*ftDz9NKvqhQG0> zLyi0Lx$~tv%DM91l7)S#ifc!*REBnr>ZAsXfd7*;L=3tDy+n_T!&F6r=qlDXh(uLxq*~9;Z27HhjD6L*sGV9?hE`PU z1V<`?NsCh(2{_jqL}4;SYd{pJ!`+RQ`A!tv;6F2y`q8#nVQKy7vz8E-2ZQ>tSITb) zOroFoB#gg8FI5!)HP{l3v5khaeAn zw%a%PRa3;Yi3`U?LoLc8$(V+xGT@rF!0rxPqeWlTT$kn$$+W ztYd7(H-xbWu;7u>F@{(UILDc(L{Z9d(;Qoq2yw7Elk(tuFYl<{qWMjIi_VLp29oijN7@T zZPa306d4Q(wytSa&mvvU3Zh`QvY-fVbf#~V)kGcc4Iz=Exdtk)y4AnQ%TcqfHp zGFWS|iBVXBz3GxE;=$cZ3Zl`ztahJHDCi6{i5M|b-`me!^;L0EdopP#*J7tg1uG&0?&USd8_8=v@eWp3ATh>(N;e8kV8=u-jZ%77Jtu2Et8xIlp;fp3Z zlaS>IB8QSsESgD+G2gh@J%fedKklJ^Z}7wHkYum#=%*f&J%#+-SHs?%rC`xGcdR!z z>cj)}2scS=RnR><`;{O~_tS}@1^4Vt&@pljxgdb4a)oZ&7v>Mx#A}Ney1TVXI7S-Q(ZuHyLh)4_U+|XU zp%dZur*Hzpbun5J2EneBYHcS8ys4jTIk`?UiVHSAI8>ZN0uyU}5FC?-;??09BTC^? zn{vz)ttykdNv48oEgxrQc#U}N+(e9Zjr3Mx+30CS(!Sa5KXQJG@oHCWa9x6&`*@Gp ziQxEW`|?ka79U$zRt0ZGXbLS%qDNLYtbuEb0Rk>hN+4QdrGaMo$`M@nI_$TE7j1i9 z4L`OoysO<@R$I|sI`(!e`{fwriecC?ApnqMfOJ6)qbHb>8k26I%FJ)pF?*z>m21YQ z_1`?NuB<0uY1H37ea2oev0LuR8{YV^+(@|8oa&qb?3hygdUcgem%Zl*_K<6Q-sHsd z^lgQggyGpW;Cj%q;klcULiaF8B8UCEjir3NVhf43r+i4k>u$Q2&&}k~g5$akyw-D> z`)0!wvMDw43H~AKP2;7^L>6w0>tZ`jaBs{MLI7WYWIN~1PFW?^B;PxDmxm@{ihYRw z~djG@pV;eM)ZMd#_-)HQdW*f2+c0AEAqS4^w0k z#T86B_nW|FBYIF3<4f#d#GZ!p!QBw-XBS8!N4xn$Z`+Dj+)_FtUKJ~ObkgvGJzds* zQ#RY=kU5N}qU$m1uQ#g0&uv&&rqorJmF6hie>2}gT(u5Q83i(>i7`XFpIIHmPmHr_Z0hcHS_e2TwtUrXC}Nq<5@t zgQc><5pfq;VY7rH9FG{z*w>@wN-zt_M6l0m%HQc(On(~LCwA?iA5~CSQ`DoF{nMsZ zP%@|P^b54dcv7{^;y98ZX6s2pG`5>t@YQzQ+pzbq!-dtD%sxzbM~19WGItaOH8h56 z`6@)sGroK@d3$a+=wOz0x<+TphWqpJbF)kn%zHy_7-3OyfeCgWuX>sx%(`YvQfxm; zemXTarr*h{r5ST-YX2MlzSKOi*LG{jJ^0z?b23=-+eFpkbK31mx7O07+RS3EQI649 zFfODTzN4ja&yFyePV!id-P-Suw9Sv0?LD8o!BTZTGuHjQ+`Wh2rs1AQOa>flDhwkc z@#4i1!@`x^anty4Y;a?d82{Tq;Y)RHN6+jr?AFZ_xPAYHUrq9iidjS5E4%{%hOFly zL*5B?%b3mmN`c|OCJ?X+%|67M>d-*=7egE#(ZEdZrbCA@D;;f?y^T08`V;1=4m&As5 znK!k6do|EqZz!@iGiByIdyGN)E&g2c7$?MjD20l5UB|-s!_sxc0~8e;^A;@_W=!y# zLsCE1?~6Qrn5@)_Z~4<#+3)u6PBVEXo*E-EoX)6ULe)UEfwGa@$Y( zT$}y8^fF8kyJ{ZStf`PH=Urv`cD*8bOwHi+!>6IoWwKfJxZg2G^eA2r0`8KfPrNXH zMG{5C7dvF*QZQy9UcR_UQROiI>)f=D+zG>y@dfnKU-$dW2w)y@U9mQ4x@Z8UVOxr|-CEfK46 z{d@dJSb#Qt@dAQG-+FnXbI^Xmb*WwLo}=faJbWUfm<+MC*?&4~|0Ry5mg}6)=5;Zp zuL6ljH8>vuV<7F+>Ht@&-h#v#76t;WmwJ1`Omdqsgj!Ftw8Jt*X&ttu*JR?MEX`CLZ zGufoLe|oW}Bk}wcL*{Z2mDioT|3V$K8V9#=o3B-m}jCI<@WkI=yJSX03UC)%Zx$}EGJE{Bmq1AOS?oWBlZ3Fkxo}^Vo@kn1q#iBv9^CENP zIdR|xDd7h;TF^Z&C2^#LsgMBE!_QyeIZ~OpzcfQv$DVx_{YlT;_<6)hd|W+A78{SV z!Y@Vj^~}gxb)V#e_EyD)-~OwE5sv4&kgf{YY)n^o_IMFJ0>WKRs2O)Sau7!&Sw?p9qm^THc*_+sRwTH+CH-;eKDF3-ym{C4i4 zU5kfZH$Xfq(w?Z^3uc~-lnCw~9kHE_FM2x28Zl5g;hdOap6Tt?!=n? z=vRr+#dCHBZkKh6xN4->OhV4QT9_>>ku>f&c{?ur9gXKVAH2*akzLGuNF9TULc1kh z8)vhe46ZL`9}7pBzfHKNma6n3@%jV7N#6zyy}SCHcQ^tpjF6sakL97(df^I?0f5-> zz&qlU+Es=38e)eBta{}o;F3*2Oh}c>uSgQ1DF+saM{R{>h?jvefrM*I>v|=bY=WFO&#T+SC1#(_VG^aiemG_f@*D z%I;m}8`cl9o#kilXw?g8l{9dQTqGE{-QjETW3wimGsp3lLi~CxdW#$? zU*K%@{FRzU>1`gII=eT|F10+k_guT(d(si(#$_SY9x~M6rlM^?;3pwT?b1WlQ#;ER1^iq}k%Y=PDalScNtCAnkQ!stl7q!t}PZr`0;0(bBbaeO_(6*Wy-eLty1TJYBK zAgRDHFUU~Y@-?Ij94|xLq<9mYeqmyJ8hy`>jD6eqT(?%0xG|M_D9IhcUF*^pPwNP1i#d=f?VA`KqbQ0 z1TuzJMy0gXysU=>U5swEKiAW`t*+E^^o#Cy-4B#?3HU19<0B~DxCz$=6}1R~s*@6T zD3bz4Px#*&HkZ~aS!f24x64SL2qq6Sqt9e@B%*3=;Hm2KdA}EQ9sMo3m;5vu_Zs_Z z+0{M7!*Qr%-D{x{JVdMb@emg*C-wEDM&0$+Fo3r(b9O@^w&Rykr z)LfIy^b$uIlzgaOoEHNEc{!&&-ApqpE8ObD-L2n!M7bR}|6Z)Ky-LefP#K{Y(Fvza zYUUr(GJMIV;z_S&!Y5#&^^|6%Rotzf|8e4Lp{&m&IU)QZv_el(N2y+z|1uDjnMCwW|?^p8RrWQP5z%+a3>WyI#vea7n5ysSii;gjd^Mu)x zAw=c)wxQQq$)IsIX5u+TuB7d-N;1?f=do6rO6soVot^RAN#D+5lX_o>OZ#-Y|7OJc z2CL4Ql(Ko5_iG^4B3%}Ii>0DgJerW?Zc-RHQWg4fr1~5=&9^{w1Ia^Ie`Jt8AVc>( zi*dyuN3@&_os~s?mj97N+Gd_YhEBU9KO6o?BK_D2l2HFE3|TwA`D949{6`L{JoCDB z>JF6^I3`9CUw|w{)@6`I7i&X0^%C6zQm4=$fpi~Y%LpWp@_`If_y7ZHjnVY49MaGK z?)v{$ftQ*`BVBdS*i!ULLLf;Mh7aBd&_XtR1ZJe&i63Z;p=p7fURwr5c)KI$WcrZlm?evEd2Pi9Pjp0~^zCUUf0HZ@5+tgPmOUR?vs!koxyi zX{)14r@}bN&|UjU?wzY{=h#A zQ#8lqbRAcqJ=Xf@et+&7Gl3#ve7qD92X`7ZCeedk2Q}ZV`SE(D%aQ}pL_=40Glf)% z4(AqDiDdOeo8ZLLiMmIU1mdQ#;j0*-bl~M^f)y$RKaF&6Q;Z!>ZGp49dGxsP?YHxn zZ4JCpYQZOw)NYOmbvBGA)|*Dj5o=PU9$U7}I4ma3BS>_8AX?C~(Fjnqxfd2YpE~9#z8J9IB%nwkM@S z-ou{0d`A5<KL*V~qq~e}sbBVNy%^w>ws-5P!CHsde!= z!71VsiW%)BJlr}FQKl3Ex5Q_N`q1Me4!vAvF|5YK1-_;iq2#>F9=5X2vBRX@4}~>G z43}XP7YnE0aeP&+=>c=rBuT95_q#c-D_&QxE;|S8s82*2N@cSfDhVFRuS0=8v{6+EX_|5SBKOUYQUwr%A0m@ToXDl$OG@{;cdF{L-HuZouxfi<-PIlGhEg;~So2y`Kh zR`^1k;-m{o>h^Z}(u;oIZz+CR&wS6(aew{da9X|WJ^N)VPGToWS2n!U`*5BVhju{? zgY9%DjzFS!e@1$TtPDXFkfi(^{Vx*!0HD|Vsi5V{gzpcs~eFgZ2-z0?i zaH>%?12L-EZ+1qqFPlYjduS?MYfy3a^{ZGxE;aiDQlH_yu+m0&aRQ5B9ys`E$;6(W zuRGjZ*XNc=J^DDr3-uu(?jTIZh?9Hyt=hyEry+ypcYy(WLGGJcroos_u5S?sUfp7h zS$q6iQ9O3$;C=<{A>UGQX9s#7XD!zH;%}x?f~`cBSrUVMo;zAdwNq$}NP!EhylhzH zcHmpo67N$AnDN(O6G@N1vYwmFe9c(G!JWatX4tyFuOp}Y4lxPs)I4EDw70Bh zUFn`Sm~mZKoiam`=wOOV{L)Lyv`x&c9^9+*rju$|$+~pke5r!YnbI>p;{ zwg32V@j{dVW`!Dg_$pxB#4woOr({QqsE-{d@^|4}rvjIkE>D`r3W-*f_b&_E_15f3 z3mkq_EGcDjewA(TVfPvO{cPb`m+55{)PU!NDsPRC*b_pSDvr^zA!vm-)bL^+7v50` z7oAC-JSv}MsN1npQ&eY>W8<*M`J^EEsm;x0JN2SN+0`+lYl4RASGsCFUdELD1-Vr- z9_+OYF5>Txd;0%nk#b)IN0{vZiPIB3%on_E_@IUDdspZ88S{ZXht+5A94$h|lJ;T0 zj!E%FH|$v8Z5@u3*05>CY=qjTcg1JuVsLkquN?*3$#Ne%g~(4MsZ9~08OnP$H}}RL zIQ{$r-L^|f{#zh>!_Q|DGauKwjg>o4Kb+rKX8VR_{7#Y$sYdXI6cX4LmNqbY8@%3r zD94IMZ-c}WMw+;D!nGcXiL@le)L8Vw%m5iWTC@qfU~cL8Mf{;C?H!Z#K5Be-MAemF1$&*yU61kbowsK4V-m2 zh5RHBCxSuV#;k#DRwqLTIpMpjJV7t)FhO&QbZpljMYezim2PDTf?N86fP{ zmbNG{7itbml5BYv{Mf9=u6?#N+qovw^880Rs2~)XJh`QAz#QFY^xW?9J+tR+pI&D7 zSEe=;^%V|z_(YG^eLzJ=z;Ib1+>=sCIQoDE?c?A0ZgPXn;@YJ4vezpTY@rsdcdMma z`p>Rp$L@gau*mALgZRT)cuP!ftIw@-TqRiWdx<6=<_~!uX+e+K>MtdVl|MSjN3Hwr zi)I-$e`RE7adYg>&JMbmsQe6Be~3hj_nF$c(;p!|?p9(lk$$ZC99{X2Dpz}U;)1eL zr<|^ne*M83HcCwDnUR39OO-DaLy!5otG_tQ-*>LvkkDRxy8P|ueV!-Wh?F2_(*_VE z3n4LCLUf%(!u(gzJ!ohxywcUQFb_cKpOg{nwT^$}{#d({fr-o}iT&*kmGT;jfYyByp(b3=ym= zk%PSxA%^Sz|>?DA&BpFH& zuFAfmT@@4NjH$g$l%7}(qrWw*zkw^Cpw(}gKJ#8Q*2u|5chOvX|N05#voRkIWoOCd zd|iC7STwttW-jmEysDDE9OzOsy(JvUy&d%I`Ps+X7WDEt&_NTcEXP}V_0Wn2=e7gR zVB-wlWCDSgL^gs`z@t@f5Ip$QrcF(Uwf4g*OkVtmC`Rs43!Qdh@r=5P#p+EW=OeT` z^R)~myd1$d#BQWnox8u=bfU=ScxCL^lv!^OI%Sdf-Eh1mlaRpE0OSFU*168bG6FBM z@iOp@_L1m`a=n4(i|PDkI0sU3;qfP5RG+Bx-S-mUr4AbiJ!Js@7?;w>N!N1tK%o)G z`~~s%_xl#Vr%n5qp+1fzF-1ig%k+c|#8sxak6uB2RJD&YM`v`~<3;acuH_{gTAX6^ zRTsLUUDl7bhI^xi2`BM4rpyj+=-{0v_>1Yo1YN~;|{eLJ6}@j74KyUS;NWOWhAyB-v- ze5$fM`sACcx{j%#a#k_PAe(sN1kuW%^XP!FTDPL?Q90#G|v%w(Pz8sZD6Vqi^*iuol8GXda&$ zLBeVL;Rbf1AWk5d%f?Pcoz+}2y-++<@63s<$A>vT@Mx9NVGnlN-*%$r%BIoRsFQ&Ja9S?FW^Ie#;`NhaNzS0Fp{UF zPY8N4qoh+)oGqLgQ%-1#S!;?wdGd5wWUwLF1dF) za@eNgW>m7XzLWkH%E5QiUk28S2?4~tU0_s!MAF4AtZUP?%G4JjhfUSrzi?9Y^pam{ zde6gRRdcyCa<86-z`zp{_yLh^QaloZd&t{kI_ry>=cx3QX>~0c{YldYU z8Lt&+PBC7ol(Di(KCh0a3^HPWx8xfOjEPS14{0!OP z9{#*A)YqHl;z6;XSd(tGkQT@$(4p{}P8iOH$Q3;4klLDHtXG5Gco2#$V9XEbT;!}c zxs;Q|vq|HWbnuR=6SEvXD5*x%G3`W^VqgC1)q)e>`)d~~gRj8F_kr98g8PWQyyEH_ zTs(pi`MwB8OR6nL?8v;%m+SsIP{$vFY98k%nqZN~QAXH4g4-sSn)>0ewu{MEZyhAw z%sYKSA3DJfC5IL(uJVI$z;@xtbGdr87omZi*`GHF6-%B~TlnI~VTj|)F_VveU3XqHGW5usSox`EUV)6|eUA6hq;~jvlg`?DpQMLP!qkR0 z34bNs$3Y_lykyj;-`stcAL1g<6ZDxGDdc*ezmA_2@4jGLh~yE=vQJn=hA;Dw+*eru zpd!3Us$_faLYSh*%hc@n@!45s@4+LXOPJG;(;1&37Xs7jNGB+^MKr1n!E`L8)tTAV z-q`gte{LYecjwa0b;k&+UbFKlbX3mc8=&jmqmUInE3w{$)UoFr53#)ivTi4+j2gN1U(k8TEjjkNM8^=zGyMVk*#gQClD``H+B#`Z zvw-k2q=_cqL-On54)xl_uHYqmp&O7v@sna8@Of9Se%O!d*M^LJ)Vb&WPw)BQzi{cl zz4?FSp8t`FQvDN#{%_osAJ}0vV7laT8MvTSZ{^*kABC2u>#8G?BQ@3f^S+HgKCKC> z<<{w*plA^N_vM#~mye-jPIudx`f6Q$e}lujxB8EC-chC?6_K^X8-zUFQIx{9(wS}i zh&*o?TV=S2evNiN^nEHVpGt!g%7mPNcGwHWSN>E;;uZ*j-7DNmXK?2#^Tean92*za zj~wTJ=yHS%1NZ^?BDwmwQD%;F719aliAS$bQ@9{=+w4LPjkC7aS~uUODA8Iwz4m=9 z33&qV!v}(>d%_XUGou$uRb>M(_Z)zP*;dEz9QC_ftyS-@-h0qleZ(!NJ3ya_Xxgcn zYTm0EdbL^2&wsBG-FCJIZK7B@8%RHjKdMSTHBrKs@Y3<#Ml^*ICzStEDWmeWQV@S9 z{#SDB0)7esGL%ZO5+X0`F*%k3Cj21LDaKV_3gElvFsBp5+lTkPSo&&mFH(bxx%|Z} zs=GmQaHyir>Gut}_X+uz#rf=XrMI>-7oU$ye_F5`oe7qFh;3k2 zA&H~S%Cq zPM=>!h9F5aXC~wn)lguH%qK@vz(cqMxU5Hu^5mbo@~5%*HQk28s^8LdAIF}U^Q3vk zFh-wTUGwwS9QOS6Pr8clBxmg%v&Dfc6!*+eZUHq&MzO6&;Mq`$?zrU=19#qs?&$sd zhhO}K?#$s{|Lz^C#bw5#c3(m>hJAfgs~Z~DgY>N=Eg_JU+MC9@XP#vz&9g+kH6|!Q zRA#pWE7$$fwZkhAk^l$eL`!D2ZZEkX&RhS+n7ycFbbhFhi#(s|E|6_Xo1mB3-$<@g zy}lwt5QDUXBET15c52x;jW+vRS=M#cVGKXp=rW4#%IS`hb4;OkrA7~4wSDhbcL4MK zE;F~fkY4@i>qLEZO@o4`^;G4okXpScTsuF%>JK_}fxJK<6CL0^V7}^u2xM*Q*U{fV zUxZ|dyM@|yY*k>8ih^6IcznjSy2H5z?Qa?J0}@U=>@jYmHnS9Ek_Ipk%wewN{4%sR zd&KuUGMa^yvKF7$+=y^vsB4zv;3F!$BIs^;&$IBLx$G5lkf@(1AWH2efi%A z_Dv0ixm%M#@@J&%)7CV1IU5r`KY~&%$_}b2d;W-!V{rh_oaY$8 zD*?ZBp0Kt?J6SyGukx{q46=+or#kK~o$V|l`)lvEriku5A9W3vs9#+O5he({`&zJ8 z_cY{^3|!n(P!!w2P*{z1=21*ukWWats;DCL-f@$m86)zh;o0R8KmpsNj{#jKM4oiD zNVOo1Cl#*eY;5nZ55CuzkMdKg8XJ+-pc>TPCKhvoA0TJ|64PPpcQ`IM4R$}>E3k|i|8!q!v(9}lCR60O zs8=3}Czr(JZ(SV_&>l^e1E7WEv)h=e?jK1M<|36EUne z5sI5y{i9-K2pz3=Mb!94WwNwGS?+!nsZGp=_@0o*yW3eoq0`wUyX~^J^uVbD7S%MF6jMpjj=BS zrak%ht;Jl0&#DQUIH3*-1E3K<{~SBL$BWI=uYQj?=wYf!l(G&UGq0$HDqtMS3t=xh zI4Zi~8mjXjZzmM4vk}D6B%U68<0!(tjHV4yH4-a^J9yLN@`^R-+pI@&`_hADrDy|A z`ZlA>uqMd%qT+R`J(n{?7lfV!oD!`lFerIo@>zI96cO6Jd>$%VHBsdzC;IE%gNjF^ z?XkBHRmGP44R3E>=9NB&>_-yBfTxHv46rF62ORs-6bg#@_?_7#TD*`uS&U-xL0i! zS(+dPd^SdY_}~rM3pJJl-RC{!dO7LVHO-1(z&W1RCnq%BU$a8E6eHZT?;0dt{2C*c z;N{fPCnNOW;JHBd1c!J# zdG(1*8PD@2d=1q3m7=ziD)Pb;>$yTl;yl66|3`SukIg}?N_jBtvGtgrRqxl~E2Q34 zRW;dU$k6sdt|zY<_Z^XT+vo;;G~4oLPBm75-aiCBnb1h|vZb{9%xV?{muNSpNjZkt zysAzptB2hA{k@xjulR@?jQGjyjhdJOE`bCEh#)-BCQYmbUXPqtN_vWec9>6d^yS)G z-@G&JXHBZm;?I4+%W{~m^+_DZ?3^?KolRe(YcGRPSh)%00yiDkJ72y9n@ip3H_tHh zMpey}(k|8szgT$un4e1fqO7no_Ynw?EhBs2%;b`**pW66LApe_d-5>Gs zlxcPyu0)x_O5*LjJZ_66bM@A1qHppt!eYS^fD#sg)wzuJLerBh&^ToL^y+>IwtIhR zY+HrsfFFIo$(L65e$e2i`u97b&c3aF_G=h6g7D^UGtL4ZimUCCnbBAq1ardfW0(34 zs4MIQ<8ul59v4Z>*x@fvefU377lowA<>oNJtW<;fDF7y9zWGl{h#CjGpb6Kf+du$g z#k%nnXu+=3|5ZznVUkw#*FnyZzvUw>Mh~xJmK|f(Hvzu93)v=v|jF@Nu3# zN`sJ$-RwbdAy($0Z+Vtk<>Q6|y*PW))2Bx*ADnR9e=at;cKdesr3e;zhffaPmkX9R zq@w^8RGSLe70~vLgRl=E(O?#s7lsI;cDs(dps!^*9dQ1(hO4^^Yxd1}PG6`muZQ%X zg-+&8Dv}HlV0+rc)y`SNdovIA(uvG4=QvDyRFi;e;Mt!~Q&O%zRE|Z5V%pFT4K+Op z_v6znyz10Su#xzUX$ngvp^&>Nf@2M%-{ed6LV$W~o^IYZ{0}!9i6h4XK@gqZE1{8< zMMWLsnPxay@CLuZH-Z);(t3`X498z+S)cK2;;qPEyuhwAV2?&5!*XHAKuM(wPo3eb zi~?3C;qtu}#}CW3&v3OWb!7(8pdTlD_pp^uu=XW5nzp+I8FZbR@q`xxJWoEm9O7?! ze67JBnb5b&E+~C#kW+KXZEjqf-aWvT;Gg1t65Mgbj&wNh^p!c4uBt{Fzx&r6Qmz~K z_v?P|6;Blgny4Q~?7B5jR~fI2nfxne>uCRVJ^t_Bz4YpdKSo7CYW!R7O|7Nb+~czy zml4-KSCznjXR5qSgWI^1^>(Xkb4aQ;6rx4KRi5G z5s$?p04CMTfSm*j8!&#~ZZB39JGSxjtK%-c7seDJGjuq>;Mh8d++J+_WZu&bo!@L* z0+B15Y>3(f%796h_LTpY{{WMxX`;?*gv;xWdgoMjxVE0!wD6!)e0U})H?dqa1SR$P zpa5rdDqQWjE!_+~lG3}HV)4%3(Lgszn3P0mK9^3ymmhunJNZ9_XsqOZ(kvKHO{gbY z5lrj|NuNC$WFl21SNqN@&UH8YdX<^med#|}L;_3^dFDRf+7##ROXzuu{g4fNJmFAQ zax^MqF;mplHw$7KwL`roU1?Dw#N-jEt5xpZ^q70g1DfNl2nh_Nz{0?HEjFL)WDhQW z;Dl&UrqMqPx&V5=vGdG49H*woM6?TBEcaj3(#t5QuGj8AV6+o<=&Sc-Tmuqd{!vx9 z;HBuNuJYgX6}cz#n;Yj3XnCd;HGbWd$ZhBYx?5lWcSBiD0?h+9KU*$tAq4-tV%%V( z^R$3Ib^2DbEEM{Y)Y{v$-+TCVTlNsCoAE@pR<61`cd7UAr9^JgeN8Sy>i=xqyG!TD zIdBD%A(k!%ew{$mk^ZtUigfK_mPPYhHtD(BOdP)Vy}mK2wRUlNKbKLE`{alccUJ1^ zo4c_YFQ{CURi^8~vtugMh#N9aL4m7{(_Y_;TA7txg+v2MH_{7WophzI=QtsdfR;-I zn1f@{|5uU~8z#7RQhhrXkV2>@0htD%9spD*R;-{JbW6a zN_eN6L5Gw|2kVkjq*Y8^Vm`CY{iPyY9oeJCdg6V_b>5U~umGF@GSc5lRj$aIX<+j@ zdybCRtcem>?!2Q~>MuM3YYiN6JtuC36N}a%6o!y9`1L)xJJZrqmP^H7)2_99D^ibX zh<{X3qyc?6HdM)mMyQ6aL1=>K1~6K06>Q2>AmiR?XY+<(=6ccPMzsty;f;a&e#_19 z^x$d0IScq1_izVcVp!H{+ye}s%12mCe#MW9%0_=-IIgU&jr zF6j&W3S|-jQe%T%$D!I}qO4EHNwPRri7zDvb9;JUSvAG0BJ3SokgYmj;$7k&01@+sUeXOAxTo-GYaYN0SaqS29(GmEm(WH#* zEtDOB9k+(*0TL7oUBWyTY~jV!d3OE7>{6+b!TKpq^)?NEpUCqoiZ0jQCBE{p*VL5F ziNHBwYCG8yAsh;*I5f8c&m>6`!&lgZZt~Y2tkjv>&pY8tAz)P0(<9Ojqi2zSVRtrm`r z+B3oJv?3~j6d#y@8Fn_tTXW>?dxw{Y7*vU8(TbAGbO$Y zlJnt{5Rg20w$X%~>^}tS0{j*xd99kp;6vU^F59Q-{~D%%=DFgeb*po*W@TlA2yiu| zXCw^Ftm=hzU4^&!qgh~@wXx%!cM#8j+w-nn#1wMdGDrKnsL#g?h7pk!r`FtF?O2^E8+nFiUcts)l%s!tY(o_r&$p$OSDghG*JiN*qd)8Y;Dnw+D6l6pq%p z3{`;XN8R@`FdO}+6`$^3KmPyDoiXVJV4}8;L7klfkNTM8OI=6;0YDu7Z~w{QrF9y~ z-Lv2*?ini=)p4%NqnRdAOxKk_)2*c*Ls9HW*o=9TlI_GFn# z#f}4+M{u_3gD4VLsQP4!Jf#f;jNEQigg#I8stiqVi2snszGU>A9^WkHdoBCptlEPk zVTsmrrsUmo45W)xKN#~wrVk8A+>V>JSead*2OXyTGavbAOs479*zy*Aw@7Go*)G34 zE*=^X!oS{jZ9wqr*vJ97B=s8tqa(?%<97G@deT6&=m$?RVe5o0QQHJR3bW|0hojBT&1nwPERcz*TBVg)sek zhwpC5mLai;o3fh1SrLN%(Y+5HBF~d@?}q`H1sJIA){t@N=W$6hg+@FL7SYFBzj&wp z>OHl+9OL!y?^?Z`Q|>&9_M(j|Qt|cK1zkcoqvr|@fjJ;~Cx>B7p2bLE(WYDRN@`+m z+V0P+(6|oypmude`cy0DXNzx@%{$J~?SQ)>vyCeTdqY6jO~V0qhA+c;tch<`#b(iZ zt{;#fJ~~`zKd(8xVaC4DUBPv&Ey?Xhh@f!KWM1ixpSXTM-XOKa>T8+*K`yj_m=iVm z#YB6&(pWF3oP1E8%@z$P`3NGeZEUd}_E@dmdK^&)*OR2G43$3uuoefRe2|!!nVM}o zMxBd?srg}X(`()EWSqgSCXqI{2j4ZRKz22pDr@3hLDJ7xch_U2?$g}&jJU~elyh~c z+G-))EP?uF>j!i40q~pc2_q{#@qek@h77a-W?fznyENT_4>Gb1PCGl>z-)jrjJy_I z!`Cxy*Yl3zs4lI)RzBrifkr9-pbyY(_jq{@x>DG#_iTa$fv&kux{Q~7pO%{`ol2o9 zV%-q29yT)N*ljfBQ7U!HaQw1&T~}YF!^(F_b$F-+5;O$yu6=}Jcw}2?MDgPOQ!(mU zd^p|3Mi4#dXx3Um#86ZyJz!q{<=8uLruYR%v3VtFb#OcLO@9oPM?@DsH zUcK-K5u16T9)luW>uDWfCOjMV(lDA(edPzZnRrK96=YfkxIBDls3#{&MRi*r#)%ci z>yp1W8DW=uklb*P)~i(m)?lZ{b?J@Cv4jmEmk~3y zKryFB6hXAzQlo?E6FR# zktgy7l7_5YCUG1AJ$;b9wbf3XLDas(7)c6aqi=uISy9KsX>Da26F)lW*Sv0e>eP)L zRBa9SVJGKXe>E+%GO1STb8Fr>cy%WEyn6ao>{-52O`bv4l4p6``e{qg0P-SuB^%9N zg`6Kg!e1oV6v@Q=(X*1Gp7<5MYxq@>=iOqTYVn5tdJkj&{f-}ApCxX#N$zeTR^Fk{ z!K}(W0Y@VS_|Gd^F>s0B?}kUd+7_veKW00tORr>bguaF4Yqi^wR#|Eq7(WHBT zlnUs(<~k;OXpik!V7r0ayiIDFG%h;sw)ZRex^}42w?_$J^+gw}^mxVnAI+RCbyY;nF%soE2;5od?Y&JX% zuzM%G{8IF_gH^tsdv58T5QxcXJ5D?*V1zz67Ery~i&v-g7?16{R5jLo@JhM7;+P`L zI#^0CJYlgVv+D}TN!K9pXlJ%0$~6K4$8*r01Hx{kd#a&wH9W+VEEE0f2A`P-T~f1* zl@t0A;8k`Q4-zAcVtdxmdqzMH{bNKFn#~)7AyMuD+FtecxaOfWqGe4v9Scb$HKcE9N^Oh-&5PN)1isyxjLXVE(u z@`Q#q%*u7D0ZrbjBwE0%xxEMIvny^9n-YP*9cd};Cnlyvxu;(Y2sL{`mo)AC?pPOggL<6?0XGc21+Cg2LA7@mC)=y)Y zUsry954v#-u43DrCQ87VaFAUb(G4b8G10`misA|`)XxOym7J@AoHp||wpx-;&JQ2n ze0uRfO1MO_yI)-u*TZM86tyQFTr0{|Z)^9yqT%F2y3L}$V(?4fuk}u4sR#a(XL!%* zr0YlugAo?8YM%b(H>A3-hefhg@D7fpG>H9oGV{r@8swhEW#jyjbiqFkQx)PD!l3muuo5hSzPl-+oh;GR4^%WFaiM+&YT7oPB zU_cavN=+F;SysD-6U$z0HZc2vdojMOSyx$`vM!ybqW#5fO*Zm$6!XF)vXv#Fl;La~ z|EUIX0q__45!Hs~29U(JjqOtns@DB6=gUj&hq;+sKVh`RI-K`+O!WBd9%XA;WaZrU zvI;Ge-172&>FN9J=~k`Mp-pQ3tAMFF%1clNU{vH1f^a(EC7i69jYO9j>R!jC}C-x5p#j9HUfD^%xN zSW$ko$^&dq0t9}IK{t{VFXn#h)3g#(2{m!cZFqdi2=X(j6+sXWB5^ta12N2x1SZ#m zy}$y5fex+i%xrw>`tP{&c+AGq#-Y-r6Orri_0y`GgM*LuKlXBKVPr@g9e7#7D)Dyk zG(H(P-W6sw0do=WXf&TtXr}ArS<=VM_3#Y{U%zPc-7C3Ki&&s@ry^=WqORVGL@{A{ zW2458t&Jf$6|?ZQTL(;)1h;+<8|KY1rZcIgR@xjZ*}ih2@#_xD>YjOjsLintpN$@$ zNZWkwhpV^5g=x5Y`k(R2_cs^2XQm~*JPSlYrSdz2m$`b4rmwQ6I?(rCCEu_i^IDCq z)HY1)iPgmJsrCw5&hnV9>_1RvR_2fYQ|PZJCsE#VuzHYG^_PmJXN`}{W*DxWC1`h? zHYQc+y%nRos|>Vz_Vw`f?{Mi_eSA%IStO@D(c!XYfZ8>zVnUNJOLI@0eCVFEO8z2^ z-FzQa@+-rJgpRFDvMH8rHwvp_4_p-)pbuqm;`nsFr$Id7%cz$O?O>Q_rH{*pTjA?J z$V5`7Yfh8#2F)R3tY)%e!ph!=(oRx8`XOM`a0l^yy{FTFeg@uZ55ln~7mVa~kn^Es zH#gi-*}W`R28Y)(g8eSD1Hh=cY^DOuQTw~^+*9soR?0QcN5}40c=7`MmkGo}FX#8Y zf2qo|On3iMy>YDThkyRB;>7ch6NR2gWQ2(Wrx^|(zp~thiq9-B`RabxB2xNKSC&@F zrA;}Tg}HXFj4v61UfD6!e(!F*+}wr|jF4FGC^An{43cmTP5PGmI}l7Iff`?Cu|%}p z*+n~};|)DBp)u7-(KQXE9|S%tvkWf_o#iV4`w?-~ia#Xs>CMm<7xq2no(*zs1W7+Q zEydb>+PM7lhKljKMur7`?j)MctGI|EmFV`|T2;+ez(_*F#EZ8pGhjG9_%%=1K5v*I zn{PSw-j+p^!U}{hc*vWt?d%@DREih2F}$Qh%D=bln4K5iS3oDJ32%dGk&`I&1WyWm z$BMzcxWRb25aCUEFy<8pey?0aRw0vV_v&k;l=h+UX;|dSSth9fi+)4$Tnovs#o8ym zD(O3SkovsrSDiD&oV~>1MTk80fRXvH?=6w1RrODkz0F8@48|g?tanm(KH(DU%Twl8 zPm-WOfzb11n*-3XcDlCAdI`VEysF5X&P1%9AGV?4|4DaElgs#@tmnEP6;O8mzuSd^ zIuPe!cW{p~e1g^txXPn^_!~KR-uBhsV%?jiDSxEmv|uzymuO_ahXbvwC%vw=E_Lnc^;@o==(F;be6n13267J-IGfx~mn}Xel z6Wv}EDwUJbl3h7hcOrgIdDv}(X8nfbZv-_-ju0yTW(6<`oZp$bHUZU7_+-wQf5KY6 z9{z$gm_{{dSaJw19xP-KrFM5hl~1I7#j0WN9kaI%*WDBq{#zr>{H-rc%@dP7x$$M5 zE_VX;ZwNb;UwZ8c3~^8}8{UBc#mKE9*vnD)W7t=xPt(Kl`~QIy?T=RSwSY(D%~tOU zx0?891)DHgKR;L@bUI89Fhr#tN9?+eqK`H6{V{;2(>0*)yoiBz_X z%NrzKIVY+2R0e;ics)FogGQeA_38_~Fax{a_awIt2%;A4EGnyiseoLGpdU~)8jy6Q z|HMZ)UI)*lv98s&S3i5GBq>C+;DE|Q$`2(LacJ%-TwA`0FHfLeNTvd`a+!usGSA-hnW1LkZVI!Gz1G z@h%UYlR~0>ltuphPxVK=ceE z4?vqhjhZuw*Tx$Bo&Fy@qU9So6X9hr2gYlq8-i#8jtb^I@~`ZVxe3+RrsnmU&))cM zPPOK{C-Opv`>>3AB(~kKbIjl8qDlCoju_BSq*LfWjBbOg;J`o|J7Aki5`7^Rkj--@ zpgZgscQtWiu`_y}pZobOI%fKN^j$A`dysQ_YluB%OkI;FZlsfQ=PaVh{-KnR7T1fO zPkV_Hslw_8;vVri^(fZdPv5KTET>=CZdvK}Z>h!Xr@!-4u|A`PCnMTK;lhAK5WKgz z%EnK6JS8PBaAk@`|5eDbe(GR_EvZHDIF6N1+sH2AFBszbZ6+ej!G}eE$-8ELU zH7sW*Ff#RzoNBW}c!TH&QJpOe1SpPbVD;C;fr(y@o{CL|QOejF}!37D4Ck8mnOq-~Q+S5vXkzZAj&|9|$MMTm$E-=3gx7X0r zyvfbz;}ao|YKeo`uN$x%dnxN|)ik~Y6vw;a>!8!h(%MTH*VlE#920F6g8sA{OiVN_5`wzi$g6@#@bEt)Cf z<}ssLEYy z0l{o>@#%M&QT!=e_%y7QhNM>iY0E>mL+RZ+J3_8045!=>~bv;UxRdF7X=^x`hZFnKOI$>tgZur*p>G_l(b3Hhv#WD3| zidVmWZ2_6BV1rx%c2_~Z2?SMoEypZD>D(3B7iX;cyu6RB^_e3rmzWBo7dnk%=GXh{ zj7?!*!;j4YIGz>&ro-ND=gL~mdT8)^LT=i|RQK4@UUH;Trjprclxuw6$*|{Pk)dde#ye>ca} zLdb1^ZrxRf_r=rH7c|VD_&M0NdE1ltC;&bMm_BlXF`{VFO-UIpm^xv+aIW2-?|y@q z(wAh$VKbzs(2z*tSV(9z;~)F~xE+;~AR~F;v}Z88 zMqv~H^4w}6`JJMxO|@FjQ=B-vH*Ws8`Orl}@g@TbME;C$2NrFC zREx)Wk*si=owaJ$nkwVFo{LznM$$g_X4hc+s?$j0V@ms7k@Jl`7r+78XfZuf5U^~! zu2y3~><##)bf~Nn*b=q8%#2tmhSajP0f2xtutEzoegyv{``rAj=wf#DMB1nfW3kAn zT&mIQZ|kZ5)?;Qo6*eRs;QWjU{m3f8;&OwawMz$>iD~0H2FbXO^s+TQCV~@lUrfAP zKTFu?KvLmI8nsgb~d8Nf#&vbnyUD6;Nh> zkH@nyNlNI5U;pl=vu;rn)va%|A)6T#L~jY09x!D8$Fl!VC%0)yaF?b?YRc`GjTIWA zw^Ck?89g=!m!p6|U76I*HV389vtec0z*p36xI^fV=ViD(YJYCeHR;_{lR8mQz58hX_S*6?k0|27x5%~omKQdt5>0ZO|MyT3_7H?--%zAV7 zR;AgQC6n;cHZ7WikQ>^AioQxpcs2m`nkRpR3j-Zmq<<349daW~8+Omd?a7xFuV;Fa z0GL~0SMP4FYTYH5+XWs;p$aZYRiu8S?Ye8Rn?Y2ijDsr`NgVU5HHE;@$CcQY3>+`! z`NbWIFpe%-TG$Fc@*?Ls17m+_QjOw6#$}OUr|(S>Q7MQv3pD|lBd`KY*eilCevq7- zi`~!05m%$4pHFzI3DjG0Z2z>S22n}etdPIG%lG#ArSi$-G_+a^EoBmnH9*bF;n}gs zT_+$0(cxIXU=JV!JCX1Xd$I4enK-ekba118;`Q$j_Ou=uUV0Q?&T8IbK&~rCuY3Tr zw9vXOp9eeASA#%=345k&i=NE%xiT*G#!4tl<*DqCXIEW&+l9y{&lae__kkj|1YCJY zSwaAy8o)l5tPG)3p+pV$v%nbG&x9TK;s?Kh1{llS)QNRJs3d42pGKqbi_){ z(naz+)Xi%X02wz#;Z(E#@JpepHf@0F#sJBkug{Y!IXRN3%*>b~xrzobFcP;0V7T}R z?L4Hlir8}xt+o_K!X zI)($5kyhlUYvc-5uk$%qUpXG0lC(JP%z8haw5%TJ*6I0J-fn8H^vsZf>esm+fV+^& zBzUFR{xZfa=~+aVXKl5C|T#4BXC!}k7s=SAjkMl410G^AGOI<)De*= z54(w5-UWgcZ73lh@UT@P+;hbR0>DIyEh;MI@Q-8V&$9AN<<)x6jG(J-Yfl*~wJZ25 zN_Z8TOG!Wm7w*4C_<pwE4+(m8uL-n4 z6}bBcV*?}B?<0Svx1%G$Si|K6^aZ%|Kf~6r{3JThCH_g+JwNFz){jp^=lQzKZ@}vE z7 z5Y=r>yV&S?(x8c%e~=+)mm(6_ZgA(>Q{i6I9%2)(Mg(*K9JO2>)T+-$p?|-Inq@Mb zehj(z2PvRYYPAJ%se}GMJJq*(2h`zrrt#dwP(;5w!U;vBCRqHXdZMU6dO3X@L$rl2 zBP*bt|G4I503~`D4C)d)X`@h$HG#cQ5OU-pxI)h*RJ9V7D#9e6#Xecdq4a#!H~6!; zS~a-_y;2RSLhWt=_fDaOz=ZXk*BOV=tPTbCkDH8BI@r_AQdSKHzA^V{O8DJs5^CWTL=f5Z9PPYbL+^T6ivEnQYCd#{8mx_f$P{9ntBdx>_OexnYLR#v z@i_z#(U!8nivZ*RuFX&i2OFzS?iSuN2=5v9c!=uN&iXZ7Z|H$oLuIP)tQS}L?PTQzQ;BYd^Rc9-pM!oVCfW`ygq0F1lpyWs6c$oE*NBxQv>@0eiN~{Gx(6;dEk8fR_n0Wv ziFA)-D9wCylp^-#PU&ra9ijJ$)V+Ox=k_EpJ5oduZNP1CU7pQrd%4wws|}O+bGf=% zWw(}{oTmJ>P8O+*v2BILN|{>yAjeXDh< z8mR5cdC_0#>58nQ%H$OZYn`X5*~1vF+=4D6WM3H#zJfsO0vxG54R%&3^G9{+jqn%z zU%lb05Y_QHVlbR`vNNI=gnul`!DHAqwdm~k#OLHFW3 z+r^pLkr2T=&x=&IKh)NlGi!b1+6`V@fbE1o4!j4YFa{B|P*gg@Z7068VNmHgXxnm^Ta{PYpZn*hrv1L+RE<#&+L(=td>N=pT|NqB;tmMX z5E8cmK7wFDd<0V`N5fgP3Vy3yY8(^#f#bsTUq>lCnvy4w#txOdzIc622Ls{_;MXTl{;bCM8~H;p9X==XCSXs+5C=|FkPGxyco??9>sW(|zj34ShmG6p z$B2hiuqA-Yp$#T~rmzF%8dyV!00~OC{4LwB{jA?z&o%UyzUM}km)aZyILL?Jw|rLE z<@BBF<;&-X)h@u5f%5HtUe5jh;)B#$3HDlD=&**KcB{WsA;rJzC;Y#| zafVNRfnp>9bsSwjEb>0xg+_G5k}7g_BoRPXdDJhbEIoc4H@ONI2xVTu;!YCS8)n`LQpau+X2&A*_TdR?hz66U_Qsk4`n^3b8T|3zEW z1Nwaycp6M`3gIST(0(>~5GN0KeC=YN+qKnB-}OX@~MP0c}K6b=|YtrNc#6Ea0(Rjg9iY`DRp8(Xc!Muy#c zznSD_74-G+uWJdAf+hC`ei}QQ`p4K(_GB(~fy9zV>IUE2o=4%GCzPubr28QVOhIz> zWl<-eO_p*I{)<|ddLBDC<-ZbNVT)C}IN8MDzG@)2GZ&c$S^U*C~ zX@n-p$6g8-)SVgB$re3V7*|yk&ok}aVqME@E^o@L{@cde0Jsp!AXY?g$5X&PjUDm( z0s4X39hf+lElEwHdu}97Xsnv=<7&js%&Ysey|x@X1A!Q{%CSw+%|CH^jgj+!arN%Y z70Gj+a|k!2KyXm^GG|t23u~hyPdmMt3nT8`)~A(Q=9m6-Q9pYbwZ~TM24ZWvTtFG2 z@LM5wrE7yY2W6XDHuwxQQht4Uaf?n|i7?fYPpHQUw<5VISAL%@?#)DX&G|;VM)f0> zwLZx%@w(b7(bf&HRv)52qBs9iO{!ZZ{Xd=>LmsCc4a`)@H#bO?c=Vrajtv`?0lj%; zha5WD0sa`*=Vr+t!b;h$h9_G!PG#eo!f`!a4-q3nC`z);&!20)r63N9Fe*N((;0W+ ztLg(~$^@@3xpqGUvU3uG+@=^bp9F7p*<(*S4`S?ja8k?hBsq+L!ILQ&(nvMLdU1ed zkm5;)xNYjNSKs=qPuYQCqiJ6))#pZtaCL$*($`T>U@%0j>Z2ff^RVzb0Ltx*ZIU*M z-UCZ;{nr~KR`P%hG5QI1T%-Y%(fW6%jS0wN8?9HNh|r4}@|K&1qixLIjHkpWb~8So zn8Uk|-Tan}17jB{I?`pIX5zIfecn2S=(%h)LUXk`O@hH)HFIuL-tvugyEERLRjfk7 z(>|Aa)@=9SAA`q%AW`l58qN^xhku`rd0RVxx!wuLJvvH5!)s-09AVFeG-vLl&?)?S z*_`wi?T(DP+mqO&oIm&5UKyMJqj_R?SD4*;JCLze$2U1qI8(?^0whV3JVH}Yz#=}t zb6OTEUv1u!1}!w0SO-Q~aFV&gbGnF$)({0#slbK+Sj z)@~FgTd!-0^Ukf_>A9~gP^HFah}*Zyn9qMJdcfM&CoIlo%a$R5S^xt^8VmxiM0H?# zR8!RzVfmj4H4B@y&o4!RAb-9O=I)&i?ND@NH8EQf!*rYWBz=-%a z{Aw6|VK7T_gPG2>udL@Q<%wT@uV?>s!EA^gzld}BxyfgMA`t{C88rQ5Q^`xt(!%BZeP2QG^}-o0_)3~R8PyHAN+1e&#$ zvTxhIg!xWI{GGeqSw8DbdREe9;`PC6j9DiSN9p^d+v-()>{rWyGgU>bqyuxW8WTVO zydfHqjBt?1KL*kE0+my_VN)}q&3XF)wy&>U8Azzkj#5=$Q zaZs2lcm6V^8_ZsPaM|-cBqV66p*m~6i@PwbXV5%U?|BWjTs0H+r9MAdf8mU5fHunvcn9M)@y#EIE%?d+9EX=2I2bfXn8P^J2xjryNdQSQ6Z>zAXN zwD}IeAC~~?=pTLb|7l~-xxr&=I^iH#MQtA&@<6%Zzgp@iWGV?+7QQybX8+ebPP%wUfsdiT3*o!K7q?MrGuy~etyO}+p&Q;Uj}@!E9o9m@${@3KOTp?pZSA~ z2Q$Fg0ce2!H-fJTyjo%hvYRM;t&6XC();DBze9<9g~P4;IXWk(9Kd*}j+!tYQ0&3) ze&;SvnOc#-A`kLefLG7=g@LJ-A>6;#8Mh=Z*p;Z2spc;PrpMTO72oE!L30&lO|*L4 zsV+n(6>gE*;ZlZeHr-RY9=I}4x@fJI=VQSuXyK*zG2J1t+beopuBoLFanS@!#bw6F-z$wy?S4%bS{>=wJaCUG2 z@@@l|iFGkB^IxhZpdve-4uYg}pP)#boNERh0ECMFg;ng9iNBkU*NT!4oX}rielOLN zzByytj%<7*l3Xbgi@x#6Rh)_wqBc?lb|RSp4}Jhal&DXcrYJR!f!*$1*fE}Hy8q4N zEIq2K?rHtxO-u?d)6GhARstt?`go6r`wWGhj;8zsR|maDxQ`Gd3)@&^Rv+>j1^cyH z??Lu8(YhHPXqVO{+AzqqI~m@)}P^>e68y*WjJ_gsRoQGkIEiZTtREr&0<0h+IX z(AydhYUcvhCrU@ZCu`)6K(Cq9(}?Y^+*$*o-<-)BV)tGM5M$&CP(YVMi_=E1Y+K{g z%Y(}owoYECWdwQpa4zT?eTK*l8!X+58gjbPi-_@kO_anF{yoj-!*FbSA!~N7_!vSV zW|6M@{i1q+9*f#geof?k=taYL`BPu!r#j>{UxS};c9=Oq9~;^QuI2&(K&IoOBeBaK zG%X{)r=r<3Y0_JlvyF3lWN|^_1y7I*-2g~pm5>%`sVy z9jI!_`{{W?SBWRFa{M|xT-9k$9?*=G1=sE-e*@lr2kc@%kYGjP9?fGCrlVCERiSxBsX<9EG<)aJjb1ZTwV$l_KeH_)agr3t#S})$9D=He9Sbnzk$Kqg z)tayzfeC0{3Vq7c;u~!~H@|#k#!$0VcU;VnM#XO;H#+b?$e$3aX^54AahUY?TB2Ga zMg03j)$1Z-@Gfy{%q>}N^67$uc;h3_?iQfLzmI+njs~$SEDKn}baD1ctd&K!OFd6r z%a*jf+}`&NfA5TwFiX7k;3^f>XCFuad=^r@xw}O)3UqemIr(5|@JD;W0hQ zWJwJ#p*}oPrTFmEyS5v^AUw1i zXbH3!y18PfvOf0}S>DX^_bgIK9j`a^RlE>3TSpbfb!JfrpS?RxVn+i|!HFMkt$SH8 zAVDm&#KzO==B~fwVU}0A+l@oZALkS6FSIz5OA+47v#zU~yBXrUEWnsJ{*G3=GEr#N zbRXlTshX9o=We0I=aigj{?JNb?COug4?lLF7tw7Q?6MQJW++1ttp4&WAZ^D9KWY&K zq}GzlES_p^#$n?|lyS3XQmxvXmS5lfrSh>1LXDtaFJtxBu_Gj49yTOg#%SLO7GEW= z5o&Y_!40pja8%Aps)l<;21Q?_Y7(>Y}ZAjh*U+C-XhWzr1v7RQ4|qD z=|WUGh=@{xh6GT02}MLf2u)FG(m{~WtB8Q~9uP!YLJ6;?xF5g0_P6%l=i4*u%sO-C z%$)Uu@eh$VPr2W_TxC-cG`B1_pZs-r2=g;>$(>Q9JqEJRMZoPyMq?-_&#WSO?vn18 zf#Q0$g=DKq;WXF)`1&w;l4>Jd4&Vzg2t$W%i)B3@gX=y8Lxk@sQ z4VK4y=A1-2jP{ydp~nnblnO(w{nVq-tRwm9D3_nQ|44D%{^=V=ivrzM)!lcTr}sV{ z&SZE(oT}vB<|mB2kAaM5Qo$xvJDLPNgaJn>ngVA7e5?=-SM{zGUDzu(ElX^_U8P*M zeKF-6d$Ne^`hk@CGw}h)${TQ!89w3$aSv;)N-J3Z+yh;>+SAm8^DJ09)zBz70`Be=8#;M6*aiw3d!fKnVm*wM3NBb9F zZ!djWv{|QB#=YefylSGrR|`Tz0gZ>FlRz?4oT#3i>tCyx?_)XpmA#cH`iSSlIqBjc ztRznJ#RBt<>}#);=9ZTx!{I3i(sjgy@I1>pGZp<4A;dTW68;H>V5VP^=<@hd&6Iae zv5W=Q ziAxBWqrAR_xS_9uX~(na1DLXpAD(Uc2W7c6{drWD!bs(gWrE;xlnMOgK><^pi`$%- z?T0D7$B=+x)jEffMxUn_i$nIrLmYn+wO1&u!aF%51ejhdPyZB>i3&B_z5TbDpI~qaLe6qdIO4m66asvPPjmD5{nJ_ zqHhthg@8^0IAL5b)QS6j0A=>;5;A4?w;=T{+6!`_o?{Hm@-bv+;@?2Qwxipp+REMf zaIx2?E=MIVKIMc~>wazXtSRf|Olbfru@HSZj^dafZR3i`lBpq?wTd1F@`QGM<86F8 zE|qD4Do!P1L@TERh<6jq1EgjqHRlQd7Xvg?^!XtC*@4_^gR_nvDX$yO?rckrS0nP0 zkYIqo6|IA%9hG6Q_RW`0XwGY7c*(SHCRlrm=v0#Pi(T%{c(pY8kH7Kwo8wWiV<#9L7;$nXp}c`mIg=^VDPVCi#jxtbtaDnKcwqJ6FK-M@ z^OX)u!j9fK;GNC2ln_JT2Wf&(JWkKYC}Jkl5Fg^K%sm?A1{IcKZL+Lpy`8-7TK9cC ztxtPwdj++0{>MR0>z|-2943wF#Q%fvew|`W&p+MZM1I(+@ejhgZ4uu;2=4~}3*kNH zELQ!QHAp3B$ABt=u;%)wd9Ii}hAKIirZTeB7a{EW!*`I?PsK=`;#CjI#{tx5i>qkaDtzG|M_5p;A36~khEboUnGKiFMBhRq-YQ%N8qV6-^&DDwIpXj= zTJe~EOZ^37Gsnw!xjKd9emg;RU@;MYWfon!^$iO*$ftlA7$u^rH;wo>}k-nONA zF+roIEmQdD;-ee!L+2C(Ref&9Kqz8Iq53mr3QIU%|~wvDP8j6L&xrsj+@4j zph1+1Uv5G-{By^4gXZ1lU_gz=4vZFnhllB*H+=V98e1O($Ce( zDr?JaeJ~^EqEc(QSf1Z-}#cKHqa)ITP2mcDVx2VP6g<)=3`hVLaZi30+OLhVg~sfm7%)% z46kVC0fo~e9A0(B7~2yG=HeU?zf2^)9D{1R5C7m=s*a(nfL+64n^hW5VJ82;M9~JM zdMg61Sw}Hshecoz{vm+K^Q^oLM9S z(32cz+eq#?UkG>oHh0EyC#O@Hj+Gaf!>Q`XqEHH6eYZF3@G+=)w3)2G+r!EdyZ>M4M=sT*B*kegYba&%&WB9dD-VgL)U{$19h8)*iDukKJo)<4G+)Y_2WPE*DCBX^t$$auDXyF^55h z=p9N`$F$*(jCNoSRSglp?IQT6SGLC5o$e_~%ln)%3b1xD{>J?&186|Q-Tn?!KqUqo za)9=>StQ|>;>5vGqFEb~Wun{PH`~NBQJxgFe%nXse(mY=MX^im4eu-7dN)sTEem}j zP_Xn2h9>6QjGj*f0;Y#RMEifQO5T~UZ*V8FUXDcf{HSGq=HIVQNuwQm%wWS4@sq9X zSu)?y*Gt>y5c^Qg0zdZfD z55XNdHo4$m&_)-&Jg~9j?PT`++r-R-X#lxWrPP$H9o{6x{fH`MV+?ST=8#JgP!1N0wQ z5w^>2l~IpiJoVbGpnzFc7@jes&k4OG6;jZo(Kh>Dl@?2Z4z!bh@9$vq{;YXAtJH zXOut=Wki%(j-+Y6nOHINb~*H^u*lojg|qy~;Q5U}-HHdDr6Sg$C^H7@GF21EYnaa? z!I^J1*4Ms3Dr^_ieLB4|aUdXipwxz{uUqsS2|{7qg6*5Lg!=3PpDC8tCF-#49GXvSTr=uOOkScDTJ@CFzLPE{a&!S^RT0{l^{L?ZKsNbx1 z5GrvrzP#)77<~h>RKW0}fl1I)#;!KI(P!;dWaW%F zxC=VKaZmuhp4_#$oWgooaVti7- zesO04mOTG9BKbf3;s5P{4yd!OUWeN~-OXkdey47D`6H0Qg6(3T&Th$~L5IEczsoJi zsZ=%|OVm3BvK`Q9C4fe2g-R9IgOQejOR0Hs#%{Z}iKS2VPk^OM#Wu5H1pBD^&Gfnj zpU}PJ2~WGzg2`LP;w-hQtfUQU`MY#8mZFeN2 zs1#qa!)Sy*$5WdPE79c1sg441*Dy=eYuNI=9jOPtVO|?tv3SzWe(01>2ZDJDVz~*0 z($j7S3&wn}jFo%L5zQUJx=lPM>nw(@xk*3CP3NN>fVSt&a7dDGX@ZX)w_n$JpdX6N!%3Da*gc!?<1$K_e;*@c9r25di2hnY>Aq>BJtjg`5mh zT7|;1KQ%r`68!#rI#p%g_b_GnUnL9v5Rl8 zuN%e1$WXSlwkR~@ya^MsTQgiQc)$Y7Wzq&ch5R!IXD)dA>dq8@zT^wpq{}1Z488qsgdJw{T4e{I@k+1?l_8Yvg_&A=DnY6i}T)<*(`G~UZ|65^jFgZ z;f3S%z-Z8O{I`js*A0fm2a1+8MktMz&kk=%KK9Oywm&41`I+O@)>URWKh~3g!;3OR zQ1E$~c5n30Mls08O)4@{Ucb+WWvuwSP3jO@Su*+i?KoGf2O6XxZP;&X2HUYeuv797 zC`+7p;J-OWcX+AHz*Y%FPw*OF9dZC9%MpKCB7oXgkXh!;+CB*bJ+sUURJk^cSe^YR z{mq^PthDownVUW28ppW&$JSrPnCJw87cK%>iK(aBL-6*FP9lFa-@LlK{hG#upjAKf z*J2kF)jw{WELe>9O;A1yx5PH{@5-NFWw4KuTCdl>oFOh)ew(mm`}L~Z$-g0GHsEUT zL*xep>9Y16u&f;PJoB+r$v#5wpLCc}rdXIr2N=AxavC2rPc{Ng(c*mCJxKRG)(OhH z@cdFyDf&f;UO}pmhW^bJNz-Qm0?rb6yR`;+sx4!{k%gY)L-6cpLA_ZuAv0cM1K&-1 zjueWR%J)%Kr}(0;owqOykcX#z-;S@{AA)#9n46wHW&^Q+IB|g7-@F-@&iRo)c2|+r zani=lvuh;TMC#KwE=l%s1>+w3fQ&U(FdX*cuA>)5$)JjrBs@;W7eUbzS@khfb^A;k+{cX}s9YaU+g ze|ytGp*=<_diIetXVEW?)SJiB|BgSx9K7&l33&1#1wP5&CbSopP8`#WMB8T1^m%Bc zyxVWMA_V)wI}D+Z6lE(-d^Xy|wQMFJ%hT2z$h-tk&|ia7y20z(y>OFr%t0}nrs_WU znMm9~oO+d0R~zr*{xWZB>9~sRiv@2OdVwnIaC00CJ4xoJiY490X1_dr*DNPl)6@Fn zMq==}(mpfjMCY0V=?P_tUXe2I)2S_mJ-i~MK2mcgPBkNt;1zTmpxxVA!}SC9#w;m0 zt%vg#56Mu*=y_=6c|vp+3n`%CqvI2D!2E`u*{$c*TgBsUNiES*(chz(dbArMBT~%+|x_9R&5(FIWuf88KHLj~~=af0E6_IM9O-q7{xJ=03tnH>Mxk4ElF7 zWKDha;|BFk%$g1nV~oHJQN36_b8}Wsv{1IZ@b@84V8cD23jtn^VYL^(e1RHD*BW*GJ?f^_eD>Sl<(6zws@zfj8l zoZL}7ueDhA)xUTGo#u7d)wWpF}kkDAW}JJsy3Di3}H zBS^yO?e9}(ZAs+bS5f$zl256i7!W58P3;h|HJ9k|FnJSQMO zY0Ud&8uHcD3kAn#;nm1W6Fo!r=R|UBoRzGuH6=dK%H|rL9m}{%mRY|J@|~~r@-19`4;lw;Ls6GBzW~LhVwj$uBRCit;BF-&uq^uo-6Klaw@QnJR-e zjwH^m?Gfd0hrGVFeGSfKzQkvIGi;!j=RLXS>02oW8)qgEVm3vc7#yh}EL|GWb8uTQ zgbL1l8h)zM%z16)YGJ&i?a>Y+Wqht;+tu#Jx&?gJ#`t?$SVD z$+o!G$PZ-6CUdbX&X(I#<=uM4Y6Yhk%k=X{HlLy`OQB=!kKE#Er+g`<*A43=CJQ()ydt@^OdpiP_iHl+zdGA9BXUT#~t^ zt8%Hs6o%QL`9Wpm(T>?_#kDhYvvF9aVhsDrgmk^9p00EHXPwmMa(O4g==DLZ*OfM@ zC-!Tn1w5$hslte0n_cde_#oyAumZ02N%^;na`$&io(>?(;OKO0+-o4F0`?q(!WUJpOZ(0h4%*@j&pfgrbbTDLIx1y4*+{ z;g~-@4$HR-U-vnR3d2^;&IFmCTQ&))Z>TkwaD)k1GEIaa0tj>UX_|*fX%y26HzywK zA#aE4h?8y+-;|lYg$w>>H-qF;+qN)W__B)@x+=JcM6CnKn(EJArtE47>JI~7)KN+y z^owfZfjKsS(O6x!uO{iIiN)uNSJ%`~<>Ss-I(_CgbZ#>Em9MZYl5Q4{{3~!ZA<^Q< zPEzbRgI*P~ZvCX}=fic5;)T-hbdDCebLOjo@TKqw<&PGdTf5!bFh0~F zbVO1tyuvmvC5y@ZELW2+(%b{TRV9`O^l`%fz`h0OFsx{9R8Phb_K2TP1O`sVM)yq@ zG!Ne(J;gdz;izijA*H9-Uw-h;`2%xwre-alxq$>kg2{vMiT7rcu8IQOWF4D^$PrAl z%V(@B-wUc{62)g1CIj@28u!%p?EsO3!gt7Na9+L9n(wAQZ~FR@t*oA(fAGcm8{Ai> zaqZRbC4v)Lih2YCkg8QcbxDF!3l)(6z%DkBGt*l3aOM@HH+a=n{bJuU4GBC!29gi- z`^(H7E?hbh(KYu6Cg%v|Wn`nKSs{6ZJCegQVzh%#r<5`!6q#~ty>VM_RJWp?f5D6mZ8E4Y2j$I=u9bR|;09%+_2D$i5E!$~UODGe{zScqvnMC8 z>qcS`j|k93xbqMG!}!1RAE4DX0?EDAQBhP&S#X{gK(aHF^62J;NU{e#~U_GxG3myt#iypUm3G`jTUI6r0{Q zcP(;PnO1nxEUiH1I9zYw{|4md2ABYv(U4rc*wKGL7{Bo%IyQePh{=Ki_a8NO!4WN1 zx+l?6>nG7N^rSwaC+(kNkJ()R?#N}1J_Vw8CG?W$!|5?2fjzoX-FdA#X1V8-+_R%^ zZ{>&VJ1*usLr^IE-DDPn*$>)YCap6H5bo_E)vHwAII)L@TU^RSVM7V4d-osT`81Wn z99i;H&v3w`7?(jj-FhtI#&dpRikH`{(-w{)s!En&MD(dL=q3!_C9D8;?iJz);|NV- z7$Z3iJuxFZxfEx5S~)*zEh8*5KhD`rORIFOpPexVukeXKW}eYHBU_VvMtW?md`y`W<4xvUnHxuw|3=K@r?2$#tp{TR)kVZS-@|{b9aXo)v(ida$ zHzvj;Bw{FXEdMWQ=gEu!&i&rwgm>(SO6^rDuU$Fx}VNFRUbFJ+pH|NNN-BY+t)+p25^j7;`l|*!EHkZ@QWBsPG0joY=s6^!e zhbPPsEe_%5`ni81%M?4$$Pgo=8{|Ak`5&>{ad>R-DK>u9$}(*(=hKrg{Br)Kp?fVn zlE->wbPWj}a;_H4%lN%!D}6e!g5xwLU;*`uxqdZ`%ogAG<@DNuPv|NHK1Kj%NlX@Hr@NvZ!WVL2HE-oD#s;5}Wkrzx^SL+!m=GD;rosc*20C*{PcK)Ct?ELs>x7;l;<){90ztAi+m>IdQ$_??*qv6oeaPjI zcHsl->hudVcM_u6Cw!J(2b)@9V;0hnh8m_1usyA6tRVJ8m_-H_23Z-u9gq4wUrDb z>f*H<2GnG6HNDqflLSMiOhSK!=DMd7qWudIhf$ablS%q{)OvC8yv3G@S`jZd&x5~` zCyObLvE;%z>vqEUXr~2D4I0gvLSb)4oLu&@k1x7n5tmme?(Cu$SIC`sZjsvt&QV+y zI~$!PT0z>SrCZV_GIQ-6Tk$FruBqoQzmN@-xE;Z&Eoy+N1hmL9pLJz2fx+%aD91-P zpl1+dhwqtr-9&lA(KV%J*XJ{j`NE`Aos83tGiwELxjwpuk+n#h&_r6Bx_GkxQ*x;Vc{=1EtsdjpHNFWc%Pt}{FB?byH~cn7M@w!sebt~ zJqGFnpYDXvv-_$xCxj^)&^s3(AxcVA@p`U2K~LTooaTMG)SMa(lhYSGcCx6auZFji z(T^lu>5~D7w0a-v4FD%|z&-KP0+Uq-``;p|tA4jrTh zm+{n)vvW$>C-JnZ?81piJ13s$eXQwzkXWj!V#rMPoCUls}aD3Ix36{=69|C>$gQL}f7m_S1ZUa2GkD(%<@=0DQg9P@$_NPa(_pPoF-;_kEfO z;d4nJIhj9G%WNNTZn;!_LnxBQ2OKRgyhEANBoJ*LN3|u~(|^kA_sCTUD@?H^!+y5D zO)^dt3v^9{gF5a55LX#%fY0M5ohWeV(p#eF>dJ z%2?d$(g$Oh^i9d$+DnT^Inwm5RI*L@jtTMIx?XhFyZLZuXDASU-i0;s@ zzflI`9PPn#GBjy+pj)CdxqxW(#%!994f6Z%r^o33vb*$fNl>q;<(%}@-TTd3flTSY z_ZHk}yl%h(I2+CEPwFHpCgkgg<*9x+ZR{7Qs!fog**j1)cE>R%YU}m$6a$;vHpAzI-)!*R=CJnr4bI z1IFno(C`92EK8W4*>Jr$xUjjAJKZZ@#*C`RMhTK}bJO=UtkA!baDSu8E$)`N3-vPE zYp4-6gXyh)G}6C+_NRmu{t8u%C3ueYK$b7AAO3Un`%&hF0_hiUpdnC=r{&C2oI!ft zXZ8nnA-%d$ea3zTbY0Hyw0_(k`qJV~`*O z+y+ERolS}YUdX$ov?q?XYLB@p&cVmi@0j4#C2WyWxZj;%h=+|rc;Mn^PC?8$nBL!% znq`Q;)wfN(Rax|`bPy^?&~Sr=2?lS#lWdUVa+DByiM}T40ws(7 zV#f;~C3c96h%EBHTjEz_wy4rA7xGidLgQ%U%&ctL{dQlFKhC|IWu9=e&nVn6TBR(=Wcj= z)Hsp|QR*6#%nS41z0MDghyRL2lOnba51T)cM}wQrtV++Y?P-s641< zFIT!oeU}r#k)i4#@-Xk$V2c2+Z%gfcj0?36o;kZuUmYmXZqajShu$!z5CZaO#Qbao zg~;fjTE@)q`qiXQeJWS^C0!ieK_us zlkK^@pOpIb?#+Zd8^_peC`hQwD7xKFI@+P@ef&A3`)xf)#I?Vt;1h!l8{_9kRF6JfXjWp@g(ZRLX(&b z^yG8^|A$I`QzsV>7he_SMZxTF$t$>LQRDk=K1no1N0L~;&6%Ytpr#we(X8YH4EV5f zc=2o0pte&w-|=V3rz{uzyAIsD9=1Pth&cRARZi$AIz>!N>V^S7`VJ|{;S|k zrqyj({99f!=q7?4aPg;(7D-Lc7RkIb|=RzVIEfJD z`t1T@{*PZ?8O5dH50pufxLkz4_s#>Bx>`JrnJmH%3o|2ho+zrQ4X!;BM9uftIOV3mEp#>~xoX7c>H#uACy zyJA&s184u52r!$GEC0aSNn~p}dg2dkh4<6B>$Lxk6X(kmf*UE3x(tS)f{yR{n{QhtmaLG160!5k8 zYJm2A&Ci>8ZST|xPVSN9f?KRh+4<5%fO$%w9>#pZmu;?@fWWtTzb zT=E(alaJly@{*A2O4>-ci0bXR{oE?~hJV5VW}f<66hOEocyB_|1R769yERZ)T8|`M zZ^5#;jmp2q8IdthM}GTOJm>Y`m8^Bo-HPI%mama@Y4Ku0q3~W)UP|Osz^6kdAOx_U z{YNl8h>GxhN4;S``_(Qh>ebrtBA1G)#O!)aX4BbMW31M)=^z z`R75f7tohQS#jVFjfHF0e6(D&4*ROjF64Y(@_tY!m~Tju z5pHsnavrjm>A=O#@I*4Wdy%Idr&mT3XM&@8nyve7#>z{G{3yba_OQ)8B^s@R~iPLgrgbflLt!CV*-0jiBig0i~Eo~G&y=S!2l#L{<#|YPZk1=ZypugA9>KnN#Qm>s=k5q#C$sv1 zza=z)R?mZQZCTuvgOiTK#|KXrZBz+6*9C2uu=bvOAaT8tPO%bg4+g^qW{^RL$#@|u zmYYjCXrA;;y;GtI@$;n|oevl4UJs*}94?{DBsx-h+C!ykpL&CDMH?7!=xl{YI?6!= zvIIyz*l29~r@b&T--`W;_4)myoj*3D-i|h@W6!RK*(9=DM-J@Kcvu*$_F%m96kE>U zijSGykCxyq`84mtj{G^xvz%geRCdaCV)9BKyXh&z35&J$8UZaB)7Dp(?PCU*SVre8 z=`wy2Ng9^~BuMV4Blct6f!RO2km-b6Oki3rw(+HHjeNKx9FklUWA5s+= zt%%D0^(2;9I0Z%8qwLIZRGLg*o-!4=zLxTNtjtJ4&O}0BO!oL`W2Se4zgGcc@gv=`uKrti_zr&>pOWHC(4F{R-gCW`k6TWjZaXQ7+Fbj~ z5@@4?zzpWt;mT-Nh-n@U8T)BhJ;`MOmwnMb^@giLvd**U3neS|tg0g+`b@b5Q-l{B z$eXPXQ3YsPaDI#mpo&XbcC?Y zbz*Fz$zS#XeDl%QhIQPf>DK&t%;b8J!>VWD{l&b$3#gg^B?RiRY%qh(7u2A}!I@Mt85-qkO^BO|IbSl@4-yksZioT|~4&2|DcEewk<0Fqf; zG+-5oqGvT|7Xg#SnziLzng-di>fTq)sCye$pd;awd{j}Ak7-l(<;BM#)5810Sa&za zbT2~hsKy<<2abn9fp26BYA(=6}^bPp~5eHUHp3)c9_n(bI70zim?*pYxa`m@5;lP^mqtf&84$O~7S(geKwmbifPL!RO=R@tlP zx=OGN)=e^3N23P)2~a`eieM;z+weCP8*Q?-d;O{ETe0kg0E%72uOrI3wmpV639or5 zrM-lwgqlK{0=R9D(5Cb!Ea3(uD8A74Cw>xtZ>zDBa!KBKi_y1OlTp7`JH0He>Bb_0 zFEd;J`3F|E++r4w<=}70YeSN1(W)|$`oomXa;#fW;#BMM-7Tr@GD_UqG<>>a0|ld> zg@OxK;Use|NF0PF4nHknOXvyp3@UlN=(t%rF<8d@LDJiuYZaGaJC%07?I}HV(8IZY z&?wagk9LFOg$s$$LM3qNH@rA>XsP(|X?u$sddFl-wws9S1glsWQvTN z=xhVbN6;yIzVe9je8PVt(FfC1(tDztvjr)QR=cRg)T?cMyW=5J5&f9{rcs<0K!2-u zfokPwCY?qU^|JT&9M681R_2_jUT!44?+?t#@}gmr)>(I^-__t@Qh?Kd0FFZahPEeX zP}0eJAr0PhE2sJTjR!01qwntICK{*&aaMm9xoqF}An>5VjpS_hanj#DrZQs~NxE;; z`ZwpPkSvxVCHZ^0dNfz25rAUVWw2KTkS4EmnHfyDEh+wPWsrc@Og!Ae4Nk z^DH?HI7+EN5C0N&xF#>$YdoI3p?lkZ5#2L*e&pdTpI(7Iy;~LDmMpy6GLeWm;8hAv zURdJFEa}>2te8;E=<>i0HD0>4btKKOWoDwo#wA88FEh8+C+SU)?Mt>mS88@hHe3*( z7vcI!G*?g>ia94zb9lhsfVnl_yyfZqQMG;7P73TN+(gU~K1RIN zQ>CgIE%$ymBmErf(iAP3ye*k^-)w|{$3;6TBe?Y?yg+IvG`kk*@U5hZ>EIujY7g~B zv2@>pK~zSrnddP+BjA`rD|UOaX!$&&Ja;h_`yt-;sOS@M zSHzWc`CX#X!^ht1!UE#%gdlhql8y6i@7yWMKXR`5Kp-z&6d;Gx<*gZ_%hbbNGHJ&k zu^(3g@puh8#LVvI2;r41{e2pP{rfynzHZjRu33YaCNkLI5j-D!bis&3h)&;`obtF! zQq$Pu;107GJVz}*-z(H3u`guxEF8qMW~avEsLgr)HC3uKz{={rcksx9eWURo%#$0d z3p-;-mM=CA3UHDP>QflJZ)agFxnB-#NG^zF=z!1Ge#FLM^k@6u{+!_>e-6M1H8$#d zw^4q~SoNzny0Ruu9hb~H!IT?^uA?e~U%%t0$b{+B30zC1x}v3q^fe$vYjU(7d|f!a zrfz6>ADe({*!`Z6^1MR{Z`)P6!^QsgwAjG5=b`c_V#CD?~@ZxZu1>}pt*hdV%)t&1M zwoYnr4R8_b%u*qjL)TC>jH9!MZbFZ{sexnqU+zgJnCS*4>C+n>HEut|Hz;?p0MWmD zToHN_L^yQHAayUgS~wHl`tkL~i;|og2gXl$+8NdeTN}71of|?@jj+v{7*5PIKeCch z1>k7szUf_=C?5Rz(S;I=@^-To99Wl%m$%8)8(xWBD-Ala zf+YbkkEzg-iCdLlJym^oNHgU`p~7V57-wE+`ma(3s|58N&Ao!;wyyhr3YB)PF~gMP zJR@GCna1T?VG*Vqroi&Te%UF0eVC-_wx6KJUiE_x9!3y6T+ig#_i?HFeZ!%PWQV=AJhBOq(7Xw0au9KGjfWkkJSN_e(bW%T?UZfT zixuH!5rKvx@0=fs&4=ae?FVZNB6YJq!pEBaR2>^7^d7o_DqtKd<-7?!^k}4VjhnVI zExUDPe4fPBJ?-BM$ILLA;8jwcYoQ=LmLhYt56x%lcGx|poyD7c+cCZ2I`X@PA?IEY zoglEk3w1i7@qO!w5IwNKnq)W;-tH5LsI+b}i?yqoDIgKC2OJ$|I97y!%jZkW1%-_5 z%5LtY7yC5@LVv0{USA-Y(S+URZfVO9?-F``*P7wrBs;EyNXF;JIlkKuNsmN=N8T0V1@tW_ zlV(IGP}XN|-9~I+dKVAXss{goY0+ov`(f~EJV;2**wG?TAZe%tOS0^r7)6ryqSn+< z3YCiNke5kfyu$F==(CUAqg>5S8cHQ=eOYv|Xuedc3CgBK=|OvQdKMZvUwnSk;&DIA zXNlp`Bdx)K`+ptcNr^8@O?n!)QE$z;rjd~Py#`5g;ChPX1=GcNBT6m(6&gWSB=SF5 zOCD)$(+q61xI7?|XL@gBFj*7534hV`#pbQ))Za!kvl@sN8LLQ=MeHnW6(d1Hi}4Uh z0WZ~4d+i;CU-(GZDpz!ic=Na(m=>HA3^Hb6{-SagaRD*6$R&4;{)r*@J#G{tnRdS@wgs1PfA?uY+8lRZrm=#yN{vilxm7)E}ku9%DjiFu&@$+ZUyuCr#Pjkr%p?{2b=`DOPdLkz)1ka=gG$uhYHA&oHw_WD$`c1(D9|Ev-7@V zYSy&;Qp_dx$rl`V{4Q}Pelfoi{%pTeFtTZuWUm;((1H}_@!@}9HJweF5(|!nb7Ppk z*Q+&YUS0vW=a@76E8EH}uWb|^$T;UO|NJ^gGZ+_bsr*jYZ-dAeBdNMV<=ZRXQ+iE8mrx=NR42p0%*Ie3yeP@W-O;}ZPA z|EN0r_S_~LN~3R0PkX*kHRCa>{Ga-Kyx6XSg?|#_%H@#r*0dN5;xB1V_^(H?+=-mO{v{SLpc3{U{wYaD z2%=gPIS`@5VIO{jWS>g?EE!+Vq5FERd;$DTa1GT?yQLrhnp5~6{6hb-!YY6OCta$w z9l5&=@|Aq6UC>XhVVL|=WNdwbuU>B z+hR)EW`yHtnP4Cq{cq!=qdt-NozvLGH3H2PPD(-R{ek5;{ej82{DBd@`hH|{0V>4P zjQM3c2mF^V$UBZ1(IjWN5I=1Gz`Dn=Q2O?xlT3q%d1)x<5A1v=<7zKJP!E8Xm}YDL zZ$89U0FoiyFcSm&uZQ`smHDqT^Z)VNWc#tPer~c)$HZIiJe9ZA>F%s&kj7jX#sa1- zf>Hl}Y>@PC>Wcp|&i;!Sec(U;f+0M@0(Pvl^;$*_rsHGaI*858;^d{*^FAz4^4bK1 zz4Vpa?l+LIF?&_1D$;d3;KoIP_`u31TB1fBI7m8hO%t#+E`cih@!x(ed8w+Xw6$wu zvkfCm=5bnAvU{KA8ds#O;vFw`*1qo&uLuig{xu+)W8i~&*wQFNPRLjDVO^=QD_+>& z!lC6DWGs61+kplA<$}T=6NJd!Q+~mZ2EBy44v*ieHH^7<=6+Ap5#OIDnKWYPVITv; zW4hp=6Q}qDXspLEj;w5tBWVVti$Wu{+c&$l(#dmGi60A-C754hQ}1i9v}3GR;9Tfn zpelxU-yq%}7y^$FgvwyBYmzIjK?eC=v!odNmEQ&(Zzo<=D+aN- zONAk1I3&-i2F+L0hv(08;{&+P*XcOcb_R z0qb-|lk%NjMw2I*b;v*Vn)iyRs~g@Z8a@2M?(BAu=OV9RYN}Ir_qDbV zv6>dRKn~DM6oTN6q*Q#w_r{?rlTQzVTo}VyY!|)sI8K-I;ug{Hl>4_Xzng<$JO&&x zJ6rKlR#`$w!D)A$I6K`Ct6%Fbd~ISco|Uw|BKJM~cn?>&swnx$plH;TUC{YRp7ssL zqJSqMs@;0m4*K&Bc#0h%yQbt!pfW56H`XgBx2z^MY($U0C^Z*(%6vDlS$!IP5CYCD zlq9Hgel`@#A#bomAU^(9UTLUnZt`HzxJk6EBQ(pfc_QX2;J8WT5(>;>K=aA06v!d1 zA&Mr@Ec9}HS*XSailPi$dXI=CntK-rK2s@+_bxb<7$~dTD{di>%~=O=FxWu}exUm+ z@ZMyHu2W(G=FJg*1j7Z9qITku-?!)Sw|#lO^E!F|EHQs}sz*oXl-UcWtrIb;XyrLB zQE2SS4CjF2uJ2t{m>e!O4FlUM^|;^>2ER~ zGT!|3@{kBK+jDkdpAG$Q?7eqXlU?3590Wm{^j?A#>7YoF8c=B>#YPpQA_5{tDFPA_ ziu4W&Hy}hQ(uwpcp`#$u6aoLx1`OC&px`nYRjLoSjaF) zs?~_PMeeFL`sXPD1wbeKv$Vj!#J}Pns3PeP2yQ@P_G$Cv^3Hq0FFhBS1G}uy%4L^> z{CafKKX^(?kLwsrV!Vf>G??xx)!*>qan?$6)(|NC87Nr-7*8s%H?W`B*&JE6or$Eg zB1z?+`e%fqHjCP(+6_xFUnrYtX1g6rWw#a|+}upFzGcu^DKNw#>9-)?KLW`GZiQ2X zg3QUTw1({>$Z~lEmKkFM24xA0wV9Btdj6=%Az3pXcfPG5sWkT?jg%{Ov=YKXHqf;r zrahKCdJyjm`|soWcH-dtnrma#0U}%Ob#*o21({l@Lh+ij@WatT+}y0EP?Mz43Z=tYjEb%C}5@LyM%!{cdXPOg01*HWC=Q@!>&q za|esJT$U}#JWA8m=v(2fyIv~y?>w%!hf=;bk9OEJA8^4!N-SOYWM@Pe;_9&e;#xS- zt?RktjMKW#RGNw5H&#*23dQRhF1t>AL%ItVR+(DVam)uW&Dp6x$d{_2r5gBAw7nCm zf-)9x(ccJLR>3~EeU=;Fe*0c~m9f62U+x@HukO_ABLCZ_p-7N?Mj)ObKnjRn7t}1{ zGE46~H(H%!RJXqZ!u8y7ymTr1w(9Z)l-h;*JRJ=MTMcccu9N%@s;OM{24D-q^oI8M zSGdUjuVdfvo64*P@}Y~C2BBr^vF6jr^AU?x@%4t<2E!a%lG?f|2b3)EVTHf&6d+-= zg}e-HmIv}B#v4*1vvh>CZ5K_vM2BfPUCSn)nukt1c%@xu)?U4*V1O=J02G!2a^4K!SB8mJ4p#5^}Ho@iAep>|60}4!Ra|cZIJoTD!h|G~ieB}Li9r$Hc{hsp!OzBRShYTOUSjU)hdDTA_g^>3%M$Btr zj{z1J1%{6?1_*w5Zqb!6V|(M?AZaL1@(~khrpr@sTv0CjynFlIr#-`mKA3Iaeaw(D zj)M*Z2bGg#VDJu}=w}^=Y0nH?7fA~vF?2QXoxNAlEaj;AEI4)ERI7QnaP<)rTgqy+ zZ{MT4eP|v^0K`YuBXadGme70VwA)D|5j!fGTh*v4x%$lUt+j0DDZZ187G=D>-Ns=O z&=*b^rUBd4gsac$2VGU~Gw16L#+4OaW+R=^i!LjDpBt22+*;p&QtU0}s7NYYbzlpL z|8D#KM<0S4oLU8V!W?q39GK}W`#CitkjXrlLRI?zRK3#ppv%j@riVX)P5yC#M_l&x zkIje0lpNu&Z6O)NmJHF2Y)5NvHzegQZ`aWx7b{c|=OaQ!>P7-;tr7w)2C`7%wRx|N zU!GtN?p%8g%Ehev7fmTgt?m|o(J)#|)c#=cq_Pwr z=5(U*SSrKbN1`A7AQP>qLmBfi$F>JA>~-ICq+4AOicsgmb{kAuT;|l_-NfeU(?#*#Hs5451Zig>JN#c3qMV@~y{20OOLXei!?*k4y>YIM)V5vl?tO z6*2w}kEPu0#x?Gs^~w6+f{M}bNvzKfuzaYdm1yxSGC{eEVjquLHaV)HY7};*8yZzn z{4sYT1enb(oG?MC89(6y2b;yw*|5N2dw$Gu9U&q&QDtCQczGze*h|l+;G_WVx3+z8 zN8Im}?NZ;EqaCKP#M_`VYz{0MXZ$Pj&R!VtdUA7oIun+ro8%^YAFj9}B2kBo{QeEM z8BVbd8Y1h_iqP^DbBI^2rGq#;pFOa66FmOAF8a{n zr(#a)=ROk1{to9~-j(jQ>C<1iA$zdW)(<)QX^S05Q@YqeytO0(JA*$DwUndbQ{Ves zQh3&_pS9IznP7tXRW!^$AxQ1E(l6(=M^_WjNHF2Z(EtN@-OytJ0gCpkwvc?sBZJHP zi0<#--flM!;mQap{}{Gvp)P7$Z&1DcrmTe=WqRsT7zPZouG83sCs*v3dNB5Lbk(rl`{B$EVY>?mKD8<7opP5!XMg9fU z=B@AT$H%mvC$abC*gRTtuOA!;2tWmj7UkN?yScn!d|Z=QP^bM)s~hb?dx~91M*zcR zjv)PI#8%$&3l}h>^;t7or<|T#eqNXJW!^6Su!^X*mG^`GH4oc1X%>a9?h1!Dpz{Dp z<#!-oCN=frr*{_2HwOgz^N8mcY-*l;I9wJWJ{Pc)Wx%Pq#@pfLxSSL#$CR$$GGlbs z7+wws$zcMY$g#8>aGjNUsLd{7^u*~};-ikTCp}9CF2B)fez*GWP@{&WEb!iN)(@7B zmoDO2O`3hUUp$4%&q!xWBV~{ef(woJ!qyIK_7toei4qO-wsF{MN0VpWRTZw@YE44t z^ut6%GL0Dz*?(ZY)&s);(hD^1+(d-q#KCc^vIzA%-NU!OIJMBZqQ^mh(z zcfv3Xw>Bv_ouWz3EsnHl zKG@;<`mTj`M&hHct(@HyA>ftG_#HRP=S-{akVc!3n8T|+cN}VY`yI(RT=KyZrB>su zFT&QYJsutJH8uRcZc8p!j!)rA!Zo zwcOGkHEHQs+kV${fA=fBxP5&>Lxbhsap9lynKKq0;&0*I zaNVS#{lmlM7A?tg2NG}d!P~Ni?=kUquE4PQBhvuhWY;Ioz#$cQ9KvTlQO~+RZvoHu zStID$dvGUj`wuZ45mpo7Pj~!H=S%mmQ3KQE z;XtJKYSW9inr+k4W8+BjEgVOC)PqV1ALyFaB5z+nggp1iZ7-TmJKdo*+WkgBB*17>6|sF-{>n(7z72+YP2d>x0u=YX}((@fAnhVZ#t z5|lZ+h={4yQkCpdz1G-Z_3HLjN5%q04Qat(mfw&Z36H-aq^bP0M(hm~D+bJ?jkqxC z$)%I13be~xSzI^xGj6Tetpju3&scoB&%rZK9nUK?*o#a_!Y(`nl!ehF%0Bu#9<&`P zIcJX$rL_gzK#`3J*``qw{aY$GE$oBlY)D4u)bK#Zd}qLs$z%=C$Q?v8`d zy|YHSi#VQ}&OQ&rsl(*PudOHgqJ7U?1tAk3Rv-_s@T^kRNSH#>AP5hZfx?SwZSP)P z(5!nA`6Gj|mhaA$rqCLXm9J`iPgHhZqCN!<%*@9aSS?q1_g>~2=j++CrhV`0%go}( z>p8g$$!OkDN$1^`KEZt~eK;}SlQI1tVFv!E_m8@O;->vCl3P`$*0FC!BVFzxvNDWB7lY8~hDm>Tdy9{{pb;?`K08*YVR1+GeI4DB%^F+Ojt*|*OmQY-I{Ft;Q7=nC)9cb7h%?{6j9cTB2% zdeN-Vc46qwntA7@&e6`TOI!b3M$0ee>HmCP08A8ir8%gA-rMc@xbr6w zy2Oj);hm;4Kysc^eChOaxjx~)j5HJUGCbfckpnA%S`kPE4d40NMoX0A-5-ZBp?k+5`kN&^UgF{geYZ znt(ZI0|mSZ7&EUFu~7LRc@vReyva!f-O>syz-NIXZUpcqBEQ3SPb29{eZ8FM**DP=hLdbZP;T@XvSCX91`D5k_cM~)5VV>LHXC! zMrbHbiPVA%poK_Tkw$W^o?oozvYy^Nh++)0JjH8Plew_yeCozJgMl5(f}Ft93NO9t z@bVAq&Rg}34wL8Fg#^DoO?E6!eB|$cg{}6vR0IRlmB~;TFp>D<3)ukNaj4vdfW`uX0(=IxDhfU{ zWY#R>V+1pvFb!ze1d4?Pi)+OiOnt(|W3Rqo?7==~j-%Yh_f`pRoO}1Z%s-2m7(_wu z)0ImJ#%k7Flm5yUY;A1JZ|i^(JFe-2^$QyAO7>?f$02!B~I+5Pppo;>&1 zctLv0fwyd6{8#7LQX&`f>(BEK7qH(y`_cVC5%n+8vi~EXHQ2*@;bZTEEdh{RG3^Jr zC`}8)J?meo$b4@+_hlE(+7GiIRI>O^jjJ6{Z#|Hrd!*k@_uM-u61;ntRz#Nuwoi>L z;T`f+gN~f3dlg=8WhRnND9w$sG&L#z^~KS=cK1ulY9c21kEm%*3>UV`8M}}H7H zS*YTCOYN+Ou@lpI*e9d!hPvZwZT{^`zBd>Tp0nS>10k52M_J#+{z?^m7aDFSzi=@CTjs zBgJ)nzVQ=PXlMW@j+Pb=3TT%JdA2@x?cu$en)Gqa)G}C#Zsbry^aZ1dmw0hV0$i6A z2^WL7l_x~Tr3~Z?w?jMy-f2+v)a3|@-$=>K8MSM1(etX7N-~+YI@d})m>#Rb&?t%? zm?Xq24ZwZb?+HB2bx4f%Ex2yv!Lf!HX4|qyKg@l0Y)YS#o6Spq({xn%(HrL7$Kl8V z92*AMr5{1uhR3zyHvJYyrg41;cDEOeFA{n#9}iM@^V6!lwV~3DY-!=ivtL|ska6?5 zCoqT^!VxbZ!)HdQLNZH%eG*nkSLM!mUjKEfa^VJ_^Z-Yopt83>RZo2+D}NPJv9n2- z`-#O1;-P89Xm+rdT@2z|VlG)iBqJLRM=jb$<(#;5Nhd+BZsK;}EDW7Vk)5pRul(uS zwKns3%j1wQ!%x7PFip`S2-go_Brxw7$)r(`?-+4Ee%2Q2r80V{PxA3?`lxDmYsAEF z`$})y7;~_`+%e+#CC7=lgzY-pu@CJ)6zW7p`ch>`BR#|Wd{C!46714R)o$TPuk7rw zTQ3FVEE!X)*(}or3@I|uIIwSc{tGziZ_1a=>f0%M#j$*;xzR;8fd5|Gv@iL~>Fxj1weuzUdxbf|85=cVJ9ZM`!7gdX|>vHj7hLCaKTyD2PD@bvg!<+Bl z5Sy`GSZ}UqjsaLulc_9jj|$#xPFPsL|2&&(4ULT#+U=CQfPTQTx-nS*u=ogIcXLr49(Lc^^A|Q2 z@FHZSFVGf>9$8FZ@t_O(bPg<*<-jN@pck%$%7dq~wk#tVrlE<23;7yTXqP9>t{>j_ zl)lc))HcZzT{l-rlx@x%Dz%ro#uJ^m(xJZfln90afEbv1NNt8qKpLx;tLyX+xLCUnC>*f)2U^0aPyOzi_2{>?UykrOF2*DxC&pW}P=2UTw z^?4o)laCar-fJgpC8M1@_aSG&pa~`3+#pk+qr^foSc*cr5fb%7s%DcS)7x1#yho3{ z44*DKnh;tS>~pARn;~M0{RbhA&Wr6*?l?dnwZ}eh7};!D!V7wFUvgQWDM>lwup>Wv zn5{}fn7AX_hTdT}dlI?YKPY4{vh|c=3i*-G(*PQN6_t{&a?cuWLexqjNA~7>54Z>J zbFo=uQEgOo3KM^PcQ|x{L|8;n1$CAP15Ho{MUpg;eD!IcLa_AKdo=K>Q*+j8y0x*q*6AB??$JO26`g@0j+W!u-Y_$ z=bRZnnY};o)N2@rT_f`y1HVPw<`7YR=|{Kv>=dAJuv{n0gEBgEUaa;W#E)3mk9ecu-|OUqzLeD4Q40SrB_9 z$~<$9Ur&3hM;tgl7-oaoe5c|;25Pj3H13`}vt>e6e__g-FkRc}wgq`ApY0;ZfBMml zY?9ydBJQFDylbFn^4Ou;7x|N}&dVb$(d=GM*V&#IsOR*Zzn|zdC zktk{a_6JndW(M&)T_7lBk=*7}?CpHYLH#aD?~)bjpwTt%1=l|5(>49m2NO#oba9E> zF?7y)$f5=8;i7W=1{N#MVFqm?>74VlXBX0NkkvN~0z`&C;d+7*#0<>W$^*1l5Um4k zP)<^XCp(PLC!xBVIWIc$JOoDGe|uqMQTXWW>#NHStSZ53NizCJT+1I!4Izmafro4$ zIfPiUIZp&;9_$na$om2j9*y?%_0MzY&Z+d1ZN(H6xV4;G&AX5rY?t`c;=ykQBV+&JTDU?&rXk$`iVQCc&+<(n2jaM=gGD&jEceTE;^1tc1 zFD;va_ zEtl*$yS!!&8wA@Yg(qC&^N^hS*6<=|dLwKh5Cb?d&%k`C+T2rZ<55)!MZPi3=|WuD zN17#_SO{7_U)?RAKV3Tul9}3TML1lNUuV2c&i?FFZ^z(p_-z1tuIJ`9$Yi)iiG6(< zKPt(xc;RnIWvk6gzwkI~!DaFnZ)CR*oN7hSdp^%z$Y8pi6#rPV zP-e2Ctv&gAYUT}H*|MQ%%q2mArEUU8HWL$iAi&_y>(?adNbzABnBj4LS2fjZ* zAi%a6s5OQDx=W$$FS-<}esw7zoIyI09+)3bbK!T3U;Yl00WBHE0Jt_RW&Bg}`QM^8 z{?_mQ1$0LnHU=0I%AhZi&PcLA7oU7FlAFBkd#z@CtEjE{j$WGh>DR{Fcf;piV3&Su zdQhCv`^E<1j5I;_w|ul_PZLeYZUUID3rQ&))9Bp))2jJdSRM^UYo?9zI0vbw1P*cYts+NF!8(}WmKrxyOCY$?fgK`<`Fx{E$fm=Vs`rN8|-2gwx@L` zs^Rb$)znKaZyeUI>)?Gg+GI}@)?d)-4QCF*pC45-IDfTdSS|0SMb4tb4^OjW8Cz*T zr;h!}{^u{-RjR)HwGeT3B37KqwH!En?_C5e*#A;&)<1&aJjV!7ZJIz?X@>0*q^g4! zG0BN7EO0>cd*N<<&2!wLuF=T5cd)uh?P_wQ(ufYqpTuzyOk&dZLAh z+S(|;ggy&7ELnLcxL)ffznR-!J0z_=8RdAYy7IlHbXxo^*-{Q>Obw~2+ZODsc z1oj<*$E;s9G_sJi*?1oWLvu8xFtN+pr1n3_N_*-Z{0=sx;C`u@4GYI!#Y1waEpv(w z^-{_rJ-6VdB;T0oq{FYkdB-!EnO6nktHp-C$^|kAYWaM~JbqCYc3$%};|4cACizBK=X|^=R*0u@;enhc*yWrD0nhw^L0Lf-uI+ZhyJ zMDM$IXe*r<>>`ZVFcN!hw<`0~mO7V3uEyccyF(nfn>0`oMTAmCGS1Q>vA5Ny0~elw z4LIv$S_#Xr7!Eo*N!)I=ZM!I7}AZOf!z)()&rSj!~%I!%&17x zRP=XFu9LXVsaEUyy{Nib_Jj=a+SXoKHssI+v6oDW?kpL`l2c#@(Ft)I#N&<%1~%! zj;fB6w?~~$D(vW?XxnTJ-y@;NkOUkN==fM5+>#EJ*MrrWnbzGhbtEo63R5z_W9G@I z_usJW-`9fmw`RQm+wV9>IKF5*o5yL=T+YXA2~IX0wN`OO_nPg`%GYHS*weV}uO63U zn|R&mXpG&smY8Xde(+cf`QAiopRIApgouoM4t0e%myABSq|6DkIHWUm)a7T=n874_ z#^$jc8pEhRJgS4?IjJ#*IiZw>J5#fZs=h6&qz1$RZ2oL6r82;TRWRlK@kw+Is1WS+dOy1Kc8FPLI%t$7KAJ(^j8adY zeW^NP@O3!!mOEsQM~jUyNlLu+7)PE@XNq7=7-kxITqE^0zjNv(To5hbL;SiVSiC?{ z9PZUl?r>?;@ktZtymdEKjOBwJ3j^w|VP0?Gz3QfIvG93Olq9@h9#-Mq6sz+m`J zd#c4oL#@lZ-(epGc6~xEDdyDU6P4N0NJKMFcmbi1jjln$YKPS?ootY4T?oR;`9{#lgza z(|G>hUd=dJUdk)F(a{d=0Gzc9%oQp0Q94UIFtQl-x$fa5c~0(hiAMFS*#@oS#s7o z-T*VJF9XBqLSmvQMZF(Obm4*&2`OS{Q+nZipS)dNtaB||>r-r=TRAi|3#SI3n7xt~ zZT=Yc$mEdYLFL`Xc-US7`7*5@>oxzrr#Em;k(OiN;$@g=`Vbn%5dM?YnTWhVgCban!-kZyP4;zUb zd2MSjm3!70?0zDR6oFCC;^z5T2ys6BjebTpw^D1yg#M)?EE4@(FYe|MaC%^04K&K7cUgUV3>D-xA#kKt#XB~?J0 zi-BJiA{Kqoe=5*dsq7wu**jsFQrMFanC_>t>f7VPk44}eter$D7ZbJRon0Xchquo3pv!qBmE}yt!r^ z?HsR)e_)VKSSP(SVf=Kot^UgPQSJjE4E}!nM!U;`tzZy*;6APg!RI)Hs`e6^@XE3e z@soCSd3h~}sQ3Ji1LF&wKFNKgsR$0`WoyCTVHP?v{z#w3^!e9}tv};i#FHN~yc%=1 zTi<)}CQq#f<*k{Sdc?`&f}7~EJB&w!nO58mH@2HDsEb1yj=}%U3i_AVyWv1=!v>sdrnabQipQl;=Od@`ekRKG zsqr~=z}c{OU-v;O(~SjAH4g z2aA#iIF9WYiwg+cc=Kk%u06iH|Cq`|>wu`bTy`={a%E~-ucU`74Cvfcd~VTIZ38Pd zba;NI_}sWtQ?{pZ=b*9N?)#Vg3?v_c?+z(O+(C?vP^fwzGE&FS+TF7YrLwJ?u9hv+ ztek40%jC;-^QZkEHYK=a0COiSF5&lnHUKLX<@*sO(8s^(FaNg0!T_%VNS4GeT@=gI z&vPr-Gyr2g0h*-zw+z4kyJ>&My_;aEh#M*OL=a7OrrmnxxFwM>JJp$h*HYQCe{tl) zOM$S3HS@e=Y^+BWRu_4YF8gabgC}lcq^W9?C<6rED{;iD)a$F(i(a|6h5Ts;uC|Cg zT-arm;KUGt-$&EVX5=#deUBYD&J9qETG($7bS3!70l}c92cPxfY}s1P=AXPyGC`}s zlDemS6`dq?VYV-}uuLEbEC!5IEbk@E7)BIID5D0F8go%PERSH0ne0@)-`? zsWkg3tIwZlkxgD;RHw6gExpHZVqRkF<*9;POV;tw{E}@9US`}sWb3k7bGrV<$RXLh zT`R%BwwRC=-6YqO3OD4}@zCL&t&bpih@G>HYD|m3qSz&l_2%4bS)}B-SiF_0w{ohd zR5;0)&aT2V^6#YU9(OkH)z8FY9S%}oG;~Q zr~jDDa5j0?rOd3hIZ56~`jT$MZn36yk*Dm&6RuyqT4reXNU{z1&ne6(K}2hqccNFw zh>LW32z526!28BqUVVivr~ZTX${FI>!ZNonl=U3!p|j#CA;03PBD!uOco0``v*kl) zNP^jT2(&$n80vr%z3&}Wm0CpyG ze4Em#BPk!z<7~y#x_aoXOicstz)St7!S;4$7PG0Wod!+as2LqPt0LG(lmmbRmjJIp zqy%6SfK23kabsFx0!494W?~`x(W`qQ-u`S7=PY$Kbd%1W*f(q}8N8H&AWwqBvL(1I zsG;vt)HjyK@06gc3SXjY60Zk)bCe(Z;FR(GHLXcKiwq7CafB*JOQqiI8cp)aua%?0N*sW`Sh|4#mX|>4orE>dKoV_xL5)5C9*Tb(amB*t zZLO6q6ZZpy%!SCjDMsnzhnLnETekd9C8iO;fLXB){H|@rS(atr>goW7~`-!YCX>-=o?#5FX z`w=2W@R`pT*{OE946VKz-d`hof6%4gQcZ%fOV838MC9D=e&Vc_73Ve=9yoKw ztvFP9fh%r~=UqFi*P<=ldnP(5uox-!^7aCkVm8+WIbRc&rv?Z0zFt-(h4edPd%0p~ zN)r4_&j?Q4?r?tIBakG($gL+hoALb#VCeT{zM~%r^1mE9(%5fK>Dm4rw*0;d1!6%y zV>CAiD0$z(_?FFZq1y-!hg7fodD{tPE*qk^qLmYzcs(BnIGjwy?o-~J=Yet;SO#K! z+D(=@ParwHUkS&DmX3&rhms#jVOix|YF_ROGdf;774SlPFjU8;J)b?~X^uIF(fF^G0hBL)b{@I+Yh@7nW5BsmXBPhzpmMuhT`;-mn5dNNGdQaJk8KFbc=(2tHlc7+{OShgZbQSaPT{@&-Bo zI~(}_+va{>2{eOUg8ov=41(zYTgoi(OUi7%@k<2ttL`=VPQTCsU%`G~=O=t>0L0V3 zn`-=J%JLs^@qfhE{}HGEN4)>fG!xwTvL_UI>)U5F|Ej>PCibM~v`5Py(;0roNnP=S z{(^Y=CqaSHe-JPGXWKj!@PuE2Dd;e6>m6!JO!p@|Tl)0d3D; zCbkwO?+Sdn?%B&BICDUL3zYzxj!~bs!WU36IVrs(4}fMdimv4JnJ25Qp7>%VOX$n_ zo$?c7N-r;5f8d~@ec*u2ei%mJtnFVDJrjQ^kf293a6#Gx^6dESE6?9jQN*>mwKc6Y zsVw{Ux`=T)VeNTJ?;npuSV`S?jg$c^(>6x!Lif+7f^UF@j7j55! zTrs@L;yXFJBO6^un;l@0O-y_wYZ$*nFp;pBlH75OdSZ;uPt};1y+~pv_-5V{^!zMl zZ4kruw8-5AXMe?TV+Jijk)xh|3qV>L7x^d@2d7GRD7>Ybx-SmZ7|n*e8?KZIuJPzP zu(oRp5JQ3Oe!22z?5q&^_FKet#EeTHt`1XCK2Uur$bL=Vqa$91&3f%rdIWc!z#=JW zpcwtfFp6J+6#vxAp&VjgXzEpubG|i0cu+YR5+u9pG;<;4Q|GlKuena>2R`9aDtN)( zOJJi0EUNR(1R-2&jv|q@s;x2hP8>-McRIHyAH?(Zr=HAXh6p0{8;T9=NqPu1CND7| z9=--MThe_ymXU`S6RfOqDb1C)Qin9()bz)L-1`NFZR-$^1cC=a95}8{NlLZl46ZwF z>NJw;erC+Xd|p$7!NZMS0Hlk(;6-F7e80g(61!!_<+|p&iOtNbDDkQBpH?aZd2wOA z`PiPvQ+ZHUPtL%DfLT1}1}RwRUP|q$H^E;H$dpP&aNY4_JQ%P1g^PqKC+JK_lcYzOD~iq-y9}Lww7>PX zMEItOOrx)NkLQ2wCjQBWxPP~M6XRYot;`?2o)RQ`-`mtR! zTSsVIz&**{B21wz_6kpq*MS3NnJ;0x>hI-&!$J<>rZPSmLA;t}9-h`G$!o@1S{Q z*e2B0(2^?ez@{i?f65|F-nzxR>^pl~RubLVUc>RXNljy}gKt&^G>nZb!67eTUg4hG z_F^G$M;K!dsl-oXx7V@5R)^2M2974_XMU zBcAJQiY#Fv=^`9A0tKIq>D7~aeE&u`V3eG19AS+ar*Aj z-(gl{;qN%;5H?v;J!K}VUmcQ{@7q`wOe58qw6xUadipWrZ&dbMWJn3^z8^_`FsrcC zj-<1XkOq3_$3f;H!UGkn6!Z@qgf1e|gWP$@crcFa(eHUJrmi z0CwYsoFR}O&>Gv1F71R94pL2)h7}EjN~T|IXI)htZoMS8x}oVKt$6WDb)|_^Sm!rs zLdGB+44VZ4t|?_JgrbF+Hj;p_M3$w46^o&Q%Uzj5<1>yHWn!1C0`Dgs`f2&$EVqXt z?8!kad6{U_K(wMCSS0e1k+gQLLa@jB+HYqgXlc4dPb;W!WtCNm$~o(U(l}%)tE^{c zv@YPi$T3d@(3Tk0mN>Ba5qNoACzi|- zlQE+&5ZUl!6G;LA7*xT!#lWqrWv*T`F%d=zXq(ZJvFa){rgW6XtbS2kc%t~0yGmuV zF4Iz&VGQ{j1l$Rj;vrj5D)Etox)I6q%+9to>O4I-ZM>?Z!}|WbIbVF*n}@7EUcOV!Ffc=vx&z+=dDI)KkkCq zlGT5zjQC?2a=GrEmf>-Y&p&uO#qgP{ekqqk3r%66558If8~;EZUfo<*;`wbAo9iKF z5`LS78x+F*pEj;o*L>}0@9B@iS1K%exkGqzzNbu621X(FCDr~q^9RsDEXK2 zgg+%JU%`?6HZCVEBd2xx_k89`DueD@S!%|f$>? zT<3-Ng7~JbC3-`m&7k*3MwXNThQ$;_Sqx0_pBI60tl8EkmzHgg-HgrHwse3V1ow~I z>UQFz4K!Nyp$uDF9$w9_e%viGr7?HrCva^!w8JE>gaCZ>9!u=^Df-KXF%EXYaEbE5 z;MI<8V@l^im!@;a*TM`&&XeT3yx|cuf)#2}A=(eMM3P>VHTSS)>8eey+7_cjNqqfN z1RevA&}E4eTG3VmOlBpAc=)9ge{_du^xJCva0oY&3Hr1Y*fV5CoFZSCsVe^IdSY@( z^AttdS6scMO#C}O5u@3+c-%pr)nwjXZdZYBH-LS1>1 zQq*3B;F$~U28+l1oqD0VvW>q+Gi#Aa~`j%=gE(KY9h;Jf6dYm z`X;afO#ArhJS6+Pr4aY8lHE(X-F#uQ!n_EczEB)^_FK_+-a0ImbhFQTH-Bfct?!cA z^nYY5vJ)Amqu9md@pzPF$eF7zg@0X==`BX$#G&R1EtO2mciDyVB1cm@8B@8W5)=2P zvK=P#RUnfE>;nX+8g7YW>@rmTW8a%ORu}F_>ZyGiuvc=?$D$-lR$Bk74ezg6Qd87F z+(P&7_I=A_U2Du%^T{hr*AQ{C5wTb|kvLEl>eo9bOVX?vS+YLy$u21Crq=5!#fuwZ zj*r=T3c~n#51OBKP!CWwKj$857A&uDc)cgYw zYk!%%Yjv?U-NDmM*KvsVN&bSrfO9-d$t=^sH0k}L%VGH}arJR~ddKyOQJn$99VU*Must0s@elzV{>h(|}eF3CZVxS{AG; zK3F!BWg4naD8+qYo&#AL;v{nUREoc^O#kKc9JTf7g_U=t6pCkAnxOp@6t)ZW%9GAV{!Nn+V7q#Sn!7BLQ{9qm!5`i)rUeiwZwHukzZ$X6Dwr&IfWs_?tV3hW>n z;8dPE@=sbCM%0!Rxl|H$rJ49K_IyZ4@nzE>RmRk(&rV63o_Q?9W+z#x0kZXcOhdaU zI^e=|3En$1pBAI5NGNhJv5a*1QQ=KHFCBKy*NS(^Wv?CC`I9Tpo+^Jsl|Jkg%hnr$ z-BJgWygQ9RaOaBBfs1x12AyL?8(t~@@%3}l^Et!x7B*4Ov8D%1VQ-$M-LGNHfl;3q zbd*C~6e0R3g3;(e5S$zjMHZjrdVrBWAyY`Ckp2pI^|w2rN`vlAIES=ss;bH|2X7xb8YSqP%mmw(*S-DN zj)hcXiaiD5eGtG|(HQ#GdH0p*K;{2LHYGYiK59=Z^SCY(H_vU?+aJEJVRl5w*Ge?% zXt{F#&+GQ*lvnU!Na863q>!~GMywuKmJe^2L3tE>8D-Bq{v~U4dN`1sqcW{`t63)b zY|#OcJ3UG!Qta|< z>7@=1I!Rb4Sx8N_0587|2I?tj8B{FcPzKR_fh9(6QtO4SLxjGncDL5qzQ-J!m@j7W z8gDi)@?WoEJRF7)U&l{j6LG|oAk0J_>{+sK0`0a7zoF`fH9l73m&bRucGP^H+BoI# zhi>!x&e>(Ku^R02-UPBy0+pwAnOs6kHad*H4;3z6e_P#dvPelI_Adq;L$x_HQUcnt z-I6adn7*}3`4(OuW~03phRFS*yvGEJpg`(z8qm{R#n1FC3w06>P>&EnBav4@kV(;0 zrB=dA4()pyMMC>5R=H~JJ{w@JD`D>3u~0@n%-5wQb|9z-+HXKpdo3vCbXX8ezfOwV zvoGAPrbl%S+}JOhB;4+CFp~BsaL*bJhrL^C`=u9Lu?QFRdJ7$;Vd$`z4P>UZ;oHo@O ztln1+FO^BvpKa0Lmqk|(mVS)mXZVRU4N)JMpZ>Zmv`HYHw1c!rvnO#qbJ7#q*;O}` z7K$PjWql8Mt|Y~L^uKZb(>DfS|wVSvi7Pd-4)1C_Q2{f(pyEt$H%Y#k%|4sMkX+7HLa zcP&O0yxcC-Fu0^&Jegv>yyF1GYZq-Hd7TIY5z@}$}G1q>nN9%vuqIJrU>Z zbq#mRSMQW?UF8kMf`@U!vAaL7#2;aROieKZK@|D{fGX@i4h0kG%S(cV3y$hbby3@D zx9YddX14c^FN@qdk$k2qIgT|g<%)I44wZWXSfoC|%o?dq(pBhVM&k4-$f=|&xTq-Y z3zyfCscYKl<(mY~>%zTci6vONaI;MyhaCHNH!%kF| z63FYD)$Ggb6s?i`k+=)juiWmxn-SU7uRoOnnL9v!M6xvq%;Gmto2f2F`LAE+s}I?C z^|X&LJczHYBeayUTLEtdr7gi3poDWx%|yXie@B_b%2IcYpGo;#y8SFA&TDA(#ZbR~ z=Pg2vfiB~vj~^P}ogF>6k{`zKNJSn4uMYA4i}7B>r<1N z%=bt4{Ak?OU!fLu8Y!a{-(f^obS00 z6Y`I9=ZC#Cenl2}g>PsNCdq(Wt*&nq%Vi|Go*C#cSySOU=UPoxTM*|xaLqy&apde{ z24gt$7!nB)dXemyqtv7AB-38O%W#tYZzj8GnMeH#OV4(p6PGKPVIC~F)IUJp|B4>I zf46{;p7%QprOM&};lbL)Ny{~ory5zReM26&#IAZ3h(S!GoT@l#e~0<2kbc_@`ltZ! zRsJ~xsS|CN@LN12xGiK#bU4*a;)?x_Jhs`WJ$te_PSjl2xBTf@E8bq%eoP{^OCL;_ zl|}}%7^+M)^&p85wTY2KtB~~dzetL{eJ@?{`l*~}UiyVu=`h*2W&d0Iv>#`XRS-lM z99UED6W5+27V_uo@)L-&efQtB8P6SRYjK&bdY5cr(Vpta)n4w-v(4y#i}?Tx9@8}= z-)B3`NN3fhxCW(krwu(tyAZeQm}AOhIg$cPW_wmlWmIai*v6{*rax5eYFy_wGY7>M z^9uSRR6$}Sr$doMnSuMoYb^_KZs-Jk!?})-{jAZFX|(sS(bX%JpEYCO%LLtOyqAb^ z!*t<@=SLEeHS&Gxd{8%e5H0})4h%^{_!IB0_c}jKZPCbPvus4p9alN~?$LXV$BChN zBm|w^jrcpPhrmcZOAI7)Kw^bd-d0jQ)?+dtSL|VPtLFiwb5fb3K0cL$)lTitH_u*t z-pTj{2^|KDK`eq9u@Ltw6fwnU|K&G1Zyr^jZgd#s%rIq2b?Q^?4p4Z-Xb_fsAu-~> z@Le47woV@^0nUT)g2!U_wTG0?ZFKA-u{=<({$62y;zs^QcfOO{53||#dsr5mulx#n z>`LCCvmT?EZXjy|sXVylk%5owmNiqwqwTI&YQ0+1vl`l(+Vuh|Nfs;~(H^i}2C38@ zDQX+&_hk1Y{^&t4P%jcA$$}7HA(j7aJBmBfVbY&cpO2M|sH|aXh~#X@bMx&r6Ny)F zYlhvI-|W&NY}J8>&Iuw=q+Kj#N@D5zzaWWOK^{uzSDNGFLsF+!6MQIFI@fQQBxi$J zB%6?p$n4#mJT~nxH6+}2W zndmV9N{L&qo+g}t41Ef|OzLgdg&Lgg(mN$Utv^TUiob5@Y-Syw_FRP(M%Tc0856u_ zfsZ7)m-K0Ce}~!g$p(3A)$2@}_kBvaoy(AmMyC&5rR@%sJ>g1Lrlf? zjo3)45G5F`GljNX0?$0x=kS0bv7cL&x4yl?tDQYn(-X)DSM03?J1zmKeHQx&(K9pw z@X=h%d~76 z(SZaWB%)Xk0wj-!Myo!95aht-$@wIR{){u=J;{1*2bbL=$aL!^ z8$Z?v2~KmNREQu>SioVpX$f>CNb}2OIbh|&)FDYK|6-<}YvD6{^VHH!P`g&<;c;QApt74F?3pHDI}cC)sBZ8OaYwsD3WqFMDz;GsDRx zSN#OD?nDGJWvNYZFBTo_y4bWU9%gYIkqJl*b6vGc;KZvwTX*Jpx@r7Gr^CKEEw=~K zBaZ!J`CJn@qYwgo$=_+fuJ4Ar;7B>y)yywU^-xCt4exq>I7ntl{8- z>8#6T@CI+XXafjb`qX_Fo^y`8dfBr;B0N*mwrav*5V;S#P)gv$-XP2rE@gpOLnKR8 zz3oBtDdI%X{fQpI)|zAq#s81J_l|0+-_}M^R1ic&DN>_?fK-t#B_b~%@?t~;q((rb zOYb2;kX|AnpeRHs(uqi~p%)QDl@fYDkeX0JAjP}h@7#UPdG{G(?{9zS+&#W=$Nq*R+mJcH5> zLrvg?ftx{6!ZCeUu6|L!p8SL3Tmr1;ae_UsA~hFqCqVKq%L$)@R&7-PWG1PG^p3bA zR#!DaajVcGw=(x!7UA=+;^8ZE!h-R;s(7v=^LY=lbVdh40LDYWwgY_B`1yOuM6?OP z4g7R?AJ<=9-FTgFe4t^Mp}jFgP5{iK_Hx@k7E$8M0Hr~gTLpqf!l$_xD^`Te6& z37NBSI4v3B#7L2Z56_;VZ{rVV{Ck)y4iw|&k@e3 zDOozp9Po%M60&MHRD)5csvyyt0`*lx<;yimYwq$o)-R`jAA}L!)xx(kCO%~-Cd>Ys| z=TWFC9aPU;bozalf{o8Vr=qgF2LuAr>LwwhSiYP#;du3xPAmstbNF%ZZwfG`w<}^ofPsvnqShEVlu}vFC0-nx_qo~8N0NefBMcIux ziqxtQXTx_3Q{suiwdc>ahQ{K$PV_xF*>Jk%4!+;dvu>i`EciOYft@VAorHLT!Ub5- zK2v$#<+t1w@;x7to^ zfDD;wk8iM=pTl7{fqa>sVG9r~wcXNGbZ)S^eNmWLQ)k4Jv(=auBNQR_e5yqn?MeHn zDX+ZAL(vYL!;d&)CIGkkdOcvOX9Bie75a8FrK$z`_Ok{>+1|hFoBZ?PrvE*06ooxQ zfC8iAsH?m&ACuwZC}GGSd_w@a3^kw+TWCbb*bcQQ1qR7EE?(q%#<0>~pYS+h>z3sH zZP#UsgKYqq&A-_sxFCsS3@p(G8njlatT7)l4YQ38x{Y?u$`3wX`5vZzs-=U>kKc~W z79_ZmtpSN3n0Bc?DF|JLH}fnfYw@4=Pq0^aRMm)5XJ6DyfXU*e@6PVF(?QW4#4cXF zBwqD4VMjIOmoWPRNKd|Jrr+Mt(+{We-H|tDb<*T}r(bZOI`1>RhuIMvkR5X|M;R{^ ze&*Fh4R)I9f3j}s9oBxwaI<0)YDf=Ta}UoPw#9bO z6sXS=*hg1-_AyiJ3q5g)Ks*GQXAS8;3_q;o@8u%CK!CN3>j29Pa{O>|bnr z>rlzYrz0SNBjudEF~O^fRpC6=?mQLxqpVOX-?`VJt|8ejmdP~Wk~mc#J;)vnWw&h0 zWQv0+7n8dgy)&KT0v8>hj9{%Ndw-6EvB4PgT>>&?3fxPbvCGpIcT<0x@o#!^1J(Km z10fH5&|r~`^}(khUsh|;UkuhP4QWgFtUt1jO1xBhw%zwFH0V7$d<=HgzK|+7RHf1s zbp90P^;JsMa~a;x>Nx>V?57u7c!?P=_7RMMnY-S^o&~h0LEAXLp|aL-ZSKo3K1- z+|^F0V1;M71%u(3$iQ1y?>MLke?XVIA)MXCpo72;8sEYn(JAXBCph#t1wZYs{?1$b z%mL@I-5P?Ip!JS%Sf? z^;0{2V(&KB2Rs%2yU4HqgX8}!)%g!|AN;e~EB~dH`G37uW}T!O>*j5!FeF@m8t7@d zJfh#?+nZsZhjz`KOQvPKw|+UZ1d&4E$>qW1FPtXp4~_Pn;f}e_zsOCD_eXSm%cXBP z$o9#D>3>sx6<6gk(TJDHW1PKOmXh7#R&NV%(S2(+(5HnfMjzWRgNy7x`XEAgz~l#} zk!!{CiFOzE8mXz8?sAXGnC7Pz#nsE z7ap%+C;@bVar&jSyNGSo?(^*53J&w&-hfcXe-^UM{nG{E0DPuBgu-JsaOoFA3^)wRb8Z1aPz1QyLGR}No}qHV zgbJ|zwR=KrV3Z|*9_}0lA~twu0F`t2Ie2el4Y9`p9%m_8Y&C(B*8lAasxLAKyHsI7 z#bKCce%SwKecZp&=~X-eAT!M48_-fjQK+gsZQKcyeT{#fX(Oww+?Rs$wg1JSzI{lI zN8AOEzf(uVN0)#oeuzw_c^i9U+K62H=pJCdLvA>5bAQWDk%p8DRN?QOEzu=2Vg+ee z?tt&R#*Tp>!Zlg}Ztf@JC`N>rD@8{-z7!|&-TcYDE?e2&b} z(Th@_YY9Y-!$!EjruKEhcI+p!z=VckgW`x33f|Wn^>^0ADyd`vdv4Xu*rKAYN|+v^ z+ed9Jwb)-!8Sv4W2?AXzN0{H*AezM}* zlJyq0rjfjw;VRh*DTbR6<$^5A0(=7`X)>N7 z7lql(Rpo!qmAYg1kP{leGIS=MYOH|kM7>a%=~o)%|3B<9pM zsV+b-kb55RDZlW=m6;Ns+n#(UtDbkZz~#6XHs5$`&mEYaf7PJb?5vo$#N_tLN?7NL zP@ThLW|e);V{di*OodJoTS^M2ocU}LLwy3^;Ra4uYLl1VuoHDZ=-X}`(N!e|U1{mVe)wRr_T2TuBD4qc{d^PQ!p$tIf^vy;!Q&2dCPD8g9(`)?+|J7H~d6 zV|USuu1to*`x;M)3Y$W+mW{FUHRAVsH=n0Q-q&yCeb1s`cCUq*_%;yk!7Y;<>{}9~ zUgUAI3FW9SpI9b3^PzI$-Eh}Df^Ry|o$7E38GNMfUV%=Z)pjczIc42=j5NUDy=RP1 z(tq+O=fT%b28KQn64zMZTR^XtVC89u7X+vh^bI~Va5vYa9J{ptU`-j$d93f>v`74A zc?diSO|G8OK*bju+=-X_Fr`@<2+DFaExp$DEic8O#9vRB|1|W1kx|Ep&)Z2IrMVo7 zcZpmiV1+QY+d{7VGBDeqvl$#q-Kgdap{y`)Rw$bzMUy^&I-SGQqSO$#=+v#>@=Abq zMGzrz=;p}hFq*%yT5B5m9!=gnu%a1@5zJ!ceCZVlFFZ#ZzEr*P1uzn2unoBRDqV2A zNn53Qu(Y7*B{AkcW=Ftmu!RdimB=`UY zdQGz!e^jala^JXvilXb*ml92QCO+`XQdxn5N^0(Rsv?ESnR``6-Jx9lHLpYMtvJp6 zSbEy5SO;Q~XCdw|bM(9M-7NT!@)W-?Ex8et26qd5yNK?D^3;29xbm0*J16TMf8_gB z$?zZ{-MPzB5N{v7quNY6zaIPLXM?8Df+bmUth#ji&*UfP+}&?tvuM~iv|+F*8tgJR zNogazg|IkpdKz!VTzWLJt4>e*adTyJv#`djBlwI_QupHRUko{sXe^85$7n_ePuQ67 zwU(V!npDulwxCM!=cSIZNM=$2GrHUA>k-DBR;j75<`9|nmHSSJ&iNED_X&FSazkwo zDuM62&OwZ<5^6!81-&HMTZn!ZrITSq7ZPHn&p?Za7wI<_r5xy$uT3&C)Ke&_ccz<( z$}!bEH=t06q|l}?Xx;ogL>;qk{dUdA$jIiEbGyWlK1k7w!!);9zlMsl)!{UG9r+g! zs;c$i@@ddrch2Mf6T=aY#>!r6G>;bQ8J6qqm*eh|+lYEPJtUjv5N5&jr#-uXm`wfJ zg1CukkseJfdvLqtEi=+QP9Nep0yYAOdduKR0#@vSR&^?h)M9irzEsV%1bP1HC5(J? zB#)X;19u)BY2JJ~mQ&<-@#e)szm<=vR0SYdf{cc`lCF|n7n#|%!~KHXJ3^;#V0l)? z_tB^(W6A~C!=V6!4+ieVy3NOx(^u%nCqZSf`W$jcm!`lwYbT4yuDtlcuFKFR*Hthe z{|M$)S20z?)$OZfke}T@kC@kHI~qkiC30V&&2jOSRE?p4swP094(Jjqja>h-W-Ce` ztU28#GBhk%H~ z2~F|9({Gxz^S*vUQ)^;^lJVn`@8Flr8Z(HZ)`_2U&3*iX!S&la^@Mj?3$^E;)TS#l z$>@-Bw|l-5n_K+Vv*Vb1PQ@LtNBvha!!q~NzNX*HcskuBCU}iEPo3dCVSZS%l7Ro{ z#3&j^;qS<1p`}qB%W!0hmdfTkN6us4{_v%LY}fxy?WTYBP#?Xi1w{V_Vg@^7$(MLq(I;R|^<${lY40NanyT>t05DQA5Rp_4$@%e($c34} zX_z*lARg^!Xm*z(-5$i9(qH@;oIS)E&|4q9tj`;@b*ruC6TAyrbFk4y1bRPh_-(S7 z-sZxh_QJa4Z9n$o>o?4;p|q6E{yPdvq*(2z8sq3Vd7@*q6{ zHY{_P(kRd($To%Z4AZYr4Z{Tyo!OU&Y@M#MlUu^OkMEe8JPEC6xMX@L+#wjbB&CS} z4(g?{kz$hPOjMuWaBJP?Kc}G|A3vae`=;2C3G^fotrGxy2NY zxeUK+lIq&KwOxOYncpkL6^|iH7Q{(`T|ofU)P`0^HCey~5Xa+%@OQ^D?j>{{g~e>{ zbk7V#h{)JMUl(NF8i45oH)KaEp&z4E^%n>z24fR39+*jrHZ2nK1bLFIecu|<4Ny;-(3;CvJzTx`^861xZeGs3 zlYaU{t`iN{BL7YGJ^L)=IFLE9I)@Yo@;@L$33IK#7#Qgnos-RRK*}auIBS`nGI3po zH$^G^)Dsns;_g-WPWnJ#HKrYM9Cj5L(s`@!kZ=lh_KnA)ESvSZvJz>i)F`w(g!NTg zdm#faA6O1cRFhNBJd7s2|ASWOgf6WZ#O;eAuhue_)+ z3xvHMiu>_6_0X*=<|TI_%oebO94*!lN|uR^1iM+X^YM^9K9V08-dK4=AHeX-WKR7& z9{LU!pSpV|!ZQY~`t6v)F`#o^QA_3Wz&mbA0>?iX1JH@v+&}q1R0%ehmCl=7AHy18 zchgBzZag=H<&VALa|nwy+U4CnJ9d#vj|2hMx&-Dy2B38(9Z)3JP%-TavOKMzJW#i% zBmD?wlwbWZjjg?XA*@f9ep=(Mt!SP7U9M?P?Q6tw^>Xi41~1S?{2%h3-=_%U+9Hae~Wi5I-=NpiM8K?1cw36Rj5=V87u9&o6vcK|WpqcOb>Bm1Xrx5lKT3^@~3>x2?`zBW^xB;dWlf{7U`f^~ki-ri|Y1>eHytdejRC z3%Zz6?7X|YIXT|h?}E02Se&Dhr^RufA2Fo~=hef`FbcnDQ$?x>cYocbo;`-B8odks zQk^l4u@v5@vk#M>rW;U{&rIJOpnQUoc8886F~Wr7Q1-R{a>E5&pvB@Aug&?F?DA4C zig2~6yn;HRa`WsHyNk&9cI)*!nTjQkw@`1GNm{f!=mrJUMfexg$&Kv|H$OF2)<(&I zv@1#1o{2RiYvIl}c{N1acR%qpnu+w)RHYSypP%DRYS7vO`2;l>M9x*&dGhcK4*T;`RC>2SVz$Tw zlI`bKf}ZO%s)sO%ZKWP&SUi{?v$$LCY-5r?MMBQdP4`rZHuBh$h6{ma#~@6QXRg;C z!riM~kBY$ZKcRed;FYk5&fU)?(8fSiKDL`ZDGIoBnc15TV#*l==@ef-+OB?P)R2=XdaFGIJIEfv#6B9 zlFjF8qqmqizRPvkp%bVYeP+3?zoF_uhF>mK`4AP-T3+X>cjcCBjHwXwOAMGIA<*nW=bjc`O*v(&-lrs3Cw82LptT2v7T;M zpG!?sJQM?Vc~k%$Lr6z#d1;y!nILwKqLOIS!PG+<`$eL11k7X}H&Q^(X?MM*1*p;= zI}(Z}D1IGZ!$g5yuo0*WZc&j$nJ%|%t?CzRSHn;T70HKi#VkB{VtrveapN0?Pz$qD#n>S=NYVOSS%3>&15{I8&<7^L@2AYeqAjW1OAdYv;7H@vGcQctEk zrrFm%Vzt}C2k{GTRfu+JFggU5k) zi$zn)75G^_x5=hPyYdBpI>2e=z(;I7O7QJ&uZSt83&BbD_PD^Ny#OzQNy+4x+ng5q zjiO$9Z?zk8$uqE*w^igmQx!}UkPen4TP|uQFG_oV6L*(dIsb(oEXQ(eBQF)I0<&nT z9&HgLhaYuye(Ec<;`CEJqnxd^#qP4~0PuJ^CUj`fI&#l&IX?>5d{gT3KhahDXHT;K zrK|RDpN-&?R83-Zr=Y$s`t+l|fXgaRjdo-km9?Pn5oZCf&qB5s3`||zT)St-KXnc# zJwp2d4%y>c_%W>$-al6IZTBZvY0DN$4dl~qBj^azk#S?=e_%O^YCJh-Q?toA=L3L* z0c~DvXULG_g0!Z=^LGk$xbw6}M4Ib1G8)*dkuPA1j7n;l&ZJ$p5{^#IX`*4Jo z1ze3*)*?Vv{jAALHgXVLdYKs4+hYCMeng=5C-gW>i`+wGT67pfb={2UqTuHT6_FdJOEqqUlDmWH>HmA81 z9qD;dY?D)U4WUpC^iY4m%s2x}P=IvPRkMk~N#p!2-I=UvgtEtF^LW9p-Vh&s9j?9T z9}E9ex--^ufOa7nzd)OBB4p<(7BRhId*xwQ5MgzdE6s&-U2CL-OS~n~TJVwjGvU*w ziiGN`r_0`18p4K-^a$Ie>5+Zr3|(@`V+N13^2b(1Ksk+lk6JR=q({-9vXU1HFfni; z>n>++e83wg-LI(ao^G%dB`?oFx*n&)jFm=D06_zMo z9o=k#76XF`HhLT8jtM4m3f$1H*LU#Z2zmX7$jl701Ms#`HBp}AL4HFRnEgQ-oSi85 z@^ND=2Tuu_9fpiQA72gVki~iXJsfJ0uwaeBetGuZs1dX&rcJhMcI})yrpXKo9#xw0GCTfayKNcx+eCXEjFsTAwas=0VD%>IUHs)GCPuruh zYtIP#P-&f|w{t6gwA~$>IMQ6~F9rt9D^#hhyzlO8T`$4XqYPC~LJpwaO?O-RSrb0Q zek@-2keYL zd^i8lJ&+j#`s<+*Ky6t@ymkK<12|3f9uwe_Gr$1k@Yg?kzVhfoD-fY=niKWfNwX?s zM?!yB_LU(I*7#8E--kS8HXYePK2IXiUP&YvVW&a z9GoaMD0SYQ$PiB9{5>{BqvXiCo>r_0ruTse9(t{i7;t4ltSF(S5`h;qhSW8LtK>V@ zgp@tiO^8j=VQ6ylJ_Wa_&IJPK%0Gf{>Rno0%e7kS1qz)7bTXq8!3NW*sjL3n)L2y; zZW$7DIpuLm&^5j~&lh@^jz9V_VbU1JzI;56mP|GTP7z5w=mwB@yNl3`4-1a%>~{VG3HZfc;_zE)$%yu%7oROdm^{*+y*r5 zPqoC8Ar!8D5oa{@5vn&<7jTH36DsSw7!ObIO&W6r;bSF%ouvJ}$#tRMvJuG;2r+_G zyJyG=J~-%$zbGc;dJP!>lCYm@7H&mVK%-kE=wCDSHvdS9PmnR7HV|WAi*>fZuzMMO zChrbIYI$dwNKyc2Loe(BF7p8OxhJa5IKr%YQKE!5 z$@2b3S}$h11p}rY+k&0ML#Ff=c-q_*o30Uthxu`@bqCYurI-;@UI)mLT{IRM3k(Zh zf*Cc*2d3{gB`izh5AC2i$R9yypgD;H$_(xch)Hk{^h}d4hT}aE)QXACs7cns#~XND zpVX2p%F3%vT)Ls)$(^PInss-WD$O(7fKa(INI|qH5n7n$aY!-Mg5HB*A@e^#FzO2> z%Gbtct4W?heic7fy~}&~2efe|1-@?9_=?cYdYqPHwIBS&qVdq5O2tMlZga|)lE9{~ z(gbb{Jt)}fl8MEc!}d0ksR2XK252R~%xpZrgsD6gPXX-LcB@6IixA%-B=br(+U+}T z)2w#z^OiZ`w1XML=i<(lr-E_e#|~HMEONkOH{3*v-NT-yT9cg@aUL-kR`nqEH#vbx zW86~xRhU!>$zEm7!?X_DPpy#-S6X7IOaI@IZ=!XEMaU?^ATF@>9zYzbuYc$Iw1S6# zx8u9xw@iDfUEZ_2qi$8m^Ug;#1?*GOWzXy~A2l4tB(Tb=d!LfrdosNWy#VA$y)gT; zAM#w3;uZXNbJ;gG3ogfHKZkt0p$k#u0<>$bL{lNTWBj&6MW=^}E*HEq#}uZV4;71i z=FyvGMdUS6!b;Mf{&tP{`5AM|s$R~6G)@6_uS3&}PVgjTVZ4*VO@y>J7M7Na^x=4C zo^7r^^o|}MsViswZLkV)oGLP0w#Uwob57qZYT8{pce(4^5WV!w(o2S3bpbPM_Ej>a zY;}&u56VZCZ3uDYFM1gB+D^4bqD1~O{qSTx?@G2SUJfQE!6hUqTC!0<#W+wK;F5iy zs%1^-2R#e;G-5WdU7=gC#hC4n>^X1P^67M}#zhG2Fe6dXHDXu5Go~4<*82Cw% z$f9=~?orL&qz5dh%c(fN^@LxxBjD-~{S!edKSP4A1!-XWi&}W8dbP0ybp(1o-=%(e zi@OYr^=hs$=q7ayG}RFpM8vWLBD!aVU1Rsn8Lgcu5mg+uEFyT`$NCplFCOt7N-n;V zvxFHExtdrwE*LkO7_~CoojBg|?ZyNB0$;eC%H8vxnUxj_2YRPbOHYzyx2ck zePBs1xzj8BYY)R&eTCpiB1o;39OXDZ1z8t6{B=Q+<9C zzsV?8%k-bGU`=Nfu@^bJzW~5f^dXZxi#)B{Q;xT3pD->1R}NZR&JyIZNmGJ$QwEls zKr25*T)49KrBo8f#GM^{Kflt7bSLIh?IzHaJb8_LnSjzIThF6oWEVikoqjl0jDSB^ z;bJR%B&YQ${qg1w$MTZj{_xiIyw1SYLm$P|X6=7#^eH5ln4`L8#WJFUP~N(Tsj1`T z;D)ecn^3_wUWRKlh(vUC*)pMLY@f2ZGDu5}qDt0qI9i!luD#Y6MsyY}U)(~k&N<X$vuEj3y72D&-db{N5{)X~}<|h-p4y-vnpZ~kBKIi%33z$_e)l9ju`j#YTqp1>hHyr*BdGxxMqwp- zci@p>>PA5y$jG}-UDe*|vRpPhX|8n6DEZaP-Y+K6C-{z1@wHSyT#iMNq6gDxBAXDw zi|RX0Hxr)n<6K$Q3{|GPJIg1Aq=9au zLu868PU15MGY=kpyx@41YJT{|vgD{95j+KYFT^wkvIHuTK5!|Qtrqioaz5vCWuB>v zKl8-x`xxIV9>r3O0l`{+L>n0V6caxsyD@1?q_htOntt#2dO=@!RlcmO%KcapvzU7+ zq3YSnvRSlq2M20NR-aZ(*K|TuJ}aPHaSlF=Uzn{ZmZ=QNqh-!C^^bBK6U(+!W~F}w zr#YP7*;`rxT09OA^0k0XG=+;CyxlfeS)2HAXwUMe#iF%lh-=8Ytvth-m<+jIVLOIt z<7XRelU<=H`jW!LBK^L4{h7-B0y>K`5sf#C1qL0!>@dc1`hY*sv=K5`RBRr6w=UNY zp5m1iOj8(-;x9DSk}4m*!}2bo)pr0(mW=K|3X!q&(}@%w@o>u~nhr&1$Bk~w{_FL0yiW7GAS+n-N6_@~@@xFp2*5pfmskFG;dz@`Sp0X_n)fyR|J*;DQY z0v+uGfAOIyk$3^_?_bE%musI3N8OmPn~Pl~02w z!Y_pSaA980To`y+4-G3of?pnd;K8MqaTa6bACby1-J4W!sU{o z@4kFZ5IoDg#4*(j>O@@xvctyP5Vk<1S>{@w5`D8K5f|+7m{F4*ET_JE3uOHU&apms zYEO$P+K+cHV|3~HrEt4lE%_CxJL)T+6nB`qP$w;6>g33xK+P{cUTnGO^vy)v6CF=} zfhVWh4!GF=PlZClG_dn?o$ibVpPI?`#FOgSv#$5fq{yiPv=?NWcw6mFQtr39S2WygQ z*nE1Y?8<_0ApX^*J>x4Cj1vN8LdwUYyC3*^U4Ib2edK>A)UAj5!K*2u^0lV2z{n4R z5Up|T`-mK~W`Rb61sp4gFr|-kk49!3AgX7~I6jk9yO*i!yB(x>G6;`8MeZ;m!bm?> zejk1IquzXhm-(tU&dR^rD?4pKc~grx^r~q54mQ7vfo^wQZvkoy1JNqn6az1`BQDxK z5D|jnjxS#n0taG7;U+}y{z~=ahBqO8pJky%RAw#v25 z;zFqEIOOeK$^>;f2lG2!7T!C>6km$#MldS>v{mjaJJ>G81~bfSF*QFQ)XrTc4&~VfjwcB&-hC}BozdElU?*4 z=?7^d`zEQ?H~ua`P;(uM`~MPUl_REkL*6_WP(ErbK3gbVDlQ`Zq7H*5xYeyD6&;GMgJIYqQY_fdITnf*f7?F>=8`ul@~E z#4|?Y(cW>u(gM`uWM=}a&L2~7izZ*?=YCV>b@;_##viQPjGN;v11K)FfmVuCpa-1; z$$v2Ky)7Oqb96nuGB^#j~g^=g?N zXvg}}B=sqb2i}Ge^9sRf`z6iim;gx99shWk;`&y&pIt^I<|5Xs`dE+ExR7<{nCE^v z(@o^nd#RKgKv3T}K?;oSP#3k0NDpcA6NG8*=Ko@lbq=!h&v2*sNJ9o*1AxPa=d~0| z2i(1*RE4jaKYARlCU8(R+_J2;hU}bjp4|GcGMOCzy@8C;`xe&F=^h6MenY9UYK~Lp zv8xOMnVT@4dB_E-_IM6q<;AAO+7IIiSTVS%=hFdt3>5|J$8>IZf6GNpO>(Rc=Tv67 zMbN3+$_JN?`!s2;D?ZvO7FkJp)e>uSBzY%Zqh$#ItX zA=Y%(61{hSOuR<+yr>Gb1Y|9EUO1mZbG=cz=P7KdmvZZghU$$oNfSTHsh+fQsjBz@ z0;FxTP*})vR=mAX!0s{)A+ZAyq>mh}bki<$H~44qRt)X+`i{7T(TVgS_2T8;eU5~) zV?^rp0iPR|t@%sI;l)Y%Vqqr(>&^;x;!C9beGl^i3ewj{}PD#Z~Z&!B0DlH z$g3K~b|9jJW=%-`O2NT{nSs#IpdxDx(g#UHg%_1-?@}N|#cBJ`vdH>)-`^8|)L%)k4O@aUO*Va3FjzSD7(;@8i zJK*o{&~yZ1>GLm!B?vII3MgP||6+KLq~8X+E*y8~HXoMhg?Kx6`Vhine=;1Y>nB??V_Esp1L#Y3}M7e)9Ng?k6jS;Z~Fib2((3}C@!IcBLfh_&EL+qbT3I4O8 z(Yb$Kp}#W7efjO9Q-C>vXrhnlXe8|y19qF54yDHKqW)w`PQ;%L4b}bg8vV%}^!JW) zdqC))+5y;;eZN2w5c-%ql)@Zd_-{S4xwKnY%qssc1~Fj8ML_?0X#e%l{_COrm#6(- zd)U7`?Y}(jzrut6jqqS#jDCgOZ#|MXTy2R}nzecck>*jmBmDCHzEJhv!CyrOe+nP} zMz|!I(=z(!;3^2(37uT&(qtR~S=VN3=zf!Nc=8}AVzdY=H2=;_Mm|FRo%A)cvS=4c z(~*SI<|{a*4k9Z3<$Y+#~7IKqUTg}^kRMOLnPh8 zGP?SCAH=9WR&pE44P5#^0lt%FTVz4$3&hc^Gr!A%x`GOZP#zsk2CtU_d-0#A$}d2D ztn+{Z4&8AL(TNEIA~K9K@+>k2#P;k%#DipSvG^Csm_~_xw(Zf7@ny#Z>gh#Pbmm@* zAkm>@YPu5*Nk zKz|JXNbydF=#^X9-1I$nssW1L46|~@mJGR#%cP zC|6G_6`1e4R-tAailoi(n*VRpKhzqJm}FcWkAi6{Wqg>-dN2qZveLbErr@KNI>&6i zEcq#W5@_#u2K@+xhnk!f{<6$OFHm%a7k*x;szijo7&ABK~o? zwGDtyt>t832VS#ETEXcnx192k4i1^j^nTyNWgGMK7sKSYb-ZrgQF)O{?a;eSC*tU#nTJH|yc?twrtTqC{~m>6w`j zOnYW8`t2^2$EIgPooC?(ccAP(GIot3&;n+m_(7e@HmKF1Qq`76+0_Iek_zF@NY$SC zzIo~uxd`=b+6uTGvt+g`+l5XLk|$%(O4W<;;rA~r;fgwqWOI<~v-QAyT81^zzd{qU zD4EgFSZ9Y7ewS)hnq57X>^Y`>A@JRA%^$B=_R&!*^*_9@u@@88IQl&~>FBV6ylZ*} z`IT9JEM58c{2UL%o|$45Q9psNZuTR=x$6rtp~?{V#@dQHnA42KXKdhzD3TXB40Q%B zgvz~eQT1Tyk7bu7xSVjRMH=4)?}FF>}rbSVD3_ZPXCD{S_74T{;b!HZGV?NpqF%rn(nPY1grrGE#wT3D5hsXE8#OXvUCpP#eGne3-y#;84K zR&G_h&ZSi78!(Ti9Kbm}PvnWzJPQEM^%s!Q!7~FCJI$D-WK_WZ1KyV&CJZzm(P}eX8hDs`@?aj`j)D&a}U6XtO3}(ff$eg zb~ZF?`^8Y@AL|~nfM$uR`JP)nI^r9U+Isc5vSqJ8ave7Vaq!5@Mp>=Rwy$uG9(jqdcPbLb<^}K_SkIEZ=o>zt+${ zXlcl{HtX4}tF2s;+zTmO(nAKgUFiC35A{4NiJ%D#`@d+UbKD6CvI&^boMFN#;Z-Iv z{1sIGTE_&(xFScDiz5XVev7%_$oi`Y!(hLSs~L7y%l8y;UbB6xa0eskZP-~_I$asi z{T2TX<06#kDL0fqcb4AVEd4BXKIgYZrTd?`t{!}{4ts`mIr8ZQ5%keGR0ov(2RXWs ztj{OuWZ3!r{;Zbtnr^Ph;hhyP#;iC4B5>)3!y1-Eh=WCyy|jY2{(8-e;nqbLz3ePi z#Tik!$B+$;q6r5o90CXz$c5=Z6c{NM@ITZ zr9CP}Zp=WprehW)zq~EGsHyY)+guPalIzHxVoUD8M^#e9sb_~;M99i|gX-W@Z!Qg1 zOY(AT$u7jHm}EYD@VicgaGmgqzjV*tRit~j>E~@nJ(Ad6!nE)GWs{Rt8K?`T%EQTpFE*r zmluHk^Zq)?iwhfA?`i^*dX< z7uGGD`BM1lGt8G>YN1C#7l#cLp2W8A;qr2Qz*l)T-cY0_`F^vUCi+m=R{DCQ}`85;(z1fVx$abyQ{B4UA* zYQHeUqf-?%V%aqEK5lkx%m2mnjeZF*5(D`$yf@!Z&y*qH2voWDt8Mm zWd!{IAWMv}F>{r(%|!pX1;>rPg)%W+0yf;eiz_-y<|H+$M&dEwAb?v&6 zR{CZociWq-xJ4huohuVp*_E8!YJ@J2eC**CjmtNEIQptA|NGn}0D)TA`WNZjf8un{k9=v*(8b6t+lr=;~|6NH34AKrx_vAPl*IU>`m=n57 z&ep!4ZY~==!z+?7A1?VWsr;&HyL@~?+K58Fsc!+_tEJJ@23K8_FLngWNT1`rAL!5T zA@K7vwyDlu0M#V z4gGoS1fI^ZUCGY8w!4Oz0+bi$NJ!PKxBV3GD<%8QM>9Wa{P%blK{!WJod=G8@oWUX zhCl|eaoTc&zp-oD z_84@)uVU|FLa12uyUWs6&N3K>kp5-z9#|jq3=@}GgCrD?)M)Qv`s}1174~)wS>xH0 zA>&niZe368&i*RPZuB=;P$P(Lag09^)7y%%0Wz=mVBb}EU*00dg<-N{_r3UHFBrUa0 z*1s8NWPiyPRM}VYim*2(Av-1OlA7=#=M~QAm1AICwPS9>RF9jFfco0Nx142I(tv>< z=i7TXi^M|rLb9Jz&XPUw%Fn^`=*)r_nrds>#>C(6yRa3`bVVkuHWvowvlK_L^9!@T z;>gzZflAQ(Fl=-%3<|i;=dPLHR_ysd_OLSNgUsfyN1YX{xsFdn%mj?F>@j4e-;>N>{Z7=}PRu;f2^;AAG7;lV+gd-TLknGbg?w7xd z#8Fw}UwGb0x@J1c{7}Cdx8&ev@1$Z&M72S1$#iy?xr^0MvhJxIxYQ)ne3RmlN@5Hi z5uDtCew$qJrOkScIwF;Lm26cOt%~~R5*6z6?`?JmAWr6_SO)p6HeP+baAh@LajU-8 zLDH39Hg0ofn&3w%L*)T_YQivB+P=_xBczj7_k&z8l-==7*NPcG~8Co!*7 z!-e6asA^C+9c&%wf3PsuVa>Ggu7TA`4HKPnhwtY{InEmwbK+koJo&JcxN;HQ;I~bd zz_da@WS@=(J)na(x%)fOdM;XFLSaH?+wbwfa_5J8gKm~icFOL3-NBiM05Qj=A4Ljw zn+SQKh&oGU9Dym?E^PibyQbuC@e(vu!JvfeT^#Tioo9ui>z;VM8~^qs$j?eltg6i* z%O_;^|7q{qqoG{C|0to09EGBq(UIGrNs8n$C>%%bxh76Yg@c1kMw3xQ?jb3a5itg1 z6hq}Qj@zh7Q?40u8`mkCaXS+;z9=+sm6NYLyR4`A28x2SY&O!-W!_JqP;_#rP~L+%hCcjZ z2JchU|AD4<2VIb+bpEn(vCO`-D?O4U5?r`V%brtA~^OxEyt^@o+ul`nG6Z3pIvCPnwj zx@uD#4Ff)S%^0BO3_)n@I@TxL9Bfk=Dn^xYU)UV!Wi3rNmxN%3OXV$NjOixPvZ9ZS zJ^esU6x=88p_D!^TW-flN=gKxlCwXZMB6j)fZ^ZhM%}%A=Rnhq$Z<$y^DJQ>rg40n zqAJiAFka{+Q!a{cUcAM})kp`jX-#e?N$3#8{QBoRGShU=-!UF-pd3(tDvl5HswQ4d z2?bWX$WprWGE4N%uwh()?UMpr^*KMlGviT)5s$ z1XqPZ#e$gkx>E6h)X?GWg(kD7Uj8aKzSn;|eRokxOonTmxA15d*G8~$BPV?%T zA!I}&eA(7erM%M`zZl0b4t}})M9Fa6hK$Z1!V_;DQL0fMmf%SRQlX;U3C<4Y=Oztl zeXA18@%9Vt<3G(rH18=)r%B%C_cy2QOR}>ax+UVNtNc6G3(K$-yhOqdQIgl2f~8{A zvi7dRh~`Dy)6dH%tYk3s{qFuBaL+;#gSxBG;@+_>4vUwA^To`jwfleRA{D%0kax{^ z^9fd6jr8nSTDSA_+;o+%__Z&cUPKxp&kZtgL&*Bt3rw3&A35zBHb1d@lE`}ZgGwfI zzAXCfPHVD@UpI`ZJXut?)!1YwU~bR}kRu9kaTYkf?k^tYb_xu*7F#%$C6ms!MfAYR zpWbV`1UflMRx7m{+Et6@V+hMfz;=dXp9LG;xgQ%rQFs58#2QKF@)T)7eAD9T`-=DC zURjR4z-0H_;p#@lP6=-_uhv#XrTdEIQ74O{dHpBXqr?z2k zOVG4%j`+jTLdK@+#_+MbUC9o47LUh7mHHJ$a?=9ngNa=w&%;0d7NfP5{pPT8k-deY zq9W>3X>HGr?iEPTLg2LSh zf%&D3PY&QIix96C_!#bfTIMgK=94Y<)^bzpY>o*9nf0c6X&CYbvYxqGo}auxrNXYm zHq~wY{m~v-!OmW*i&Zq#dA~+@!=nbY#c0NCNYdvA3p)XLL2fdcJxBGBc{|K6i4gZe zZqv6M<~oTTE{!{m zN8|df&G%XkG$)50X5zLXhaOQR>og*|1u}d*FR*~Bh>!a0kMB6N3!P|tEHGgBwWX?= z-lzg%uZabfRsm1Rt~0=d1ttNH%X#v$5!O5Dz(=`wPkt1AuBP^y8C~aWz;Z2WYpt4l zo&wP{3KIePjyCTsOrr%FF4yJk>-5)^yk4iBnl`@{yT`M#Vf-8$y2BYXOens3v zq})8c&ubBntW>7T)@kk8ERY=3el_sgm0vs^HY>ENh7MPsp<6{k7iJBvpshu0X{u*5 z?RrwpEF4gNTgMY#sXUS8clQ zk=1gEkT8a3Vvwf|H(jvFpGlV#G*n`rTw*9^s>`t7TbA<6GVe4DoaQvh&&Krs_}H|j z^d|jq=56h|o*topyU$jE0hw6<XsPZxv9u_%eISV;b&`=o3Kww4HCV72sUkJ zuLs*2>?X*B0t*J*ric!KcDwu? z+V7d07#`RB5vg0WSr(dc@w)q)#zs{_BG=szGQV%B+B|1*rfeqBT`3=WiK%*o0oNS& z@gwp-9MXe(6}len%CHDAZJs6XOYgbY>uH_E3PM(4W65+G!C)PdT@~YhuC6l_Az4c% z)+k&`Yg2>gs?50FTt~@A2>aNE=`EtbX0xHJqp?k}a*SIw+naXm67gC6?#lNWd<7@X z9CwRRv(u;{IYGEURxlvg#@3lm9l`bO@Z^SPjpvup3|j7aDdmqT-9JnfR|4&akXgSU zjGR6pqFkyu>ruXJ#yj0DFtk`c;m>PUy3j%l&}grD&oJC$!FX85zZ@mHAIKhk6C; zdmPQ!a;RsYkBNrC9+u)cBB>f$`#HZ|v+?}N104i6#J$dRD_`Pf5dP4EUS`rkJ@H{& z;(|@=fKK@paZmH-Y3(xu)&%tnqS?{V9MCF8K|X%8c$(4|wfKxpola+7RT~Mdy6(ls z-P~I)^Mcs41H`^;RiutDZ_(V@D>C-dXQN4xO{*41@oK=PeBax9^^fZ+`#W}&FIW|a zdYoc~9l7g}A`M7 ztC$Gs$VgGEmJt-kE(u^$Qu6j#l_u9;(P;X@D|V>&P&O3jB;!VYsqSvKeUnEp(Jq6r zxB1=RqDN|x4N#TT8spSFR(IPOOe0R!WhU8uYxOQt?h^&2>Oo1a!YTG#T$WbQ1r-VL z*Pi*p3z8uB3cE<1HkIa*OksbYye0s-f}Q395T5CSk)@nRYNfDE zt}Bp2B#!_(tcWfptU&Bwt2HNn{W`K8$g8^`$XS8R;z5557z@EajvdAEpDf#%MyS0r z=b7S`qE;ZUaQvKqFS~XJ{x$Nykoxlha=r!Hj}e9k*K<*m8lAzcgDo$G#p>&34{ThY zvj&;q#3|O)X^$7B5^QQ3T&vE3?jUfbgi;y4J-?~8;llU#+2DE_!kNacq9yjZZ)1uNB zFBJ(fc^pgn7pWY3@WBYS@(+uSth?Ko*fCWQxz{kmHIsbm$6Rmv&k%a*!2{;q6+FEW zk}MalB@q>xP|T&CeRTo2rCkQnW|_EVDn zEMbewv}xr0pQq@&HfJPv^97J4JdbUd=T59Zjycjnl}EsF2I#@eY4Z#qid-E9i0Z6~ zQrNYIx*##SYfS@>%VW!S;5a9myE@D`cKq8F^8`EaROFIeDV8lm2N}g5-|#5D`bFxZ zz^(sP)Mrh(e4zgnhYs||{iXjL1;I!`FcRbqwyzGOwF1%lrXKA3O4$8kAh9NEwKf$5 z4`Gvxoj(lTmqQw0(WKDx@JmD|I-=86XcD(N4(?0Vnu3$x*8-j(G>QF7G~lnfOksz^ zF~A0oih$vSeg!qVp*5dri+Qxg+*XO>e~$Bd1@iivnasbh#z_|mkfH#lzAD_YW>esF z+1$az@x|Bf(85H7CmHHVmN5!fULELy;QTj3A-}K4tK9l<*k7{u*Np1H2qnj)R>0+feVmuZ5$`dJwHzy(n_-Q2&}$!GFi^f+%y^^cEEOVZeOutw8SmZLO5= zt5R47jr}HF@XfZF--QyzSN&f!|BL2tghTqD&iauw1h z6#79GI(Im84llIeFGWVDjhieBv3|JPDf-Sx>IvbILm8nf=!B@sc!^Nf*;2TpY>w!L z);t;vAiu|Yf($zh!T!_gHme)TL?p8kO)q5|#JjyDk3sTwwtM5Cw8GpFtU@C{KXYoOo2Q$WvK|Ko|gCDe{=M zHZX-4k1f3$OZoZ1{Goxt8xYg6iB&GM{6L@<=7{N2-1MJJIb_G&?_=kP)zqv~DB%iu zwGz5$=12282Jn!#9alh&@Ew`ifVR63C_FSbQht_yah95I9WECb*bw>S?A+?RB7dfn z*=Z{b^&~=F<_Yv;R?}QtVUPcRQzKv~zS-%u5HkgQv=l3BxdIaZu*lKfzCF1Dl5>Ih Wvj`kHw{)@sa<5rdssc0^>irL*dULb@ literal 0 HcmV?d00001 diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-installed.jpg b/hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-installed.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f822015c90d26c35d052526a85ef08d34132db60 GIT binary patch literal 23871 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 + +In this tutorial, we'll be talking about customizing the command line interface for your language. We recommend reading through previous tutorials about [writing a grammar](/tutorials/writing_a_grammar) and [validation](/tutorials/validation). Once you have a good grasp on those concepts, then you should be all set for setting up a CLI. We will also continue to use the [MiniLogo](https://github.com/langium/langium-minilogo) language as a motivating example. + +## Overview + +Once you have a grammar and some validation in place, you may want to start configuring a basic CLI for your language. This is an important step where your language begins to become more accessible to other programs. Having a CLI for your language is a powerful way to access functionality that is expressed through Langium, but without having to interact directly with Langium. A well designed CLI can be used by other applications to provide advanced language features, without making those other applications unnecessarily complex. + +## About the Command Line Interface + +If you've been using a language built with the yeoman generator for Langium, you should be able to find your CLI defined in **src/cli/index.ts**. This file describes the general layout of your languages's command line interface, and lets you register specific commands. By default, you're provided with a single command for your CLI, the **generate** command. + +Much like the command implies, it allows you to take a program written in your DSL, parse it, and traverse the AST to produce some sort of generated output. We won't talk about the generator itself in this tutorial (that will come in the [next tutorial on generation](/tutorials/generation)). Instead we'll focus on a simple example for parsing and validating a program, which allows learning more about the CLI itself. + +## Adding a Parse and Validate Action + +To start, let's write up a custom action to allow us to **parse** and **validate** a program in our language. If we've already written up a grammar, and already added some basic validation, then all we have to do is hookup the CLI action here to get this to work. This action will help us verify that our MiniLogo programs have no syntax errors, and also pass our custom validations. + +Feel free to keep (or remove) the existing **generate** action, as we won't be setting that up until the next tutorial. We'll be sure to present example code for that as well, so don't worry about deleting functions that you'll need later. + +In order to add our new command, we need to register it in the default export for the **index.ts** file. In this function, there's a **command** object, which is a collection of commands for our CLI. Let's call our command `parseAndValidate`, and give it some extra details, like: + +- **arguments**: Indicating that it takes a single file +- a **description** detailing what this action does +- an **action** that performs the actual parsing and validation + +We could also add additional options, but we won't be doing that for this action. + +We can register our parse and validate action like so: + +```ts +program + .command('parseAndValidate') + .argument('', 'Source file to parse & validate (ending in ${fileExtensions})') + .description('Indicates where a program parses & validates successfully, but produces no output code') + .action(parseAndValidate) // we'll need to implement this function +``` + +Finally, we need to implement the `parseAndValidate` function itself. This will allow us to be able to parse & validate our programs, but without producing any output. We just want to know when our program is 'correct' by the constraints of our language implementation. + +Using parts of the existing `generateAction` function we got by default, we can do our parsing & validation without having to write too much new code at all. + +```ts +import { extractDocument } from './cli-util'; +... +/** + * Parse and validate a program written in our language. + * Verifies that no lexer or parser errors occur. + * Implicitly also checks for validation errors while extracting the document + * + * @param fileName Program to validate + */ +export const parseAndValidate = async (fileName: string): Promise => { + // retrieve the services for our language + const services = createHelloWorldServices(NodeFileSystem).HelloWorld; + // extract a document for our program + const document = await extractDocument(fileName, services); + // extract the parse result details + const parseResult = document.parseResult; + // verify no lexer, parser, or general diagnostic errors show up + if (parseResult.lexerErrors.length === 0 && + parseResult.parserErrors.length === 0 + ) { + console.log(chalk.green(`Parsed and validated ${fileName} successfully!`)); + } else { + console.log(chalk.red(`Failed to parse and validate ${fileName}!`)); + } +}; +``` + +Some amount of the contents for our custom action are shared with the `generateAction` function. This isn't surprising given that we still need to set up our language's services. + +## Building and Running the CLI + +Now that we have our new action in place, we'll want to build and verify the CLI works for a program written in our language. + +If you've been following along from the hello world example produced by the yeoman generator, then you'll have some errors at this point that need to be corrected as follows. + +If you have errors with regards to any imports of `HelloWorld...`, this is likely related to your `grammar NAME` in your langium file being something different than the original `HelloWorld`. The name of these imports will change based on your grammar file's name after `npm run langium:generate`, so in each case you should be able to change each import to `MyLanguage...` to resolve the issue. + +You may also have build errors related to the generator logic, especially if it was written for the hello-world semantic model. For now, we can comment out the generator function's contents in **src/cli/generator.ts**, return an empty string, and comment/remove the imports to make Typescript happy. In the next tutorial, we'll come back to it and implement an initial version of a generator for our language. + +If you have any other errors while building, double check that the exported & imported names match up. More often than note there's a small discrepancy here, especially when you use a different language name than the default. + +At this point, you should be able to run the following with no errors from the project root. + +```bash +npm run langium:generate +npm run build +``` + +If everything looks good, you should have access to the CLI in **/bin/cli**. We also need a program we can test and validate. For the MiniLogo language we have a simple example program that we can validate: + +```minilogo +def test() { + pen(down) + move(10,10) + pen(up) +} + +test() +``` + +We'll save this under our project root as **test.logo**, and we can test that it's correct using our CLI like so: + +```bash +./bin/cli parseAndValidate test.logo +``` +NOTE: The langium-minilogo repo places `test.logo` in an `examples` subdirectory under the project root. So, for that case, the CLI usage would be: +```bash +./bin/cli parseAndValidate examples/test.logo +``` +It does not matter where you place your .logo files. Organize them as you see fit. + +We should get an output indicating that there were no errors with our program. + +> Parsed and validated test.logo successfully! + +If you get a message that indicates you need to choose a file with a given extension, you'll want to go back and update your list of extensions in your **package.json** and your **langium-config.json** in your project root. Then you'll need to run `npm run langium:generate` followed by `npm run build` to get that change incorporated into your CLI. + +If we wanted to verify that we *can* get errors, we can modify our program a bit to include a duplicate definition (which we should have a validation for, as we implemented in the validation tutorial). + +```minilogo +def test() { + pen(down) + move(10,10) + pen(up) +} + +// redefinition of test, should 'not' validate +def test() { + pen(up) +} + +test() +``` + +Running the CLI again should show that this program has an error, and better yet it will show us exactly the error in question. + +> There are validation errors: +> +> line 7: Def has non-unique name 'test'. [test] + +This is perfect, as we didn't have to implement too much more logic to get validation in our CLI. Since we already hooked up our validation service before, the CLI just handles the interaction with an external program. This separation of concerns makes for a very flexible implementation that is easy to adapt over time. + +That sums up how to add basic CLI functionality. [In the next tutorial, we will be talking about generation in more detail](/tutorials/generation), specifically about techniques that you can use to traverse your AST and produce a generated output. diff --git a/hugo/content/docs/1_learn/minilogo/generation.md b/hugo/content/docs/1_learn/minilogo/generation.md new file mode 100644 index 00000000..adad2497 --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/generation.md @@ -0,0 +1,378 @@ +--- +title: "Generation" +weight: 3 +--- + +{{< toc format=html >}} + +In this tutorial we'll be showing how to implement basic generation for your language. When we're talking about generation, we're talking about transforming an AST from your Langium-based language into some output target. This could be another language of similar functionality (transpilation), a lower level language (compilation), or generating some artifacts/data that will be consumed by another application. If you haven't already, make sure to go back over and check out the [tutorial on customizing your CLI](/tutorials/customizing_cli), as it touches on details about how to implement endpoints for your application (like generation). + +Per usual, we'll be using the MiniLogo language as a motivating example here. + +We'll be describing how to write a simple MiniLogo generator to output drawing a JSON array of drawing instructions. This tutorial will give you a general idea of how you can traverse an AST to produce generated output. + +## Setting up the Generator API + +To write the generator, we're going to work in the **src/cli/generator.ts** file. If you're using a language produced by the yeoman generator for Langium, then you should already have a function in here called `generateJavascript`. For MiniLogo, we'll change this to `generateCommands`, which will generate drawing commands to be handled later. We will also change the function signature to take a `Model`, and return a string of the generated file path. + +```ts +// import the 'Model' type from our semantic model +import { Model } from '../language/generated/ast.ts'; + +export function generateCommands(mode: Model, filePath: string, destination: string | undefined): string { + // ... +} +``` + +This function will serve as our generator endpoint. All MiniLogo programs that we want to generate from will be processed from here. + +Now, our objective is to take a program like this: + +```minilogo +def test() { + pen(down) + move(10,10) + pen(up) +} + +test() +``` + +And translate it into a generated JSON-like list of drawing commands like so: + +```json +[ + { cmd: 'penDown' }, + { cmd: 'move', x: 10, y: 10 }, + { cmd: 'penUp' } +] +``` + +## Deciding Output to Generate + +Notice that there's no notion of macros, definitions, for loops, or other constructs that are present in MiniLogo. We only need to produce a generated output that contains information relevant to our *semantic domain*. If you remember this term from the very beginning of writing our grammar, then you'll likely also remember that our semantic domain is a series of transformations performed on a drawing context. With this in mind, we can safely reduce a MiniLogo program to such a series of transformations on the pen, position, and color. We don't need to include anything else. In this context, you could think of it like a form of evaluation. + +To be able to produce this output, we need to be able to traverse through all nodes of our AST. We can perform such a traversal by creating functions that map from our AST to our generated output. This is as simple as accessing the properties stored on a node, and writing functions to process the types of those properties such that generation is defined for every type of node in your AST. + +An example of this would be defining a `generateStatements` function that takes a list of Statements, and produces some generated result from those statements. Anytime we were working with a node that contained statements, we could invoke this function on it, and return the results. + +We can add this function to our `generateCommands` function to begin generation from the top-level statements in our `Model`. + +```ts +export function generateCommands(mode: Model, filePath: string, destination: string | undefined): string { + const result: Object[] = generateStatements(model.stmts); + +} + +... + +function generateStatements(stmts: Stmt[]): Object[] { ... } +``` + +As a side note, to support generation with string content (like for generating file/program contents) we've added a `CompositeGeneratorNode` that is designed to help collect generated output. This is located in our **cli-util.ts**, and provides more structure with constructing textual outputs, without resorting to direct manipulation of strings. + +## Generating from Statements + +Now, let's expand on `generateStatements`. From our grammar, there are 5 types of statements: + +- **pen** +- **move** +- **macro** +- **for** +- **color** + +We we want to expand our function to handle each of these cases. This is easy to do using some special `isTYPE` functions made available from our semantic model. These are automatically generated from our grammar, and allow us to verify the type of a node from our AST at runtime. + +```ts +import { isPen, isMove, isMacro, isFor, isColor } from '../language/generated/ast'; + +... + +if(isPen(stmt)) { + ... +} else if(isMove(stmt)) { + ... +} else if(isMacro(stmt)) { + ... +} else if(isFor(stmt)) { + ... +} else if (isColor(stmt)) { + ... +} +``` + +For `isPen` we have the easiest case where we could emit something like so: + +```ts +{ + cmd: stmt.mode === 'up' ? 'penUp' : 'penDown' +}; +``` + +However, for the rest of the statements, we need to be able to evaluate expressions first. + +## Writing an Expression Evaluator + +We need to *evaluate* our expressions to final values for statements, as we don't want to emit literal expressions like `1 + x * 5`; but rather their evaluated result. We'll handle this in a new `evalExprWithEnv` function. + +```ts +// map of names to values +type MiniLogoGenEnv = Map; + +// evalutes exprs in the context of an env +function evalExprWithEnv(e: Expr, env: MiniLogoGenEnv): number { + ... +} +``` + +As we mentioned before, in order to perform generation in this context, we're also writing an evaluator for our language. Thankfully, MiniLogo is relatively simple, especially since it doesn't have variables outside of definitions and for loops. + +So let's write our expression evaluator. Assuming we have the function declaration from above, our first case to be added into that function is for `Lit`. Again, this is imported from our generated semantic model. + +```ts +if(isLit(e)) { + return e.val; +} +``` + +Pretty easy. A literal returns its value. Now for references. + +```ts +if(isRef(e)) { + const v = env.get(e.val.ref?.name ?? ''); + if (v !== undefined) { + return v; + } + // handle the error case... +} +``` + +Since we have cross references, we can retrieve the node in question (ref), and check if we have a value stored for its name. In the case that we do, we return the value, otherwise we would want to report an error. + +For binary expressions, we can invoke `evalExprWithEnv` recursively on the left & right operands. Since we used actions to restructure our semantic model a bit, we have access to this `isBinExpr` function to find `BinExpr` nodes. It's quite convenient, since we can now handle all 4 cases at once. + +```ts +if(isBinExpr(e)) { + let opval = e.op; + let v1 = evalExprWithEnv(e.e1, env); + let v2 = evalExprWithEnv(e.e2, env); + + switch(opval) { + case '+': return v1 + v2; + case '-': return v1 - v2; + case '*': return v1 * v2; + case '/': return v1 / v2; + default: throw new Error(`Unrecognized bin op passed: ${opval}`); + } +} +``` + +For negated expressions, it's also fairly straight forward. We invert whatever value we would get normally. + +```ts +if (isNegExpr(e)) { + return -1 * evalExprWithEnv(e.ne, env); +} +``` + +Lastly, for groups we extract the 'grouped' value and evaluate it. + +```ts +if(isGroup(e)) { + return evalExprWithEnv(e.ge, env); +} +``` + +Lastly, it's always a good measure to *sanity check* that you aren't missing a case. Throwing an error is often much more desirable than having something silently fail, and produce strange results on generation. This means adding a default for your switches, and a final `else` clause to handle unexpected nodes. + +With all those cases above, we can combine them into a series of `else if` clauses to have a clean case-by-case check. + +## Generating from Statements with the Evaluator + +Now that we can evaluate expressions, we can handle the rest of our statement cases. In order to incorporate our `env`, we'll also want to update our `generateStatements` function, and create a new `evalStmt` function to help out. + +```ts +function generateStatements(stmts: Stmt[]): Object[] { + // minilogo evaluation env + let env : MiniLogoGenEnv = new Map(); + + // generate mini logo cmds off of statements + return stmts.flatMap(s => evalStmt(s,env)).filter(e => e !== undefined) as Object[]; +} + +/** + * Takes an statement, an environment, and produces a list of generated objects + */ +function evalStmt(stmt: Stmt, env: MiniLogoGenEnv) : (Object | undefined)[] { + if (isPen(stmt)) { + return [{ + cmd: stmt.mode === 'up' ? 'penUp' : 'penDown' + }]; + } + + // ... the rest of our cases will follow ... +} +``` + +This gives us an `env` that can be updated by evaluating each statement, and persist from one to another; which is what we want for MiniLogo. Now, for `isMove`, we just need to evaluate the x & y arguments to their values using this env + +```ts +if (isMove(stmt)) { + return [{ + cmd: 'move', + x: evalExprWithEnv(stmt.ex, env), + y: evalExprWithEnv(stmt.ey, env) + }]; +} +``` + +For `isMacro` we need to save and restore our execution environment after the macro has been evaluated. We can do this by generating a new env, setting the parameters from the arguments, and passing that new env to the macro's statements instead. + +*Keep in mind* arguments need to be evaluated before setting them into the env, and we want to carefully do this using the *original* env, not the new one being constructed. If there are names that already exist, and would be shadowed by this macro, then it could change the result of the macro (or even the value of subsequent arguments). + +```ts +// get the cross ref +const macro: Def = stmt.def.ref as Def; + +// copied env +let macroEnv = new Map(env); + +// produce pairs of string & exprs, using a tmp env +// this is important to avoid mixing of params that are only present in the tmp env w/ our actual env +let tmpEnv = new Map(); + +// evalute args independently, staying out of the environment +macro.params.map((elm, idx) => tmpEnv.set(elm.name, evalExprWithEnv(stmt.args[idx], macroEnv))); +// add new params into our copied env +tmpEnv.forEach((v,k) => macroEnv.set(k,v)); + +// evaluate all statements under this macro +return macro.body.flatMap(s => evalStmt(s, macroEnv)); +``` + +For `isFor`, we also use a copied env, so that we don't alter the original env outside of the loop. + +```ts +// compute for loop bounds +// start +let vi = evalExprWithEnv(stmt.e1, env); +// end +let ve = evalExprWithEnv(stmt.e2, env); + +let results : (Object | undefined)[] = []; + +// perform loop +const loopEnv = new Map(env); +while(vi < ve) { + loopEnv.set(stmt.var.name, vi++); + stmt.body.forEach(s => { + results = results.concat(evalStmt(s, new Map(loopEnv))); + }); +} + +return results; +``` + +Lastly, to handle `isColor`, check whether one set of properties is defined or the other (like color vs. any of the r,g,b properties). + +```ts +if (stmt.color) { + // literal color text or hex + return [{cmd:'color', color: stmt.color}] +} else { + // color as rgb + const r = evalExprWithEnv(stmt.r!, env); + const g = evalExprWithEnv(stmt.g!, env); + const b = evalExprWithEnv(stmt.b!, env); + return [{cmd:'color', r, g, b}] +} +``` + +With that, we're effectively done writing the core of our generator! The last changes to make are to write the output to a file, and to connect what we've written here with a command in our CLI. + +## Connecting the Generator to the CLI + +To do this, we can go back to the top of our generator, and update the `generateCommands` function to write the generated result to a file. Most of the structure here is carried over from the original code first setup by the yeoman generator, which makes it convenient to add in. + +```ts +export function generateCommands(model: Model, filePath: string, destination: string | undefined): string { + const data = extractDestinationAndName(filePath, destination); + const generatedFilePath = `${path.join(data.destination, data.name)}.json`; + + if (!fs.existsSync(data.destination)) { + fs.mkdirSync(data.destination, { recursive: true }); + } + + const result = generateStatements(model.stmts); + + fs.writeFileSync(generatedFilePath, JSON.stringify(result, undefined, 2)); + return generatedFilePath; +} +``` + +And to connect it to the CLI, which is setup in **src/cli/index.ts**, we can register it by slightly modifying the existing `generateAction` endpoint that was there by default. + +```ts +export const generateAction = async (fileName: string, opts: GenerateOptions): Promise => { + const services = createHelloWorldServices(NodeFileSystem).HelloWorld; + const model = await extractAstNode(fileName, services); + // now with 'generateCommands' instead + const generatedFilePath = generateCommands(model, fileName, opts.destination); + console.log(chalk.green(`MiniLogo commands generated successfully: ${generatedFilePath}`)); +}; +``` + +Towards the bottom of the same file, we'll modify the description for the logic that registers this action: + +```ts +program + .command('generate') + .argument('', `source file (possible file extensions: ${fileExtensions})`) + .option('-d, --destination

', 'destination directory of generating') + // new description + .description('generates MiniLogo commands that can be used as simple drawing instructions') + .action(generateAction); +``` + +And that's it. Now we can run the following to generate commands from a MiniLogo file of our choice. + +```bash +npm run build +./bin/cli generate test.logo +``` + +This should produce **generated/test.json**, which contains a JSON array of the drawing commands generated by our program. For the following example program: + +```minilogo +def test() { + pen(down) + move(10,10) + pen(up) +} + +test() +``` + +our JSON output should be: + +```json +[ + { + "cmd": "penDown" + }, + { + "cmd": "move", + "x": 10, + "y": 10 + }, + { + "cmd": "penUp" + } +] +``` + +If you're looking at the implementation of [MiniLogo that we've already written in the Langium organization on Github](https://github.com/langium/langium-minilogo), you may notice that the program and output there are *slightly* different. This interpretation of MiniLogo has gone through some iterations, and so there are some slight differences here and there. What's most important is that your version produces the generated output that you expect. + +We could continue to extend on this with new features, and generate new sorts of output using a given input language. In this tutorial, we're able to take a MiniLogo program and convert it into some simple JSON drawing instructions that can be consumed by another program. This opens the door for us to write such a program in another language, such as Python or Javascript, and draw with these results. In later tutorials, we'll be talking about how to run Langium in the web with generation, so that we can immediately verify our results by drawing on an HTML5 canvas. + +We recommend that you next read [the guide on bundling your language with Langium to reduce its size](/guides/code-bundling), before moving onto the tutorial about [bundling an extension](/tutorials/building_an_extension). This is an important step before deployment as an extension for VSCode, and also if you're planning to later deploy your language in the web. diff --git a/hugo/content/docs/1_learn/minilogo/generation_in_the_web.md b/hugo/content/docs/1_learn/minilogo/generation_in_the_web.md new file mode 100644 index 00000000..46f923de --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/generation_in_the_web.md @@ -0,0 +1,331 @@ +--- +title: "Generation in the Web" +weight: 7 +--- + +{{< toc format=html >}} + +*Updated on Oct. 4th, 2023 for usage with monaco-editor-wrapper 3.1.0 & above.* + +In this tutorial we'll be talking about how to perform generation in the web by listening for document builder notifications. There are multiple ways to hook into Langium to utilize the generator, such as by directly exporting the generator API. However, by listening to notifications from the document builder, we can do this with less code. This lets us quickly integrate new functionality into our existing Langium + Monaco integration, and focus more on what we would want to do with the generated output. + +*(This tutorial previously utilized custom LSP commands to achieve the same goal of generation. This is still a valid approach, but we've found setting up listening for notifications this way is much more straightforward. We've implemented this in our own example languages as well, and would recommend it going forward.)* + +We'll assume that you've already looked over most of the other tutorials at this point. It is particularly important that you have a language with working generation, and have a working instance of Langium + Monaco for your language (or another editor of your choice). In the case that you don't have a language to work with, you can follow along with [MiniLogo](https://github.com/langium/langium-minilogo), which is the example language used throughout many of these tutorials. + +Since we're working with MiniLogo here, we already know that our generated output is in the form of drawing instructions that transform some drawing context. The generated output that we've implemented so far consists of a JSON array of commands, making it very easy to interpret. Now that we're working in a web-based context, this approach lends itself naturally towards manipulating an HTML5 canvas. + +The parts that we still need to setup are: + +- handle document validations, and generate notifications with our generator output +- listen for these notifications in the client, and extract the generated output +- interpret the generated output as drawing commands, and update the canvas + +## Handling Document Validations + +This is the first step we'll need, since without being able to generate notifications in the first place we would have nothing to listen to. + +Thankfully a lot of the groundwork has already been done in previous tutorials, as well as within Langium itself. We just need to setup the an onBuildPhase listener for the document builder in our LS. Using the LS entry point **main-browser.ts** that we setup in the last tutorial on Langium + Monaco, we can add the following code to the end of our `startLanguageServer` function. + +```ts +// modified import from the previous tutorial: Langium + Monaco +import { + BrowserMessageReader, + BrowserMessageWriter, + Diagnostic, + NotificationType, + createConnection +} from 'vscode-languageserver/browser.js'; + +// additional imports +import { Model } from './generated/ast.js'; +import { Command, getCommands } from './minilogo-actions.js'; +import { generateStatements } from '../generator/generator.js'; + +// startLanguageServer... + +// Send a notification with the serialized AST after every document change +type DocumentChange = { uri: string, content: string, diagnostics: Diagnostic[] }; +const documentChangeNotification = new NotificationType('browser/DocumentChange'); +// use the built-in AST serializer +const jsonSerializer = MiniLogo.serializer.JsonSerializer; +// listen on fully validated documents +shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Validated, documents => { + // perform this for every validated document in this build phase batch + for (const document of documents) { + const model = document.parseResult.value as Model; + let json: Command[] = []; + + // only generate commands if there are no errors + if(document.diagnostics === undefined + || document.diagnostics.filter((i) => i.severity === 1).length === 0 + ) { + json = generateStatements(model.stmts); + } + + // inject the commands into the model + // this is safe so long as you careful to not clobber existing properties + // and is incredibly helpful to enrich the feedback you get from the LS per document + (model as unknown as {$commands: Command[]}).$commands = json; + + // send the notification for this validated document, + // with the serialized AST + generated commands as the content + connection.sendNotification(documentChangeNotification, { + uri: document.uri.toString(), + content: jsonSerializer.serialize(model, { sourceText: true, textRegions: true }), + diagnostics: document.diagnostics ?? [] + }); + } +}); +``` + +And that's it for setting up the onBuildPhase listener itself. We still need to address the usage of `generateMiniLogoCmds`, which is tied to the LS implementation. + +Based on the work done in previous tutorials, we already have set up a working generator with MinLogo. If you haven't already set this up you can go back to the [tutorial on generation](/tutorials/generation) and give it a look over. Ideally, we'll already have setup our `generateStatements` function for MiniLogo, meaning so long as the imported module doesn't have any modules that are browser incompatible, we should be able to use it as is. Based on the previous setup however, we should have a **generator.js** file that is free of such conflicts, as much of them should be separated into the cli directly. + +This saves us quite a bit of time, since we don't need to handle setting up & dispatching a document for validation, we simply tap into the existing workflow and collect the result when it's ready. This is a great example of how Langium's architecture allows us to easily extend existing functionality, and add new features without having to rewrite existing code. + +As a concluding note for this section, don't forget to rebuild your language server bundle! It might not be a bad idea to clean as well, just to be sure everything is working as expected at this step. + +## Listening for Notifications in the Client + +The next step we need to make is to actually listen for these notifications from the client's end. This takes us back to the [Langium + Monaco](/tutorials/langium_and_monaco) setup in the previous tutorial. + +After starting the wrapper successfully, we want to retrieve the MonacoLanguageClient instance (a wrapper around the language client itself) and listen for `browser/DocumentChange` notifications. + +```ts +// wrapper has started... + +// get the language client +const client = wrapper.getLanguageClient(); +if (!client) { + throw new Error('Unable to obtain language client!'); +} + +// listen for document change notifications +client.onNotification('browser/DocumentChange', onDocumentChange); + +function onDocumentChange(resp: any) { + let commands = JSON.parse(resp.content).$commands; + // ... do something with these commands +} +``` + +Now this works, but when do we receive notifications, and how often? Well a good thing you asked, because if you started this up and began editing your program, you would be receiving a notification for every single change! Including whitespace changes. Now that's probably not what we're looking for, but the content is correct, we just want to slow it down a bit. We can do this by setting a timeout and a semaphore to prevent multiple notifications from being processed at once. + +```ts +let running = false; +let timeout: number | null = null; + +function onDocumentChange(resp: any) { + // block until we're finished with a given run + if (running) { + return; + } + + // clear previous timeouts + if (timeout) { + clearTimeout(timeout); + } + + timeout = window.setTimeout(async () => { + running = true; + let commands = JSON.parse(resp.content).$commands; + await updateMiniLogoCanvas(commands); + running = false; + + }, 200); // delay of 200ms is arbitrary, choose what makes the most sense in your use case +} +``` + +And now we have a nice delay where repeated updates are discarded, until we have about 200ms without a subsequent update. That allows us to take the commands we're working with, and start doing something with them. The semaphore will prevent following updates from overriding the current run, allowing it to finish before starting a new execution. + +You may have also noticed we added `updateMiniLogoCanvas` as the action to perform with our commands. This will be implemented in the next step, where we interpret our drawing commands. + +That's it for listening for notifications! Now that we have our commands extracted, we'll can actually perform a series of drawing actions on an HTML5 canvas. + +## Interpreting Draw Commands (Drawing) + +If you've gotten to this point then you're on the final stretch! The last part we need to implement is the actual logic that takes our drawing commands and updates the canvas. This logic will be the content of the `updateMiniLogoCanvas` function, and we'll walk through each step here. + +First, let's get a handle on our canvas, as well as the associated 2D context. + +```ts +const canvas : HTMLCanvasElement | null = document.getElementById('minilogo-canvas') as HTMLCanvasElement | null; +if (!canvas) { + throw new Error('Unable to find canvas element!'); +} + +const context = canvas.getContext('2d'); +if (!context) { + throw new Error('Unable to get canvas context!'); +} +``` + +We'll also want to clean up the context, in case we already drew something there before. This will be relevant when we're updating the canvas multiple times with a new program. + +```ts +context.clearRect(0, 0, canvas.width, canvas.height); +``` + +Next, we want to setup a background grid to display. It's not essential for drawing, but it looks nicer than an empty canvas. + +```ts +context.beginPath(); +context.strokeStyle = '#333'; +for (let x = 0; x <= canvas.width; x+=(canvas.width / 10)) { + context.moveTo(x, 0); + context.lineTo(x, canvas.height); +} +for (let y = 0; y <= canvas.height; y+=(canvas.height / 10)) { + context.moveTo(0, y); + context.lineTo(canvas.width, y); +} +context.stroke(); +``` + +After drawing a grid, let's reset the stroke to a white color. + +```ts +context.strokeStyle = 'white'; +``` + +Let's also setup some initial drawing state. This will be used to keep track of the pen state, and where we are on the canvas. + +```ts +// maintain some state about our drawing context +let drawing = false; +let posX = 0; +let posY = 0; +``` + +And let's begin evaluating each of our commands. To do this, we'll setup an interval that repeatedly shifts the top element from our list of commands, evaluates it, and repeats. Once we're out of commands to evaluate, we'll clear the interval. The whole invocation will be wrapped in a promise, to make it easy to await later on. Feel free to adjust the delay (or remove it entirely) in your version. + +```ts +const doneDrawingPromise = new Promise((resolve) => { + // use the command list to execute each command with a small delay + const id = setInterval(() => { + if (cmds.length > 0) { + dispatchCommand(cmds.shift() as MiniLogoCommand, context); + } else { + // finish existing draw + if (drawing) { + context.stroke(); + } + clearInterval(id); + resolve(''); + } + }, 1); +}); +``` + +`dispatchCommand` itself only needs to handle 4 cases: + +- penUp +- penDown +- move +- color + +Knowing this, and the details about what properties each command type can have, we can evaluate each command and update our context. This can be done with a switch and a case for each command type. + +*Be sure to add this function inside the `updateMiniLogoCanvas` function, otherwise it will not have access to the necessary state!* + +```ts +// dispatches a single command in the current context +function dispatchCommand(cmd: MiniLogoCommand, context: CanvasRenderingContext2D) { + if (cmd.name) { + switch (cmd.name) { + // pen is lifted off the canvas + case 'penUp': + drawing = false; + context.stroke(); + break; + + // pen is put down onto the canvas + case 'penDown': + drawing = true; + context.beginPath(); + context.moveTo(posX, posY); + break; + + // move across the canvas + // will draw only if the pen is 'down' + case 'move': + const x = cmd.args.x; + const y = cmd.args.y; + posX += x; + posY += y; + if (!drawing) { + // move, no draw + context.moveTo(posX, posY); + } else { + // move & draw + context.lineTo(posX, posY); + } + break; + + // set the color of the stroke + case 'color': + if ((cmd.args as { color: string }).color) { + // literal color or hex + context.strokeStyle = (cmd.args as { color: string }).color; + } else { + // literal r,g,b components + const args = cmd.args as { r: number, g: number, b: number }; + context.strokeStyle = `rgb(${args.r},${args.g},${args.b})`; + } + break; + + // fallback in case we missed an instruction + default: + throw new Error('Unrecognized command received: ' + JSON.stringify(cmd)); + + } + } +} +``` + +Now that we can interpret commands into drawing instructions, we're effectively done with setting up the last part of MiniLogo. Since we're listening to document updates, we don't need to do anything other than to just start it up and start with an example program. + +That's it, we're all done writing up our TS file. We should now be able to run the following (assuming the generator script is also executed by `build:web`), and get our results in `localhost:3000`. + +```bash +npm run build:web +npm run serve +``` + +If all went well, you should see a white diamond sketched out on the canvas when the page loads. If not, double check that you receive & use the `code` value correctly in your `createUserConfig` function. You can also add the program yourself from here: + +```minilogo +def test() { + move(100, 0) + pen(down) + move(100, 100) + move(-100, 100) + move(-100, -100) + move(100, -100) + pen(up) +} +color(white) +test() +``` + +Once you have something drawing on the screen, you're all set, congratulations! You've just successfully written your own Langium-based language, deployed it in the web, and hooked up generation to boot. In fact, you've done *quite* a lot if you've gone through all of these tutorials so far. + +- writing your own grammar +- implementing custom validation +- customizing your CLI +- adding generation +- configuring code bundling +- building an extension +- setting up Langium + Monaco in the web +- adding a document build phase listener +- listening for notifications in the client, and using the results + +And the concepts that we've gone over from the beginning to now are not just for MiniLogo of course, they can be easily generalized to work for your own language as well. As you've been going through these tutorials, we hope that you've been thinking about how you could have done things *differently* too. Whether a simple improvement, or another approach, we believe it's this creative kind of thinking that takes an idea of a language and really allows it to grow into something great. + +One easy note is how the example code shown in these tutorials was designed to be easy to demonstrate. It could definitely be improved with better error checking, better logic, generator optimizations, etc; something to keep in mind. + +It's also easy to imagine how one could extend their generator to produce their own functionality besides drawing. For example, imagine that you might have multiple generator targets, as there is no requirement to have a single generator output form like we've done in these tutorials. You could add as many different output forms as you need for each specific target, and even share some functionality between generators. + +We hope that these tutorials have given you a practical demonstration of how to construct a language in Langium, and facilitated further exploration into more advanced topics & customizations. If you're interested about learning more about Langium, you can continue through our other tutorials, reach out to us via discussions on Github, or continue working on your Langium-based language. diff --git a/hugo/content/docs/1_learn/minilogo/langium_and_monaco.md b/hugo/content/docs/1_learn/minilogo/langium_and_monaco.md new file mode 100644 index 00000000..48111921 --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/langium_and_monaco.md @@ -0,0 +1,619 @@ +--- +title: "Langium + Monaco Editor" +weight: 6 +--- + +{{< toc format=html >}} + +*Updated on Oct. 4th, 2023 for usage with monaco-editor-wrapper 3.1.0 & above, as well as Langium 2.0.2* + +In this tutorial we'll be talking about running Langium in the web with the Monaco editor. If you're not familiar with Monaco, it's the editor that powers VS Code. We're quite fond of it at TypeFox, so we've taken the time to write up this tutorial to explain how to integrate Langium in the web with Monaco, no backend required. + +Although we're using Monaco in this tutorial, that does not mean that you cannot use another code editor of your choice. For example, you can use Code Mirror with Langium as well. Generally, if an editor has LSP support, it is very likely you can integrate it easily with Langium, since it's LSP compatible. + +Without further ado, let's jump into getting your web-based Langium experience setup! + +## Technologies You'll Need + +- [Langium](https://www.npmjs.com/package/langium) 2.0.2 or greater +- [Monaco Editor Wrapper](https://www.npmjs.com/package/monaco-editor-wrapper) 3.1.0 or greater +- [ESBuild](https://www.npmjs.com/package/esbuild) 0.18.20 or greater + +## Getting your Language Setup for the Web + +To begin, you're going to need a Langium-based language to work with. We have already written [MiniLogo](https://github.com/langium/langium-minilogo) in Langium as an example for deploying a language in the web. However, if you've been following along with these tutorials so far, you should be ready to move your own language into a web-based context. + +Per usual, we'll be using MiniLogo as the motivating example here. + +## Factoring out File System Dependencies + +In order to build for the browser, we need to create a bundle that is free of any browser-incompatible modules. To do this, let's create a new entry point for our language server in **src/language-server/main-browser.ts**. This will mirror the regular entry point that we use to build already, but will target a browser-based context instead. We'll start with the following content: + +```ts +import { startLanguageServer, EmptyFileSystem } from 'langium'; +import { BrowserMessageReader, BrowserMessageWriter, createConnection } from 'vscode-languageserver/browser.js'; +// your services & module name may differ based on your language's name +import { createMiniLogoServices } from './minilogo-module.js'; + +declare const self: DedicatedWorkerGlobalScope; + +/* browser specific setup code */ +const messageReader = new BrowserMessageReader(self); +const messageWriter = new BrowserMessageWriter(self); + +const connection = createConnection(messageReader, messageWriter); + +// Inject the shared services and language-specific services +const { shared, MiniLogo } = createMiniLogoServices({connection, ...EmptyFileSystem }); + +// Start the language server with the shared services +startLanguageServer(shared); +``` + +Again, this is based on code that was originally produced by the yeoman generator, so it should look familiar. + +Most of this is in line with what's contained in the **main.ts** file. The exceptions being the message readers & writers, and the notion of an `EmptyFileSystem` for the browser. There is a virtual file system API that we could utilize on most modern browsers, but for this tutorial we'll assume we aren't using any file system. Instead we'll have a single source 'file' located in memory. + +We'll also need to include a library to resolve the missing `DedicatedWorkerGlobalScope`, which is normally not accessible until we update our **tsconfig.json** in our project root. We need to supplement the libs entry with `DOM` and `WebWorker`. From the yeoman generator example, the `lib` entry usually has just `["ESNext"]`. + +```json +{ + "compilerOptions": { + ... + "lib": ["ESNext", "DOM", "WebWorker"] + } +} +``` + +Now that we have a new entry point for the browser, we need to add a script to our **package.json** to build a web worker for this language. The bundle this script produces will contain the language server for your language. The following script example is specific to MiniLogo, but should capture the general approach quite nicely: + +```json +{ + ... + "build:worker": "esbuild --minify ./out/language-server/main-browser.js --bundle --format=iife --outfile=./public/minilogo-server-worker.js", +} +``` + +Assuming `esbuild` is installed, and we've properly factored out any modules that are not suitable for a browser-based context, we should be good to go! + +Running `npm run build:worker` we should see the bundle is successfully generated without issue. If you're still having problems building the worker, double check that you're not coupled to `fs` or other file system dependent modules in a related file. + +Note that although our generator is still connected to using the file system, it's not relevant for the worker bundle to function. + +## Setting up Monaco + +Now we're going to setup Monaco, but not with Langium yet, as we want to be sure it's working first before connecting the two. + +For convenience, we're going to use the Monaco Editor Wrapper (MER) to wrap around some of Monaco's core functionality, along with the Monaco Editor Workers package to assist. These packages are both maintained by TypeFox, and are designed to make it easier to use Monaco in a web-based context. We'll be using the following versions of these packages: + +- [Monaco Editor Wrapper](https://www.npmjs.com/package/monaco-editor-wrapper) version **3.1.0** +- [monaco-editor-workers](https://www.npmjs.com/package/monaco-editor-workers) version **0.39.0** + +Both these packages should be installed as dependencies for your language. In particular, this guide will assume that you're using version **3.1.0** or later of the monaco-editor-wrapper package, and version **0.39.0** of the monaco-editor-workers package. + +Additionally, we'll want a way to serve this bundled language server. The choice of how you want to go about this is ultimately up to you. Previously we've recommended `express` as a development dependency (don't forget to also add `@types/express` too), as a powerful & lightweight NodeJS server framework. However, we'll be going with the built-in NodeJS support for standing up a web-server; however again the choice is yours here. + +We'll also want to add some more scripts to our package.json to copy over the necessary files from the monaco-editor-wrapper & monaco-editor-worker into the **public** folder. We'll be referencing these library assets to setup the webpage for Langium + Monaco. + +```json +{ + ... + "prepare:public": "node scripts/prepare-public.mjs", + "build:web": "npm run build && npm run prepare:public && npm run build:worker && node scripts/copy-monaco-assets.mjs", +} +``` + +Both scripts reference *mjs* files that need to be added as well into the scripts folder: + +**scripts/prepare-public.mjs** + +```js +import * as esbuild from 'esbuild' +import shell from 'shelljs' + +// setup & copy over css & html to public +shell.mkdir('-p', './public'); +shell.cp('-fr', './src/static/*.css', './public/'); +shell.cp('-fr', './src/static/*.html', './public'); + +// bundle minilogo.ts, and also copy to public +await esbuild.build({ + entryPoints: ['./src/static/minilogo.ts'], + minify: true, + sourcemap: true, + bundle: true, + outfile: './public/minilogo.js', +}); +``` + +**scripts/copy-monaco-assets.mjs** + +```js +import shell from 'shelljs' + +// copy workers to public +shell.mkdir('-p', './public/monaco-editor-workers/workers'); +shell.cp( + '-fr', + './node_modules/monaco-editor-workers/dist/index.js', + './public/monaco-editor-workers/index.js' +); +shell.cp( + '-fr', + './node_modules/monaco-editor-workers/dist/workers/editorWorker-es.js', + './public/monaco-editor-workers/workers/editorWorker-es.js' +); +shell.cp( + '-fr', + './node_modules/monaco-editor-workers/dist/workers/editorWorker-iife.js', + './public/monaco-editor-workers/workers/editorWorker-iife.js' +); +``` + +This saves us from writing these extra details into our package json, and focusing on the overall goal each step. + +The last script, `build:web` is there to provide a convenient way to invoke all the intermediate build steps in sequence. However you'll want to wait before running the `build:web` script, as we still need to add our **static** assets to make that work; which will come in the next step. + +As a quick note, if you went with another editor you would want to make sure that the assets required for that editor will also be copied into **public** folder as part of your output. + +## Setting up a Static Page + +And now for the actual HTML page itself, plus it's supporting assets. To keep things organized, we're splitting up the JS and CSS. We'll be putting all of these files into a new location from our project root, **src/static/**. + +Here's the raw contents of the HTML content stored in **src/static/index.html**. This will serve as a frame for Monaco to be setup within. + +```html + + + + + + + MiniLogo in Langium + + +

MiniLogo in Langium

+ + +
+ +
+
+
+
+
+ +
+ +
+
+ + +
+ +
+ +
+
+
+

Powered by

+ Langium +
+ + + + +``` + +And here's the associated CSS stored in **src/static/styles.css**. This will style Monaco correctly so it renders as expected. + +```css +html,body { + background: rgb(33,33,33); + font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; + color: white; + /* for monaco */ + margin: 0; + padding: 0; + width: 100%; + height: 100%; +} +h1 { + text-align: center; +} +#minilogo-canvas { + display: block; + margin: 8px auto; + text-align: center; +} +#page-wrapper { + display: flex; + max-width: 2000px; + margin: 4px auto; + padding: 4px; + min-height: 75vh; + justify-content: center; +} +#page-wrapper .half { + display: flex; + width: 40vw; +} +.build { + display: block; + margin: 8px auto; + width: 300px; + height: 30px; + background: none; + border: 2px #fff solid; + color: #fff; + transition: 0.3s; + font-size: 1.2rem; + border-radius: 4px; +} +.build:hover { + border-color: #6cf; + color: #6cf; + cursor: pointer; +} +.build:active { + color: #fff; + border-color: #fff; +} +footer { + text-align: center; + color: #444; + font-size: 1.2rem; + margin-bottom: 16px; +} +@media(max-width: 1000px) { + #page-wrapper { + display: block; + } + #page-wrapper .half { + display: block; + width: auto; + } + #minilogo-canvas { + margin-top: 32px; + } + #page-wrapper { + min-height: auto; + } +} + +/* for monaco */ +.wrapper { + display: flex; + flex-direction: column; + height: 100%; + width: 100%; +} + +#monaco-editor-root { + flex-grow: 1; +} + +#status-msg { + color: red; +} +``` + +Finally, there's the actual Javascript setting up our Monaco instance (stored in **src/static/minilogo.ts**), and for setting up Langium as well. This is the most complex part of setting up Langium + Monaco in the web, so we'll walk through the file in parts. + +(*Update on Oct. 4th, 2023: Previously we wrote this as **src/static/setup.js**. This new file can be considered the same, but reworked into TypeScript & updated for the new versions of Langium & the MER.*) + +First, we need to import and setup the worker, as well as some language client wrapper configuration. + +```ts +import { MonacoEditorLanguageClientWrapper, UserConfig } from "monaco-editor-wrapper/bundle"; +import { buildWorkerDefinition } from "monaco-editor-workers"; +import { addMonacoStyles } from 'monaco-editor-wrapper/styles'; + +/** + * Setup Monaco's own workers and also incorporate the necessary styles for the monaco-editor + */ +function setup() { + buildWorkerDefinition( + './monaco-editor-workers/workers', + new URL('', window.location.href).href, + false + ); + addMonacoStyles('monaco-editor-styles'); +} +``` + +Then, we'll want to instantiate our language client wrapper. In previous versions of the `monaco-editor-wrapper` package (before 2.0.0), configuration was performed by manually setting properties on the `MonacoEditorLanguageClientWrapper` instance. However, as of 3.1.0 (at the time of writing this), the constructor for `MonacoEditorLanguageClientWrapper` now takes a configuration object as its first argument. This configuration object allows us to set the same properties as before, but with more fine-grained control over all the properties that are set. + +We're going to walk through the parts that will be used to build up this configuration first, and then joining the actual configuration object together afterwards. + +To start, let's keep in mind that our current language id will be `minilogo`. This should match the id of the language that will be recognized by our language server. + +Then, we'll want to add some static syntax highlighting. To do this we have a couple choices, using a TextMate or a [Monarch grammar](https://microsoft.github.io/monaco-editor/monarch.html). Both will provide us with the ability to parse our language, and apply styling to our tokens. However we have to choose one, we cannot use both simultaneously. This is related to how Monaco itself is configured with regards to whether we're using the VSCode API config, or the classic editor config. This makes sense to a degree, as we can only prepare the editor one way or the other. + +For MiniLogo, our monarch grammar will look like so: + +```ts +/** + * Returns a Monarch grammar definition for MiniLogo + */ +function getMonarchGrammar() { + return { + keywords: [ + 'color','def','down','for','move','pen','to','up' + ], + operators: [ + '-',',','*','/','+','=' + ], + symbols: /-|,|\(|\)|\{|\}|\*|\/|\+|=/, + + tokenizer: { + initial: [ + { regex: /#(\d|[a-fA-F]){3,6}/, action: {"token":"string"} }, + { regex: /[_a-zA-Z][\w_]*/, action: { cases: { '@keywords': {"token":"keyword"}, '@default': {"token":"string"} }} }, + { regex: /(?:(?:-?[0-9]+)?\.[0-9]+)|-?[0-9]+/, action: {"token":"number"} }, + { include: '@whitespace' }, + { regex: /@symbols/, action: { cases: { '@operators': {"token":"operator"}, '@default': {"token":""} }} }, + ], + whitespace: [ + { regex: /\s+/, action: {"token":"white"} }, + { regex: /\/\*/, action: {"token":"comment","next":"@comment"} }, + { regex: /\/\/[^\n\r]*/, action: {"token":"comment"} }, + ], + comment: [ + { regex: /[^\/\*]+/, action: {"token":"comment"} }, + { regex: /\*\//, action: {"token":"comment","next":"@pop"} }, + { regex: /[\/\*]/, action: {"token":"comment"} }, + ], + } + }; +} +``` + +We can produce this Monarch grammar by updating our **langium-config.json** to produce a Monarch file as output. Note that although we're talking about MiniLogo here, we based this example off of the hello-world example produced by the yeoman generator. As such, we still have hello world names here and there, and for this tutorial we'll just use the same name again as for the TextMate grammar. + +```json +... +"textMate": { + "out": "syntaxes/minilogo.tmLanguage.json" +}, +"monarch": { + "out": "syntaxes/minilogo.monarch.ts" +} +``` + +To generate this file, run `npm run langium:generate`. You can then copy over the definition of the grammar from **syntaxes/hello-world.monarch.ts** (or whatever other name you have given this file). Keep in mind that this generated monarch grammar is *very* simple. If you want more complex highlighting, we recommend writing your own custom monarch grammar, and storing it somewhere else to prevent it from being overridden. If you're interested, you can find more details about the [Monarch grammar highlighting language here](https://microsoft.github.io/monaco-editor/monarch.html). + +Then, we want to setup the code that shows up by default. The following is a fixed MiniLogo program that should display a white diamond in the top left corner of the screen. + +```ts +/** + * Retrieves the program code to display, either a default or from local storage + */ +function getMainCode() { + let mainCode = ` + def test() { + move(100, 0) + pen(down) + move(100, 100) + move(-100, 100) + move(-100, -100) + move(100, -100) + pen(up) + } + color(white) + test() + + `; + + // optionally: use local storage to save the code + // and seek to restore any previous code from our last session + if (window.localStorage) { + const storedCode = window.localStorage.getItem('mainCode'); + if (storedCode !== null) { + mainCode = storedCode; + } + } + + return mainCode; +} +``` + +Since we're planning to use a language server with Monaco, we'll need to setup a language client config too. To do this we'll also need to generate a worker using our language server worker file, but that's fairly straightforward to setup here. Keep in mind that you'll need to have access to the bundle produced from your **main-browser.ts** from before. Here the built result is copied over as **public/minilogo-server-worker.js**. + +```ts +/** + * Creates & returns a fresh worker using the MiniLogo language server + */ +function getWorker() { + const workerURL = new URL('minilogo-server-worker.js', window.location.href); + return new Worker(workerURL.href, { + type: 'module', + name: 'MiniLogoLS' + }); +} +``` + +By creating the worker in advance, we give ourselves the ability to directly interact with the worker/LS independent of the wrapper itself, and to even pre-configure it before use. This can be hugely beneficial, especially if we expect to customize our LS on the fly. + +Lastly, let's setup the user config, which will be used to startup the wrapper. + +```ts +type WorkerUrl = string; + +/** + * Classic configuration for the monaco editor (for use with a Monarch grammar) + */ +interface ClassicConfig { + code: string, + htmlElement: HTMLElement, + languageId: string, + worker: WorkerUrl | Worker, + monarchGrammar: any; +} + +/** + * Generates a valid UserConfig for a given Langium example + * + * @param config An extended or classic editor config to generate a UserConfig from + * @returns A completed UserConfig + */ +function createUserConfig(config: ClassicConfig): UserConfig { + // setup urls for config & grammar + const id = config.languageId; + + // generate langium config + return { + htmlElement: config.htmlElement, + wrapperConfig: { + editorAppConfig: { + $type: 'classic', + languageId: id, + useDiffEditor: false, + code: config.code, + theme: 'vs-dark', + languageDef: config.monarchGrammar + }, + serviceConfig: { + enableModelService: true, + configureConfigurationService: { + defaultWorkspaceUri: '/tmp/' + }, + enableKeybindingsService: true, + enableLanguagesService: true, + debugLogging: false + } + }, + languageClientConfig: { + options: { + $type: 'WorkerDirect', + worker: config.worker as Worker, + name: `${id}-language-server-worker` + } + } + }; +} +``` + +This particular UserConfig will be for configuring a classic editor, rather than a VSCode extension-based editor. This is because we're using a Monarch grammar, which is not supported by the extension configuration. However, if we wanted to use a TextMate grammar, we could use the extension based configuration instead. + +```json +editorAppConfig: { + $type: 'vscodeApi', + languageId: id, + useDiffEditor: false, + code: config.code, + ... +} +``` + +You would just need to fill in the rest of the details for associating a TextMate grammar & such. [Here's an example from the monaco-components repo](https://github.com/TypeFox/monaco-components/blob/4f301445eca943b9775166704304637cf5e8bd00/packages/examples/src/langium/config/wrapperLangiumVscode.ts#L37). + +Regardless of how the user config is setup, we can now invoke that helper function with a handful of configuration details, and have a working UserConfig to pass to the wrapper. + +```ts +// create a wrapper instance +const wrapper = new MonacoEditorLanguageClientWrapper(); + +// start up with a user config +await wrapper.start(createUserConfig({ + htmlElement: document.getElementById("monaco-editor-root")!, + languageId: 'minilogo', + code: getMainCode(), + worker: getWorker(), + monarchGrammar: getMonarchGrammar() +})); +``` + +That's it! Now if everything was configured correctly, we should have a valid wrapper that will display the code we want in our browser. + +## Serving via NodeJS + +Now that we have our files all setup, and our build process prepared, we can put together a mini server application to make viewing our public assets easy. We'll do this by adding **src/web/app.ts** to our project, and giving it the following contents: + +```ts +/** + * Simple server app for serving generated examples locally + * Based on: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Node_server_without_framework + */ +import * as fs from "node:fs"; +import * as http from "node:http"; +import * as path from "node:path"; + +const port = 3000; + +const MIME_TYPES: Record = { + default: "application/octet-stream", + html: "text/html; charset=UTF-8", + js: "application/javascript", + css: "text/css", +}; + +const STATIC_PATH = path.join(process.cwd(), "./public"); + +const toBool = [() => true, () => false]; + +const prepareFile = async (url: string) => { + const paths = [STATIC_PATH, url]; + if (url.endsWith("/")) { + paths.push("index.html"); + } + const filePath = path.join(...paths); + const pathTraversal = !filePath.startsWith(STATIC_PATH); + const exists = await fs.promises.access(filePath).then(...toBool); + const found = !pathTraversal && exists; + // there's no 404, just redirect to index.html in all other cases + const streamPath = found ? filePath : STATIC_PATH + "/index.html"; + const ext = path.extname(streamPath).substring(1).toLowerCase(); + const stream = fs.createReadStream(streamPath); + return { found, ext, stream }; +}; + +http + .createServer(async (req, res) => { + const file = await prepareFile(req.url!); + const statusCode = file.found ? 200 : 404; + const mimeType: string = MIME_TYPES[file.ext] || MIME_TYPES.default; + res.writeHead(statusCode, { "Content-Type": mimeType }); + file.stream.pipe(res); + console.log(`${req.method} ${req.url} ${statusCode}`); + }) + .listen(port); + +console.log(`Server for MiniLogo assets listening on http://localhost:${port}`); +``` + +If you would like to compact this, and don't mind adding additional deps to your project, you can include `express` and `@types/express` to your project, and use the following code instead: + +```ts +/** + * Simple express app for serving generated examples + */ + +import express from 'express'; +const app = express(); +const port = 3000; +app.use(express.static('./public')); +app.listen(port, () => { +console.log(`Server for MiniLogo assets listening on http://localhost:${port}`); +}); +``` + +And to invoke the server, we need to add one more script to our package.json. + +```json +{ + ... + "serve": "node ./out/web/app.js" +} +``` + +That's it! Now we can build all the assets, and run express to be able to view our demo of Langium in the web from **localhost:3000**. + +```bash +npm run build:web +npm run serve +``` + +You should be greeted with a page that contains a working Monaco instance and a small MiniLogo program in the editor. This editor has the highlighting we would expect, and also is fully connected to the language server for our language. This means we have full LSP support for operations that we would expect to have in a native IDE, such as VSCode. + +And that's it, we have successfully implemented Langium + Monaco in the web for our language. It's not doing much at this time besides presenting us with an editor, but in the next tutorial we'll talk about [using the same setup to add generation in the web](/tutorials/generation_in_the_web). Since our generation has already been configured natively in prior tutorials, we can use what we've written to quickly implement a web application that translates MiniLogo programs into drawing instructions for an HTML5 canvas. diff --git a/hugo/content/docs/1_learn/minilogo/validation.md b/hugo/content/docs/1_learn/minilogo/validation.md new file mode 100644 index 00000000..b41015bd --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/validation.md @@ -0,0 +1,153 @@ +--- +title: "Validation" +weight: 1 +--- + +{{< toc format=html >}} + +In this tutorial, we will be talking about implementing validation for your Langium-based language. We recommend first reading the previous tutorial about [writing a grammar](/tutorials/writing_a_grammar/), as we will assume you're familiar with the topics covered there. We'll also assume that you have a working language to add validation to, so double check that `npm run langium:generate` succeeds without errors before you proceed. + +For this tutorial, we'll be implementing validation for the [MiniLogo language](https://github.com/langium/langium-minilogo), but you can use your own language to follow along as well. + +## Overview + +Adding validation is an important step to building a language, as there are often invalid cases that cannot be filtered out through your grammar alone. + +Consider the case of having unique names for identifiers. In MiniLogo we have definitions with names, and we also have parameters that are identified by name. One problem here is if we have several definitions that share the same name. We could also have a similar problem with parameters, where perhaps the same name is used multiple times in the same definition. In the second case, this is most certainly undesirable, but in the first it depends on how you want your language to handle redefinitions. + +Let's consider the case where you want to allow redeclaring a previous definition. This opens the door to allowing redeclaring or shadowing of definitions. If you ever wanted to extend your language down the road, such as by adding the ability to import other programs (along with their definitions) then you might consider allowing a definition to be redefined. However, it could also lead to unintended redeclarations that may be harder to track down. Ultimately, this choice depends on the desired semantics for your language, and is something you should consider carefully. + +In this example we're going to *disallow* names that are non-unique for definitions, and we'll be doing the same for arguments of a definition as well. + +## The Validation Registry + +In order to express these constraints, we need to modify our language's **validator**. By default, this can be found in **src/language/YOUR-LANGUAGE-validator.ts**; with a name that corresponds to your language. This file begins with a validation registry that extends the default validation registry. The validation registry allows us to register validation checks for our language. + +The constructor for the registry is of particular interest, as it allows associating validation functions with *specific* nodes in your AST. Here you can see an example of the constructor below for the default hello world language from the yeoman generator. + +```ts +/** + * Registry for validation checks. + */ +export class HelloWorldValidationRegistry extends ValidationRegistry { + constructor(services: HelloWorldServices) { + super(services); + const validator = services.validation.HelloWorldValidator; + const checks: ValidationChecks = { + // we want to add checks here... + Person: validator.checkPersonStartsWithCapital + }; + this.register(checks, validator); + } +} +``` + +From this example, we have a single validation for the `Person` node. + +```ts +Person: validator.checkPersonStartsWithCapital +``` + +Before we changed our grammar in the last tutorial, the `Person` node corresponded with a parser rule named `Person`. Similarly, most nodes that we can validate will share the name of the parser rule that instantiates them. However, there are a couple cases where this is different: + +- when `Rule infers AnotherName` (or uses `return`), the node's type will be `AnotherName` +- when the body of a parser rule has an action (like `{AnotherName}`, possibly starting with `infer`) this new name will exist instead for this *part* of the rule body + +## Finding Nodes to Validate + +With this in mind, we can look back at our grammar that we've written for MiniLogo (from the last tutorial), and find the parser rules that refer to the nodes we want to validate. For this language we have a pair of cases to check, as mentioned above: + +- Validate that definitions have unique names in a Model +- Validate that arguments have unique names in a Definition + +In order to perform a validation, we need to know the type of that node to validate. Beyond checking our grammar to find this, we can also check the semantic model (akin to the abstract syntax) of our language. This was generated while running `npm run langium:generate`, and is located in **src/language/generated/ast.ts**. Peeking into this model, we can see that our rule for `Model` was written like so: + +```langium +entry Model: (stmts+=Stmt | defs+=Def)*; +``` + +which produces the following node type in our semantic model: + +```ts +export interface Model extends AstNode { + defs: Array + stmts: Array +} +``` + +## Registering Validations + +So, we can register a validation on all nodes of type `Model` (which should be just the root), like so. Note the import coming from the generated file, which contains the definitions that compose our semantic model. The name **ast.ts** reflects it's usage as identifying node types that constitute an AST in our language (akin to an abstract syntax). + +```ts +import { Model } from './generated/ast'; +... +const checks: ValidationChecks = { + Model: (m: Model, accept: ValidationAcceptor) => { + // and validate the model 'm' here + } +}; +``` + +We also have a perfectly good validator class that's just below this part of the file that we can use, but it's still setup to perform validation on the old `Person` node. We can safely remove the old function, add our custom validation there, and associate it back with our validation registry checks. + +The updated validator class looks like so: + +```ts +/** + * Implementation of custom validations. + */ +export class HelloWorldValidator { + + // our new validation function for defs + checkUniqueDefs(model: Model, accept: ValidationAcceptor): void { + // create a set of visited functions + // and report an error when we see one we've already seen + const reported = new Set(); + model.defs.forEach(d => { + if (reported.has(d.name)) { + accept('error', `Def has non-unique name '${d.name}'.`, {node: d, property: 'name'}); + } + reported.add(d.name); + }); + } + +} +``` + +To call this validator in our registry, we can modify the check that is listed in our registry like so (removing the previously written lambda/arrow function). + +```ts +const checks: ValidationChecks = { + Model: validator.checkUniqueDefs, +}; +``` + +Great! Now we have a simple validation in place to guard against duplicate definitions in MiniLogo. + +Now that we've shown how this can be done, we can implement this for parameters as well. Looking at our grammar, we can see params are contained as part of a Definition, so we'll register validation for Definition nodes and report if any parameter are duplicated. + +```ts +const checks: ValidationChecks = { + Model: validator.checkUniqueDefs, + Def: validator.checkUniqueParams +}; +``` + +And we can define this new function in our validator class, which is very close in structure to our first function. + +```ts +checkUniqueParams(def: Def, accept: ValidationAcceptor): void { + const reported = new Set(); + def.params.forEach(p => { + if (reported.has(p.name)) { + accept('error', `Param ${p.name} is non-unique for Def '${def.name}'`, {node: p, property: 'name'}); + } + reported.add(p.name); + }); +} +``` + +Although we've only implemented a pair of validations, hopefully this demonstrates the flexibility of the validator API. The validator can help enforce constraints or features of your language, and ensure that your programs are correct. You could also explore more customized validations for specific cases, perhaps where a parameter and a definition share the same name -- which is not handled here. So long as you can identify the AST node type that you need to validate, you can implement the logic here. + +That's all for validation. Next we'll be talking about how we can [customize our CLI](/tutorials/customizing_cli). diff --git a/hugo/content/docs/1_learn/minilogo/writing_a_grammar.md b/hugo/content/docs/1_learn/minilogo/writing_a_grammar.md new file mode 100644 index 00000000..e971bf9b --- /dev/null +++ b/hugo/content/docs/1_learn/minilogo/writing_a_grammar.md @@ -0,0 +1,312 @@ +--- +title: "Writing a Grammar" +weight: 0 +--- + +{{< toc format=html >}} + +In this tutorial we will be talking about writing a grammar for your language in Langium. As a motivating example, we'll be describing how to write a grammar for the MiniLogo language. If you're not familiar with MiniLogo, it's a smaller implementation of the Logo programming language. Logo itself is a lot like Turtle from Python. Ultimately, we'll be using MiniLogo to express drawing instructions that can be used to draw on a canvas. + +We've already written an implementation of [MiniLogo on Github using Langium](https://github.com/langium/langium-minilogo). This tutorial will be following along with this project, by walking through the grammar implementation step by step. Later tutorials will also follow along with MiniLogo to create an easy to follow series. + +## Planning + +Before we get started writing the grammar, we'll want to first identify a couple important aspects of our language. Namely, these are: + +- The Semantic Domain +- The Concrete Syntax + +The Semantic Domain describes the types of values that will be produced by evaluating our language. In the case of MiniLogo our semantic domain is going to have a single part, an updated drawing state that contains information on: + +- position +- whether we're drawing or not +- color of the drawing stroke + +We'll also be producing values and updating an environment as well, which are important to keep in mind. + +Basically, a MiniLogo program can be considered equivalent to a series of transformations on some drawing context. This goal for MiniLogo will guide our design throughout these tutorials. + +In addition, we'll want to get an idea of what our concrete syntax will be. This step can be done on paper if you like, but the overall goal is to get a feel for how you want the language to look. Your choice of concrete syntax will also drive your grammar's design. If your design is chosen well, it can simplify the way your grammar is constructed. If your syntax is complex, the grammar may also be complex as well. Not only this, but it's also important to try and strike a balance between syntax that is special to your language, and syntax that is at least somewhat shared with other languages. The more unfamiliar the language appears, the more likely your users will struggle trying to pick it up. + +In our case, we're going to use a C-like concrete syntax. This will make it easy to understand the structure of our programs for most users. This is also chosen because it allows us to use curly braces to delimit blocks of code, which is quite easy to implement in Langium. You could also go for a Python style language, where whitespace has significance in determining which block some code belongs to. Unfortunately, this is not as easy to do out of the box with Langium, due to it ignoring whitespace by default, but it can be configured to work for such languages. + +## Sketching the Grammar + +Now that we have an idea of our semantics and our concrete syntax, we can then start writing out a grammar. Conveniently, MiniLogo already has a grammar and concrete syntax described, and that in turn is based off of the [Logo programming language](https://el.media.mit.edu/logo-foundation/what_is_logo/logo_programming.html). [MiniLogo](https://web.engr.oregonstate.edu/~walkiner/teaching/cs381-wi21/minilogo.html) itself was designed by Eric Walkingshaw at Oregon State University, and was used to teach students. It's not something that we've created, but rather something that we found to be an ideal demonstration of Langium's capabilities, while also remaining friendly for newcomers. + +As an aside, our version of MiniLogo will be an *approximation* of Dr. Walkingshaw's version. We won't adhere to it completely, and we won't be incorporating some elements, such as variable declarations. + +To get started sketching the grammar we'll be using the **Hello World** example from the yeoman generator. You can read about how to get this setup in the [Getting Started](/docs/getting-started/) section of our docs. We'll be working with a fresh from the generator using only the defaults, and building up from that. We'll begin by modifying the default grammar file, and updating it to work for MiniLogo. You can find this file under **src/language/hello-world.langium** in your new project. If you used a name other than the default, the file will still be there, but using your custom name instead. + +We'll be overriding the existing langium grammar file completely, so delete the old contents before we begin. + +The first line that we'll then add is the declaration of our grammar. + +```langium +grammar MiniLogo +``` + +This simply describes the name of the grammar that will be proceeding, and is required. + +Next, we'll need to describe an entry rule. This will be a parser rule that must be matched first when recognizing a MiniLogo program. This rule is particularly special, because it will become the root of the resulting abstract syntax tree, which captures the essential structure of our program. For MiniLogo, our entry rule Will be `Model`. You could also make it `Program`, but whatever you choose it should capture the same notion. Regardless of your choice, this rule should match any number of Statements and/or Definitions to follow the MiniLogo specification. + +```langium +entry Model: (stmts+=Stmt | defs+=Def)*; +``` + +Each instance of a statement will be stored under the `stmts` property as an element of an Array. The same will be done for Definitions using `defs` as well. Note the trailing `*` after the grouping, which means technically a program containing *nothing* is also a valid MiniLogo program. + +To iterate on this a little bit further we'll need to describe what a Statement (Stmt) and a Definition (Def) are in the context of MiniLogo. + +First, let's talk about **Definitions**. A definition corresponds to: + +- a name +- a list of parameters +- a block of *statements* + +And we want definitions to look like so in our concrete syntax: + +```minilogo +def myDef() { + ... +} +... +def anotherDef(x,y,z) { + ... +} +``` + +We can recognize this concrete syntax, and capture the relevant information for our AST, with the following rule: + +```langium +Def: 'def' name=ID '(' (params+=Param (',' params+=Param)*)? ')' Block; +``` + +As an additional note, much like regular expressions we use modifiers in our grammar to indicate that definitions can take any number of comma separated parameters. + +You may be wondering what `Block` is as well. Block corresponds to a rule *fragment*, which is akin to a reusable rule body. It's not a rule itself, but an reusable piece that can be reused to complete rules. It's particularly handy when you find yourself writing the same pattern repeatedly, and want to factor it out. + +```langium +fragment Block: '{' body+=Stmt* '}'; +``` + +Then we have **Statements**, which consist of Commands or Macros. + +```langium +Stmt: Cmd | Macro; +``` + +A **Command** describes an action that transforms the drawing state (which connects to our semantic domain from before). The commands in MiniLogo can be expressed like so: + +```langium +Cmd: Pen | Move | Color | For; +``` + +Where each command is also a separate rule: + +- **Pen**: Corresponds to a command that turns on/off drawing +- **Move**: Updates the position of the pen (relatively) +- **Color**: Sets the stroke color of what is drawn +- **For**: A standard for loop control flow + +These commands describe the essential drawing instructions that we will be representing. We'll go over those in a moment. + +A statement can also be a **Macro**. A Macro has 2 distinct parts: + +- a reference to a Definition (more on this shortly, think of it like a 'function' for now) +- a list of arguments to apply this definition to + +In our concrete syntax, we want macros to look like this: + +```minilogo +myMacro() +... +anotherMacro(1, 2, 3 * 3) +``` + +We can encode this in MiniLogo like so: + +```langium +Macro: def=[Def:ID] '(' (args+=Expr (',' args+=Expr)*)? ')'; +``` + +In this case `def` will be a **Cross Reference** to an existing Definition. This is a special syntax that says *def will be assigned to a Definition object at runtime identified by an ID terminal token*. Although we haven't introduced this terminal yet, it's a simple rule that captures literal strings as tokens. It's also important to note that cross references implicitly utilize the `name` property to hookup the cross reference to the target object. + +We also want to add the notion of a Parameter, which is quite simple to write in: + +```langium +Param: name=ID; +``` + +As you may have guessed, by using the `name` property for a parameter, we're allowing Langium to automatically setup cross references for parameters as well. + +## Adding Commands + +For the commands, we'll go through each one, and show examples of the concrete syntax we're trying to capture: + +**Pen** needs to have two modes, up and down. So it should capture syntax like this: + +```minilogo +pen(up) +... +pen(down) +``` + +We can express this with the following parser rule. + +```langium +Pen: 'pen' '(' mode=('up' | 'down') ')'; +``` + +**Move** commands will take a pair of expressions, corresponding to the x and y components, and can look like so: + +```minilogo +move(1,5) +... +move(x * 10, y * 10) +``` + +We haven't defined it yet, but we can use an **Expr** rule to represent where our expressions will go, and capture this command like this: + +```langium +Move: 'move' '(' ex=Expr ',' ey=Expr ')'; +``` + +We'll define expressions shortly. + +Simple for loops can be defined too, which should look like this: + +```minilogo +for x = 0 to 10 { + ... +} +``` + +Again, we don't have **Expr** defined yet, but we can still use it here. Also, since we have a block of statements, we can reuse that `Block` fragment that was defined earlier. + +```langium +For: 'for' var=Param '=' e1=Expr 'to' e2=Expr Block; +``` + +**Color** commands are the last one to add, and they'll change the stroke color in a few ways. The first is by setting the RGB components as integers directly: + +```minilogo +color(128,64,255) +``` + +The second is by passing in the name of a stroke color: + +```minilogo +color(blue) +``` + +The last is by passing a hexadecimal value: + +```minilogo +color(#66CCFF) +... +color(#6cf) +``` + +The corresponding rule for this syntax is a special case where we have 3 different overloaded forms of the same command. To capture all of these forms, we can use two different sets of properties: + +- r,g,b values for each color +- a single color value that can be either an ID or HEX + +We can encode this like so: + +```langium +Color: 'color' '(' ((r = Expr ',' g=Expr ',' b=Expr) | color=ID | color=HEX) ')'; +``` + +What's interesting here is that the color & r,g,b properties are *both* optional. Since in either case only one or the other will be defined. With the two forms, this is enough information to quickly determine what kind of color command we have, and to handle it correctly later on. + +## Adding Expressions + +Now we're at the core of our language, **Expressions**. In MiniLogo we want to be able to express not only literal values, but also references and arithmetic operations such as addition, subtraction, multiplication, and division. When implementing expressions, we need to keep in mind that Langium is based off of Chevrotain, which produces top-down parsers. This means we have to watch out for cases that lead to left-recursion. In order to avoid this, we need to be careful not to define a rule with itself on the left-hand side. For example, something like `Expr: e1=Expr ...` would not work, because the parser would infinitely try to parse another expression forever. + +However, we can work around this. We can introduce expressions and avoid left-recursion by writing them from the bottom up in terms of order of operations. We'll start with `Add` (which also includes subtraction): + +```langium +Expr: Add; +``` + +Then writing a rule to handle the addition (and subtraction) case. + +```langium +Add infers Expr: + Mult ({infer BinExpr.e1=current} op=('+'|'-') e2=Mult)*; +``` + +To explain a bit, the `Add` rule introduces: + +- a parser rule that produces an **Expr** instance (that's what the infers is doing here) +- starts by recognizing a `Mult` instance +- *then* if there's a binary operator to parse + - rewrite this parsed object into a **BinExpr** that will *extend* **Expr** (that's what the second `{infer ...}` is doing) + - also capture the first `Mult` under the `e1` property (that's what the `current` keyword refers to) + - capture the operand +/- + - capture the following `Mult` instance (the right hand side of our binary expression) +- *else* simply returns the result of `Mult` (the case where we don't have a binary expression) + +We can then repeat this pattern with the `Mult` rule: + +```langium +Mult infers Expr: + PrimExpr ({infer BinExpr.e1=current} op=('*'|'/') e2=PrimExpr)*; +``` + +Lastly we can then introduce `Primary` expressions, or `PrimExpr`. This rule will match all the primitive cases, such as literals, references, groupings, and negation. + +```langium +PrimExpr: Lit | Ref | Group | NegExpr; + +// literal int +Lit: val=INT; +// cross-reference to a parameter +Ref: val=[Param:ID]; +// grouped expression with parentheses +Group: '(' ge=Expr ')'; +// negated expression +NegExpr: '-' ne=Expr; +``` + +By writing our parser rules first for Addition & Subtraction, and then later for Multiplication and Division, we can construct an abstract syntax text tree that will correctly preserve order of operations. + +As a note, we could also write these rules *without using actions to rewrite our parse tree*. When we're talking about actions, we're talking about those cases of `{infer ...}`. However, then we'll get nodes like `Add` and `Mult`, instead of `Expr` and `BinaryExpr`. This is a tradeoff that is a bit tough to grasp at first in the grammar, but translates to a more sensible AST to work on later. This is especially helpful when we get to generation. + +## Adding Terminals + +Now that we're almost done with our grammar, we need to add in the terminal rules. Conveniently, the body of a terminal rule can be defined as a Javascript regular expression; sharing the same syntax. This makes it very clear to determine what our terminals should recognize. + +```langium +// recognize a hexadecimal sequence, used to recognize colors for the 'Color' command +terminal HEX returns string: /#(\d|[a-fA-F])+/; + +// recognize an identifier +terminal ID returns string: /[_a-zA-Z][\w_]*/; + +// recognize an Integer (but represented via a 'number' type) +terminal INT returns number: /-?[0-9]+/; +``` + +Then, lastly, we want to add *hidden terminals*. These will describe tokens that we want to parse and *discard* while parsing any input. Since we're adding whitespace & comments as hidden terminals, it's the same as saying we do *not* care about these tokens while parsing, but we do recognize that they are tokens; they just don't play a role in capturing the structure of our language. + +```langium +hidden terminal WS: /\s+/; +hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; +hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; +``` + +And that's it, we're all set writing up the grammar for MiniLogo. To verify that we correctly implemented the grammar with no problems, we can run the following command in the project root: + +```bash +npm run langium:generate +``` + +The generation should finish successfully, indicating that our grammar doesn't have any errors in it. In some cases, you may get warnings -- such as from unreachable rules in your grammar -- but these won't prevent the generation from completing successfully. Also, when we're referring to the generation, we're talking about the construction of the following from your grammar: + +- a semantic model (that ASTs can be mapped onto) +- a parser that recognizes our language + +With that, we have the beginnings of our very own language! Hopefully this gives a good idea of how to express a grammar in Langium, particularly with consideration to your concrete syntax & semantic domain. You can also consider the ways we can express cases that are left-recursive, like expressions, in an alternative fashion. Overall, our grammar should now be ready for the next step of [validation in the following tutorial](/tutorials/validation). diff --git a/hugo/content/docs/1_learn/overview.md b/hugo/content/docs/1_learn/workflow/_index.md similarity index 92% rename from hugo/content/docs/1_learn/overview.md rename to hugo/content/docs/1_learn/workflow/_index.md index 4e8dfcd6..bdcc93da 100644 --- a/hugo/content/docs/1_learn/overview.md +++ b/hugo/content/docs/1_learn/workflow/_index.md @@ -1,7 +1,7 @@ --- -title: "Overview" -weight: 100 -url: /docs/learn +title: "Our workflow" +weight: 0 +url: /docs/learn/worflow --- {{}} @@ -26,3 +26,4 @@ flowchart TD click G "/docs/learn/generate_everything" click H "/docs/recipes" {{}} + diff --git a/hugo/content/docs/1_learn/create_validations.md b/hugo/content/docs/1_learn/workflow/create_validations.md similarity index 54% rename from hugo/content/docs/1_learn/create_validations.md rename to hugo/content/docs/1_learn/workflow/create_validations.md index 6dcd5d19..f691decf 100644 --- a/hugo/content/docs/1_learn/create_validations.md +++ b/hugo/content/docs/1_learn/workflow/create_validations.md @@ -1,6 +1,6 @@ --- title: "Create validations" weight: 700 -url: /docs/learn/create_validations +url: /docs/learn/worflow/create_validations --- TODO diff --git a/hugo/content/docs/1_learn/generate_ast.md b/hugo/content/docs/1_learn/workflow/generate_ast.md similarity index 57% rename from hugo/content/docs/1_learn/generate_ast.md rename to hugo/content/docs/1_learn/workflow/generate_ast.md index f78bd305..6847baf8 100644 --- a/hugo/content/docs/1_learn/generate_ast.md +++ b/hugo/content/docs/1_learn/workflow/generate_ast.md @@ -1,6 +1,6 @@ --- title: "Generate the AST" weight: 500 -url: /docs/learn/generate_ast +url: /docs/learn/worflow/generate_ast --- TODO diff --git a/hugo/content/docs/1_learn/generate_everything.md b/hugo/content/docs/1_learn/workflow/generate_everything.md similarity index 56% rename from hugo/content/docs/1_learn/generate_everything.md rename to hugo/content/docs/1_learn/workflow/generate_everything.md index a7bc8fa2..bf6fd972 100644 --- a/hugo/content/docs/1_learn/generate_everything.md +++ b/hugo/content/docs/1_learn/workflow/generate_everything.md @@ -1,6 +1,6 @@ --- title: "Generate your artifacts" weight: 800 -url: /docs/learn/generate_everything +url: /docs/learn/worflow/generate_everything --- TODO diff --git a/hugo/content/docs/1_learn/install.md b/hugo/content/docs/1_learn/workflow/install.md similarity index 93% rename from hugo/content/docs/1_learn/install.md rename to hugo/content/docs/1_learn/workflow/install.md index 58302ab5..5c2aff40 100644 --- a/hugo/content/docs/1_learn/install.md +++ b/hugo/content/docs/1_learn/workflow/install.md @@ -1,7 +1,7 @@ --- title: "Install Yeoman" weight: 200 -url: /docs/learn/install +url: /docs/learn/worflow/install --- Before diving into Langium itself, let's get your environment ready for development: diff --git a/hugo/content/docs/1_learn/resolve_cross_references.md b/hugo/content/docs/1_learn/workflow/resolve_cross_references.md similarity index 54% rename from hugo/content/docs/1_learn/resolve_cross_references.md rename to hugo/content/docs/1_learn/workflow/resolve_cross_references.md index 21e2b319..6a75f426 100644 --- a/hugo/content/docs/1_learn/resolve_cross_references.md +++ b/hugo/content/docs/1_learn/workflow/resolve_cross_references.md @@ -1,6 +1,6 @@ --- title: "Resolve cross-references" weight: 600 -url: /docs/learn/resolve_cross_references +url: /docs/learn/worflow/resolve_cross_references --- TODO diff --git a/hugo/content/docs/1_learn/scaffold.md b/hugo/content/docs/1_learn/workflow/scaffold.md similarity index 98% rename from hugo/content/docs/1_learn/scaffold.md rename to hugo/content/docs/1_learn/workflow/scaffold.md index 5c8f7996..a42f1ec2 100644 --- a/hugo/content/docs/1_learn/scaffold.md +++ b/hugo/content/docs/1_learn/workflow/scaffold.md @@ -1,7 +1,7 @@ --- title: "Scaffold a Langium project" weight: 300 -url: /docs/learn/scaffold +url: /docs/learn/worflow/scaffold --- To create your first working DSL, execute the Yeoman generator: diff --git a/hugo/content/docs/1_learn/write_grammar.md b/hugo/content/docs/1_learn/workflow/write_grammar.md similarity index 57% rename from hugo/content/docs/1_learn/write_grammar.md rename to hugo/content/docs/1_learn/workflow/write_grammar.md index 579c77fc..ef55d401 100644 --- a/hugo/content/docs/1_learn/write_grammar.md +++ b/hugo/content/docs/1_learn/workflow/write_grammar.md @@ -1,6 +1,6 @@ --- title: "Write the grammar" weight: 400 -url: /docs/learn/write_grammar +url: /docs/learn/worflow/write_grammar --- TODO diff --git a/hugo/content/docs/2_recipes/builtin-library.md b/hugo/content/docs/2_recipes/builtin-library.md new file mode 100644 index 00000000..fb749d5c --- /dev/null +++ b/hugo/content/docs/2_recipes/builtin-library.md @@ -0,0 +1,164 @@ +--- +title: "Builtin Libraries" +weight: 300 +--- + +Languages usually offer their users some high-level programming features that they do not have to define themselves. +For example, TypeScript provides users with typings for globally accessible variables such as the `window`, `process` or `console` objects. +They are part of the JavaScript runtime, and not defined by any user or a package they might import. +Instead, these features are contributed through what we call builtin libraries. + +Loading a builtin library in Langium is very simple. We first start off with defining the source code of the library using the *hello world* language from the [getting started guide](/docs/getting-started): + +```ts +export const builtinHelloWorld = ` +person Jane +person John +`.trimLeft(); +``` + +Next, we load our builtin library code through the `loadAdditionalDocuments` method provided by the `DefaultWorkspaceManager`: + +```ts +import { + AstNode, + DefaultWorkspaceManager, + LangiumDocument, + LangiumSharedServices +} from "langium"; +import { WorkspaceFolder } from 'vscode-languageserver'; +import { URI } from "vscode-uri"; +import { builtinHelloWorld } from './builtins'; + +export class HelloWorldWorkspaceManager extends DefaultWorkspaceManager { + + private documentFactory: LangiumDocumentFactory; + + constructor(services: LangiumSharedServices) { + super(services); + this.documentFactory = services.workspace.LangiumDocumentFactory; + } + + protected override async loadAdditionalDocuments( + folders: WorkspaceFolder[], + collector: (document: LangiumDocument) => void + ): Promise { + await super.loadAdditionalDocuments(folders, collector); + // Load our library using the `builtin` URI schema + collector(this.documentFactory.fromString(builtinHelloWorld, URI.parse('builtin:///library.hello'))); + } +} +``` + +As a last step, we have to bind our newly created workspace manager: + +```ts +// Add this to the `hello-world-module.ts` included in the yeoman generated project +export type HelloWorldSharedServices = LangiumSharedServices; + +export const HelloWorldSharedModule: Module> = { + workspace: { + WorkspaceManager: (services) => new HelloWorldWorkspaceManager(services) + } +} +``` + +Be aware that this shared module is not injected by default. You have to add it manually to the `inject` call for the shared injection container. + +```ts +export function createHellowWorldServices(context: DefaultSharedModuleContext): { + shared: LangiumSharedServices, + services: HelloWordServices + } { + const shared = inject( + createDefaultSharedModule(context), + HelloWorldGeneratedSharedModule, + HelloWorldSharedModule + ); + const services = inject( + createDefaultModule({ shared }), + HelloWorldGeneratedModule, + HelloWorldModule + ); + shared.ServiceRegistry.register(services); + return { shared, services }; +} +``` + +Once everything is wired together, we are done from the perspective of our DSL. +At startup, our language server will run the `loadAdditionalDocuments` method which makes our library available for any workspace documents of the user. + +However, when trying to navigate to the builtin library elements, vscode will show users an error message, complaining that it cannot find the builtin library file. +This is expected, as the builtin library only lives in memory. +To fix this issue, we need to implement a custom `FileSystemProvider` on the client(`src/extension.ts` in the *hello world* example) that allows navigation to the builtin library files: + +```ts +import * as vscode from 'vscode'; +import { builtinHelloWorld } from './language/builtins'; + +export class DslLibraryFileSystemProvider implements vscode.FileSystemProvider { + + static register(context: vscode.ExtensionContext) { + context.subscriptions.push( + vscode.workspace.registerFileSystemProvider('builtin', new DslLibraryFileSystemProvider(context), { + isReadonly: true, + isCaseSensitive: false + })); + } + + stat(uri: vscode.Uri): vscode.FileStat { + const date = Date.now(); + return { + ctime: date, + mtime: date, + size: Buffer.from(builtinHelloWorld).length, + type: vscode.FileType.File + }; + } + + readFile(uri: vscode.Uri): Uint8Array { + // We could return different libraries based on the URI + // We have only one, so we always return the same + return new Uint8Array(Buffer.from(builtinHelloWorld)); + } + + // The following class members only serve to satisfy the interface + + private readonly didChangeFile = new vscode.EventEmitter(); + onDidChangeFile = this.didChangeFile.event; + + watch() { + return { + dispose: () => {} + }; + } + + readDirectory(): [] { + throw vscode.FileSystemError.NoPermissions(); + } + + createDirectory() { + throw vscode.FileSystemError.NoPermissions(); + } + + writeFile() { + throw vscode.FileSystemError.NoPermissions(); + } + + delete() { + throw vscode.FileSystemError.NoPermissions(); + } + + rename() { + throw vscode.FileSystemError.NoPermissions(); + } +} +... +// register the file system provider on extension activation +export function activate(context: vscode.ExtensionContext) { + DslLibraryFileSystemProvider.register(context); +} +``` + +This registers an in-memory file system for vscode to use for the `builtin` file schema. +Every time vscode is supposed to open a file with this schema, it will invoke the `stat` and `readFile` methods of the registered file system provider. diff --git a/hugo/content/docs/2_recipes/code-bundling.md b/hugo/content/docs/2_recipes/code-bundling.md new file mode 100644 index 00000000..29089879 --- /dev/null +++ b/hugo/content/docs/2_recipes/code-bundling.md @@ -0,0 +1,119 @@ +--- +title: "Code Bundling" +weight: 0 +--- + +When you first create a Langium project using the [Yeoman generator](/docs/getting-started/#your-first-example-language), it will only contain a plain TypeScript configuration, without any additional build processes. +However, if you want to make your language available for consumption in a non-development context, you'll want to create a bundle. +It is not absolutely necessary in a Node.js context, since you can always resolve local `node_modules` but it's still recommended [for vscode extensions](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). +It improves performance and decreases file size by minifying your code and only including what you actually need. + +We generally recommend using [esbuild](https://esbuild.github.io/) to bundle Langium based language servers and extensions. To install it, simply run: + +```sh +npm i --save-dev esbuild +``` + +You can see a minimal configuration file below that bundles both your language server and your extension. + +```ts +//@ts-check +import * as esbuild from 'esbuild'; + +const watch = process.argv.includes('--watch'); +const minify = process.argv.includes('--minify'); + +const ctx = await esbuild.context({ + entryPoints: ['src/extension.ts', 'src/language/main.ts'], + outdir: 'out', + bundle: true, + target: "es6", + loader: { '.ts': 'ts' }, + external: ['vscode'], // the vscode-module is created on-the-fly and must be excluded. + platform: 'node', // VSCode extensions run in a node process + sourcemap: !minify, + minify +}); + +if (watch) { + await ctx.watch(); +} else { + await ctx.rebuild(); + ctx.dispose(); +} +``` + +Store it in a module JavaScript file (`.mjs`) and create a corresponding script in your `package.json` file: + +```js +"scripts": { + "build": "node ./esbuild.mjs" +} +``` + +If you want to use a Langium language server in the browser, you can get away with an even smaller setup with the following script: + +```js +"scripts": { + "build:worker": "esbuild ./src/main.ts --bundle --format=iife --outfile=./public/languageServerWorker.js" +} +``` + +If you're more inclined to use [webpack](https://webpack.js.org/), a configuration for an extension bundler can be seen below: + +```js +const path = require('path'); + +const commonConfig = { + target: 'node', + mode: 'none', + devtool: 'nosources-source-map', + externals: { + vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded + }, + resolve: { + extensions: ['.ts', '.js'] + }, + module: { + rules: [ + { + test: /\.js$/, + enforce: 'pre', + loader: 'source-map-loader', + exclude: /vscode/ + }, + { + test: /\.ts$/, + exclude: /node_modules/, + use: [ + { + loader: 'ts-loader' + } + ] + } + ] + } +} +const lspConfig = { + ...commonConfig, + entry: './src/language/main.ts', // the entry point of the language server + output: { + path: path.resolve(__dirname, 'out', 'language'), + filename: 'main.js', + libraryTarget: 'commonjs2', + devtoolModuleFilenameTemplate: '../../[resource-path]', + clean: true + } +}; +const vscodeConfig = { + ...commonConfig, + entry: './src/extension.ts', // the entry point of this extension + output: { + path: path.resolve(__dirname, 'out'), + filename: 'extension.js', + libraryTarget: 'commonjs2', + devtoolModuleFilenameTemplate: '../[resource-path]' + } +}; +module.exports = [lspConfig, vscodeConfig]; +``` diff --git a/hugo/content/docs/2_recipes/formatting.md b/hugo/content/docs/2_recipes/formatting.md new file mode 100644 index 00000000..5fec2a44 --- /dev/null +++ b/hugo/content/docs/2_recipes/formatting.md @@ -0,0 +1,112 @@ +--- +title: "Formatting" +weight: 300 +--- + +Langium's formatting API allows to easily create formatters for your language. +We start building a custom formatter for our language by creating a new class that inherits from `AbstractFormatter`. + +```ts +import { AbstractFormatter, AstNode, Formatting } from 'langium'; + +export class CustomFormatter extends AbstractFormatter { + protected format(node: AstNode): void { + // This method is called for every AstNode in a document + } +} +... +// Bind the class in your module +export const CustomModule: Module = { + lsp: { + Formatter: () => new CustomFormatter() + } +}; +``` + +The entry point for the formatter is the abstract `format(AstNode)` method. The `AbstractFormatter` calls this method for every node of our model. +To perform custom formatting for every type of node, we will use pattern matching. +In the following example, we will take a closer look at a formatter for the [domain-model](https://github.com/eclipse-langium/langium/tree/main/examples/domainmodel) language. +In particular, we will see how we can format the root of our model (`DomainModel`) and each nested element (`Entity` and `PackageDeclaration`). + +To format each node, we use the `getNodeFormatter` method of the `AbstractFormatter`. The resulting generic `NodeFormatter` provides us with methods to select specific parts of a parsed `AstNode` such as properties or keywords. + +Once we have selected the nodes of our document that we are interested in formatting, we can start applying a specific formatting. +Each formatting option allows to prepend/append whitespace to each note. +The `Formatting` namespace provides a few predefined formatting options which we can use for this: + +* `newLine` Adds one newline character (while preserving indentation). +* `newLines` Adds a specified amount of newline characters. +* `indent` Adds one level of indentation. Automatically also adds a newline character. +* `noIndent` Removes all indentation. +* `oneSpace` Adds one whitespace character. +* `spaces` Adds a specified amount of whitespace characters. +* `noSpace` Removes all spaces. +* `fit` Tries to fit the existing text into one of the specified formattings. + +We first start off by formatting the `Domainmodel` element of our DSL. +It is the root node of every document and just contains a list of other elements. +These elements need to be realigned to the root of the document in case they are indented. +We will use the `Formatting.noIndent` options for that: + +```ts +if (ast.isDomainmodel(node)) { + // Create a new node formatter + const formatter = this.getNodeFormatter(node); + // Select a formatting region which contains all children + const nodes = formatter.nodes(...node.elements); + // Prepend all these nodes with no indent + nodes.prepend(Formatting.noIndent()); +} +``` + +Our other elements, namely `Entity` and `PackageDeclaration`, can be arbitrarily deeply nested, so using `noIndent` is out of the question for them. +Instead we will use `indent` on everything between the `{` and `}` tokens. The formatter internally keeps track of the current indentation level: + +```ts +if (ast.isEntity(node) || isPackageDeclaration(node)) { + const formatter = this.getNodeFormatter(node); + const bracesOpen = formatter.keyword('{'); + const bracesClose = formatter.keyword('}'); + // Add a level of indentation to each element + // between the opening and closing braces. + // This even includes comment nodes + formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent()); + // Also move the newline to a closing brace + bracesClose.prepend(Formatting.newLine()); + // Surround the name property of the element + // With one space to each side + formatter.property("name").surround(Formatting.oneSpace()); +} +``` + +Note that most predefined `Formatting` methods accept additional arguments which make the resulting formatting more lenient. +For example, the `prepend(newLine({ allowMore: true }))` formatting will not apply formatting in case the node is already preceeded by one **or more** newlines. +It will still correctly indent the node in case the indentation is not as expected. + +
+Full Code Sample + +```ts +import { AbstractFormatter, AstNode, Formatting } from 'langium'; +import * as ast from './generated/ast'; + +export class DomainModelFormatter extends AbstractFormatter { + + protected format(node: AstNode): void { + if (ast.isEntity(node) || ast.isPackageDeclaration(node)) { + const formatter = this.getNodeFormatter(node); + const bracesOpen = formatter.keyword('{'); + const bracesClose = formatter.keyword('}'); + formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent()); + bracesClose.prepend(Formatting.newLine()); + formatter.property('name').surround(Formatting.oneSpace()); + } else if (ast.isDomainmodel(node)) { + const formatter = this.getNodeFormatter(node); + const nodes = formatter.nodes(...node.elements); + nodes.prepend(Formatting.noIndent()); + } + } +} +``` + +
diff --git a/hugo/content/docs/2_recipes/multiple-languages.md b/hugo/content/docs/2_recipes/multiple-languages.md new file mode 100644 index 00000000..52853e4b --- /dev/null +++ b/hugo/content/docs/2_recipes/multiple-languages.md @@ -0,0 +1,447 @@ +--- +title: "Multiple dependent languages" +weight: 400 +--- + +This guide is about integrating multiple dependent languages in one Langium project. + +One common situation where it makes sense to create dependent languages is when you only want to read concepts in one language and predefine them in another file (probably also a built-in one). Think of splitting SQL into a defining `CREATE TABLE table (...)`) and a reading part (`SELECT * FROM table`). + +> Notice that for `n` independent languages, you can simply create `n` independent Langium projects. + +If you want to see a living example, I recommend to visit the [`requirements` example](https://github.com/eclipse-langium/langium/tree/main/examples/requirements) of the main [Langium repository](https://github.com/eclipse-langium/langium). + +## Our plan + +The entire change touches several files. Let's summarize what needs to be done: + +1. the **grammar** (the `*.langium` file) needs to be split into the three parts that were discussed above +2. the **Langium configuration** (the `langium-config.json` file in the Langium project root) needs to split the language configuration into three parts +3. the **module file** of your language (`XXX-module.ts`) needs to create the new language services as well. +4. Last, but not least, you have to **cleanup all dependent files**. Here we can give general hints. +5. if you have a **VSCode extension** + 1. the `package.json` needs to be adapted + 2. the extension entry point file (`src/extension/main.ts`) needs to be changed slightly + +## Our scenario + +To keep this guide easy, I will use the [`hello-world` project](/docs/getting-started/). + +Let’s imagine that we have three languages: + +* the first language **defines** persons +* the second language **greets** persons of the first language +* the third language **configures** which person you are + +Just as a finger practice, let's require that you cannot greet yourself. + +{{}} +flowchart + Implementation -->|requires| Definition + Configuration -->|requires| Definition + Implementation -->|requires| Configuration +{{}} + +## Let's start + +### Grammar + +The most relevant change might be in the grammar. Here is the original grammar from the `hello-world` example, which is generated by Langium's Yeoman generator: + +```langium +grammar MultipleLanguages + +entry Model: + (persons+=Person | greetings+=Greeting)*; + +Person: + 'person' name=ID; + +Greeting: + 'Hello' person=[Person:ID] '!'; + +hidden terminal WS: /\s+/; +terminal ID: /[_a-zA-Z][\w_]*/; +terminal INT returns number: /[0-9]+/; +terminal STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/; + +hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; +hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; +``` + +Now, split it into three new files (let's call the entry rules units and the files we can name like `multiple-languages-(configuration|definition|implementation).langium`): + +Our definition grammar: + +```langium +grammar MultiDefinition + +entry DefinitionUnit: + (persons+=Person)*; + +Person: + 'person' name=ID; + +hidden terminal WS: /\s+/; +terminal ID: /[_a-zA-Z][\w_]*/; + +hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; +hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; +``` + +Our configuration grammar (note the import): + +```langium +grammar MultiConfiguration + +import "multiple-languages-definition"; + +entry ConfigurationUnit: 'I' 'am' who=[Person:ID] '.'; +``` + +Our implementation grammar (note the import again): + +```langium +grammar MultiImplementation + +import "multiple-languages-definition"; + +entry ImplementationUnit: + (greetings+=Greeting)*; + +Greeting: + 'Hello' person=[Person:ID] '!'; +``` + +### Langium configuration + +Splitting the grammar alone is not sufficient to generate anything using the CLI. You need to change the `langium-config.json` in the root folder as well. Let's make it happen! + +The initial version of this file was: + +```js +{ + "projectName": "MultipleLanguages", + "languages": [{ + "id": "multiple-languages", + "grammar": "src/language/multiple-languages.langium", + "fileExtensions": [".hello"], + "textMate": { + "out": "syntaxes/multiple-languages.tmLanguage.json" + }, + "monarch": { + "out": "syntaxes/multiple-languages.monarch.ts" + } + }], + "out": "src/language/generated" +} +``` + +The actual change is simple: Triple the object in the `languages` list and fill in reasonable values. Like here: + +```js +{ + "projectName": "MultipleLanguages", + "languages": [{ + "id": "multiple-languages-configuration", + "grammar": "src/language/multiple-languages-configuration.langium", + "fileExtensions": [".me"], + "textMate": { + "out": "syntaxes/multiple-languages-configuration.tmLanguage.json" + }, + "monarch": { + "out": "syntaxes/multiple-languages-configuration.monarch.ts" + } + }, { + "id": "multiple-languages-definition", + "grammar": "src/language/multiple-languages-definition.langium", + "fileExtensions": [".who"], + "textMate": { + "out": "syntaxes/multiple-languages-definition.tmLanguage.json" + }, + "monarch": { + "out": "syntaxes/multiple-languages-definition.monarch.ts" + } + }, { + "id": "multiple-languages-implementation", + "grammar": "src/language/multiple-languages-implementation.langium", + "fileExtensions": [".hello"], + "textMate": { + "out": "syntaxes/multiple-languages-implementation.tmLanguage.json" + }, + "monarch": { + "out": "syntaxes/multiple-languages-implementation.monarch.ts" + } + }], + "out": "src/language/generated" +} +``` + +From now on you are able to run the Langium CLI using the NPM scripts (`npm run langium:generate`). It will generate one file for the abstract syntax tree (AST) containing all languages concepts (it is also a good idea to keep the names of these concepts disjoint). + +For the next step you need to run the Langium generator once: + +```sh +npm run langium:generate +``` + +### Language module file + +The module file describes how your language services are built. +After adding two more languages, some important classes get generated - which need to be registered properly. + +1. Open the module file (`/src/language/multiple-languages-module.ts`). +2. You will notice a wrong import (which is ok, we renamed it in the previous steps and derived new classes by code generation). +3. Import the new generated modules instead. + Replace this line: + + ```ts + import { + MultipleLanguagesGeneratedModule, + MultipleLanguagesGeneratedSharedModule + } from './generated/module.js'; + ``` + + with the following: + + ```ts + import { + MultiConfigurationGeneratedModule, + MultiDefinitionGeneratedModule, + MultiImplementationGeneratedModule, + MultipleLanguagesGeneratedSharedModule + } from './generated/module.js'; + ``` + +4. In the function `createMultipleLanguagesServices` you will notice an error line now, because we deleted the old class name in the previous step. The code there needs to basically be tripled. But before we do this, we need to define the new output type of `createMultipleLanguagesServices`. In the end this should lead to this definition: + + ```ts + export function createMultipleLanguagesServices(context: DefaultSharedModuleContext): { + shared: LangiumSharedServices, + Configuration: MultipleLanguagesServices, + Definition: MultipleLanguagesServices, + Implementation: MultipleLanguagesServices + } { + const shared = inject( + createDefaultSharedModule(context), + MultipleLanguagesGeneratedSharedModule + ); + const Configuration = inject( + createDefaultModule({ shared }), + MultiConfigurationGeneratedModule, + MultipleLanguagesModule + ); + const Definition = inject( + createDefaultModule({ shared }), + MultiDefinitionGeneratedModule, + MultipleLanguagesModule + ); + const Implementation = inject( + createDefaultModule({ shared }), + MultiImplementationGeneratedModule, + MultipleLanguagesModule + ); + shared.ServiceRegistry.register(Configuration); + shared.ServiceRegistry.register(Definition); + shared.ServiceRegistry.register(Implementation); + registerValidationChecks(Configuration); + registerValidationChecks(Definition); + registerValidationChecks(Implementation); + return { shared, Configuration, Definition, Implementation }; + } + ``` + +After this step, Langium is set up correctly. But if you try to build now, the compiler will throw you some errors, because the old concepts of the AST are not existing anymore. + +> Be aware of the fact that we are using `MultipleLanguagesModule` in all three services, three independent services! If you want to avoid this (because of duplicated state etc.), you should put some work into creating instances for each service. + +### Cleanup + +Let's clean up the error lines. Here are some general hints: + +* keep in mind, that you are dealing with three file types now, namely `*.me`, `*.who` and `*.hello` + * you can distinguish them very easily by selecting the right sub service from the result object of `createMultipleLanguagesServices`, which is either `Configuration`, `Definition` or `Implementation`, but not `shared` + * all these services have a sub service with file extensions: `[Configuration,Definition,...].LanguageMetaData.fileExtensions: string[]` + * so, when you are obtaining any documents from the `DocumentBuilder` you can be sure that they are parsed by the matching language service + * to distinguish them on your own, use the AST functions for determining the root type, for example for the Configuration language use `isConfigurationUnit(document.parseResult.value)` + +### VSCode extension + +If you have a VSCode extension, you need to touch two files: `package.json` and `src/extension/main.ts`. + +#### File `package.json` + +In this file we define what services this extension will contribute to VSCode. + +Before the change only one language and grammar was defined: + +```js +//... +"contributes": { + "languages": [ + { + "id": "multiple-languages", + "aliases": [ + "Multiple Languages", + "multiple-languages" + ], + "extensions": [".hello"], + "configuration": "./language-configuration.json" + } + ], + "grammars": [ + { + "language": "multiple-languages", + "scopeName": "source.multiple-languages", + "path": "./syntaxes/multiple-languages.tmLanguage.json" + } + ] +}, +//... +``` + +After the change, we tripled the information. Be aware of that the language ids must match the ids from the Langium configuration. Also make sure that the paths to the syntax files and the language configuration are correct. + +> For the language configuration for VSCode, we reused the old file three times. If you want to make a more precise configuration per language, you should also split this file. But let's use the same for a moment and for simplicity. + +```js +//... +"contributes": { + "languages": [ + { + "id": "multiple-languages-configuration", + "aliases": [ + "Multiple Languages Configuration", + "multiple-languages-configuration" + ], + "extensions": [".me"], + "configuration": "./language-configuration.json" + }, { + "id": "multiple-languages-definition", + "aliases": [ + "Multiple Languages Definition", + "multiple-languages-definition" + ], + "extensions": [".who"], + "configuration": "./language-configuration.json" + }, { + "id": "multiple-languages-implementation", + "aliases": [ + "Multiple Languages Implementation", + "multiple-languages-implementation" + ], + "extensions": [".hello"], + "configuration": "./language-configuration.json" + } + ], + "grammars": [ + { + "language": "multiple-languages-configuration", + "scopeName": "source.multiple-languages-configuration", + "path": "./syntaxes/multiple-languages-configuration.tmLanguage.json" + }, + { + "language": "multiple-languages-definition", + "scopeName": "source.multiple-languages-definition", + "path": "./syntaxes/multiple-languages-definition.tmLanguage.json" + }, + { + "language": "multiple-languages-implementation", + "scopeName": "source.multiple-languages-implementation", + "path": "./syntaxes/multiple-languages-implementation.tmLanguage.json" + } + ] +}, +``` + +#### File `src/extension/main.ts` + +And here is the extension file before the change: + +```ts +// Options to control the language client +const clientOptions: LanguageClientOptions = { + documentSelector: [{ scheme: 'file', language: 'multiple-languages' }] +}; +``` + +After the change, it should look like this (the language IDs should be the same as they are in the Langium configuration): + +```ts +// Options to control the language client +const clientOptions: LanguageClientOptions = { + documentSelector: [ + { scheme: 'file', language: 'multiple-languages-configuration' }, + { scheme: 'file', language: 'multiple-languages-definition' }, + { scheme: 'file', language: 'multiple-languages-implementation' } + ] +}; +``` + +## Test the extension + +Now everything should be executable. **Do not forget to build**! + +Let's run the extension and create some files in our workspace: + +### Definition `people.who` + +```text +person Markus +person Michael +person Frank +``` + +### Configuration `thats.me` + +```text +I am Markus. +``` + +### Implementation `greetings.hello` + +```text +Hello Markus! +Hello Michael! +``` + +## Checklist + +You should be able now...: + +* to see proper syntax highlighting +* to trigger auto completion for keywords +* to jump to the definition by Cmd/Ctrl-clicking on a person's name + +## Add a validator (task) + +As promised, let's add a simple validation rule, that you cannot greet yourself. Therefore we enter our name in the `thats.me` file like we did in the previous step. + +Try to include the following code to our validator. This is meant as task, try to find the missing pieces on your own :-). + +```ts +checkNotGreetingYourself(greeting: Greeting, accept: ValidationAcceptor): void { + const document = getDocument(greeting); + const configFilePath = join(document.uri.fsPath, '..', 'thats.me'); + const configDocument = this.documents.getOrCreateDocument(URI.file(configFilePath)); + if (greeting.person.ref) { + if (configDocument && isConfigurationUnit(configDocument.parseResult.value)) { + if(configDocument.parseResult.value.who.ref === greeting.person.ref) { + accept('warning', 'You cannot greet yourself 🙄!', { node: greeting, property: 'person' }); + } + } + } +} +``` + +After doing so, your name should display a warning, stating that you cannot greet yourself. + +## Troubleshooting + +In this section we will list common mistakes. + +* One prominent mistake is forgetting to build Langium and Typescript files, before running the extension. + +* Since we are basically just copy-pasting given configuration, be aware of what you are pasting. Make sure that the code still makes sense after copying. You probably forgot to adapt the pasted code. + +If you encounter any problems, we are happy to help in our [discussions](https://github.com/eclipse-langium/langium/discussions) page or our [issue tracker](https://github.com/eclipse-langium/langium/issues). diff --git a/hugo/content/docs/2_recipes/scoping/_index.md b/hugo/content/docs/2_recipes/scoping/_index.md new file mode 100644 index 00000000..e75d086e --- /dev/null +++ b/hugo/content/docs/2_recipes/scoping/_index.md @@ -0,0 +1,31 @@ +--- +title: "Scoping" +weight: 100 +--- + +You likely know scopes from programming, where some variables are only available from certain areas (such as blocks) in your program. For example, take the short Typescript snippet below. Based on the block (scope) where a variable is declared, it may or may not be available at another location in the same program. + +```ts +let x = 42; +x = 3; // References the `x` defined in the previous line + +if (condition) { + let y = 42; +} +y = 3; // Cannot link, `y` isn't in any of the available scopes +``` + +This kind of behavior is called lexical scoping. Although this default scoping implementation is suitable for prototyping -- and for some simple languages once finished -- this behavior can be easily modified to fit the needs of your language's domain. + +In general, the way we resolve references is split into three phases of the document lifecycle: +- [Symbol indexing](/docs/document-lifecycle#symbol-indexing) is responsible for making objects globally available for referencing. +- [Scope computation](/docs/document-lifecycle#computing-scopes) determines which elements are reachable from a given position in your document. +- Finally, the [linking phase](/docs/document-lifecycle#linking) eagerly links each reference within a document to its target using your language's scoping rules. + +In this guide, we'll look at different scoping kinds and styles and see how we can achieve them using Langium: + +1. [Qualified Name Scoping](./qualified-name) +2. [Class Member Scoping](./class-member) + +Note that these are just example implementations for commonly used scoping methods. +The scoping API of Langium is designed to be flexible and extensible for any kind of use case. diff --git a/hugo/content/docs/2_recipes/scoping/class-member.md b/hugo/content/docs/2_recipes/scoping/class-member.md new file mode 100644 index 00000000..bbcce962 --- /dev/null +++ b/hugo/content/docs/2_recipes/scoping/class-member.md @@ -0,0 +1,148 @@ +--- +title: "Class Member Scoping" +weight: 200 +--- + +In this guide we will take a look at member based scoping. It's a mechanism you are likely familiar with from object oriented languages such as Java, C# and JavaScript: + +```ts +class A { + b: B; +} + +class B { + value: string; +} + +function test(): void { + const a = new A(); + const b = a.b; // Refers to the `b` defined in class `A` + const value = b.value; // Refers to the `value` defined in class `B` +} +``` + +Member based scoping like this requires not only a modification of the default scoping provider, but also some other prerequisites. +This includes adding a member call mechanism in your grammar and a rudimentary type system. +For this guide, we will use excerpts from the [langium-lox](https://github.com/langium/langium-lox) project to demonstrate how you can set this up yourself. +This project implements a strongly-typed version of the [Lox language](https://craftinginterpreters.com/the-lox-language.html) from the popular book [Crafting Interpreters](https://craftinginterpreters.com/). + +We'll first start with the `MemberCall` grammar rule, which references one of our `NamedElements`. These elements could be variable declarations, functions, classes or methods and fields of those classes. Additionally, we want to allow function calls on elements. Note that the grammar has no notion of whether these elements can actually be executed as functions. Instead, we always allow function calls on every named element, and simply provide validation errors in case an element is called erroneously. After parsing the first member call, we continue parsing further members as long as the input text provides us with further references to elements; which are separated by dots. + +```langium +type NamedElement = FunctionDeclaration | VariableDeclaration | MethodMember | FieldMember | Class; + +MemberCall: + // Reference a named element of our grammar + // Variables, functions, etc. + element=[NamedElement:ID] + // Parse an operation call on this element + (explicitOperationCall?='(' ( + // Parse any arguments for the operation call + arguments+=Expression (',' arguments+=Expression)* + )? ')')? + // Create a new `MemberCall` and assign the old one to the `previous` property + // The previous member call can either be the member call that was parsed in the previous section + // Or one that is parsed in the next section due to the repetition at the end of this group + ({infer MemberCall.previous=current} + // We repeat the named element reference + ("." element=[NamedElement:ID] ( + // Parse an operation call again + explicitOperationCall?='(' + ( + arguments+=Expression (',' arguments+=Expression)* + )? + ')')? + // Our language allows to return functions in functions + // So we need to be able to call multiple functions without any element references + | ( + explicitOperationCall?='(' + ( + arguments+=Expression (',' arguments+=Expression)* + )? + ')')) + )*; +``` + +A very important aspect of these chained member calls is the action (`{infer MemberCall.previous=current}`) which rewrites the resulting AST. In this case, it reverses the direction of member call AST nodes. Instead of starting with the first encountered member call and then traversing down to the last, we start with the last and traverse the list of member calls up using the `previous` property. The reason for doing this becomes clear when looking at the scope provider for the Lox language: + +```ts +export class LoxScopeProvider extends DefaultScopeProvider { + + override getScope(context: ReferenceInfo): Scope { + // target element of member calls + if (context.property === 'element' && isMemberCall(context.container)) { + const memberCall = context.container; + const previous = memberCall.previous; + if (!previous) { + return super.getScope(context); + } + const previousType = inferType(previous); + if (isClassType(previousType)) { + return this.scopeClassMembers(previousType.literal); + } + // When the target of our member call isn't a class + // This means it is either a primitive type or a type resolution error + // Simply return an empty scope + return EMPTY_SCOPE; + } + return super.getScope(context); + } + + private scopeClassMembers(classItem: Class): Scope { + // Since Lox allows class-inheritance, + // we also need to look at all members of possible super classes for scoping + const allMembers = getClassChain(classItem).flatMap(e => e.members); + return this.createScopeForNodes(allMembers); + } +} +``` + +When trying to compute the type of an expression, we are only interested in the final piece of the member call. However, to derive the type and scope of the final member call, we have to recursively identify the type of the previous member call. This is done by looking at the member call stored in the `previous` property and inferring its type. See [here for the full implementation of the type inference system in Lox](https://github.com/langium/langium-lox/blob/main/src/language-server/type-system/infer.ts). This kind of type inference requires scoping. + +To illustrate this behavior a bit better, take a look at the following code snippet: + +```ts +class Container { + sub: SubContainer +} + +class SubContainer { + name: string +} + +// Constructor call +var element = Container(); +// Member access +println(element.sub.name); +``` + +We recursively alternate between the scope provider and the type inference system until we arrive at a member call without any previous member call. At this point we resolve the reference using the default lexical scoping which is builtin into Langium. With our scope provider in place, we can visualize how it interacts with Langium's implementation of Lox in the following sequence diagram: + +{{}} +sequenceDiagram + participant R as Language Runtime + participant T as Type System + participant S as Scope Provider + participant L as Lexical Scope + R->>T: Ask for type of expression
`element.sub.name` + T->>S: Ask for `name` node + S->>T: Ask for `sub` type + T->>S: Ask for `sub` node + S->>T: Ask for `element` type + T->>S: Ask for `element` node + S->>L: Ask for `element` node + L->>S: Give `element` node + S->>T: Give `element` node + T->>S: Ask for `Container` node + S->>L: Ask for `Container` node + L->>S: Give `Container` node + S->>T: Give `Container` node + T->>S: Give `Container` type result + S->>T: Give `sub` node + T->>S: Give `SubContainer` type result + S->>T: Give `name` node + T->>R: Give `string` type result +{{
}} + +When trying to infer the type of the expression `element.sub.name`, +we can see that this results in quite a lot of computations throughout the scoping and type systems. It is therefore recommended to cache type inference information as this naive approach to inference can quickly lead to performance issues. diff --git a/hugo/content/docs/2_recipes/scoping/qualified-name.md b/hugo/content/docs/2_recipes/scoping/qualified-name.md new file mode 100644 index 00000000..528006d5 --- /dev/null +++ b/hugo/content/docs/2_recipes/scoping/qualified-name.md @@ -0,0 +1,238 @@ +--- +title: "Qualified Name Scoping" +weight: 100 +--- + +Qualified name scoping refers to a style of referencing elements using a fully qualified name. +Such a fully qualified name is usually composed of the original name of the target element and the names of its container elements. +You will usually see this method of scoping in C-like languages using namespaces or in Java using packages. +The following code snippet shows an example of how qualified name scoping works from an end-user perspective, by using a function in a C++ namespace: + +```cpp +namespace Langium { + void getDocumentation(); +} + +void main() { + // Should call the `getDocumentation` function defined in the `Langium` namespace + Langium::getDocumentation(); +} +``` + +As can be seen, using qualified name scoping is quite helpful in this case. It allows us to reference the `getDocumentation` function through the scope computed & made available by the `Langium` namespace, even though it's not directly accessible within the scope of `main` by itself. + +Note that such behavior can also be accomplished using [class member scoping](./class-member). +However, there is one core advantage to using globally available elements: +Compared to member scoping, this type of scoping requires few resources. +The lookup required for qualified name scoping can be done in near constant time with just a bit of additional computation on a **per-document** basis, whereas member scoping needs to do a lot of computation on a **per-reference** basis. +With large workspaces, complex scoping might become a performance bottleneck. + +This behavior can be achieved in Langium by exporting the `getDocumentation` function under the name `Langium::getDocumentation`. To do this, we will first set up a new `ScopeComputation` class that extends the `DefaultScopeComputation`. This class will be responsible for our custom scope computation. Then, we'll want to bind our custom scope computation class in our module: + +```ts +// Scope computation for our C++-like language +export class CppScopeComputation extends DefaultScopeComputation { + + constructor(services: LangiumServices) { + super(services); + } +} + +// Services module for overriding the scope computation +// Your language module is usually placed in your `-module.ts` file +export const CppModule: Module = { + references: { + ScopeComputation: (services) => new CppScopeComputation(services) + } +} +``` + +Next, we can start implementing our custom scoping by overriding the `computeExports` function. This function is particularly important, as it allows us to change export nodes of our model using qualified names: We'll also want to annotate this function with `override`, since there's already a default definition provided. + +```ts +export class CppScopeComputation extends DefaultScopeComputation { + + // Emitting previous implementation for brevity + + /** + * Export all functions using their fully qualified name + */ + override async computeExports(document: LangiumDocument): Promise { + const exportedDescriptions: AstNodeDescription[] = []; + for (const childNode of streamAllContents(document.parseResult.value)) { + if (isFunctionDeclaration(childNode)) { + const fullyQualifiedName = this.getQualifiedName(childNode, childNode.name); + // `descriptions` is our `AstNodeDescriptionProvider` defined in `DefaultScopeComputation` + // It allows us to easily create descriptions that point to elements using a name. + exportedDescriptions.push(this.descriptions.createDescription(modelNode, fullyQualifiedName, document)); + } + } + return exportedDescriptions; + } + + /** + * Build a qualified name for a model node + */ + private getQualifiedName(node: AstNode, name: string): string { + let parent: AstNode | undefined = node.$container; + while (isNamespace(parent)) { + // Iteratively prepend the name of the parent namespace + // This allows us to work with nested namespaces + name = `${parent.name}::${name}`; + parent = parent.$container; + } + return name; + } +``` + +Once we start exporting functions using their fully qualified name, references such as `QualifiedName::target` will start working correctly. We can even nest multiple namespaces to create `Fully::Qualified::Name::target`. However, this leads us to another problem. We can now only reference functions using their fully qualified names, even if they're locally available: + +```cpp +namespace QualifiedName { + void target(); + void test() { + // Will not link correctly + target(); + // Requires the new fully qualified name + QualifiedName::target(); + } +} +``` + +To rectify this problem, we have to override the `computeLocalScopes` method, which provides access to elements that aren't exported globally. We can also use this method to provide secondary access to globally available objects using a local name. + +```ts +export class CppScopeComputation extends DefaultScopeComputation { + + // Emitting previous implementation for brevity + + override async computeLocalScopes(document: LangiumDocument): Promise { + const model = document.parseResult.value as CppProgram; + // This map stores a list of descriptions for each node in our document + const scopes = new MultiMap(); + this.processContainer(model, scopes, document); + return scopes; + } + + private processContainer( + container: CppProgram | Namespace, + scopes: PrecomputedScopes, + document: LangiumDocument + ): AstNodeDescription[] { + const localDescriptions: AstNodeDescription[] = []; + for (const element of container.elements) { + if (isFunctionDeclaration(element)) { + // Create a simple local name for the function + const description = this.descriptions.createDescription(element, element.name, document); + localDescriptions.push(description); + } else if (isNamespace(element)) { + const nestedDescriptions = this.processContainer(element, scopes, document, cancelToken); + for (const description of nestedDescriptions) { + // Add qualified names to the container + // This could also be a partial qualified name + const qualified = this.createQualifiedDescription(element, description, document); + localDescriptions.push(qualified); + } + } + } + scopes.addAll(container, localDescriptions); + return localDescriptions; + } + + private createQualifiedDescription( + container: Namespace, + description: AstNodeDescription, + document: LangiumDocument + ): AstNodeDescription { + // `getQualifiedName` has been implemented in the previous section + const name = this.getQualifiedName(container.name, description.name); + return this.descriptions.createDescription(description.node!, name, document); + } +} +``` + +This new change now allows us to use local names of functions in the local scope, while they are still exported using their fully qualified name to the global scope. +Another example for this style of scoping can be seen in the [domain-model example language](https://github.com/eclipse-langium/langium/tree/main/examples/domainmodel). +Also, click the following note to see the full implementation of the scope computation service. + +
+Full Implementation + +```ts +export class CppScopeComputation extends DefaultScopeComputation { + + /** + * Export all functions using their fully qualified name + */ + override async computeExports(document: LangiumDocument): Promise { + const exportedDescriptions: AstNodeDescription[] = []; + for (const childNode of streamAllContents(document.parseResult.value)) { + if (isFunctionDeclaration(childNode)) { + const fullyQualifiedName = this.getQualifiedName(childNode, childNode.name); + // `descriptions` is our `AstNodeDescriptionProvider` defined in `DefaultScopeComputation` + // It allows us to easily create descriptions that point to elements using a name. + exportedDescriptions.push(this.descriptions.createDescription(modelNode, fullyQualifiedName, document)); + } + } + return exportedDescriptions; + } + + override async computeLocalScopes(document: LangiumDocument): Promise { + const model = document.parseResult.value as CppProgram; + // This multi-map stores a list of descriptions for each node in our document + const scopes = new MultiMap(); + this.processContainer(model, scopes, document); + return scopes; + } + + private processContainer( + container: CppProgram | Namespace, + scopes: PrecomputedScopes, + document: LangiumDocument + ): AstNodeDescription[] { + const localDescriptions: AstNodeDescription[] = []; + for (const element of container.elements) { + if (isFunctionDeclaration(element)) { + // Create a simple local name for the function + const description = this.descriptions.createDescription(element, element.name, document); + localDescriptions.push(description); + } else if (isNamespace(element)) { + const nestedDescriptions = this.processContainer(element, scopes, document, cancelToken); + for (const description of nestedDescriptions) { + // Add qualified names to the container + // This could also be a partially qualified name + const qualified = this.createQualifiedDescription(element, description, document); + localDescriptions.push(qualified); + } + } + } + scopes.addAll(container, localDescriptions); + return localDescriptions; + } + + private createQualifiedDescription( + container: Namespace, + description: AstNodeDescription, + document: LangiumDocument + ): AstNodeDescription { + const name = this.getQualifiedName(container.name, description.name); + return this.descriptions.createDescription(description.node!, name, document); + } + + /** + * Build a qualified name for a model node + */ + private getQualifiedName(node: AstNode, name: string): string { + let parent: AstNode | undefined = node.$container; + while (isNamespace(parent)) { + // Iteratively prepend the name of the parent namespace + // This allows us to work with nested namespaces + name = `${parent.name}::${name}`; + parent = parent.$container; + } + return name; + } +} +``` + +
diff --git a/hugo/content/old/guides/multiple-languages.md b/hugo/content/old/guides/multiple-languages.md index e9b0ee0d..52853e4b 100644 --- a/hugo/content/old/guides/multiple-languages.md +++ b/hugo/content/old/guides/multiple-languages.md @@ -23,7 +23,6 @@ The entire change touches several files. Let's summarize what needs to be done: 1. the `package.json` needs to be adapted 2. the extension entry point file (`src/extension/main.ts`) needs to be changed slightly - ## Our scenario To keep this guide easy, I will use the [`hello-world` project](/docs/getting-started/). @@ -43,7 +42,7 @@ flowchart Implementation -->|requires| Configuration {{}} -## Let's start! +## Let's start ### Grammar @@ -73,6 +72,7 @@ hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; Now, split it into three new files (let's call the entry rules units and the files we can name like `multiple-languages-(configuration|definition|implementation).langium`): Our definition grammar: + ```langium grammar MultiDefinition @@ -90,6 +90,7 @@ hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; ``` Our configuration grammar (note the import): + ```langium grammar MultiConfiguration @@ -99,6 +100,7 @@ entry ConfigurationUnit: 'I' 'am' who=[Person:ID] '.'; ``` Our implementation grammar (note the import again): + ```langium grammar MultiImplementation @@ -192,13 +194,16 @@ After adding two more languages, some important classes get generated - which ne 2. You will notice a wrong import (which is ok, we renamed it in the previous steps and derived new classes by code generation). 3. Import the new generated modules instead. Replace this line: + ```ts import { MultipleLanguagesGeneratedModule, MultipleLanguagesGeneratedSharedModule } from './generated/module.js'; ``` + with the following: + ```ts import { MultiConfigurationGeneratedModule, @@ -207,7 +212,9 @@ After adding two more languages, some important classes get generated - which ne MultipleLanguagesGeneratedSharedModule } from './generated/module.js'; ``` + 4. In the function `createMultipleLanguagesServices` you will notice an error line now, because we deleted the old class name in the previous step. The code there needs to basically be tripled. But before we do this, we need to define the new output type of `createMultipleLanguagesServices`. In the end this should lead to this definition: + ```ts export function createMultipleLanguagesServices(context: DefaultSharedModuleContext): { shared: LangiumSharedServices, @@ -253,10 +260,10 @@ After this step, Langium is set up correctly. But if you try to build now, the c Let's clean up the error lines. Here are some general hints: * keep in mind, that you are dealing with three file types now, namely `*.me`, `*.who` and `*.hello` - * you can distinguish them very easily by selecting the right sub service from the result object of `createMultipleLanguagesServices`, which is either `Configuration`, `Definition` or `Implementation`, but not `shared` - * all these services have a sub service with file extensions: `[Configuration,Definition,...].LanguageMetaData.fileExtensions: string[]` - * so, when you are obtaining any documents from the `DocumentBuilder` you can be sure that they are parsed by the matching language service - * to distinguish them on your own, use the AST functions for determining the root type, for example for the Configuration language use `isConfigurationUnit(document.parseResult.value)` + * you can distinguish them very easily by selecting the right sub service from the result object of `createMultipleLanguagesServices`, which is either `Configuration`, `Definition` or `Implementation`, but not `shared` + * all these services have a sub service with file extensions: `[Configuration,Definition,...].LanguageMetaData.fileExtensions: string[]` + * so, when you are obtaining any documents from the `DocumentBuilder` you can be sure that they are parsed by the matching language service + * to distinguish them on your own, use the AST functions for determining the root type, for example for the Configuration language use `isConfigurationUnit(document.parseResult.value)` ### VSCode extension @@ -371,7 +378,7 @@ const clientOptions: LanguageClientOptions = { }; ``` -## Test the extension! +## Test the extension Now everything should be executable. **Do not forget to build**! @@ -379,7 +386,7 @@ Let's run the extension and create some files in our workspace: ### Definition `people.who` -``` +```text person Markus person Michael person Frank @@ -387,13 +394,13 @@ person Frank ### Configuration `thats.me` -``` +```text I am Markus. ``` ### Implementation `greetings.hello` -``` +```text Hello Markus! Hello Michael! ``` @@ -401,11 +408,12 @@ Hello Michael! ## Checklist You should be able now...: + * to see proper syntax highlighting * to trigger auto completion for keywords * to jump to the definition by Cmd/Ctrl-clicking on a person's name -# Add a validator (task) +## Add a validator (task) As promised, let's add a simple validation rule, that you cannot greet yourself. Therefore we enter our name in the `thats.me` file like we did in the previous step. @@ -428,7 +436,7 @@ checkNotGreetingYourself(greeting: Greeting, accept: ValidationAcceptor): void { After doing so, your name should display a warning, stating that you cannot greet yourself. -# Troubleshooting +## Troubleshooting In this section we will list common mistakes. @@ -437,4 +445,3 @@ In this section we will list common mistakes. * Since we are basically just copy-pasting given configuration, be aware of what you are pasting. Make sure that the code still makes sense after copying. You probably forgot to adapt the pasted code. If you encounter any problems, we are happy to help in our [discussions](https://github.com/eclipse-langium/langium/discussions) page or our [issue tracker](https://github.com/eclipse-langium/langium/issues). - From 680198653f734e38caf1da9994f0545455c2b626 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Fri, 5 Apr 2024 11:20:49 +0200 Subject: [PATCH 03/19] Quick save --- hugo/content/docs/1_learn/workflow/_index.md | 29 ---------- .../docs/1_learn/workflow/generate_ast.md | 6 --- .../docs/1_learn/workflow/write_grammar.md | 6 --- .../_index.md | 0 .../features.md | 0 .../playground.md | 0 .../showcases.md | 0 .../content/docs/{1_learn => learn}/_index.md | 0 .../{1_learn => learn}/minilogo/_index.md | 0 .../minilogo/building_an_extension/icon.png | Bin .../minilogo/building_an_extension/index.md | 0 .../installed-extension.jpg | Bin .../building_an_extension/minilogo-vsix.jpg | Bin .../minilogo-with-icon.png | Bin .../building_an_extension/vsix-install.jpg | Bin .../building_an_extension/vsix-installed.jpg | Bin .../minilogo/customizing_cli.md | 0 .../{1_learn => learn}/minilogo/generation.md | 0 .../minilogo/generation_in_the_web.md | 0 .../minilogo/langium_and_monaco.md | 0 .../{1_learn => learn}/minilogo/validation.md | 0 .../minilogo/writing_a_grammar.md | 0 hugo/content/docs/learn/workflow/_index.md | 51 ++++++++++++++++++ .../workflow/create_validations.md | 2 +- .../docs/learn/workflow/generate_ast.md | 33 ++++++++++++ .../workflow/generate_everything.md | 2 +- .../{1_learn => learn}/workflow/install.md | 2 +- .../workflow/resolve_cross_references.md | 2 +- .../{1_learn => learn}/workflow/scaffold.md | 2 +- .../docs/learn/workflow/write_grammar.md | 10 ++++ .../docs/{2_recipes => recipes}/_index.md | 0 .../{2_recipes => recipes}/builtin-library.md | 0 .../{2_recipes => recipes}/code-bundling.md | 0 .../docs/{2_recipes => recipes}/formatting.md | 0 .../multiple-languages.md | 0 .../{2_recipes => recipes}/scoping/_index.md | 0 .../scoping/class-member.md | 0 .../scoping/qualified-name.md | 0 38 files changed, 99 insertions(+), 46 deletions(-) delete mode 100644 hugo/content/docs/1_learn/workflow/_index.md delete mode 100644 hugo/content/docs/1_learn/workflow/generate_ast.md delete mode 100644 hugo/content/docs/1_learn/workflow/write_grammar.md rename hugo/content/docs/{0_introduction => introduction}/_index.md (100%) rename hugo/content/docs/{0_introduction => introduction}/features.md (100%) rename hugo/content/docs/{0_introduction => introduction}/playground.md (100%) rename hugo/content/docs/{0_introduction => introduction}/showcases.md (100%) rename hugo/content/docs/{1_learn => learn}/_index.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/_index.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/icon.png (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/index.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/installed-extension.jpg (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/minilogo-vsix.jpg (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/minilogo-with-icon.png (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/vsix-install.jpg (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/building_an_extension/vsix-installed.jpg (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/customizing_cli.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/generation.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/generation_in_the_web.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/langium_and_monaco.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/validation.md (100%) rename hugo/content/docs/{1_learn => learn}/minilogo/writing_a_grammar.md (100%) create mode 100644 hugo/content/docs/learn/workflow/_index.md rename hugo/content/docs/{1_learn => learn}/workflow/create_validations.md (54%) create mode 100644 hugo/content/docs/learn/workflow/generate_ast.md rename hugo/content/docs/{1_learn => learn}/workflow/generate_everything.md (55%) rename hugo/content/docs/{1_learn => learn}/workflow/install.md (93%) rename hugo/content/docs/{1_learn => learn}/workflow/resolve_cross_references.md (53%) rename hugo/content/docs/{1_learn => learn}/workflow/scaffold.md (98%) create mode 100644 hugo/content/docs/learn/workflow/write_grammar.md rename hugo/content/docs/{2_recipes => recipes}/_index.md (100%) rename hugo/content/docs/{2_recipes => recipes}/builtin-library.md (100%) rename hugo/content/docs/{2_recipes => recipes}/code-bundling.md (100%) rename hugo/content/docs/{2_recipes => recipes}/formatting.md (100%) rename hugo/content/docs/{2_recipes => recipes}/multiple-languages.md (100%) rename hugo/content/docs/{2_recipes => recipes}/scoping/_index.md (100%) rename hugo/content/docs/{2_recipes => recipes}/scoping/class-member.md (100%) rename hugo/content/docs/{2_recipes => recipes}/scoping/qualified-name.md (100%) diff --git a/hugo/content/docs/1_learn/workflow/_index.md b/hugo/content/docs/1_learn/workflow/_index.md deleted file mode 100644 index bdcc93da..00000000 --- a/hugo/content/docs/1_learn/workflow/_index.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: "Our workflow" -weight: 0 -url: /docs/learn/worflow ---- - -{{}} -flowchart TD - A(["1. Install Yeoman generator"]); - B(["2. Scaffold a Langium project"]); - C(["3. Write the grammar"]); - D(["4. Generate AST files"]); - E(["5. Resolve cross-references"]); - F(["6. Create validations"]); - G(["7. Generate what you want"]); - H(["8. Find advanced topics"]); - A --> B --> C --> D --> E --> F --> G --> H; - G -- reiterate --> C; - - click A "/docs/learn/install" - click B "/docs/learn/scaffold" - click C "/docs/learn/write_grammar" - click D "/docs/learn/generate_ast" - click E "/docs/learn/resolve_cross_references" - click F "/docs/learn/create_validations" - click G "/docs/learn/generate_everything" - click H "/docs/recipes" -{{}} - diff --git a/hugo/content/docs/1_learn/workflow/generate_ast.md b/hugo/content/docs/1_learn/workflow/generate_ast.md deleted file mode 100644 index 6847baf8..00000000 --- a/hugo/content/docs/1_learn/workflow/generate_ast.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Generate the AST" -weight: 500 -url: /docs/learn/worflow/generate_ast ---- -TODO diff --git a/hugo/content/docs/1_learn/workflow/write_grammar.md b/hugo/content/docs/1_learn/workflow/write_grammar.md deleted file mode 100644 index ef55d401..00000000 --- a/hugo/content/docs/1_learn/workflow/write_grammar.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: "Write the grammar" -weight: 400 -url: /docs/learn/worflow/write_grammar ---- -TODO diff --git a/hugo/content/docs/0_introduction/_index.md b/hugo/content/docs/introduction/_index.md similarity index 100% rename from hugo/content/docs/0_introduction/_index.md rename to hugo/content/docs/introduction/_index.md diff --git a/hugo/content/docs/0_introduction/features.md b/hugo/content/docs/introduction/features.md similarity index 100% rename from hugo/content/docs/0_introduction/features.md rename to hugo/content/docs/introduction/features.md diff --git a/hugo/content/docs/0_introduction/playground.md b/hugo/content/docs/introduction/playground.md similarity index 100% rename from hugo/content/docs/0_introduction/playground.md rename to hugo/content/docs/introduction/playground.md diff --git a/hugo/content/docs/0_introduction/showcases.md b/hugo/content/docs/introduction/showcases.md similarity index 100% rename from hugo/content/docs/0_introduction/showcases.md rename to hugo/content/docs/introduction/showcases.md diff --git a/hugo/content/docs/1_learn/_index.md b/hugo/content/docs/learn/_index.md similarity index 100% rename from hugo/content/docs/1_learn/_index.md rename to hugo/content/docs/learn/_index.md diff --git a/hugo/content/docs/1_learn/minilogo/_index.md b/hugo/content/docs/learn/minilogo/_index.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/_index.md rename to hugo/content/docs/learn/minilogo/_index.md diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/icon.png b/hugo/content/docs/learn/minilogo/building_an_extension/icon.png similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/icon.png rename to hugo/content/docs/learn/minilogo/building_an_extension/icon.png diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/index.md b/hugo/content/docs/learn/minilogo/building_an_extension/index.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/index.md rename to hugo/content/docs/learn/minilogo/building_an_extension/index.md diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/installed-extension.jpg b/hugo/content/docs/learn/minilogo/building_an_extension/installed-extension.jpg similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/installed-extension.jpg rename to hugo/content/docs/learn/minilogo/building_an_extension/installed-extension.jpg diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-vsix.jpg b/hugo/content/docs/learn/minilogo/building_an_extension/minilogo-vsix.jpg similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-vsix.jpg rename to hugo/content/docs/learn/minilogo/building_an_extension/minilogo-vsix.jpg diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-with-icon.png b/hugo/content/docs/learn/minilogo/building_an_extension/minilogo-with-icon.png similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/minilogo-with-icon.png rename to hugo/content/docs/learn/minilogo/building_an_extension/minilogo-with-icon.png diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-install.jpg b/hugo/content/docs/learn/minilogo/building_an_extension/vsix-install.jpg similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-install.jpg rename to hugo/content/docs/learn/minilogo/building_an_extension/vsix-install.jpg diff --git a/hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-installed.jpg b/hugo/content/docs/learn/minilogo/building_an_extension/vsix-installed.jpg similarity index 100% rename from hugo/content/docs/1_learn/minilogo/building_an_extension/vsix-installed.jpg rename to hugo/content/docs/learn/minilogo/building_an_extension/vsix-installed.jpg diff --git a/hugo/content/docs/1_learn/minilogo/customizing_cli.md b/hugo/content/docs/learn/minilogo/customizing_cli.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/customizing_cli.md rename to hugo/content/docs/learn/minilogo/customizing_cli.md diff --git a/hugo/content/docs/1_learn/minilogo/generation.md b/hugo/content/docs/learn/minilogo/generation.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/generation.md rename to hugo/content/docs/learn/minilogo/generation.md diff --git a/hugo/content/docs/1_learn/minilogo/generation_in_the_web.md b/hugo/content/docs/learn/minilogo/generation_in_the_web.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/generation_in_the_web.md rename to hugo/content/docs/learn/minilogo/generation_in_the_web.md diff --git a/hugo/content/docs/1_learn/minilogo/langium_and_monaco.md b/hugo/content/docs/learn/minilogo/langium_and_monaco.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/langium_and_monaco.md rename to hugo/content/docs/learn/minilogo/langium_and_monaco.md diff --git a/hugo/content/docs/1_learn/minilogo/validation.md b/hugo/content/docs/learn/minilogo/validation.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/validation.md rename to hugo/content/docs/learn/minilogo/validation.md diff --git a/hugo/content/docs/1_learn/minilogo/writing_a_grammar.md b/hugo/content/docs/learn/minilogo/writing_a_grammar.md similarity index 100% rename from hugo/content/docs/1_learn/minilogo/writing_a_grammar.md rename to hugo/content/docs/learn/minilogo/writing_a_grammar.md diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md new file mode 100644 index 00000000..a1dd0100 --- /dev/null +++ b/hugo/content/docs/learn/workflow/_index.md @@ -0,0 +1,51 @@ +--- +title: "Our workflow" +weight: 0 +url: /docs/learn/worflow +--- + +## Workflow diagram + +{{}} +flowchart TD + A(["1. Install Yeoman generator"]); + B(["2. Scaffold a Langium project"]); + C(["3. Write the grammar"]); + D(["4. Generate AST files"]); + E(["5. Resolve cross-references"]); + F(["6. Create validations"]); + G(["7. Generate what you want"]); + H(["8. Find advanced topics"]); + A --> B --> C --> D --> E --> F --> G --> H; + G -- reiterate --> C; + + click A "/docs/learn/workflow/install" + click B "/docs/learn/workflow/scaffold" + click C "/docs/learn/workflow/write_grammar" + click D "/docs/learn/workflow/generate_ast" + click E "/docs/learn/workflow/resolve_cross_references" + click F "/docs/learn/workflow/create_validations" + click G "/docs/learn/workflow/generate_everything" + click H "/docs/recipes" +{{}} + +## Explanation + +This is the workflow we recommend for developing a language with Langium. It is a step-by-step guide that will help you to get started with Langium and to understand the basics of language development. + +This simple introduction can be seen as three main parts: + +* setting up your project environment (1.+2.): this is only done once +* specifying the language features (3.-7.): this cycle you need to reiterate for each new language feature +* everything advanced (8.): here the limit of the common workflow is reached, for specific questions you can find answers in the [recipes](/docs/recipes). + +While the first part is straight-forward. The last part is about advanced topics that differ from project to project. +The middle part will be explained briefly in the following section. + +## Core workflow + +3. [_changing the grammar_](/docs/learn/write_grammar): The first step in the core workflow starts from the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. +4. [_generating the AST_](/docs/learn/generate_ast): The AST is the backbone of your language. It is used to represent the structure of your language elements. The AST is generated from the grammar. One important part of the AST are the _cross-references_. They are used to resolve references between language elements. If you have cross-references in your language, you need to _resolve_ them, after this step. The actual generation is done by a call of the Langium CLI. +5. [_resolving cross-references_](/docs/learn/resolve_cross_references): The cross-references are used to resolve references between language elements (between different sub trees of one file or even elements of other files(!)). This step is quite important, because it is the basis for the next steps. You can also see it like this: Step 4 will generate an AST with gaps, this fifth step will fill these gaps. +6. [_create validations_](/docs/learn/workflow/create_validations): From here we have a fully utilized AST. Now every input file that matches the syntax will be accepted. But we want to have more control over the input. We want to check if the input is semantically correct. This is done by creating _validations_. They are used to check the input against a set of rules. If the input does not match the rules, an error will be thrown. +7. [_generate what you want_](/docs/learn/workflow/generate_everything): Now you have a fully working language. You can generate whatever you want from the input. This can be code, documentation, or anything else. You can use the AST to traverse the input and generate the output. diff --git a/hugo/content/docs/1_learn/workflow/create_validations.md b/hugo/content/docs/learn/workflow/create_validations.md similarity index 54% rename from hugo/content/docs/1_learn/workflow/create_validations.md rename to hugo/content/docs/learn/workflow/create_validations.md index f691decf..c3f2de11 100644 --- a/hugo/content/docs/1_learn/workflow/create_validations.md +++ b/hugo/content/docs/learn/workflow/create_validations.md @@ -1,6 +1,6 @@ --- title: "Create validations" weight: 700 -url: /docs/learn/worflow/create_validations +url: /docs/learn/workflow/create_validations --- TODO diff --git a/hugo/content/docs/learn/workflow/generate_ast.md b/hugo/content/docs/learn/workflow/generate_ast.md new file mode 100644 index 00000000..c5c4853c --- /dev/null +++ b/hugo/content/docs/learn/workflow/generate_ast.md @@ -0,0 +1,33 @@ +--- +title: "Generate the AST" +weight: 500 +url: /docs/learn/workflow/generate_ast +--- + +{{}} +graph TB + Model-->persons + Model-->greetings + + persons-->P1[Person] + P1 --> H1('person') + P1 --> N1[name] + N1 --> NL1('John') + + persons-->P2[Person] + P2 --> H2('person') + P2 --> N2[name] + N2 --> NL2('Jane') + + greetings-->G1[Greeting] + G1 --> KW1('hello') + G1 --> PRef1[Ref] + G1 --> EM1('!') + PRef1 --> QM1{?} + + greetings-->G2[Greeting] + G2 --> KW2('hello') + G2 --> PRef2[Ref] + G2 --> EM2('!') + PRef2 --> QM2{?} +{{}} \ No newline at end of file diff --git a/hugo/content/docs/1_learn/workflow/generate_everything.md b/hugo/content/docs/learn/workflow/generate_everything.md similarity index 55% rename from hugo/content/docs/1_learn/workflow/generate_everything.md rename to hugo/content/docs/learn/workflow/generate_everything.md index bf6fd972..f3928c3e 100644 --- a/hugo/content/docs/1_learn/workflow/generate_everything.md +++ b/hugo/content/docs/learn/workflow/generate_everything.md @@ -1,6 +1,6 @@ --- title: "Generate your artifacts" weight: 800 -url: /docs/learn/worflow/generate_everything +url: /docs/learn/workflow/generate_everything --- TODO diff --git a/hugo/content/docs/1_learn/workflow/install.md b/hugo/content/docs/learn/workflow/install.md similarity index 93% rename from hugo/content/docs/1_learn/workflow/install.md rename to hugo/content/docs/learn/workflow/install.md index 5c2aff40..f23cb46d 100644 --- a/hugo/content/docs/1_learn/workflow/install.md +++ b/hugo/content/docs/learn/workflow/install.md @@ -1,7 +1,7 @@ --- title: "Install Yeoman" weight: 200 -url: /docs/learn/worflow/install +url: /docs/learn/workflow/install --- Before diving into Langium itself, let's get your environment ready for development: diff --git a/hugo/content/docs/1_learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md similarity index 53% rename from hugo/content/docs/1_learn/workflow/resolve_cross_references.md rename to hugo/content/docs/learn/workflow/resolve_cross_references.md index 6a75f426..9c639bad 100644 --- a/hugo/content/docs/1_learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -1,6 +1,6 @@ --- title: "Resolve cross-references" weight: 600 -url: /docs/learn/worflow/resolve_cross_references +url: /docs/learn/workflow/resolve_cross_references --- TODO diff --git a/hugo/content/docs/1_learn/workflow/scaffold.md b/hugo/content/docs/learn/workflow/scaffold.md similarity index 98% rename from hugo/content/docs/1_learn/workflow/scaffold.md rename to hugo/content/docs/learn/workflow/scaffold.md index a42f1ec2..c30c486d 100644 --- a/hugo/content/docs/1_learn/workflow/scaffold.md +++ b/hugo/content/docs/learn/workflow/scaffold.md @@ -1,7 +1,7 @@ --- title: "Scaffold a Langium project" weight: 300 -url: /docs/learn/worflow/scaffold +url: /docs/learn/workflow/scaffold --- To create your first working DSL, execute the Yeoman generator: diff --git a/hugo/content/docs/learn/workflow/write_grammar.md b/hugo/content/docs/learn/workflow/write_grammar.md new file mode 100644 index 00000000..919a2a71 --- /dev/null +++ b/hugo/content/docs/learn/workflow/write_grammar.md @@ -0,0 +1,10 @@ +--- +title: "Write the grammar" +weight: 400 +url: /docs/learn/workflow/write_grammar +--- +Your Langium project is now setup and ready to be used. The next step is to define the grammar of your language. The grammar is the most important part of your language definition. It defines the syntax of your language and how the language elements are structured. + +The grammar is defined in a `.langium` file. Make sure that you have installed the VS Code extension for Langium. This extension provides syntax highlighting and code completion for `.langium` files. + +- add grammar schema description \ No newline at end of file diff --git a/hugo/content/docs/2_recipes/_index.md b/hugo/content/docs/recipes/_index.md similarity index 100% rename from hugo/content/docs/2_recipes/_index.md rename to hugo/content/docs/recipes/_index.md diff --git a/hugo/content/docs/2_recipes/builtin-library.md b/hugo/content/docs/recipes/builtin-library.md similarity index 100% rename from hugo/content/docs/2_recipes/builtin-library.md rename to hugo/content/docs/recipes/builtin-library.md diff --git a/hugo/content/docs/2_recipes/code-bundling.md b/hugo/content/docs/recipes/code-bundling.md similarity index 100% rename from hugo/content/docs/2_recipes/code-bundling.md rename to hugo/content/docs/recipes/code-bundling.md diff --git a/hugo/content/docs/2_recipes/formatting.md b/hugo/content/docs/recipes/formatting.md similarity index 100% rename from hugo/content/docs/2_recipes/formatting.md rename to hugo/content/docs/recipes/formatting.md diff --git a/hugo/content/docs/2_recipes/multiple-languages.md b/hugo/content/docs/recipes/multiple-languages.md similarity index 100% rename from hugo/content/docs/2_recipes/multiple-languages.md rename to hugo/content/docs/recipes/multiple-languages.md diff --git a/hugo/content/docs/2_recipes/scoping/_index.md b/hugo/content/docs/recipes/scoping/_index.md similarity index 100% rename from hugo/content/docs/2_recipes/scoping/_index.md rename to hugo/content/docs/recipes/scoping/_index.md diff --git a/hugo/content/docs/2_recipes/scoping/class-member.md b/hugo/content/docs/recipes/scoping/class-member.md similarity index 100% rename from hugo/content/docs/2_recipes/scoping/class-member.md rename to hugo/content/docs/recipes/scoping/class-member.md diff --git a/hugo/content/docs/2_recipes/scoping/qualified-name.md b/hugo/content/docs/recipes/scoping/qualified-name.md similarity index 100% rename from hugo/content/docs/2_recipes/scoping/qualified-name.md rename to hugo/content/docs/recipes/scoping/qualified-name.md From 94d2c17d1b9b73a6779f4ddcf9652819c4af2ac0 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Fri, 5 Apr 2024 14:27:43 +0200 Subject: [PATCH 04/19] Add more about AST generation and reference resolution --- hugo/content/docs/learn/workflow/_index.md | 6 +- .../docs/learn/workflow/generate_ast.md | 36 ++++- .../workflow/resolve_cross_references.md | 139 +++++++++++++++++- 3 files changed, 176 insertions(+), 5 deletions(-) diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index a1dd0100..9da47498 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -44,8 +44,8 @@ The middle part will be explained briefly in the following section. ## Core workflow -3. [_changing the grammar_](/docs/learn/write_grammar): The first step in the core workflow starts from the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. -4. [_generating the AST_](/docs/learn/generate_ast): The AST is the backbone of your language. It is used to represent the structure of your language elements. The AST is generated from the grammar. One important part of the AST are the _cross-references_. They are used to resolve references between language elements. If you have cross-references in your language, you need to _resolve_ them, after this step. The actual generation is done by a call of the Langium CLI. -5. [_resolving cross-references_](/docs/learn/resolve_cross_references): The cross-references are used to resolve references between language elements (between different sub trees of one file or even elements of other files(!)). This step is quite important, because it is the basis for the next steps. You can also see it like this: Step 4 will generate an AST with gaps, this fifth step will fill these gaps. +3. [_changing the grammar_](/docs/learn/workflow/write_grammar): The first step in the core workflow starts from the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. +4. [_generating the AST_](/docs/learn/workflow/generate_ast): The AST is the backbone of your language. It is used to represent the structure of your language elements. The AST is generated from the grammar. One important part of the AST are the _cross-references_. They are used to resolve references between language elements. If you have cross-references in your language, you need to _resolve_ them, after this step. The actual generation is done by a call of the Langium CLI. +5. [_resolving cross-references_](/docs/learn/workflow/resolve_cross_references): The cross-references are used to resolve references between language elements (between different sub trees of one file or even elements of other files(!)). This step is quite important, because it is the basis for the next steps. You can also see it like this: Step 4 will generate an AST with gaps, this fifth step will fill these gaps. 6. [_create validations_](/docs/learn/workflow/create_validations): From here we have a fully utilized AST. Now every input file that matches the syntax will be accepted. But we want to have more control over the input. We want to check if the input is semantically correct. This is done by creating _validations_. They are used to check the input against a set of rules. If the input does not match the rules, an error will be thrown. 7. [_generate what you want_](/docs/learn/workflow/generate_everything): Now you have a fully working language. You can generate whatever you want from the input. This can be code, documentation, or anything else. You can use the AST to traverse the input and generate the output. diff --git a/hugo/content/docs/learn/workflow/generate_ast.md b/hugo/content/docs/learn/workflow/generate_ast.md index c5c4853c..02095d84 100644 --- a/hugo/content/docs/learn/workflow/generate_ast.md +++ b/hugo/content/docs/learn/workflow/generate_ast.md @@ -4,6 +4,38 @@ weight: 500 url: /docs/learn/workflow/generate_ast --- +After defining the grammar, you can generate the abstract syntax tree (AST) of your language. The AST is a tree representation of the source code that can be used to analyze and transform the code. The AST definition is generated by the Langium CLI. Simply call the followin command on your terminal: + +```bash +npm run langium:generate +``` + +This line will call `langium generate` on your Langium project. The Langium CLI will generate the files in the `src/generated` directory. +It will create the following files (depending on your given Langium configuration): + +* a _grammar_ file: which contains your entire grammar definition in JSON format. +* a _module_ file: which contains language-specific setup objects for the final module definition of your language. +* an _ast_ file: which contains the definition of your AST. +* several _syntax highlighting_ files: like for PrismJS, TextMate or Monarch. + +## The syntax tree + +An AST of your language is now ready to be get parsed. One important concept in Langium are _cross-references_. With them you can reference other elements in your language. For example, you can reference a variable in a function call. The AST will contain a reference to the variable. This is useful for code analysis and transformation. Technologies like ANTLR or other parser-only generators do not support this feature. For them you are forced to resolve these references in-place everytime the developer is confronted with them. + +After this generation steps, cross-references are not resolved yet. This is done in the next step. + +## Example + +Imagine you are using the Hello-World example from the Yeoman generator. For an input file like this you will get the following syntax tree from Langium during runtime: + +```text +person John +person Jane + +Hello John! +Hello Jane! +``` + {{}} graph TB Model-->persons @@ -30,4 +62,6 @@ graph TB G2 --> PRef2[Ref] G2 --> EM2('!') PRef2 --> QM2{?} -{{}} \ No newline at end of file +{{}} + +Mind the gaps (question marks) for the cross-references inside the greetings. This job has to be done by the developer. Fortunately Langium provides a default implementation for cross-reference resolution. You can also implement your own resolution strategy. diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index 9c639bad..a5eb04bf 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -3,4 +3,141 @@ title: "Resolve cross-references" weight: 600 url: /docs/learn/workflow/resolve_cross_references --- -TODO + +This step takes place after generating the AST. The AST definition was created and you are able to parse input files. But the AST is not complete yet. It contains _cross-references_ that are not resolved. Cross-references are used to reference other elements in your language. + +## Problem + +Let's illustrate the problem using the Hello-World example from the Yeoman generator: + +```text +person John +person Jane + +Hello John! +Hello Jane! +``` + +The following syntax tree is generated by the Langium parser during the runtime. Mind the gaps with the question marks. These are the missing pieces you want to fill out in this step. + +{{}} +graph TB + Model-->persons + Model-->greetings + + persons-->P1[Person] + P1 --> H1('person') + P1 --> N1[name] + N1 --> NL1('John') + + persons-->P2[Person] + P2 --> H2('person') + P2 --> N2[name] + N2 --> NL2('Jane') + + greetings-->G1[Greeting] + G1 --> KW1('hello') + G1 --> PRef1[Ref] + PRef1 -- $refText --> RT1('John') + G1 --> EM1('!') + PRef1 --> QM1{?} + + greetings-->G2[Greeting] + G2 --> KW2('hello') + G2 --> PRef2[Ref] + PRef2 -- $refText --> RT2('John') + G2 --> EM2('!') + PRef2 --> QM2{?} +{{}} + +You normally can achieve the cross-reference resolution by implementing a so-called scope provider and a scope computation. When setup correctly given syntax tree will change to this: + +{{}} +graph TB + Model-->persons + Model-->greetings + + persons-->P1[Person] + P1 --> H1('person') + P1 --> N1[name] + N1 --> NL1('John') + + persons-->P2[Person] + P2 --> H2('person') + P2 --> N2[name] + N2 --> NL2('Jane') + + greetings-->G1[Greeting] + G1 --> KW1('hello') + G1 --> PRef1[Ref] + PRef1 -- $refText --> RT1('John') + G1 --> EM1('!') + PRef1 -..-> P1 + + greetings-->G2[Greeting] + G2 --> KW2('hello') + G2 --> PRef2[Ref] + PRef2 -- $refText --> RT2('John') + G2 --> EM2('!') + PRef2 -..-> P2 +{{}} + +## Resolution of cross-references + +As already hinted, you can implement a scope provider and a scope computation. Fortunately, Langium comes with default implementations for both. But eventually as your language grows, you might want to implement your own strategy because the default is not sufficient. In the follwoing sections I will sketch how to interpret their interfaces. + +### Scope provider + +#### Terms + +The _scope provider_ is responsible for providing a _scope_ for a given cross-reference represented by the `ReferenceInfo` type. + +A _scope_ is a collection of AST nodes that are represented by the `AstNodeDescription` type. + +The _description_ is like a (string) path through the AST of a document. It can be also seen as a tuple of document URI, JSON path, name and type of the AST node. + +A _reference info_ contains the concrete AST reference (which points to nothing yet). The info also has a the parent AST node (a so-called container) of the reference and the property name under which you can find the reference under its container. In the form of this tuple (`container`, `property`, `reference`) Langium visits all cross-references using the scope providers `getScope` method. + +```ts +export interface ScopeProvider { + getScope(context: ReferenceInfo): Scope; +} + +export interface ReferenceInfo { + reference: Reference + container: AstNode + property: string + index?: number +} + +export interface Scope { + getElement(name: string): AstNodeDescription | undefined; + getAllElements(): Stream; +} +``` + +#### Purpose + +So, what is the purpose of the scope provider? As mentioned above: it visits each cross-reference and tries to find the corresponding AST nodes over the entire workspace, that can be a candidate for the cross-reference's place. It is important to understand that we do not decide here which of these nodes is the perfect match! That decision is part of the so-called linker of the Langium architecture. + +If your cross-reference's `$refText` contains the name `Jane` does not matter here. We need to provide all nodes that are possible at this position. So in the result, you would return `Jane` and `John` AST nodes - for both cross-references! + +The background for this behavior is, that this mechanism can be used for two things: the cross-reference resolution and the code completion. The code completion needs to know all possible candidates for a given cross-reference. The resolution of the cross-reference is done by the linker: Given a scope for a certain cross-reference, the linker decides which of the candidates is the right one - for example the first candidate with the same name. + +### Scope computation + +The _scope computation_ is responsible for defining per document file... + +1. which AST nodes are getting exported to the global scope. These nodes will be collected by the so-called _index manager_. +2. which AST nodes (as descriptions) are available in the local scope of a certain AST node. This is meant as a cache computation for the scope provider. + +The _index manager_ is keeping in mind the global symbols of your language. It can be used by the scope provider to find the right candidates for a cross-reference. + +```ts +export interface ScopeComputation { + computeExports(document: LangiumDocument, cancelToken?: CancellationToken): Promise; + computeLocalScopes(document: LangiumDocument, cancelToken?: CancellationToken): Promise; +} +``` + +So, while the scope computation is defining what symbols are globally exported (like using the `export` keyword in Typescript), the scope provider is the place to implement the `import` of these symbols using the index manager and the semantics of your import logic. From 74e482eb611edc0d7cf675ee88b5e0f46dc2f851 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Fri, 5 Apr 2024 16:00:54 +0200 Subject: [PATCH 05/19] Add validations and some cross-ref resolution --- .../docs/learn/workflow/create_validations.md | 57 ++++++++++++++++++- .../workflow/resolve_cross_references.md | 55 +++++++++++++++++- 2 files changed, 110 insertions(+), 2 deletions(-) diff --git a/hugo/content/docs/learn/workflow/create_validations.md b/hugo/content/docs/learn/workflow/create_validations.md index c3f2de11..ea812cca 100644 --- a/hugo/content/docs/learn/workflow/create_validations.md +++ b/hugo/content/docs/learn/workflow/create_validations.md @@ -3,4 +3,59 @@ title: "Create validations" weight: 700 url: /docs/learn/workflow/create_validations --- -TODO + +After resolving the cross-references, you can assume that the syntax tree is complete. Now you can start with the validation of the input files. The validation process is a crucial part of the language engineering workflow. The parser ensures the syntactic correctness of the input files. The validation process ensures the semantic correctness of the input files. + +As an example, let's consider the Hello-World example from the Yeoman generator. One semantic of this language could be that each declared person must be greeted at most once. To be clear, the following input file is invalid, we are greeting John twice: + +```text +person John +person Jane + +Hello John! +Hello Jane! +Hello John! //should throw: You can great each person at most once! This is the 2nd greeting of John. +``` + +To accomplish this, you need to implement a validator. The validator is a visitor that traverses a certain part of the syntax tree and checks for semantic errors. The following code snippet shows how you can implement a validator for the Hello-World example. Mind that the Hello-World already has a validator, you just need to add the following one. + +```ts +import type { ValidationAcceptor, ValidationChecks } from 'langium'; +import type { HelloWorldAstType, Model, Person } from './generated/ast.js'; +import type { HelloWorldServices } from './hello-world-module.js'; + +export function registerValidationChecks(services: HelloWorldServices) { + const registry = services.validation.ValidationRegistry; + const validator = services.validation.HelloWorldValidator; + const checks: ValidationChecks = { + //registers a validator for all Model AST nodes + Model: validator.checkPersonAreGreetedAtMostOnce + }; + registry.register(checks, validator); +} + +export class HelloWorldValidator { + checkPersonAreGreetedAtMostOnce(model: Model, accept: ValidationAcceptor): void { + //create a multi-counter variable using a map + const counts = new Map(); + //initialize the counter for each person to zero + model.persons.forEach(p => counts.set(p, 0)); + //iterate over all greetings and count the number of greetings for each person + model.greetings.forEach(g => { + const person = g.person.ref; + //Attention! if the linker was unsucessful, person is undefined + if(person) { + //set the new value of the counter + const newValue = counts.get(person)!+1; + counts.set(person, newValue); + //if the counter is greater than 1, create a helpful error + if(newValue > 1) { + accept('error', `You can great each person at most once! This is the ${newValue}${newValue==2?'nd':'th'} greeting of ${person.name}.`, { + node: g + }); + } + } + }); + } +} +``` diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index a5eb04bf..b9940125 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -4,7 +4,7 @@ weight: 600 url: /docs/learn/workflow/resolve_cross_references --- -This step takes place after generating the AST. The AST definition was created and you are able to parse input files. But the AST is not complete yet. It contains _cross-references_ that are not resolved. Cross-references are used to reference other elements in your language. +This step takes place after generating the AST. The AST definition was created and you are able to parse input files. But the AST is not complete yet. It contains _cross-references_ that are not resolved. Cross-references are used to reference other elements in your language. ## Problem @@ -141,3 +141,56 @@ export interface ScopeComputation { ``` So, while the scope computation is defining what symbols are globally exported (like using the `export` keyword in Typescript), the scope provider is the place to implement the `import` of these symbols using the index manager and the semantics of your import logic. + +## Cross-reference resolution from a high-level perspective + +1. The AST gets generated by the parser for each document in the workspace. +2. The scope computation is called for each document in the workspace. All exported AST nodes are collected by the index manager. +3. The scope computation is called for each document in the workspace, again. All local scopes get computed and attached to the document. +4. The linker and the scope provider are called for each cross-reference in the workspace. The scope provider uses the index manager to find candidates for each cross-reference. The linker decides which candidate is the right one for each cross-reference. + +## Example + +For the Hello-World example, you can implement a scope provider and a scope computation like this (keep in mind that this is a alternative solution to the default implementation of Langium, which already works for most cases): + +```ts +import { ReferenceInfo, Scope, ScopeProvider, AstUtils, LangiumCoreServices, AstNodeDescriptionProvider, MapScope, EMPTY_SCOPE } from "langium"; +import { isGreeting, isModel } from "./generated/ast.js"; + +export class HelloWorldScopeProvider implements ScopeProvider { + private astNodeDescriptionProvider: AstNodeDescriptionProvider; + constructor(services: LangiumCoreServices) { + //get some helper services + this.astNodeDescriptionProvider = services.workspace.AstNodeDescriptionProvider; + } + getScope(context: ReferenceInfo): Scope { + //make sure which cross-reference you are handling right now + if(isGreeting(context.container) && context.property === 'person') { + //Success! We are handling the cross-reference of a greeting to a person! + + //get the root node of the document + const model = AstUtils.getContainerOfType(context.container, isModel)!; + //select all persons from this document + const persons = model.persons; + //transform them into node descriptions + const descriptions = persons.map(p => this.astNodeDescriptionProvider.createDescription(p, p.name)); + //create the scope + return new MapScope(descriptions); + } + return EMPTY_SCOPE; + } +} +``` + +Please make sure to override the default scope provider in your language module file like this: + +```ts +//... +export const HelloWorldModule: Module = { + //validation: ... + references: { + ScopeProvider: (services) => new HelloWorldScopeProvider(services) + } +}; +//... +``` \ No newline at end of file From dd1eb7ad7e3c23a9ab40d1dbcf6dbaf1b9949ae3 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Fri, 5 Apr 2024 16:36:09 +0200 Subject: [PATCH 06/19] Quick save --- hugo/content/docs/introduction/features.md | 100 +++- .../docs/learn/workflow/create_validations.md | 4 +- .../workflow/resolve_cross_references.md | 2 +- .../docs/learn/workflow/write_grammar.md | 52 +- hugo/content/docs/recipes/_index.md | 2 +- hugo/content/docs/reference/_index.md | 4 + .../docs/reference/configuration-services.md | 221 ++++++++ .../docs/reference/document-lifecycle.md | 133 +++++ hugo/content/docs/reference/glossary.md | 20 + .../docs/reference/grammar-language.md | 518 ++++++++++++++++++ hugo/content/docs/reference/sematic-model.md | 409 ++++++++++++++ 11 files changed, 1458 insertions(+), 7 deletions(-) create mode 100644 hugo/content/docs/reference/_index.md create mode 100644 hugo/content/docs/reference/configuration-services.md create mode 100644 hugo/content/docs/reference/document-lifecycle.md create mode 100644 hugo/content/docs/reference/glossary.md create mode 100644 hugo/content/docs/reference/grammar-language.md create mode 100644 hugo/content/docs/reference/sematic-model.md diff --git a/hugo/content/docs/introduction/features.md b/hugo/content/docs/introduction/features.md index e37c7106..eafe4339 100644 --- a/hugo/content/docs/introduction/features.md +++ b/hugo/content/docs/introduction/features.md @@ -2,4 +2,102 @@ title: "Features" weight: 200 --- -TODO \ No newline at end of file +Designing programming languages from the ground up is hard, independent of whether your language is a "simple" domain specific language or a full-fledged general-purpose programming language. +Not only do you have to keep up with the requirements of your domain experts, but you have to deal with all the technical complexity that comes with building a language, including questions such as: + +- How do I get from a string to a semantic model which I can work with? +- How do I resolve references to other parts of my model, even if they are located in a separate file? +- How do I provide a great editing experience to users of my language? + +This is the point where Langium comes into play. Langium aims to lower the barrier to entry for creating a language by removing the technical complexity, allowing you to focus on your domain's requirements. + +In this chapter, you'll get a closer look at the requirements developers usually have to implement by themselves when building a programming language: + +- [Language Parsing](#language-parsing) +- [Semantic Models](#semantic-models) +- [Cross References and Linking](#cross-references-and-linking) +- [Workspace Management](#workspace-management) +- [Editing Support](#editing-support) +- [Try it out!](#try-it-out) + +Langium provides out-of-the-box solutions for these problems, with the ability to fine-tune every part of it to fit your domain requirements. + +--- + +## Language Parsing + +Programming languages and domain specific languages (DSLs) cannot be parsed using simple regular expressions (RegExp). Instead they require a more sophisticated parsing strategy. To define a custom language in Langium, you interact with a high level representation of your context-free grammar using the [Langium grammar language](/docs/grammar-language), in a similar fashion to EBNF. + +Based on the grammar, Langium is then able to construct a parser which transforms an input string into a semantic model representation. Just as the name suggests, this model captures the essential structure to describe your language. + +## Semantic Models + +Langium grammars are not only used to parse your language, but also to generate a semantic model for your Language as TypeScript interfaces. When a program in your language is then parsed, the generated AST will be automatically produced using these interfaces. The following language snippet parses a simple object `{ name: 'John' }`. + +```langium +Person: + 'person' // keyword + name=ID // semantic assignment +; +``` + +To interact with the semantic model in a type safe manner, the `langium-cli` tool generates TypeScript type definitions from your parser rules. The `Person` parser rule generates the following interface: + +```ts +interface Person { + name: String +} +``` + +These interfaces allow you to safely traverse your abstract syntax tree. In case your grammar changes, they will also notify you of any breaking changes which might require you to change your domain logic. + +## Cross References and Linking + +To express any kind of relationship between elements in your language, you will need to **reference** them. +The process of resolving these references, i.e. identifying what element of your language hides behind a certain name, is called _linking_. +Performing the linking process in a deterministic manner with a lot of objects in your project requires sound linking design. + +Langium accomplishes this feat by using the concept of 'scoping'. You likely know scopes from programming, where some variables are only available from certain scopes: + +```ts +let x = 42; +x = 3; // References the `x` defined in the previous line + +if (something) { + let y = 42; +} +y = 3; // Cannot link, `y` isn't in any of the available scopes +``` + +The same occurs in Langium. To enable more complex scoping behavior, you can add custom domain scoping. For example, common object-oriented languages need a more involved scoping mechanism to resolve references to fields and methods of a class: + +```ts +class X { + y(): void { ... } +} + +const instance = new X(); // Symbol `X` is in the local scope +instance.y(); // Symbol `y` exists in the scope of the `X` class +``` + +Once your domain specific scoping rules have been defined, Langium will take care of linking by itself, reporting any errors. + +## Workspace Management + +Like with common modularized programming languages, domain logic written in your DSL will usually be split across multiple files to facilitate ease of use and maintenance. This is also possible using Langium, which automatically tries to pick up any files belonging to your current project. + +When running a Langium based language in a [language server](https://microsoft.github.io/language-server-protocol/), all files in your workspace (the folder containing your current project) belonging to your DSL will automatically be picked up and processed. In addition, any changes in your workspace will be handled as well. Dealing with added, changed or deleted files in a workspace with multiple hundreds of files can become complicated and decrease performance drastically if not done correctly. Langium employs heuristics to only invalidate and recompute what is actually necessary. + +The workspace management also keeps track of the global scope. This allows users of your DSL to reference elements across files within the same workspace. + +## Editing Support + +The Langium framework is deeply integrated with the [language server protocol](https://microsoft.github.io/language-server-protocol/) (LSP). The LSP aims to reduce integration efforts when designing a language by providing an interface that all IDEs can use to provide editing support. This allows Langium based languages to easily interact with common IDEs and editors with LSP support, including Visual Studio Code, Eclipse, IntelliJ and many more. + +The LSP includes commonly used language features, such as code completion, custom validations/diagnostics, finding references, formatting and many more. This allows for deep IDE integration without binding your language to a single IDE. Langium offers out-of-the-box support for most of these language features, with additional extension points for your domain specific requirements. + +## Try it out! + +You can try out most of these features using our [showcase](/showcase/) and [playground](/playground/). The languages shown there are written using Langium and integrated in the monaco-editor. + +If you're interested in Langium, you can check out our [getting started](/docs/getting-started) page next. There you'll learn how to get started writing your first language, and to learn more about how Langium can help you achieve your language designing goals. diff --git a/hugo/content/docs/learn/workflow/create_validations.md b/hugo/content/docs/learn/workflow/create_validations.md index ea812cca..d732bfd4 100644 --- a/hugo/content/docs/learn/workflow/create_validations.md +++ b/hugo/content/docs/learn/workflow/create_validations.md @@ -14,7 +14,7 @@ person Jane Hello John! Hello Jane! -Hello John! //should throw: You can great each person at most once! This is the 2nd greeting of John. +Hello John! //should throw: You can great each person at most once! This is the 2nd greeting to John. ``` To accomplish this, you need to implement a validator. The validator is a visitor that traverses a certain part of the syntax tree and checks for semantic errors. The following code snippet shows how you can implement a validator for the Hello-World example. Mind that the Hello-World already has a validator, you just need to add the following one. @@ -50,7 +50,7 @@ export class HelloWorldValidator { counts.set(person, newValue); //if the counter is greater than 1, create a helpful error if(newValue > 1) { - accept('error', `You can great each person at most once! This is the ${newValue}${newValue==2?'nd':'th'} greeting of ${person.name}.`, { + accept('error', `You can great each person at most once! This is the ${newValue}${newValue==2?'nd':'th'} greeting to ${person.name}.`, { node: g }); } diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index b9940125..9b192edf 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -193,4 +193,4 @@ export const HelloWorldModule: Module = { + references: { + ScopeProvider: (services) => new ArithmeticsScopeProvider(services) + } +}; +``` +In the `ArithmeticsModule` singleton instance, we map a property with the name of our service (here `ScopeProvider`) to a concrete implementation of the service. This means that the first time we access the service named `ScopeProvider`, a new instance of the class `ArithmeticsScopeProvider` will be created instead of the default implementation `DefaultScopeProvider`. The provided factory function is invoked only once, which means that all services are handled as singletons. + +In order to successfully override an existing service, the property name (here `ScopeProvider`) must match exactly that of the default implementation. + +The `ArithmeticsScopeProvider` overrides two methods from `DefaultScopeProvider`: +```TypeScript +export class ArithmeticsScopeProvider extends DefaultScopeProvider { + + protected createScope(elements: Stream, outerScope: Scope): Scope { + return new StreamScope(elements, outerScope, { caseInsensitive: true }); + } + + protected getGlobalScope(referenceType: string): Scope { + return new StreamScope(this.indexManager.allElements(referenceType), undefined, { caseInsensitive: true }); + } + +} +``` +The functions `createScope` and `getGlobalScope` are already defined in `DefaultScopeProvider` but needed to be overridden to add the option `{caseInsensitive: true}`. This is achieved through inheritance: By using the keyword `extends`, `ArithmeticsScopeProvider` inherits from `DefaultScopeProvider`, which means that it can access properties and methods as well as override methods declared in the superclass. + +In the `DefaultScopeProvider`, those two methods are declared as: +```Typescript +protected createScope(elements: Stream, outerScope: Scope): Scope { + return new StreamScope(elements, outerScope); +} + +protected getGlobalScope(referenceType: string): Scope { + return new StreamScope(this.indexManager.allElements(referenceType)); +} +``` + +Now, when we call either `createScope` or `getGlobalScope` from the `ScopeProvider` service, the call will be made from the `ArithmeticsScopeProvider` instead of the `DefaultScopeProvider`. Functions that were not overridden will still be called from `DefaultScopeProvider` via inheritance. + +Of course it is also possible to replace the default implementation with a completely separate one that does not inherit from the default service class. + +### Adding New Services +To add services that are not available by default in Langium, e.g. application specific ones, we first need to edit the type `ArithmeticsAddedService`. +By default, the Yeoman-based generator adds a validator service where you can implement validation rules specific to your language. New services are added as properties to the type declaration: +```Typescript +export type ArithmeticsAddedServices = { + ArithmeticsValidator: ArithmeticsValidator +} +``` +The `ArithmeticsAddedService` type now has a property `ArithmeticsValidator` of type `ArithmeticsValidator`. + +For the sake of organization and clarity, the services can be nested inside of other properties acting as "groups": +```Typescript +export type ArithmeticsAddedServices = { + validation: { + ArithmeticsValidator: ArithmeticsValidator + }, + secondGroup: { + AnotherServiceName: AnotherServiceType + }, + nthGroup: { + withASubGroup: { + YetAnotherServiceName: YetAnotherServiceType + } + } +} +``` + +Now that we have declared our new services inside of the `ArithmeticsAddedServices` type definition, we need to specify to the module how we want them to be implemented. To do so, we need to update the `ArithmeticsModule`: +```Typescript +export const ArithmeticsModule: Module = { + validation: { + ArithmeticsValidator: () => new ArithmeticsValidator() + } +}; +``` +Similarly to [overridden services](#overriding-and-extending-services), the first access to the `ArithmeticsValidator` property will create a new instance of the class `ArithmeticsValidator`. + +The `ArithmeticsValidator` service does not depend on other services, and no argument is passed during the instantiation of the class. If you implement a service that depends on other services, the constructor of your service should expect `Services` as argument. The initializer function can expect that object as argument and pass it to your services constructor, such as: +```Typescript +export const ArithmeticsModule: Module = { + ServiceWithDependencies = (services) => new ServiceClass(services); +} +``` +The services which `ServiceClass` depends on need to be registered in the constructor: +```Typescript +export class ServiceClass { + private readonly serviceOne: ServiceOne; + private readonly serviceTwo: ServiceTwo; + private readonly serviceN: ServiceN; + + constructor(services: ArithmeticsServices) { + this.serviceOne = services.ServiceOne; + this.serviceTwo = services.Group.ServiceTwo; + this.serviceN = services.Group.SubGroup.ServiceN; + } + /* service logic */ +} +``` + +#### Resolving cyclic dependencies + +In case one of the services the `ServiceClass` above depends on, also has a dependency back to the `ServiceClass`, your module will throw an error similar to this: `Cycle detected. Please make "ServiceClass" lazy.` Ideally, such cyclic dependencies between services should be avoided. Sometimes, cycles are unavoidable though. In order to make them lazy, assign a lambda function that returns the service in the constructor. You can then invoke this function in your service logic to get access to the depending service: +```Typescript +export class ServiceClass { + private readonly serviceOne: () => ServiceOne; + + constructor(services: ArithmeticsServices) { + this.serviceOne = () => services.ServiceOne; // <-- lazy evaluated service + } + /* service logic */ + method() { + this.serviceOne().methodOne(); + } +} +``` + +#### Using ArithmeticsValidator in other services +The `ArithmeticsValidator` needs to be registered inside of the `ValidationRegistry`. This done by [overriding](#overriding-and-extending-services) `ValidationRegistry` with `ArithmeticsValidationRegistry`. + +Briefly, `ArithmeticsValidator` implements two checks, `checkDivByZero` and `checkNormalisable`: +```Typescript +export class ArithmeticsValidator { + checkDivByZero(binExpr: BinaryExpression, accept: ValidationAcceptor): void { + ... + } + + checkNormalisable(def: Definition, accept: ValidationAcceptor): void { + ... + } +} +``` +These two new checks need to be registered inside of the `ValidationRegistry`. We extend `ValidationRegistry` with `ArithmeticsValidationRegistry` to implement our new functionalities: +```Typescript +export class ArithmeticsValidationRegistry extends ValidationRegistry { + constructor(services: ArithmeticsServices) { + super(services); + const validator = services.validation.ArithmeticsValidator; + const checks: ArithmeticsChecks = { + BinaryExpression: validator.checkDivByZero, + Definition: validator.checkNormalisable + }; + this.register(checks, validator); + } +} +``` +Inside of the `ArithmeticsValidationRegistry`, we obtain our `ArithmeticsValidator` with `const validator = services.validation.ArithmeticsValidator`, which will create a new instance of `ArithmeticsValidator`. Then we declare the `checks` to be registered and register them inside of the registry via the function `register` which is declared in the superclass. The `ArithmeticsValidationRegistry` only adds validation checks to the `ValidationRegistry`, but does not override any functionality from it. + +The implementation of `ArithmeticsValidationRegistry` needs to be registered in `ArithmeticsModule`. The complete `ArithmeticsModule` is: +```Typescript +export const ArithmeticsModule: Module = { + references: { + ScopeProvider: (services) => new ArithmeticsScopeProvider(services) + }, + validation: { + ValidationRegistry: (services) => new ArithmeticsValidationRegistry(services), + ArithmeticsValidator: () => new ArithmeticsValidator() + } +}; +``` + +## Language Server Protocol +If you want to modify aspects of the Language Server, this section will help you find the relevant service for handling a given LSP request. + +#### CompletionProvider +The `CompletionProvider` service is responsible for handling a [Completion Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion) at a given cursor position. When a *Completion Request* is submitted by the client to the server, the `CompletionProvider` will create a `CompletionList` of all possible `CompletionItem` to be presented in the editor. The `CompletionProvider` service computes a new `CompletionList` after each keystroke. + +#### DocumentSymbolProvider +The `DocumentSymbolProvider` service is responsible for handling a [Document Symbols Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol). The `DocumentSymbolProvider` is used to return a hierarchy of all symbols found in a document as an array of `DocumentSymbol`. + +#### HoverProvider +The `HoverProvider` service is responsible for handling a [Hover Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover) at a given text document position. By default, Langium implements tooltips with the content of the preceding multiline comment when hovering a symbol. + +#### FoldingRangeProvider +The `FoldingRangeProvider` service is responsible for handling a [Folding Range Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_foldingRange). This service identifies all the blocks that can be folded in a document. + +#### ReferenceFinder +The `ReferenceFinder` service is responsible for handling a [Find References Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references). This service is used to find all references to a given symbol inside of a document. + +#### DocumentHighlighter +The `DocumentHighlighter` service is responsible for handling a [Document Highlights Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentHighlight). This service will find all references to a symbol at a given position (via the `References` service) and highlight all these references in a given document. + +#### RenameHandler +The `RenameHandler` service is responsible for handling a [Rename Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename) or a [Prepare Rename Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_prepareRename). First, the service will check the validity of the *Prepare Rename Request*. If the request is valid, the service will find all references to the selected symbol inside of a document and replace all occurrences with the new value. diff --git a/hugo/content/docs/reference/document-lifecycle.md b/hugo/content/docs/reference/document-lifecycle.md new file mode 100644 index 00000000..3672e486 --- /dev/null +++ b/hugo/content/docs/reference/document-lifecycle.md @@ -0,0 +1,133 @@ +--- +title: 'Document Lifecycle' +weight: 400 +--- + +`LangiumDocument` is the central data structure in Langium that represents a text file of your DSL. Its main purpose is to hold the parsed Abstract Syntax Tree (AST) plus additional information derived from it. After its creation, a `LangiumDocument` must be "built" before it can be used in any way. The service responsible for building documents is called `DocumentBuilder`. + +A `LangiumDocument` goes through seven different states during its lifecycle: +1. `Parsed` when an AST has been generated from the content of the document. +2. `IndexedContent` when the AST nodes have been processed by the `IndexManager`. +3. `ComputedScopes` when local scopes have been prepared by the `ScopeComputation`. +4. `Linked` when the `Linker` has resolved cross-references. +5. `IndexedReferences` when the references have been indexed by the `IndexManager`. +6. `Validated` when the document has been validated by the `DocumentValidator`. +7. `Changed` when the document has been modified. + +State 1 is the initial state after creation of a document, and states 2 to 6 are part of its build process. State 7 is a final state used to mark the document as invalid due to a change in the source text. + +The following diagram depicts how the `DocumentBuilder` processes `LangiumDocument`s depending on their state. More details about each step of the lifecycle can be found below. + +{{}} +graph TD; +N(LangiumDocumentFactory) -.-|Creation of LangiumDocuments| C{{Parsed}} + +A(DocumentBuilder) -->|Indexing of symbols| D(IndexManager) -.- E{{IndexedContent}} +A -->|Computing scopes| F(ScopeComputation) -.- G{{ComputedScopes}} +A -->|Linking| H(Linker) -.- I{{Linked}} +A -->|Indexing of cross-references| J(IndexManager) -.- K{{IndexedReferences}} +A -->|Validation| L(DocumentValidator) -.- M{{Validated}} + +click N "./#creation-of-langiumdocuments" +click D "./#indexing-of-symbols" +click F "./#computing-scopes" +click H "./#linking" +click J "./#indexing-of-cross-references" +click L "./#validation" +{{}} + +## Creation of LangiumDocuments +When the workspace is initialized, all files having an extension matching those defined in `langium-config.json` are collected by the `WorkspaceManager` service. The `LangiumDocumentFactory` service creates a new instance of `LangiumDocument` for each source file. Those documents are then stored in memory by the `LangiumDocuments` service so they can be accessed later. + +Files in the workspace are mapped to instances of `TextDocument` as implemented by the `vscode-languageserver` package. Such a `TextDocument` holds the content of the respective file as a `string`. In contrast, a `LangiumDocument` represents the file content as an AST. This means that the creation of a `LangiumDocument` by the `LangiumDocumentFactory` service is accompanied by the parsing of the content of a `TextDocument` into an AST. During the creation of a `LangiumDocument` (i.e. after the document has been parsed), its state is set to `Parsed`. + +{{}} +graph LR; +A(LangiumDocuments

manages LangiumDocument instances) --> B(LangiumDocumentFactory

creates a LangiumDocument) +B --> C(LangiumParser

parses a string into an AST) +{{
}} + +Once all `LangiumDocument`s have been created, the `DocumentBuilder` service will sequentially process each `LangiumDocument` as described below. + +## Indexing of Symbols +Symbols are AST nodes that can be identified with a *name* and hence can be referenced from a *cross-reference*. Symbols that are *exported* can be referenced from other documents, while non-exported symbols are local to the document containing them. The `IndexManager` service keeps an index of all symbols that are exported from documents in the workspace. The set of all these exported symbols is called the *global scope*. + +Indexing of the exported symbols of an AST is executed on documents with the state `Parsed`. The default `ScopeComputation` service creates an `AstNodeDescription` for the root node (i.e. the node created by parsing the entry rule) and each named `AstNode` directly descending from the root node. This `AstNodeDescription` contains the `type` of the node, its identifier (i.e. the `name` property), the URI of the document where the node is located, and the location of the node inside of the document. The generated set of `AstNodeDescription`s makes symbols from a `LangiumDocument` accessible to other documents in the same workspace. + +The default `ScopeComputation` can be overridden to change the selection of exported symbols, or to export them with different names than the plain value of their `name` property. However, keep in mind that you cannot access any cross-references in this phase because that requires the document state to be at least `ComputedScopes`, which happens later in the build process. + +Once the initial indexing is done, the document's state is set to `IndexedContent`. + +{{}} +graph LR; +A(IndexManager

manages exported content
of LangiumDocuments
) --> B(ScopeComputation

creates descriptions
of all exported symbols
) +B --> C(NameProvider

resolves the name of an AstNode) +B --> D(AstNodeLocator

gets the path of an AstNode) +{{
}} + +## Computing Scopes +This phase is executed on documents with the state `IndexedContent` and is required to complete **prior to** resolving cross-references. + +Local scope computation consists of gathering all symbols contained in the AST, done by the `ScopeComputation` service (in addition to the indexing explained in the previous section). Metadata of the gathered symbols are represented with `AstNodeDescription` like in the [initial indexing phase](#indexing-of-symbols). These metadata are attached to the `LangiumDocument` in a multi-map structure that associates a (possibly empty) set of symbol descriptions to each container node of the AST, called the *precomputed scopes*. These are used in the linking phase to construct the actual *scope* of a cross-reference, i.e. all possible symbols that are reachable. A symbol in the precomputed scopes is reachable from a specific cross-reference if it is associated with a direct or indirect container of that reference. Symbols associated to the root node are reachable from the whole AST, while symbols associated with an inner node are reachable from the respective sub-tree. + +The default implementation of the `ScopeComputation` service attaches the description of every symbol to its direct container. This means that the container holds information about which named nodes are nested inside of it. You can override this default behavior to change the position where a symbol is reachable, or to change the name by which it can be referenced. It is even possible to associate the same symbol to multiple container nodes, possibly with different names, to control precisely where and how references to it can be resolved. However, keep in mind that you cannot access any cross-references in this phase. More complex, context-dependent scope mechanisms can be implemented in the `ScopeProvider` (see [next section](#linking)). + +The *"Domainmodel"* example includes a [customization of scopes precomputation](https://github.com/eclipse-langium/langium/blob/main/examples/domainmodel/src/language-server/domain-model-scope.ts) where every *entity* contained in a *package declaration* is exposed using its *qualified name*, that is the concatenation of the package name and entity name separated with `.` (similar to Java). + +In languages with a type system, you would typically implement computation of types in an additional pre-processing step in order to make type information available in the document. This additional step can be registered to run after scope computation with the `onBuildPhase` method of `DocumentBuilder`. How types are computed heavily depends on the kind of type system, so there is no default implementation for it. + +Once local scopes are computed and attached to the document, the document's state is set to `ComputedScopes`. + +{{}} +graph LR; +A(ScopeComputation

gathers all symbols from the AST and
stores their metadata in a MulitMap
) --> B(NameProvider

resolves the name of an AST node) +A --> C(AstNodeDescriptionProvider

creates descriptions of the
gathered symbols
) +C --> D(AstNodeLocator

gets the path of an AstNode) +{{
}} + +## Linking +Once local scopes have been prepared, cross-references are resolved via the `Linker` service. The `Linker` retrieves all cross-references in a `LangiumDocument` and tries to resolve them. Reference resolution consists of three main steps: + + 1. Query the `ScopeProvider` to obtain a *scope*. A scope describes all symbols that are reachable from the AST node holding the cross-reference. + 2. In the obtained scope, find the description of a symbol whose name matches the identifier given at the cross-reference. + 3. Load the AST node for that description. The AST node is given either directly (for a local symbol) or indirectly though a path string (for a symbol exported from another document). + +The default implementation of the `ScopeProvider` service creates a hierarchical scope by traveling from the given cross-reference via its container nodes up to the root of the AST, and collecting symbol descriptions from the precomputed scopes (created in the [preceding phase](#computing-scopes)). The symbols are filtered to match the type of the cross-reference target. Symbols that are closer to the cross-reference *shadow* those that are further above in the AST, which means they have higher priority to be chosen as cross-reference targets. As the last resort, the global scope computed in the [initial indexing phase](#indexing-of-symbols) is included in the hierarchical scope. Symbols that cannot be found locally are looked up in the global scope. + +The `ScopeProvider` can be overridden to implement complex scenarios for scoping and cross-reference resolution. Since cross-references can be linked *lazily* in this phase, it is possible to create a scope for a cross-reference depending on the resolved target of another cross-reference. + +Once the linking is complete, the document's state is set to `Linked`. + +{{}} +graph LR; +A(Linker

links references to their target AstNodes) --> B(ScopeProvider

creates a Scope for the context of a Reference) +A --> C(AstNodeLocator

resolves an AstNode from its path) +{{
}} + +## Indexing of Cross-References +Once the cross-references have been resolved by the linker, the `IndexManager` kicks in a second time to create descriptions of cross-references between different documents. Such a `ReferenceDescription` implies a dependency from its source document to its target document. This information ensures an efficient lookup to identify which other documents may be impacted by a change in a `LangiumDocument`. + +After the cross-references have been indexed, the document's state is set to `IndexedReferences`. + +{{}} +graph LR; +A(IndexManager

manages metadata of cross-references
between documents
) --> B(ReferenceDescriptionProvider

creates descriptions of all cross-references) +B --> C(AstNodeLocator

gets the path of an AstNode) +{{
}} + +## Validation +The `DocumentValidator` creates an array of `Diagnostic`s from a `LangiumDocument`. This array contains all errors that have occurred during lexing, parsing, and linking, and the results of a set of custom validations with varying severity (_error_, _warning_, _info_). The custom validations are registered with the `ValidationRegistry` service. + +After the diagnostics have been created, the document's state is set to `Validated`. + +{{}} +graph LR; +A(DocumentValidator

translate parser and linker errors to Diagnostics,
and executes custom validation checks
) --> B(ValidationRegistry

manages custom validation checks for each AST node type) +{{
}} + +At this point, all documents have been processed by the `DocumentBuilder` and the workspace is ready to process requests from the editor (e.g. completion). + +## Modifications of a document +When a `TextDocument` is modified, the language client (IDE) notifies the language server, which triggers corresponding events. In Langium, a change in a `TextDocument`'s content leads to the invalidation of the associated `LangiumDocument`. The document's state is set to `Changed` and the document's entry is removed from the `LangiumDocuments` service. If the `TextDocument` was deleted, the corresponding `LangiumDocument` is removed from the index in the `IndexManager` service. If the document's content was modified, a new instance of `LangiumDocument` is created [as described above](#creation-of-langiumdocuments). All other documents that may have been affected as a result of the modification get their references unlinked and their state is modified such that they run through the [linking phase](#linking) again. The `DocumentBuilder` then processed the newly created document along with all other documents that have not reached the `Validated` state yet. + +To determine which documents are affected by a change, the `IndexManager` uses the reference descriptions gathered in the [reference indexing phase](#indexing-of-cross-references). diff --git a/hugo/content/docs/reference/glossary.md b/hugo/content/docs/reference/glossary.md new file mode 100644 index 00000000..5c953e84 --- /dev/null +++ b/hugo/content/docs/reference/glossary.md @@ -0,0 +1,20 @@ +--- +title: "Glossary" +weight: 50 +--- + +Anyone who is new to DSL development should carefully read the following primer on the terms we are using in our documentation: + +_abstract syntax tree_: A tree of elements that represents a text document. Each element is a simple JS object that combines multiple input tokens into a single object. Commonly abbreviated as _AST_. + +_document_: An abstract term to refer to a text file on your file system or an open editor document in your IDE. + +_grammar_: Defines the form of your language. In Langium, a grammar is also responsible for describing how the _AST_ is built. + +_parser_: A program that takes a _document_ as its input and computes an _abstract syntax tree_ as its output. + +_parser rule_: A parser rule describes how a certain _AST_ element is supposed to be parsed. This is done by invoking other _parser rules_ or _terminals_. + +_terminal_: A terminal is the smallest parseable part of a document. It usually represents small pieces of text like names, numbers, keywords or comments. + +_token_: A token is a substring of the _document_ that matches a certain _terminal_. It contains information about which kind of _terminal_ it represents as well as its location in the document. \ No newline at end of file diff --git a/hugo/content/docs/reference/grammar-language.md b/hugo/content/docs/reference/grammar-language.md new file mode 100644 index 00000000..587afefd --- /dev/null +++ b/hugo/content/docs/reference/grammar-language.md @@ -0,0 +1,518 @@ +--- +title: "Grammar Language" +weight: 100 +--- +The grammar language describes the syntax and structure of your language. The [Langium grammar language](https://github.com/eclipse-langium/langium/blob/main/packages/langium/src/grammar/langium-grammar.langium) is implemented using Langium itself and therefore follows the same syntactic rules as any language created with Langium. The grammar language will define the structure of the *abstract syntax tree* (AST) which in Langium is a collection of *TypeScript types* describing the content of a parsed document and organized hierarchically. The individual nodes of the tree are then represented with JavaScript objects at runtime. + +In the following, we describe the Langium syntax and document structure. +## Language Declaration +An *entry* Langium grammar file (i.e. a grammar which contains an [entry rule](#the-entry-rule)) always starts with a header which declares the name of the language. For example, a language named `MyLanguage` would be declared with: + +```langium +grammar MyLanguage +``` + +Every grammar file has a `.langium` extension and the *entry grammar file* needs to be referenced in `langium-config.json`. If you used the [Yeoman generator](https://www.npmjs.com/package/generator-langium) to start your project, the configuration is already prepared. + +### Import of other grammar languages +It is possible to reuse grammar rules from other `.langium` files by importing them into your own grammar file. +```langium +import './path/to/an/other/langium/grammar'; +``` +This will import **all grammar rules** from the imported grammar file. It is therefore crucial to ensure that there are no duplicate rules between the different grammar files. + +Contrary to *entry grammars*, imported grammars do not need to start with the keyword `grammar`. + +## Terminal Rules +The first step in parsing your language is *lexing*, which transforms a stream of characters into a stream of tokens. A token is a sequence of one or many characters which is matched by a *terminal rule*, creating an atomic symbol. The names of terminal rules are conventionally written in upper case. + +The Langium parser is created using [Chevrotain](https://github.com/chevrotain/chevrotain) which has a built-in lexer based on [Javascript Regular Expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). + +Langium also allows the use of [Extended Backus-Naur Form (EBNF) Expressions](#extended-backus-naur-form-terminals) for terminals, but we *highly* recommend that you write your terminals using Regular Expressions instead. EBNF expressions are internally translated by langium into Regular Expressions, as they are intended to allow porting Xtext grammars into Langium grammars -- given their similarity. + +With that said, both types of expressions can be used jointly in the same grammar. + +The declaration of a terminal rule starts with the keyword `terminal`: +```langium +terminal ID: /[_a-zA-Z][\w_]*/; +``` +Here, the token `ID` will match a stream of characters starting with the character `_`, a small letter, or a capital letter followed by a sequence of zero or many ([cardinality](#cardinalities) *) alphanumeric characters (`\w`) or `_`. + +**The order in which terminal rules are defined is critical** as the lexer will always return the first match. + +### Return Types +A terminal rule returns an instance of a _TypeScript primitive type_. If no return type is specified, the terminal rule will return a `string` by default. +```langium +terminal ID: /[_a-zA-Z][\w_]*/; +terminal INT returns number: /[0-9]+/; +``` +Here, the terminal rule `ID` will return an instance of `string` while the terminal rule `INT` will return an instance of `number`. + +The available return types in Langium are: +- `string` +- `number` +- `boolean` +- `bigint` +- `Date` + +### Hidden Terminal Rules +The lexer tries to match every character in the document to a terminal rule or a keyword. It is therefore necessary to specify which characters or sequence of characters need to be ignored during lexing and parsing. Generally, you would want to ignore whitespaces and comments. This is achieved by adding the keyword `hidden` when defining a terminal rule. These *hidden terminal rules* are global and will be valid for all parser rules in the document. +```langium +hidden terminal WS: /\s+/; +hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; +hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; +``` + +## Parser Rules +While [terminal rules](#terminal-rules) indicate to the lexer what sequence of characters are valid tokens, *parser rules* indicate to the parser what sequence of tokens are valid. Parser rules lay the structure of objects to be created by the parser and result in the creation of the *abstract syntax tree* (AST) which represents the syntactic structure of your language. In Langium, parser rules are also responsible for defining the type of objects to be parsed. + +### Declaration +A parser rule always starts with the name of the rule followed by a colon. +```langium +Person: + 'person' name=ID; +``` +In this example, the parser will create an object of type `Person`. This object will have a property `name` which value and type must match the terminal rule `ID` (i.e. the property `name` is of type `string` and cannot start with a digit or special character). + +By default, the parser will create an object with an inferred type corresponding to the parser rule name. It is possible to override this behavior by explicitly defining the type of the object to be created. This is done by adding the keyword `returns` followed by a separately declared type, or the keyword `infers` followed by the name of the type to be inferred for this rule (more about this [in the next chapter](../sematic-model)): +```langium +Person infers OtherType: + 'person' name=ID; +``` +The parser rule `Person` will now lead to the creation of objects of type `OtherType` instead of `Person`. + +### The Entry Rule +The *entry rule* is a parser rule that defines the starting point of the parsing step. The *entry rule* starts with the keyword `entry` and matches other parser rules. +```langium +entry Model: + (persons+=Person | greetings+=Greeting)*; +``` +In this example, the *entry rule* `Model` defines a group of alternatives. The parser will go through the input document and try to parse `Person` or `Greeting` objects and add them to the `persons` or `greetings` arrays, respectively. The parser reads the token stream until all inputs have been consumed. + +### Extended Backus-Naur Form Expressions +Parser rules are defined using *Extended Backus-Naur Form*-like (EBNF) expressions similar to the [Xtext](https://www.eclipse.org/Xtext/) notation. + +#### Cardinalities +A cardinality defines the number of elements in a given set. Four different cardinalities can be defined for any expression: +1. exactly one (no operator) +2. zero or one (operator `?`) +3. zero or many (operator `*`) +4. one or many (operator `+`) + +#### Groups +Expressions can be put in sequence specifying the order they have to appear: +```langium +Person: + 'person' name=ID address=Address; +``` +In this example, the rule `Person` must start with the `person` keyword followed by an `ID` token and an instance of the `Address` rule. + +#### Alternatives +It is possible to match one of multiple valid options by using the pipe operator `|`. The already mentioned `Model` example specifies to parse either `Person` or `Greeting`, zero or many times (cardinality *): +```langium +entry Model: + (persons+=Person | greetings+=Greeting)*; +``` + +#### Keywords +Keywords are *inline terminals* which need to match a character sequence surrounded by single or double quotes, for example `'person'` or `"person"`. Keywords must not be empty and must not contain white space. + +#### Assignments +Assignments define properties on the type returned by the surrounding rule. +There are three different ways to assign an expression (right side) to a property (left side). + +1. `=` is used for assigning **a single value** to a property. + ```langium + Person: + 'person' name=ID + ``` + Here, the property `name` will accept only one expression matching the terminal rule `ID`. + +2. `+=` is used to assign **multiple values** to an array property. + ```langium + Contact: + addresses+=STRING addresses+=STRING; + ``` + Here, the array property `addresses` will accept two expressions matching the terminal rule `STRING`. + +3. `?=` is used to assign a **value to a property of type boolean**. The value of the property of type `boolean` is set to `true` if the right part of the assignment is consumed by the parser. + ```langium + Employee: + 'employee' name=ID (remote?='remote')? + ``` + Here the value of the property `remote` will be set to `true` if the keyword `remote` was successfully parsed as a part of the rule call. If the keyword `remote` is not consumed (cardinality is `?`), the property `remote` is set to `false`. + +#### Cross-References +With Langium, you can declare *cross-references* directly in the grammar. A *cross-reference* allows to reference an object of a given type. The syntax is: +```langium +property=[Type:TOKEN] +``` +The `property` will be a reference to an object of type `Type` identified by the token `TOKEN`. If the `TOKEN` is omitted, the parser will use the terminal or data type rule associated with the `name` assignment of the `Type` rule. If no such rule exists, then the token is mandatory. +```langium +Person: + 'person' name=ID; +Greeting: + 'Hello' person=[Person:ID] '!'; +``` +The `Person` in square brackets does not refer to the parser rule `Person` but instead refers to an object of type `Person`. It will successfully parse a document like: +``` +person Bob +Hello Bob ! +``` +but the following: +``` +person Bob +Hello Sara ! +``` +will result in an error message since the cross reference resolution will fail because a `Person` object with the name 'Sara' has not been defined, even though 'Sara' is a valid `ID`. + +#### Unassigned Rule Calls +Parser rules do not necessarily need to create an object, they can also refer to other parser rules which in turn will be responsible for returning the object. +For example, in the [Arithmetics example](https://github.com/eclipse-langium/langium/blob/main/examples/arithmetics/src/language-server/arithmetics.langium): +```langium +AbstractDefinition: + Definition | DeclaredParameter; +``` +The parser rule `AbstractDefinition` will not create an object of type AbstractDefinition. Instead, it calls either the `Definition` or `DeclaredParameter` parser rule which will be responsible for creating an object of a given type (or call other parser rules if they are unassigned rule calls themselves). + +In contrast, an assigned rule call such as `parameter=DeclaredParameter` means that an object is created in the current parser rule and assigns the result of the `DeclaredParameter` parser rule to the specified property `parameter` of that object. + +#### Unordered Groups + +In regular groups, expressions must occur in the exact order they are declared. +```langium +Person: + 'person' name=ID age=INT +``` +Here a `Person` object **needs** to first declare the property `name` then `age`. +``` +person Bob 25 +``` +will successfully be parsed to an object of type `Person` while +``` +person 25 Bob +``` +will throw an error. + +However, it is possible to declare a group of properties in an unordered fashion using the `&` operator +```langium +Person: + 'person' name=ID & age=INT +``` +will now allow `name` and `age` to be declared in any order. +``` +person 25 Bob +``` +will then successfully create an object of type `Person`. + +Cardinality (?,*,+ operators) also applies to unordered group. Please note that assignments with a cardinality of `+` or `*` have to appear continuously and cannot be interrupted by an other assignment and resumed later. + +#### Simple Actions +It is possible for a rule to return different types depending on declaration +```langium +interface TypeOne { + name: string +} +RuleOne returns TypeOne: + 'keywordOne' name=ID | RuleTwo; + +interface TypeTwo extends TypeOne {} +RuleTwo returns TypeTwo: + 'keywordTwo' name=ID; +``` +A rule call is one of the ways to specify the return type. With more complex rules, the readability will be highly impacted. *Actions* allow to improve the readability of the grammar by explicitly defining the return type. Actions are declared inside of curly braces `{}`: +```langium +RuleOne returns TypeOne: + 'keywordOne' name=ID | {TypeTwo} 'keywordTwo' name=ID; +``` + +The example above requires that the return types `TypeOne` and `TypeTwo` are declared separately (see [the next chapter](../semantic-model)). If the type returned by the action is created on-the-fly, the keyword `infer` needs to be added: +```langium +RuleOne infers TypeOne: + 'keywordOne' name=ID | {infer TypeTwo} 'keywordTwo' name=ID; +``` +Now both `TypeOne` and `TypeTwo` are inferred from the rule definition. Note that we use the keyword `infers` (declarative) for the grammar rule, but `infer` (imperative) for the action. + +#### Tree-Rewriting Actions +The parser is built using [Chevrotain](https://github.com/chevrotain/chevrotain) which implements a LL(k) parsing algorithm (left-to-right). Conceptually, a LL(k) grammar cannot have rules containing left recursion. + +Consider the following: +```langium +Addition: + Addition '+' Addition | '(' Addition ')' | value=INT; +``` +The parser rule `Addition` is left-recursive and will not be parseable. We can go around this issue by *left-factoring* the rule, *i.e.* by factoring out the common left-factor. We introduce a new rule `SimpleExpression`: +```langium +Addition: + SimpleExpression ('+' right=SimpleExpression)*; + +SimpleExpression: + '(' Addition ')' | value=INT; +``` +Unfortunately, *left-factoring* does not come without consequences and can lead to the generation of unwanted nodes. It is possible to "clean" the tree by using *tree-rewriting actions*. +```langium +Addition returns Expression: + SimpleExpression ({Addition.left=current} '+' right=SimpleExpression)*; + +SimpleExpression: + '(' Addition ')' | value=INT; +``` +Essentially this means that when a `+` keyword is found, a new object of type `Addition` is created and the current object is assigned to the `left` property of the new object. The `Addition` then becomes the new current object. In imperative pseudo code it may look like this: +```js +function Addition() { + let current = SimpleExpression() + while (nextToken == '+') { + let newObject = new Addition + newObject.left = current + current = newObject + current.right = SimpleExpression() + } +} +``` +Please refer to [this blog post](https://www.typefox.io/blog/parsing-expressions-with-xtext) for further details. + +### Data Type Rules +Data type rules are similar to terminal rules as they match a sequence of characters. However, they are parser rules and are therefore context-dependent. This allows for more flexible parsing, as they can be interspersed with hidden terminals, such as whitespaces or comments. Contrary to terminal rules, they cannot use *regular expressions* to match a stream of characters, so they have to be composed of keywords, terminal rules or other data type rules. + +The following example from the [domain model example](https://github.com/eclipse-langium/langium/blob/main/examples/domainmodel/src/language-server/domain-model.langium) uses the `QualifiedName` data type rule to enable references to other elements using their fully qualified name. +```langium +QualifiedName returns string: + ID ('.' ID)*; +``` +Data type rules need to specify a primitive return type. + +### Rule Fragments +If you are facing repetitive patterns in your grammar definition, you can take advantage of *Rule Fragments* to improve the grammar's maintainability. +```langium +Student: + 'student' firstName=ID lastName=ID address=STRING phoneNumber=STRING grades=Grades; +Teacher: + 'teacher' firstName=ID lastName=ID address=STRING phoneNumber=STRING classes=Classes; +TechnicalStaff: + 'tech' firstName=ID lastName=ID address=STRING phoneNumber=STRING; +``` +The parser rules Student, Teacher, and TechnicalStaff partly share the same syntax. +If, for example, the assignment for `phoneNumber` had to be updated, we would need to make changes everywhere the `phoneNumber` assignment was used. +We can introduce *Rule Fragments* to extract similar patterns and improve maintainability: +```langium +fragment Details: + firstName=ID lastName=ID address=STRING phoneNumber=STRING; + +Student: + 'student' Details grades=Grades; +Teacher: + 'teacher' Details classes=Classes; +TechnicalStaff: + 'tech' Details; +``` + +Fragment rules are not part of the AST and will therefore never create an object, instead they can be understood as being textually inserted where they are referenced. + +### Guard Conditions +It may be useful to group parser rules with small variations inside of a single parser rule. Given the following example: +```langium +entry Model: + element+=RootElement; + +RootElement infers Element: + isPublic?='public'? + 'element' name=ID '{' + elements+=Element* + '}'; + +Element: + 'element' name=ID '{' + elements+=Element* + '}'; +``` +The only difference between `RootElement` and `Element` is that the former has the boolean property `isPublic`. +We can refactor the grammar so that only `Element` is present in the grammar with a *guard condition* that will determine which concrete syntax should be used by the parser: +```langium +entry Model: + element+=Element; + +Element: + ( isPublic?='public')? + 'element' name=ID '{' + elements+=Element* + '}'; +``` +`Element` has the guard `isRoot`, which will determine whether the optional group containing the `isPublic` property is allowed to be parsed. + +The *entry rule* `Model` sets the value of `isRoot` to `true` with `element+=Element`, while `isRoot` is set to `false` inside of the `Element` parser rule with `elements+=Element`. + +In general, a guard condition on a group decides whether the parser is allowed to parse the group or not depending on the result of the evaluated condition. Logical operations can be applied, such as `&` (and), `|` (or) and `!` (not) to fine-tune the exact conditions in which the group is supposed to be parsed. + +Additionally, guard conditions can also be used inside of alternatives. See the following example: +```langium +entry Model: + element+=Element; + +Element: + ( 'root' | 'element') name=ID '{' + elements+=Element* + '}'; +``` + +The parser will always exclude alternatives whose guard conditions evaluate to `false`. All other alternatives remain possible options for the parser to choose from. + + +### More Examples + +Not all parser rules need to be mentioned in the entry rule, as shown in this example: +```langium +entry Model: + (persons+=Person | greetings+=Greeting)*; + +Person: + 'person' name=ID address=Address; + +Greeting: + 'Hello' person=[Person] '!'; + +Address: + street=STRING city=ID postcode=INT; +``` +Here the `Person` parser rule includes a property `address` which matches the parser rule `Address`. We decided that an `Address` will never be present in the input document on its own and will always be parsed in relation to a `Person`. It is therefore not necessary to include an array of `Address` inside of the entry rule. + +--- + +Keywords are meant to provide a visible structure to the language and guide the parser in deciding what type of object needs to be parsed. +Consider the following: +```langium +Student: + name=ID; + +Teacher: + name=ID; + +Person: + Student | Teacher; +``` +In this example, a `Person` can either be a `Student` or a `Teacher`. This grammar is ambiguous because the parser rules `Student` and `Teacher` are identical. The parser will not be able to differentiate between the parser rules for `Student` and `Teacher` when trying to parse a `Person`. +Keywords can help removing such ambiguity and guide the parser in defining if a `Student` or `Teacher` needs to be parsed. +We can add a keyword to the parser rule `Student`, `Teacher`, or to both of them: +```langium +Student: + 'student' name=ID; + +Teacher: + 'teacher' name=ID; + +Person: + Student | Teacher; +``` +Now the ambiguity is resolved and the parser is able to differentiate between the two parser rules. + +Parser rules can have many keywords: +```langium +Person: + 'person' name=ID 'age' age=INT; +``` + +--- + +If an assignment has a cardinality of `+` or `*`, then the expressions belong to a single group and must not be interrupted by other expressions. +```langium +Paragraph: + 'paragraph' (sentences+=STRING)+ id=INT; +``` +Here, the property `sentences` will accept one or many expressions matching the terminal rule `STRING` followed by an `INT`. The parsing of a document containing: +``` +paragraph "The expression group " 3 "was interrupted" +``` +will throw an error since the `STRING` expressions are not continuous. It is however possible to interrupt and resume a sequence of expressions by using [hidden terminal symbols](#hidden-terminal-rules): +``` +paragraph "expression one" /* comment */ "expression two" 3 +``` +The above example will be successfully parsed. + +## More on Terminal Rules + +### Extended Backus-Naur Form Terminals + +*For full disclosure, we recommend using regular expressions when writing your terminals, as EBNF expressions are translated to regular expressions internally anyway. EBNF support is primarily intended for supporting grammars that were originally written in Xtext, but are being ported to Langium.* + +As mentioned earlier, terminal rules can be described using *regular expressions* or *EBNF expressions*. + +EBNF expressions are very similar to [parser rules](#extended-backus-naur-form-expressions), which are described above. In this section, we describe which EBNF expressions are supported for terminals and their equivalent in *Javascript Regular Expressions* where possible. + +#### Terminal Groups +Tokens can be put in sequence specifying the order they have to appear: +```langium +terminal FLIGHT_NUMBER: ('A'..'Z')('A'..'Z')('0'..'9')('0'..'9')('0'..'9')('0'...'9')?; +``` +In this example, the token `FLIGHT_NUMBER` must start with two capital letters followed by three or four digits. + +#### Terminal Alternatives +It is possible to match one of multiple valid options by using the pipe operator `|`. The terminal rule `STRING` can use alternatives to match a sequence of characters between double quotes `""` or single quotes `''`: +```langium +terminal STRING: '"' !('"')* '"' | ''' !(''')* '''; +``` +In regular expression, alternatives are also possible with the pipe operator `|`: +```langium +terminal STRING: /"[^"]*"|'[^']*'/; +``` + +#### Character Range +The operator `..` is used to declare a character range. It is equivalent to the operator `-` within a character class in a regular expression. It matches any character in between the left character and the right character (inclusive on both ends). +```langium +terminal INT returns number: ('0'..'9')+; +``` +is equivalent to the regular expression: +```langium +terminal INT returns number: /[0-9]+/; +``` +Here, `INT` is matched to one or more characters (by using the operand `+`, which defines a [cardinality](#cardinalities) of 'one or many') between `0` and `9` (inclusive on both ends). + +#### Wildcard Token +The operator `.` is used to match any character and is similar in regular expression. +```langium +terminal HASHTAG: '#'.+; +``` +In this example, the terminal rule `HASHTAG` matches a sequence of character starting with `#` followed by one or many ([cardinality](#cardinalities) +) characters. + +Equivalent in regular expression: +```langium +terminal HASHTAG: /#.+/; +``` +#### Until Token +The operator `->` indicates that all characters should be consumed from the left token *until* the right token occurs. For example, the terminal rule for multi-line comment can be implemented as: +```langium +terminal ML_COMMENT: '/*' -> '*/'; +``` +Langium will transform the until token into the regular expression `[\s\S]*?` which matches any character non-greedily: +```langium +terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; +``` + +#### Negated Token +It is possible to negate tokens using the operator `!`. In Langium this produces a *negative lookahead*. I.e., it does *not* consume tokens, but it is a 'guard' for what the following expression can recognize. + +For example, if you want to recognize a word that doesn't start with `no`, then you could write such an expression in EBNF like so: +```langium +terminal NONO: (!'no')('a'..'z'|'A'..'Z')+; +``` + +For reference, this would correspond to the following regular expression: +```langium +terminal NONO: /(?!no)[a-zA-Z]+/; +``` + +Note, if you're coming from Xtext, negated tokens works differently here. In Xtext, negated tokens allow recognizing the *complement* of a set of characters (or anything 'but' what is listed in the negation), very much akin to a negated character class in regular expressions. This is *very* important to keep in mind if you're porting a grammar from Xtext, as Langium's interpretation of negated tokens deviates from that of Xtext. + +#### Terminal Rule Calls +A terminal rule can include other terminal rules in its definition. +```langium +terminal DOUBLE returns number: INT '.' INT; +``` +Note that it is easy to create conflicts between terminal rules when using *terminal rule calls*. See [Data Type Rules](#data-type-rules) for further details. + +### Terminal Fragments +Fragments allow for sub-definition of terminal rules to be extracted. They are not consumed by the lexer and have to be consumed by other terminal rules. +```langium +terminal fragment CAPITAL_LETTER: ('A'..'Z'); +terminal fragment SMALL_LETTER: ('a'..'z'); +terminal NAME: CAPITAL_LETTER SMALL_LETTER+; +``` +In this example, the lexer will not transform a single capital or small letter into a valid token but will match a sequence of one capital letter followed by one or many small letters. diff --git a/hugo/content/docs/reference/sematic-model.md b/hugo/content/docs/reference/sematic-model.md new file mode 100644 index 00000000..de480119 --- /dev/null +++ b/hugo/content/docs/reference/sematic-model.md @@ -0,0 +1,409 @@ +--- +title: "Semantic Model Inference" +weight: 200 +--- + +When AST nodes are created during the parsing of a document, they are given a type. The language grammar dictates the shape of those types and how they might be related to each other. All types form the *semantic model* of your language. There are two ways by which Langium derives semantic model types from the grammar, by **[inference](#inferred-types)** and by **[declaration](#declared-types)**. + +*Inference* is the default behavior in Langium. During the generation of the semantic model types, Langium infers the possible types directly from the grammar rules. While this is a powerful approach for simple languages and prototypes, it is not recommended for more mature languages since minimal changes in the grammar can easily lead to breaking changes. + +To minimize the chance of breaking changes, Langium introduces *declared types* where the semantic model types are explicitly defined by the user in the grammar via a *TypeScript-like* syntax. + +In the following, we detail how grammar rules shape the semantic model via inference and declaration. + +## Inferred Types +*Inferred types* result from letting Langium infer the types of the nodes from the grammar rules. Let's have a look at how various rules shape these type definitions: + +### Parser Rules +The simplest way to write a parser rule is as follows: +```langium +X: name=ID; +``` +With this syntax, Langium will **infer** the type of the node to be generated when parsing the rule. By convention, the type of the node will be named after the name of the rule, resulting in this **TypeScript interface** in the semantic model: +```langium +interface X extends AstNode { + name: string +} +``` +It is also possible to control the naming of the interface by using the following syntax: +```langium +X infers MyType: name=ID; +``` +resulting in the following interface in the semantic model: +```langium +interface MyType extends AstNode { + name: string +} +``` +Please note that an `interface X` is no longer present in the semantic model. + +It is important to understand that the name of the parser rule and the name of the type it infers work on two separate abstraction levels. The name of the parser rule is used at the *parsing level* where types are ignored and only the parsing rule is considered, while the name of the type is used at the *types level* where both the type and the parser rule play a role. This means that the name of the type can be changed without affecting the parsing rules hierarchy, and that the name of the rule can be changed - if it explicitly infers or returns a given type - without affecting the semantic model. + +By inferring types within the grammar, it is also possible to define several parser rules creating the same semantic model type. For example, the following grammar has two rules `X` and `Y` inferring a single semantic model type `MyType`: +```langium +X infers MyType: name=ID; +Y infers MyType: name=ID count=INT; +``` +This result in the creation of a single interface in the semantic model 'merging' the two parser rules with non-common properties made optional: +```langium +interface MyType extends AstNode { + count?: number + name: string +} +``` + +### Terminal Rules +Terminal rules are linked to built-in types in the semantic model. They do not result in semantic model types on their own but determine the type of properties in semantic model types inferred from a parser rule: +```langium +terminal INT returns number: /[0-9]+/; +terminal ID returns string: /[a-zA-Z_][a-zA-Z0-9_]*/; + +X: name=ID count=INT; +``` + +```langium +// generated interface +interface X extends AstNode { + name: string + count: number +} +``` + +The property `name` is of type `string` because the terminal rule `ID` is linked to the built-in type `string`, and the property `count` is of type `number` because the terminal rule `INT` is linked to the built-in type `number`. + +### Data type rules +Data type rules are similar to terminal rules in the sense that they determine the type of properties in semantic model types inferred from parser rules. However, they lead to the creation of type aliases for built-in types in the semantic model: +```langium +QualifiedName returns string: ID '.' ID; + +X: name=QualifiedName; +``` + +```langium +// generated types +type QualifiedName = string; + +interface X extends AstNode { + name: string +} +``` + +### Assignments +There are three available kinds of [assignments](../grammar-language/#assignments) in a parser rule: + +1. `=` for assigning a **single value** to a property, resulting in the property's type to be derived from the right hand side of the assignment. +2. `+=` for assigning **multiple values** to a property, resulting in the property's type to be an array of the right hand side of the assignment. +3. `?=` for assigning a **boolean** to a property, resulting in the property's type to be a `boolean`. + +```langium +X: name=ID numbers+=INT (numbers+=INT)* isValid?='valid'?; +``` + +```langium +// generated interface +interface X extends AstNode { + name: string + numbers: Array + isValid: boolean +} +``` + +The right-hand side of an assignment can be any of the following: +* A terminal rule or a data type rule, which results in the type of the property to be a built-in type. +* A parser rule, which results in the type of the property to be the type of the parser rule. +* A cross-reference, which results in the type of the property to be a *Reference* to the type of the cross-reference. +* An alternative, which results in the type of the property to be a type union of all the types in the alternative. + +```langium +X: 'x' name=ID; + +Y: crossValue=[X:ID] alt=(INT | X | [X:ID]); +``` + +```langium +// generated types +interface X extends AstNode { + name: string +} + +interface Y extends AstNode { + crossValue: Reference + alt: number | X | Reference +} +``` + +### Unassigned Rule Calls + +A parser rule does not necessarily need to have assignments. It may also contain only *unassigned rule calls*. These kind of rules can be used to change the types' hierarchy. + +```langium +X: A | B; + +A: 'A' name=ID; +B: 'B' name=ID count=INT; +``` + +```langium +// generated types +type X = A | B; + +interface A extends AstNode { + name: string +} + +interface B extends AstNode { + name: string + count: number +} +``` + +### Simple Actions + +Actions can be used to change the type of a node **inside** of a parser rule to another semantic model type. For example, they allow you to simplify parser rules which would have to be split into multiple rules. + +```langium +X: + {infer A} 'A' name=ID + | {infer B} 'B' name=ID count=INT; + +// is equivalent to: +X: A | B; +A: 'A' name=ID; +B: 'B' name=ID count=INT; +``` + +```langium +// generated types +type X = A | B; + +interface A extends AstNode { + name: string +} + +interface B extends AstNode { + name: string + count: number +} +``` + +### Assigned actions + +Actions can also be used to control the structure of the semantic model types. This is a more advanced topic, so we recommend getting familiar with the rest of the documentation before diving into this section. + +Let's consider two different grammars derived from the [Arithmetics example](https://github.com/eclipse-langium/langium/blob/main/examples/arithmetics/src/language-server/arithmetics.langium). These grammars are designed to parse a document containing a single definition comprised of a name and an expression assignment, with an expression being any amount of additions or a numerical value. + +The first one does not use assigned actions: + +```langium +Definition: + 'def' name=ID ':' expr=Expression; +Expression: + Addition; +Addition infers Expression: + left=Value ('+' right=Expression)?; + +Primary infers Expression: + '(' Expression ')' | {Literal} value=NUMBER; +``` + +When parsing a document containing `def x: (1 + 2) + 3`, this is the shape of the semantic model node: + +{{}} +graph TD; +expr((expr)) --> left((left)) +expr --> right((right)) +left --> left_left((left)) +left --> left_right((right)) +right --> right_left((left)) +left_left --> left_left_v{1} +left_right --> left_right_{2} +right_left --> right_left_v{3} +{{}} + +We can see that the nested `right -> left` nodes in the tree are unnecessary and we would like to remove one level of nesting from the tree. + +This can be done by refactoring the grammar and adding an assigned action: + +```langium +Definition: + 'def' name=ID ':' expr=Addition ';'; +Expression: + Addition; +Addition infers Expression: + Primary ({infer Addition.left=current} '+' right=Primary)*; + +Primary infers Expression: + '(' Expression ')' | {Literal} value=NUMBER; +``` + +Parsing the same document now leads to this semantic model: + +{{}} +graph TD; +expr((expr)) --> left((left)) +expr --> right((right)) +left --> left_left((left)) +left --> left_right((right)) +right --> right_v{3} +left_left --> left_left_v{1} +left_right --> left_right_{2} +{{}} + +While this is a fairly trivial example, adding more layers of expression types in your grammar massively degrades the quality of your syntax tree as each layer will add another empty `right` property to the tree. Assigned actions alleviate this issue completely. + +## Declared Types + +Because type inference takes into account every entity of a parser rule, even the smallest changes can update your inferred types. This can lead to unwanted changes in your semantic model and incorrect behavior of services that depend on it. *Declared types* are a means to minimize the risk of introducing breaking changes when modifying the grammar. + +In most cases, especially for early language designs, letting the type inference take care of generating your types will be your best choice. As your language starts to mature, it may then be of interest to fix parts of your semantic model using declared types. + +With that aside, declared types can be *especially* helpful for more mature and complex languages, where a stable semantic model is key and breaking changes introduced by inferred types can break your language services. Declared types allow the user to **fix** the type of their parser rules and rely on the power of validation errors to detect breaking changes. + + + +Let's look at the example from the previous section: + +```langium +X infers MyType: name=ID; +Y infers MyType: name=ID count=INT; + +// should be replaced by: +interface MyType { + name: string + count?: number +} + +X returns MyType: name=ID; +Y returns MyType: name=ID count=INT; +``` + +We now explicitly declare `MyType` directly in the grammar with the keyword `interface`. The parser rules `X` and `Y` creating nodes of type `MyType` need to explicitly declare the type of the node they create with the keyword `returns`. + +Contrary to [inferred types](#inferred-types), all properties must be explicitly declared in order to be valid inside of a parser rule. The following syntax: + +```langium +Z returns MyType: name=ID age=INT; +``` + +will show the following validation error `A property 'age' is not expected` because the declaration of `MyType` does not include the property `age`. In short, *declared types* add a layer of safety via validation to the grammar that prevents mismatches between the expected semantic model types and the shape of the parsed nodes. + +A declared type can also extend types, such as other declared types or types inferred from parser rules: + +```langium +interface MyType { + name: string +} + +interface MyOtherType extends MyType { + count: number +} + +Y returns MyOtherType: name=ID count=INT; +``` + +Explicitly declaring union types in the grammar is achieved with the keyword `type`: + +```langium +type X = A | B; +``` + +```langium +// generates: +type X = A | B; +``` + + + +Using `returns` always expects a reference to an already existing type. To create a new type for your rule, use the `infers` keyword or explicitly declare an interface. + +### Cross-references, Arrays, and Alternatives + +Declared types come with special syntax to declare cross-references, arrays, and alternatives: + +```langium +interface A { + reference: @B + array: B[] + alternative: B | C +} + +interface B { + name: string +} + +interface C { + name: string + count: number +} + +X returns A: reference=[B:ID] array+=Y (array+=Y)* alternative=(Y | Z); + +Y returns B: 'Y' name=ID; + +Z returns C: 'Z' name=ID count=INT; +``` + +### Actions + +Actions referring to a declared type have the following syntax: + +```langium +interface A { + name: string +} + +interface B { + name: string + count: number +} + +X: + {A} 'A' name=ID + | {B} 'B' name=ID count=INT; +``` + +Note the absence of the keyword `infer` compared to [actions which infer a type](#simple-actions). + +## Reference Unions + +Trying to reference different types of elements can be an error prone process. Take a look at the following rule which tries to reference either a `Function` or a `Variable`: + +```langium +MemberCall: (element=[Function:ID] | element=[Variable:ID]); +``` + +As both alternatives are only an `ID` from a parser perspective, this grammar is not decidable and the `langium` CLI script will throw an error during generation. Luckily, we can improve on this by adding a layer of indirection using an additional parser rule: + +```langium +NamedElement: Function | Variable; + +MemberCall: element=[NamedElement:ID]; +``` + +This allows us to reference either `Function` or `Variable` using the common rule `NamedElement`. However, we have now introduced a rule which is never actually parsed, but only exists for the purpose of the type system to pick up on the correct target types of the reference. Using declared types, we are able to refactor this unused rule, making our grammar more resilient in the process: + +```langium +// Note the `type` prefix here +type NamedElement = Function | Variable; + +MemberCall: element=[NamedElement:ID]; +``` + +We can also use interfaces in place of union types with similar results: + +```langium +interface NamedElement { + name: string +} + +// Infers an interface `Function` that extends `NamedElement` +Function returns NamedElement: {infer Function} "function" name=ID ...; + +// This also picks up on the `Function` elements +MemberCall: element=[NamedElement:ID]; +``` From edcec73a0d932f5aa841ba33ba8e97e1a82f652d Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Fri, 5 Apr 2024 17:01:16 +0200 Subject: [PATCH 07/19] Quick save --- hugo/content/docs/learn/_index.md | 2 +- hugo/content/docs/learn/workflow/generate_everything.md | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/hugo/content/docs/learn/_index.md b/hugo/content/docs/learn/_index.md index 77cb5f19..e8707ba3 100644 --- a/hugo/content/docs/learn/_index.md +++ b/hugo/content/docs/learn/_index.md @@ -3,4 +3,4 @@ title: "Learn Langium" weight: 0 url: /docs/learn --- -TODO \ No newline at end of file + diff --git a/hugo/content/docs/learn/workflow/generate_everything.md b/hugo/content/docs/learn/workflow/generate_everything.md index f3928c3e..cc5040e0 100644 --- a/hugo/content/docs/learn/workflow/generate_everything.md +++ b/hugo/content/docs/learn/workflow/generate_everything.md @@ -3,4 +3,8 @@ title: "Generate your artifacts" weight: 800 url: /docs/learn/workflow/generate_everything --- -TODO +The syntax was ensured. The semantics were checked. Your workspace is free of errors. Now the AST is a valid representation of your input file written in your language. It is time to generate some cool stuff! + +Depending on your domain and on your requirements there are different ways to generate artifacts from your AST. + +- TODO when code make a source map From 40f209cca0c7c2975ca16647a59eb8776a02f586 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Thu, 11 Apr 2024 15:44:09 +0200 Subject: [PATCH 08/19] Collapse menu for better overview --- hugo/config.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hugo/config.toml b/hugo/config.toml index b54db004..b49c87f1 100644 --- a/hugo/config.toml +++ b/hugo/config.toml @@ -80,4 +80,7 @@ enableRobotsTXT = true # (Optional, default 'title') Configure how to sort file-tree menu entries. Possible options are 'title', 'linktitle', # 'date', 'publishdate', 'expirydate' or 'lastmod'. Every option can be used with a reverse modifier as well # e.g. 'title_reverse'. - #geekdocFileTreeSortBy = "title" \ No newline at end of file + #geekdocFileTreeSortBy = "title" + + geekdocCollapseSection = true + geekdocCollapseAllSections = true \ No newline at end of file From 06e7ffad90b503988a4fabe77390bc4a5c2765d8 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Thu, 11 Apr 2024 16:42:13 +0200 Subject: [PATCH 09/19] Expand on code generation --- .../learn/workflow/generate_everything.md | 45 ++++++++++++++++++- .../workflow/resolve_cross_references.md | 4 +- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/hugo/content/docs/learn/workflow/generate_everything.md b/hugo/content/docs/learn/workflow/generate_everything.md index cc5040e0..349c88e6 100644 --- a/hugo/content/docs/learn/workflow/generate_everything.md +++ b/hugo/content/docs/learn/workflow/generate_everything.md @@ -7,4 +7,47 @@ The syntax was ensured. The semantics were checked. Your workspace is free of er Depending on your domain and on your requirements there are different ways to generate artifacts from your AST. -- TODO when code make a source map +## How to write the generator? + +The simplest way is to generate text into a string. Let's print out every greeting from the `hello-world` example. + +```typescript +import type { Model } from '../language/generated/ast.js'; + +export function generateJavaScript(model: Model): string { + return `"use strict"; +${model.greetings + .map(greeting => `console.log('Hello, ${greeting.person.ref?.name}!');`) + .join("\n") +}`; +} +``` + +## How to test the generator? + +You can test the generator by comparing the generated text with the expected text. Here is an example. + +```typescript +import { EmptyFileSystem } from "langium"; +import { parseHelper } from "langium/test"; +import { createHelloWorldServices } from "./your-project/hello-world-module.js"; +import { Model } from "./your-project/generated/ast.js"; +import { generateJavaScript } from "./your-project/generator.js"; + +const services = createHelloWorldServices(EmptyFileSystem); +const parse = parseHelper(services.HelloWorld); +const document = await parse(` + person Langium + Hello Langium! +`, {validation: true}); + +expect(document.parseResult.lexerErrors).toHaveLength(0); +expect(document.parseResult.parserErrors).toHaveLength(0); +expect(document.diagnostics ?? []).toHaveLength(0); + +const javaScript = generateJavaScript(document.parseResult.value); +expect(javaScript).toBe(`"use strict"; +console.log('Hello, Langium!');`); +``` + +The `expect` function can be any assertion library you like. The `Hello world` example uses Vitest. diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index 9b192edf..8519bbce 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -45,7 +45,7 @@ graph TB greetings-->G2[Greeting] G2 --> KW2('hello') G2 --> PRef2[Ref] - PRef2 -- $refText --> RT2('John') + PRef2 -- $refText --> RT2('Jane') G2 --> EM2('!') PRef2 --> QM2{?} {{}} @@ -77,7 +77,7 @@ graph TB greetings-->G2[Greeting] G2 --> KW2('hello') G2 --> PRef2[Ref] - PRef2 -- $refText --> RT2('John') + PRef2 -- $refText --> RT2('Jane') G2 --> EM2('!') PRef2 -..-> P2 {{}} From 796f72723101a779110f5e4d7d5e7d5f79e5d514 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Thu, 11 Apr 2024 16:57:17 +0200 Subject: [PATCH 10/19] Remove old documentation --- hugo/content/docs/_index.md | 2 +- hugo/content/old/_index.md | 4 - hugo/content/old/docs/_index.md | 12 - .../old/docs/configuration-services.md | 221 ------- hugo/content/old/docs/document-lifecycle.md | 133 ---- hugo/content/old/docs/getting-started.md | 122 ---- hugo/content/old/docs/grammar-language.md | 518 --------------- hugo/content/old/docs/langium-overview.md | 103 --- hugo/content/old/docs/sematic-model.md | 409 ------------ hugo/content/old/guides/_index.md | 8 - hugo/content/old/guides/builtin-library.md | 164 ----- hugo/content/old/guides/code-bundling.md | 119 ---- hugo/content/old/guides/formatting.md | 112 ---- hugo/content/old/guides/multiple-languages.md | 447 ------------- hugo/content/old/guides/scoping/_index.md | 31 - .../old/guides/scoping/class-member.md | 148 ----- .../old/guides/scoping/qualified-name.md | 238 ------- hugo/content/old/tutorials/_index.md | 22 - .../tutorials/building_an_extension/icon.png | Bin 163818 -> 0 bytes .../tutorials/building_an_extension/index.md | 90 --- .../installed-extension.jpg | Bin 119541 -> 0 bytes .../building_an_extension/minilogo-vsix.jpg | Bin 33381 -> 0 bytes .../minilogo-with-icon.png | Bin 121740 -> 0 bytes .../building_an_extension/vsix-install.jpg | Bin 114994 -> 0 bytes .../building_an_extension/vsix-installed.jpg | Bin 23871 -> 0 bytes hugo/content/old/tutorials/customizing_cli.md | 151 ----- hugo/content/old/tutorials/generation.md | 378 ----------- .../old/tutorials/generation_in_the_web.md | 331 ---------- .../old/tutorials/langium_and_monaco.md | 619 ------------------ hugo/content/old/tutorials/validation.md | 153 ----- .../old/tutorials/writing_a_grammar.md | 312 --------- 31 files changed, 1 insertion(+), 4846 deletions(-) delete mode 100644 hugo/content/old/_index.md delete mode 100644 hugo/content/old/docs/_index.md delete mode 100644 hugo/content/old/docs/configuration-services.md delete mode 100644 hugo/content/old/docs/document-lifecycle.md delete mode 100644 hugo/content/old/docs/getting-started.md delete mode 100644 hugo/content/old/docs/grammar-language.md delete mode 100644 hugo/content/old/docs/langium-overview.md delete mode 100644 hugo/content/old/docs/sematic-model.md delete mode 100644 hugo/content/old/guides/_index.md delete mode 100644 hugo/content/old/guides/builtin-library.md delete mode 100644 hugo/content/old/guides/code-bundling.md delete mode 100644 hugo/content/old/guides/formatting.md delete mode 100644 hugo/content/old/guides/multiple-languages.md delete mode 100644 hugo/content/old/guides/scoping/_index.md delete mode 100644 hugo/content/old/guides/scoping/class-member.md delete mode 100644 hugo/content/old/guides/scoping/qualified-name.md delete mode 100644 hugo/content/old/tutorials/_index.md delete mode 100644 hugo/content/old/tutorials/building_an_extension/icon.png delete mode 100644 hugo/content/old/tutorials/building_an_extension/index.md delete mode 100644 hugo/content/old/tutorials/building_an_extension/installed-extension.jpg delete mode 100644 hugo/content/old/tutorials/building_an_extension/minilogo-vsix.jpg delete mode 100644 hugo/content/old/tutorials/building_an_extension/minilogo-with-icon.png delete mode 100644 hugo/content/old/tutorials/building_an_extension/vsix-install.jpg delete mode 100644 hugo/content/old/tutorials/building_an_extension/vsix-installed.jpg delete mode 100644 hugo/content/old/tutorials/customizing_cli.md delete mode 100644 hugo/content/old/tutorials/generation.md delete mode 100644 hugo/content/old/tutorials/generation_in_the_web.md delete mode 100644 hugo/content/old/tutorials/langium_and_monaco.md delete mode 100644 hugo/content/old/tutorials/validation.md delete mode 100644 hugo/content/old/tutorials/writing_a_grammar.md diff --git a/hugo/content/docs/_index.md b/hugo/content/docs/_index.md index 42656038..21039921 100644 --- a/hugo/content/docs/_index.md +++ b/hugo/content/docs/_index.md @@ -1,4 +1,4 @@ --- -title: "New documentation" +title: "Documentation" weight: 0 --- \ No newline at end of file diff --git a/hugo/content/old/_index.md b/hugo/content/old/_index.md deleted file mode 100644 index 9b2501dc..00000000 --- a/hugo/content/old/_index.md +++ /dev/null @@ -1,4 +0,0 @@ ---- -title: "Old documentation" -weight: 100 ---- diff --git a/hugo/content/old/docs/_index.md b/hugo/content/old/docs/_index.md deleted file mode 100644 index 9ab17e51..00000000 --- a/hugo/content/old/docs/_index.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -title: "Documentation" -weight: 100 ---- - -Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. - -This reference documentation provides [an overview](/docs/langium-overview), a [getting started guide](/docs/getting-started) and a deep dive into several aspects of Langium. Additional topics are covered in [the Guides section](/guides/) and step-by-step walkthroughs are available in [the tutorials section](/tutorials/). - -## Want to contribute? - -Visit the [Langium repository](https://github.com/eclipse-langium/langium) to take part in improving Langium. diff --git a/hugo/content/old/docs/configuration-services.md b/hugo/content/old/docs/configuration-services.md deleted file mode 100644 index 8dbad125..00000000 --- a/hugo/content/old/docs/configuration-services.md +++ /dev/null @@ -1,221 +0,0 @@ ---- -title: "Configuration via Services" -weight: 300 ---- - -Langium supports the configuration of most aspects of your language and language server via a set of *services*. Those services are configured by *modules*, which are essentially mappings from a service name to its implementation. - -We can separate services and modules into two main categories: - -#### Shared Services -The *shared services* are services that are shared across all Langium languages. In many applications there is only one Langium language, but the overall structure of the services is the same. -* The `ServiceRegistry` is responsible for registering and accessing the different languages and their services. -* The `Connection` service is used in a language server context; it sends messages to the client and registers message handlers for incoming messages. -* The `AstReflection` service provides access the structure of the AST types. -* Shared services involved in the document lifecycle (future documentation) - -#### Language Specific Services -The *language specific services* are services specific to one Langium language and isolated from other languages. -* Services for [LSP features](#language-server-protocol) -* Services involved in the document lifecycle (future documentation) -* Utility services (e.g. `References`, `JsonSerializer`) - -## Customization -If you have used the [Yeoman generator](https://www.npmjs.com/package/generator-langium), the entry point to services customization is found in the `src/language/...-module.ts` file, where '...' is the name of your language. There you can register new services or override the default implementations of services. Langium implements the *Inversion of Control* principle via the *Dependency Injection* pattern, which promotes loosely-coupled architectures, maintainability, and extensibility. - -For the following sections, we will use the [arithmetics example](https://github.com/eclipse-langium/langium/tree/main/examples/arithmetics) to describe the procedure for replacing or adding services. Note that all names prefixed with *Arithmetics* should be understood as being specific to the language named *Arithmetics*, and in your project those services' names will be prefixed with your own language name. - -Please note that it is *not mandatory* to implement all custom code via dependency injection. The main reason for using dependency injection is when your custom code *depends* on other services. In many cases you can use plain functions instead of service classes to implement your application logic. - -### Overriding and Extending Services -Thanks to the dependency injection pattern used in Langium, your can change the behavior of a service or add to its functionality in one place without having to modify every piece of code that depends on the service to be overridden or extended. - -The [arithmetics example](https://github.com/eclipse-langium/langium/tree/main/examples/arithmetics) provides a custom implementation of the `ScopeProvider` service, which overrides functionalities from the default implementation `DefaultScopeProvider`. - -First, we need to register the new implementation of `ScopeProvider` inside of the `ArithmeticsModule`: - -```Typescript -export const ArithmeticsModule: Module = { - references: { - ScopeProvider: (services) => new ArithmeticsScopeProvider(services) - } -}; -``` -In the `ArithmeticsModule` singleton instance, we map a property with the name of our service (here `ScopeProvider`) to a concrete implementation of the service. This means that the first time we access the service named `ScopeProvider`, a new instance of the class `ArithmeticsScopeProvider` will be created instead of the default implementation `DefaultScopeProvider`. The provided factory function is invoked only once, which means that all services are handled as singletons. - -In order to successfully override an existing service, the property name (here `ScopeProvider`) must match exactly that of the default implementation. - -The `ArithmeticsScopeProvider` overrides two methods from `DefaultScopeProvider`: -```TypeScript -export class ArithmeticsScopeProvider extends DefaultScopeProvider { - - protected createScope(elements: Stream, outerScope: Scope): Scope { - return new StreamScope(elements, outerScope, { caseInsensitive: true }); - } - - protected getGlobalScope(referenceType: string): Scope { - return new StreamScope(this.indexManager.allElements(referenceType), undefined, { caseInsensitive: true }); - } - -} -``` -The functions `createScope` and `getGlobalScope` are already defined in `DefaultScopeProvider` but needed to be overridden to add the option `{caseInsensitive: true}`. This is achieved through inheritance: By using the keyword `extends`, `ArithmeticsScopeProvider` inherits from `DefaultScopeProvider`, which means that it can access properties and methods as well as override methods declared in the superclass. - -In the `DefaultScopeProvider`, those two methods are declared as: -```Typescript -protected createScope(elements: Stream, outerScope: Scope): Scope { - return new StreamScope(elements, outerScope); -} - -protected getGlobalScope(referenceType: string): Scope { - return new StreamScope(this.indexManager.allElements(referenceType)); -} -``` - -Now, when we call either `createScope` or `getGlobalScope` from the `ScopeProvider` service, the call will be made from the `ArithmeticsScopeProvider` instead of the `DefaultScopeProvider`. Functions that were not overridden will still be called from `DefaultScopeProvider` via inheritance. - -Of course it is also possible to replace the default implementation with a completely separate one that does not inherit from the default service class. - -### Adding New Services -To add services that are not available by default in Langium, e.g. application specific ones, we first need to edit the type `ArithmeticsAddedService`. -By default, the Yeoman-based generator adds a validator service where you can implement validation rules specific to your language. New services are added as properties to the type declaration: -```Typescript -export type ArithmeticsAddedServices = { - ArithmeticsValidator: ArithmeticsValidator -} -``` -The `ArithmeticsAddedService` type now has a property `ArithmeticsValidator` of type `ArithmeticsValidator`. - -For the sake of organization and clarity, the services can be nested inside of other properties acting as "groups": -```Typescript -export type ArithmeticsAddedServices = { - validation: { - ArithmeticsValidator: ArithmeticsValidator - }, - secondGroup: { - AnotherServiceName: AnotherServiceType - }, - nthGroup: { - withASubGroup: { - YetAnotherServiceName: YetAnotherServiceType - } - } -} -``` - -Now that we have declared our new services inside of the `ArithmeticsAddedServices` type definition, we need to specify to the module how we want them to be implemented. To do so, we need to update the `ArithmeticsModule`: -```Typescript -export const ArithmeticsModule: Module = { - validation: { - ArithmeticsValidator: () => new ArithmeticsValidator() - } -}; -``` -Similarly to [overridden services](#overriding-and-extending-services), the first access to the `ArithmeticsValidator` property will create a new instance of the class `ArithmeticsValidator`. - -The `ArithmeticsValidator` service does not depend on other services, and no argument is passed during the instantiation of the class. If you implement a service that depends on other services, the constructor of your service should expect `Services` as argument. The initializer function can expect that object as argument and pass it to your services constructor, such as: -```Typescript -export const ArithmeticsModule: Module = { - ServiceWithDependencies = (services) => new ServiceClass(services); -} -``` -The services which `ServiceClass` depends on need to be registered in the constructor: -```Typescript -export class ServiceClass { - private readonly serviceOne: ServiceOne; - private readonly serviceTwo: ServiceTwo; - private readonly serviceN: ServiceN; - - constructor(services: ArithmeticsServices) { - this.serviceOne = services.ServiceOne; - this.serviceTwo = services.Group.ServiceTwo; - this.serviceN = services.Group.SubGroup.ServiceN; - } - /* service logic */ -} -``` - -#### Resolving cyclic dependencies - -In case one of the services the `ServiceClass` above depends on, also has a dependency back to the `ServiceClass`, your module will throw an error similar to this: `Cycle detected. Please make "ServiceClass" lazy.` Ideally, such cyclic dependencies between services should be avoided. Sometimes, cycles are unavoidable though. In order to make them lazy, assign a lambda function that returns the service in the constructor. You can then invoke this function in your service logic to get access to the depending service: -```Typescript -export class ServiceClass { - private readonly serviceOne: () => ServiceOne; - - constructor(services: ArithmeticsServices) { - this.serviceOne = () => services.ServiceOne; // <-- lazy evaluated service - } - /* service logic */ - method() { - this.serviceOne().methodOne(); - } -} -``` - -#### Using ArithmeticsValidator in other services -The `ArithmeticsValidator` needs to be registered inside of the `ValidationRegistry`. This done by [overriding](#overriding-and-extending-services) `ValidationRegistry` with `ArithmeticsValidationRegistry`. - -Briefly, `ArithmeticsValidator` implements two checks, `checkDivByZero` and `checkNormalisable`: -```Typescript -export class ArithmeticsValidator { - checkDivByZero(binExpr: BinaryExpression, accept: ValidationAcceptor): void { - ... - } - - checkNormalisable(def: Definition, accept: ValidationAcceptor): void { - ... - } -} -``` -These two new checks need to be registered inside of the `ValidationRegistry`. We extend `ValidationRegistry` with `ArithmeticsValidationRegistry` to implement our new functionalities: -```Typescript -export class ArithmeticsValidationRegistry extends ValidationRegistry { - constructor(services: ArithmeticsServices) { - super(services); - const validator = services.validation.ArithmeticsValidator; - const checks: ArithmeticsChecks = { - BinaryExpression: validator.checkDivByZero, - Definition: validator.checkNormalisable - }; - this.register(checks, validator); - } -} -``` -Inside of the `ArithmeticsValidationRegistry`, we obtain our `ArithmeticsValidator` with `const validator = services.validation.ArithmeticsValidator`, which will create a new instance of `ArithmeticsValidator`. Then we declare the `checks` to be registered and register them inside of the registry via the function `register` which is declared in the superclass. The `ArithmeticsValidationRegistry` only adds validation checks to the `ValidationRegistry`, but does not override any functionality from it. - -The implementation of `ArithmeticsValidationRegistry` needs to be registered in `ArithmeticsModule`. The complete `ArithmeticsModule` is: -```Typescript -export const ArithmeticsModule: Module = { - references: { - ScopeProvider: (services) => new ArithmeticsScopeProvider(services) - }, - validation: { - ValidationRegistry: (services) => new ArithmeticsValidationRegistry(services), - ArithmeticsValidator: () => new ArithmeticsValidator() - } -}; -``` - -## Language Server Protocol -If you want to modify aspects of the Language Server, this section will help you find the relevant service for handling a given LSP request. - -#### CompletionProvider -The `CompletionProvider` service is responsible for handling a [Completion Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_completion) at a given cursor position. When a *Completion Request* is submitted by the client to the server, the `CompletionProvider` will create a `CompletionList` of all possible `CompletionItem` to be presented in the editor. The `CompletionProvider` service computes a new `CompletionList` after each keystroke. - -#### DocumentSymbolProvider -The `DocumentSymbolProvider` service is responsible for handling a [Document Symbols Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentSymbol). The `DocumentSymbolProvider` is used to return a hierarchy of all symbols found in a document as an array of `DocumentSymbol`. - -#### HoverProvider -The `HoverProvider` service is responsible for handling a [Hover Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_hover) at a given text document position. By default, Langium implements tooltips with the content of the preceding multiline comment when hovering a symbol. - -#### FoldingRangeProvider -The `FoldingRangeProvider` service is responsible for handling a [Folding Range Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_foldingRange). This service identifies all the blocks that can be folded in a document. - -#### ReferenceFinder -The `ReferenceFinder` service is responsible for handling a [Find References Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_references). This service is used to find all references to a given symbol inside of a document. - -#### DocumentHighlighter -The `DocumentHighlighter` service is responsible for handling a [Document Highlights Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_documentHighlight). This service will find all references to a symbol at a given position (via the `References` service) and highlight all these references in a given document. - -#### RenameHandler -The `RenameHandler` service is responsible for handling a [Rename Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_rename) or a [Prepare Rename Request](https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_prepareRename). First, the service will check the validity of the *Prepare Rename Request*. If the request is valid, the service will find all references to the selected symbol inside of a document and replace all occurrences with the new value. diff --git a/hugo/content/old/docs/document-lifecycle.md b/hugo/content/old/docs/document-lifecycle.md deleted file mode 100644 index 3672e486..00000000 --- a/hugo/content/old/docs/document-lifecycle.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: 'Document Lifecycle' -weight: 400 ---- - -`LangiumDocument` is the central data structure in Langium that represents a text file of your DSL. Its main purpose is to hold the parsed Abstract Syntax Tree (AST) plus additional information derived from it. After its creation, a `LangiumDocument` must be "built" before it can be used in any way. The service responsible for building documents is called `DocumentBuilder`. - -A `LangiumDocument` goes through seven different states during its lifecycle: -1. `Parsed` when an AST has been generated from the content of the document. -2. `IndexedContent` when the AST nodes have been processed by the `IndexManager`. -3. `ComputedScopes` when local scopes have been prepared by the `ScopeComputation`. -4. `Linked` when the `Linker` has resolved cross-references. -5. `IndexedReferences` when the references have been indexed by the `IndexManager`. -6. `Validated` when the document has been validated by the `DocumentValidator`. -7. `Changed` when the document has been modified. - -State 1 is the initial state after creation of a document, and states 2 to 6 are part of its build process. State 7 is a final state used to mark the document as invalid due to a change in the source text. - -The following diagram depicts how the `DocumentBuilder` processes `LangiumDocument`s depending on their state. More details about each step of the lifecycle can be found below. - -{{}} -graph TD; -N(LangiumDocumentFactory) -.-|Creation of LangiumDocuments| C{{Parsed}} - -A(DocumentBuilder) -->|Indexing of symbols| D(IndexManager) -.- E{{IndexedContent}} -A -->|Computing scopes| F(ScopeComputation) -.- G{{ComputedScopes}} -A -->|Linking| H(Linker) -.- I{{Linked}} -A -->|Indexing of cross-references| J(IndexManager) -.- K{{IndexedReferences}} -A -->|Validation| L(DocumentValidator) -.- M{{Validated}} - -click N "./#creation-of-langiumdocuments" -click D "./#indexing-of-symbols" -click F "./#computing-scopes" -click H "./#linking" -click J "./#indexing-of-cross-references" -click L "./#validation" -{{}} - -## Creation of LangiumDocuments -When the workspace is initialized, all files having an extension matching those defined in `langium-config.json` are collected by the `WorkspaceManager` service. The `LangiumDocumentFactory` service creates a new instance of `LangiumDocument` for each source file. Those documents are then stored in memory by the `LangiumDocuments` service so they can be accessed later. - -Files in the workspace are mapped to instances of `TextDocument` as implemented by the `vscode-languageserver` package. Such a `TextDocument` holds the content of the respective file as a `string`. In contrast, a `LangiumDocument` represents the file content as an AST. This means that the creation of a `LangiumDocument` by the `LangiumDocumentFactory` service is accompanied by the parsing of the content of a `TextDocument` into an AST. During the creation of a `LangiumDocument` (i.e. after the document has been parsed), its state is set to `Parsed`. - -{{}} -graph LR; -A(LangiumDocuments

manages LangiumDocument instances) --> B(LangiumDocumentFactory

creates a LangiumDocument) -B --> C(LangiumParser

parses a string into an AST) -{{
}} - -Once all `LangiumDocument`s have been created, the `DocumentBuilder` service will sequentially process each `LangiumDocument` as described below. - -## Indexing of Symbols -Symbols are AST nodes that can be identified with a *name* and hence can be referenced from a *cross-reference*. Symbols that are *exported* can be referenced from other documents, while non-exported symbols are local to the document containing them. The `IndexManager` service keeps an index of all symbols that are exported from documents in the workspace. The set of all these exported symbols is called the *global scope*. - -Indexing of the exported symbols of an AST is executed on documents with the state `Parsed`. The default `ScopeComputation` service creates an `AstNodeDescription` for the root node (i.e. the node created by parsing the entry rule) and each named `AstNode` directly descending from the root node. This `AstNodeDescription` contains the `type` of the node, its identifier (i.e. the `name` property), the URI of the document where the node is located, and the location of the node inside of the document. The generated set of `AstNodeDescription`s makes symbols from a `LangiumDocument` accessible to other documents in the same workspace. - -The default `ScopeComputation` can be overridden to change the selection of exported symbols, or to export them with different names than the plain value of their `name` property. However, keep in mind that you cannot access any cross-references in this phase because that requires the document state to be at least `ComputedScopes`, which happens later in the build process. - -Once the initial indexing is done, the document's state is set to `IndexedContent`. - -{{}} -graph LR; -A(IndexManager

manages exported content
of LangiumDocuments
) --> B(ScopeComputation

creates descriptions
of all exported symbols
) -B --> C(NameProvider

resolves the name of an AstNode) -B --> D(AstNodeLocator

gets the path of an AstNode) -{{
}} - -## Computing Scopes -This phase is executed on documents with the state `IndexedContent` and is required to complete **prior to** resolving cross-references. - -Local scope computation consists of gathering all symbols contained in the AST, done by the `ScopeComputation` service (in addition to the indexing explained in the previous section). Metadata of the gathered symbols are represented with `AstNodeDescription` like in the [initial indexing phase](#indexing-of-symbols). These metadata are attached to the `LangiumDocument` in a multi-map structure that associates a (possibly empty) set of symbol descriptions to each container node of the AST, called the *precomputed scopes*. These are used in the linking phase to construct the actual *scope* of a cross-reference, i.e. all possible symbols that are reachable. A symbol in the precomputed scopes is reachable from a specific cross-reference if it is associated with a direct or indirect container of that reference. Symbols associated to the root node are reachable from the whole AST, while symbols associated with an inner node are reachable from the respective sub-tree. - -The default implementation of the `ScopeComputation` service attaches the description of every symbol to its direct container. This means that the container holds information about which named nodes are nested inside of it. You can override this default behavior to change the position where a symbol is reachable, or to change the name by which it can be referenced. It is even possible to associate the same symbol to multiple container nodes, possibly with different names, to control precisely where and how references to it can be resolved. However, keep in mind that you cannot access any cross-references in this phase. More complex, context-dependent scope mechanisms can be implemented in the `ScopeProvider` (see [next section](#linking)). - -The *"Domainmodel"* example includes a [customization of scopes precomputation](https://github.com/eclipse-langium/langium/blob/main/examples/domainmodel/src/language-server/domain-model-scope.ts) where every *entity* contained in a *package declaration* is exposed using its *qualified name*, that is the concatenation of the package name and entity name separated with `.` (similar to Java). - -In languages with a type system, you would typically implement computation of types in an additional pre-processing step in order to make type information available in the document. This additional step can be registered to run after scope computation with the `onBuildPhase` method of `DocumentBuilder`. How types are computed heavily depends on the kind of type system, so there is no default implementation for it. - -Once local scopes are computed and attached to the document, the document's state is set to `ComputedScopes`. - -{{}} -graph LR; -A(ScopeComputation

gathers all symbols from the AST and
stores their metadata in a MulitMap
) --> B(NameProvider

resolves the name of an AST node) -A --> C(AstNodeDescriptionProvider

creates descriptions of the
gathered symbols
) -C --> D(AstNodeLocator

gets the path of an AstNode) -{{
}} - -## Linking -Once local scopes have been prepared, cross-references are resolved via the `Linker` service. The `Linker` retrieves all cross-references in a `LangiumDocument` and tries to resolve them. Reference resolution consists of three main steps: - - 1. Query the `ScopeProvider` to obtain a *scope*. A scope describes all symbols that are reachable from the AST node holding the cross-reference. - 2. In the obtained scope, find the description of a symbol whose name matches the identifier given at the cross-reference. - 3. Load the AST node for that description. The AST node is given either directly (for a local symbol) or indirectly though a path string (for a symbol exported from another document). - -The default implementation of the `ScopeProvider` service creates a hierarchical scope by traveling from the given cross-reference via its container nodes up to the root of the AST, and collecting symbol descriptions from the precomputed scopes (created in the [preceding phase](#computing-scopes)). The symbols are filtered to match the type of the cross-reference target. Symbols that are closer to the cross-reference *shadow* those that are further above in the AST, which means they have higher priority to be chosen as cross-reference targets. As the last resort, the global scope computed in the [initial indexing phase](#indexing-of-symbols) is included in the hierarchical scope. Symbols that cannot be found locally are looked up in the global scope. - -The `ScopeProvider` can be overridden to implement complex scenarios for scoping and cross-reference resolution. Since cross-references can be linked *lazily* in this phase, it is possible to create a scope for a cross-reference depending on the resolved target of another cross-reference. - -Once the linking is complete, the document's state is set to `Linked`. - -{{}} -graph LR; -A(Linker

links references to their target AstNodes) --> B(ScopeProvider

creates a Scope for the context of a Reference) -A --> C(AstNodeLocator

resolves an AstNode from its path) -{{
}} - -## Indexing of Cross-References -Once the cross-references have been resolved by the linker, the `IndexManager` kicks in a second time to create descriptions of cross-references between different documents. Such a `ReferenceDescription` implies a dependency from its source document to its target document. This information ensures an efficient lookup to identify which other documents may be impacted by a change in a `LangiumDocument`. - -After the cross-references have been indexed, the document's state is set to `IndexedReferences`. - -{{}} -graph LR; -A(IndexManager

manages metadata of cross-references
between documents
) --> B(ReferenceDescriptionProvider

creates descriptions of all cross-references) -B --> C(AstNodeLocator

gets the path of an AstNode) -{{
}} - -## Validation -The `DocumentValidator` creates an array of `Diagnostic`s from a `LangiumDocument`. This array contains all errors that have occurred during lexing, parsing, and linking, and the results of a set of custom validations with varying severity (_error_, _warning_, _info_). The custom validations are registered with the `ValidationRegistry` service. - -After the diagnostics have been created, the document's state is set to `Validated`. - -{{}} -graph LR; -A(DocumentValidator

translate parser and linker errors to Diagnostics,
and executes custom validation checks
) --> B(ValidationRegistry

manages custom validation checks for each AST node type) -{{
}} - -At this point, all documents have been processed by the `DocumentBuilder` and the workspace is ready to process requests from the editor (e.g. completion). - -## Modifications of a document -When a `TextDocument` is modified, the language client (IDE) notifies the language server, which triggers corresponding events. In Langium, a change in a `TextDocument`'s content leads to the invalidation of the associated `LangiumDocument`. The document's state is set to `Changed` and the document's entry is removed from the `LangiumDocuments` service. If the `TextDocument` was deleted, the corresponding `LangiumDocument` is removed from the index in the `IndexManager` service. If the document's content was modified, a new instance of `LangiumDocument` is created [as described above](#creation-of-langiumdocuments). All other documents that may have been affected as a result of the modification get their references unlinked and their state is modified such that they run through the [linking phase](#linking) again. The `DocumentBuilder` then processed the newly created document along with all other documents that have not reached the `Validated` state yet. - -To determine which documents are affected by a change, the `IndexManager` uses the reference descriptions gathered in the [reference indexing phase](#indexing-of-cross-references). diff --git a/hugo/content/old/docs/getting-started.md b/hugo/content/old/docs/getting-started.md deleted file mode 100644 index cf53d7ee..00000000 --- a/hugo/content/old/docs/getting-started.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: "Getting Started" -weight: 50 ---- - -Before diving into Langium itself, let's get your environment ready for development: - -1. You have a working [Node environment](https://nodejs.org/en/download/) with version 16 or higher. -2. Install Yeoman and the Langium extension generator. -```bash -npm i -g yo generator-langium -``` - -For our getting started example, we would also recommend you to install the latest version of [vscode](https://code.visualstudio.com/). - -## Your first example language - -To create your first working DSL, execute the yeoman generator: - -```bash -yo langium -``` - -Yeoman will prompt you with a few basic questions about your DSL: - -1. _Extension name_: Will be used as the folder name of your extension and its `package.json`. -2. _Language name_: Will be used as the name of the grammar and as a prefix for some generated files and service classes. -3. _File extensions_: A comma separated list of file extensions for your DSL. - -Afterwards, it will generate a new project and start installing all dependencies, including the `langium` framework as well as the `langium-cli` command line tool required for generating code based on your grammar definition. - -After everything has successfully finished running, open your newly created Langium project with vscode via the UI (File > Open Folder...) or execute the following command, replacing `hello-world` with your chosen project name: - -```bash -code hello-world -``` - -Press F5 or open the debug view and start the available debug configuration to launch the extension in a new _Extension Development Host_ window. Open a folder and create a file with your chosen file extension (`.hello` is the default). The `hello-world` language accepts two kinds of entities: The `person` and `Hello` entity. Here's a quick example on how to use them both: - -``` -person Alice -Hello Alice! - -person Bob -Hello Bob! -``` - -The file `src/language/hello-world.langium` in your newly created project contains your grammar. - -## Explaining the terms - -If you're already familiar with the terms used in parsing or DSL frameworks, you can skip this short excursion and go straight to the next part. However, anyone who is new to DSL development should carefully read the following primer on the terms we are using in our documentation: - -_abstract syntax tree_: A tree of elements that represents a text document. Each element is a simple JS object that combines multiple input tokens into a single object. Commonly abbreviated as _AST_. - -_document_: An abstract term to refer to a text file on your file system or an open editor document in your IDE. - -_grammar_: Defines the form of your language. In Langium, a grammar is also responsible for describing how the _AST_ is built. - -_parser_: A program that takes a _document_ as its input and computes an _abstract syntax tree_ as its output. - -_parser rule_: A parser rule describes how a certain _AST_ element is supposed to be parsed. This is done by invoking other _parser rules_ or _terminals_. - -_terminal_: A terminal is the smallest parseable part of a document. It usually represents small pieces of text like names, numbers, keywords or comments. - -_token_: A token is a substring of the _document_ that matches a certain _terminal_. It contains information about which kind of _terminal_ it represents as well as its location in the document. - - - -## Explaining the grammar - -Here's the grammar that parses the previous text snippet: - -```langium -grammar HelloWorld - -hidden terminal WS: /\s+/; -terminal ID: /[_a-zA-Z][\w]*/; - -entry Model: (persons+=Person | greetings+=Greeting)*; - -Person: - 'person' name=ID; - -Greeting: - 'Hello' person=[Person] '!'; -``` - -Let's go through this one by one: - -```langium -grammar HelloWorld -``` - -Before we tell Langium anything about our grammar contents, we first need to give it a name - in this case it's `HelloWorld`. The `langium-cli` will pick this up to prefix any generated services with this name. - -```langium -hidden terminal WS: /\s+/; -terminal ID: /[_a-zA-Z][\w]*/; -``` - -Here we define our two needed terminals for this grammar: The whitespace `WS` and identifier `ID` terminals. Terminals parse a part of our document by matching it against their regular expression. The `WS` terminal parses any whitespace characters with the regex `/\s+/`. This allows us consume whitespaces in our document. As the terminal is declared as `hidden`, the parser will parse any whitespace and discard the results. That way, we don't have to care about how many whitespaces a user uses in their document. Secondly, we define our `ID` terminal. It parses any string that starts with an underscore or letter and continues with any amount of characters that match the `\w` regex token. It will match `Alice`, `_alice`, or `_al1c3` but not `4lice` or `#alice`. Langium is using the JS regex dialect for terminal definitions. - -```langium -entry Model: (persons+=Person | greetings+=Greeting)*; -``` - -The `Model` parser rule is the `entry` point to our grammar. Parsing always starts with the `entry` rule. Here we define a repeating group of alternatives: `persons+=Person | greetings+=Greeting`. This will always try to parse either a `Person` or a `Greeting` and add it to the respective list of `persons` or `greetings` in the `Model` object. Since the alternative is wrapped in a repeating group `*`, the parser will continue until all input has been consumed. - -```langium -Person: 'person' name=ID; -``` - -The `Person` rule starts off with the `'person'` keyword. Keywords are like terminals, in the sense that they parse a part of the document. The set of keywords and terminals create the tokens that your language is able to parse. You can imagine that the `'person'` keyword here is like an indicator to tell the parser that an object of type `Person` should be parsed. After the keyword, we assign the `Person` a name by parsing an `ID`. - -```langium -Greeting: 'Hello' person=[Person] '!'; -``` - -Like the previous rule, the `Greeting` starts with a keyword. With the `person` assignment we introduce the _cross reference_, indicated by the brackets `[]`. A cross reference will allow your grammar to reference other elements that are contained in your file or workspace. By default, Langium will try to resolve this cross reference by parsing the terminal that is associated with its `name` property. In this case, we are looking for a `Person` whose `name` property matches the parsed `ID`. - -That finishes the short introduction to Langium! Feel free to play around with the grammar and use `npm run langium:generate` to regenerate the generated TypeScript files. To go further, we suggest that you continue with our [tutorials](/tutorials/). diff --git a/hugo/content/old/docs/grammar-language.md b/hugo/content/old/docs/grammar-language.md deleted file mode 100644 index 54c443d5..00000000 --- a/hugo/content/old/docs/grammar-language.md +++ /dev/null @@ -1,518 +0,0 @@ ---- -title: "The Grammar Language" -weight: 100 ---- -The grammar language describes the syntax and structure of your language. The [Langium grammar language](https://github.com/eclipse-langium/langium/blob/main/packages/langium/src/grammar/langium-grammar.langium) is implemented using Langium itself and therefore follows the same syntactic rules as any language created with Langium. The grammar language will define the structure of the *abstract syntax tree* (AST) which in Langium is a collection of *TypeScript types* describing the content of a parsed document and organized hierarchically. The individual nodes of the tree are then represented with JavaScript objects at runtime. - -In the following, we describe the Langium syntax and document structure. -## Language Declaration -An *entry* Langium grammar file (i.e. a grammar which contains an [entry rule](#the-entry-rule)) always starts with a header which declares the name of the language. For example, a language named `MyLanguage` would be declared with: - -```langium -grammar MyLanguage -``` - -Every grammar file has a `.langium` extension and the *entry grammar file* needs to be referenced in `langium-config.json`. If you used the [Yeoman generator](https://www.npmjs.com/package/generator-langium) to start your project, the configuration is already prepared. - -### Import of other grammar languages -It is possible to reuse grammar rules from other `.langium` files by importing them into your own grammar file. -```langium -import './path/to/an/other/langium/grammar'; -``` -This will import **all grammar rules** from the imported grammar file. It is therefore crucial to ensure that there are no duplicate rules between the different grammar files. - -Contrary to *entry grammars*, imported grammars do not need to start with the keyword `grammar`. - -## Terminal Rules -The first step in parsing your language is *lexing*, which transforms a stream of characters into a stream of tokens. A token is a sequence of one or many characters which is matched by a *terminal rule*, creating an atomic symbol. The names of terminal rules are conventionally written in upper case. - -The Langium parser is created using [Chevrotain](https://github.com/chevrotain/chevrotain) which has a built-in lexer based on [Javascript Regular Expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). - -Langium also allows the use of [Extended Backus-Naur Form (EBNF) Expressions](#extended-backus-naur-form-terminals) for terminals, but we *highly* recommend that you write your terminals using Regular Expressions instead. EBNF expressions are internally translated by langium into Regular Expressions, as they are intended to allow porting Xtext grammars into Langium grammars -- given their similarity. - -With that said, both types of expressions can be used jointly in the same grammar. - -The declaration of a terminal rule starts with the keyword `terminal`: -```langium -terminal ID: /[_a-zA-Z][\w_]*/; -``` -Here, the token `ID` will match a stream of characters starting with the character `_`, a small letter, or a capital letter followed by a sequence of zero or many ([cardinality](#cardinalities) *) alphanumeric characters (`\w`) or `_`. - -**The order in which terminal rules are defined is critical** as the lexer will always return the first match. - -### Return Types -A terminal rule returns an instance of a _TypeScript primitive type_. If no return type is specified, the terminal rule will return a `string` by default. -```langium -terminal ID: /[_a-zA-Z][\w_]*/; -terminal INT returns number: /[0-9]+/; -``` -Here, the terminal rule `ID` will return an instance of `string` while the terminal rule `INT` will return an instance of `number`. - -The available return types in Langium are: -- `string` -- `number` -- `boolean` -- `bigint` -- `Date` - -### Hidden Terminal Rules -The lexer tries to match every character in the document to a terminal rule or a keyword. It is therefore necessary to specify which characters or sequence of characters need to be ignored during lexing and parsing. Generally, you would want to ignore whitespaces and comments. This is achieved by adding the keyword `hidden` when defining a terminal rule. These *hidden terminal rules* are global and will be valid for all parser rules in the document. -```langium -hidden terminal WS: /\s+/; -hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; -hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; -``` - -## Parser Rules -While [terminal rules](#terminal-rules) indicate to the lexer what sequence of characters are valid tokens, *parser rules* indicate to the parser what sequence of tokens are valid. Parser rules lay the structure of objects to be created by the parser and result in the creation of the *abstract syntax tree* (AST) which represents the syntactic structure of your language. In Langium, parser rules are also responsible for defining the type of objects to be parsed. - -### Declaration -A parser rule always starts with the name of the rule followed by a colon. -```langium -Person: - 'person' name=ID; -``` -In this example, the parser will create an object of type `Person`. This object will have a property `name` which value and type must match the terminal rule `ID` (i.e. the property `name` is of type `string` and cannot start with a digit or special character). - -By default, the parser will create an object with an inferred type corresponding to the parser rule name. It is possible to override this behavior by explicitly defining the type of the object to be created. This is done by adding the keyword `returns` followed by a separately declared type, or the keyword `infers` followed by the name of the type to be inferred for this rule (more about this [in the next chapter](../sematic-model)): -```langium -Person infers OtherType: - 'person' name=ID; -``` -The parser rule `Person` will now lead to the creation of objects of type `OtherType` instead of `Person`. - -### The Entry Rule -The *entry rule* is a parser rule that defines the starting point of the parsing step. The *entry rule* starts with the keyword `entry` and matches other parser rules. -```langium -entry Model: - (persons+=Person | greetings+=Greeting)*; -``` -In this example, the *entry rule* `Model` defines a group of alternatives. The parser will go through the input document and try to parse `Person` or `Greeting` objects and add them to the `persons` or `greetings` arrays, respectively. The parser reads the token stream until all inputs have been consumed. - -### Extended Backus-Naur Form Expressions -Parser rules are defined using *Extended Backus-Naur Form*-like (EBNF) expressions similar to the [Xtext](https://www.eclipse.org/Xtext/) notation. - -#### Cardinalities -A cardinality defines the number of elements in a given set. Four different cardinalities can be defined for any expression: -1. exactly one (no operator) -2. zero or one (operator `?`) -3. zero or many (operator `*`) -4. one or many (operator `+`) - -#### Groups -Expressions can be put in sequence specifying the order they have to appear: -```langium -Person: - 'person' name=ID address=Address; -``` -In this example, the rule `Person` must start with the `person` keyword followed by an `ID` token and an instance of the `Address` rule. - -#### Alternatives -It is possible to match one of multiple valid options by using the pipe operator `|`. The already mentioned `Model` example specifies to parse either `Person` or `Greeting`, zero or many times (cardinality *): -```langium -entry Model: - (persons+=Person | greetings+=Greeting)*; -``` - -#### Keywords -Keywords are *inline terminals* which need to match a character sequence surrounded by single or double quotes, for example `'person'` or `"person"`. Keywords must not be empty and must not contain white space. - -#### Assignments -Assignments define properties on the type returned by the surrounding rule. -There are three different ways to assign an expression (right side) to a property (left side). - -1. `=` is used for assigning **a single value** to a property. - ```langium - Person: - 'person' name=ID - ``` - Here, the property `name` will accept only one expression matching the terminal rule `ID`. - -2. `+=` is used to assign **multiple values** to an array property. - ```langium - Contact: - addresses+=STRING addresses+=STRING; - ``` - Here, the array property `addresses` will accept two expressions matching the terminal rule `STRING`. - -3. `?=` is used to assign a **value to a property of type boolean**. The value of the property of type `boolean` is set to `true` if the right part of the assignment is consumed by the parser. - ```langium - Employee: - 'employee' name=ID (remote?='remote')? - ``` - Here the value of the property `remote` will be set to `true` if the keyword `remote` was successfully parsed as a part of the rule call. If the keyword `remote` is not consumed (cardinality is `?`), the property `remote` is set to `false`. - -#### Cross-References -With Langium, you can declare *cross-references* directly in the grammar. A *cross-reference* allows to reference an object of a given type. The syntax is: -```langium -property=[Type:TOKEN] -``` -The `property` will be a reference to an object of type `Type` identified by the token `TOKEN`. If the `TOKEN` is omitted, the parser will use the terminal or data type rule associated with the `name` assignment of the `Type` rule. If no such rule exists, then the token is mandatory. -```langium -Person: - 'person' name=ID; -Greeting: - 'Hello' person=[Person:ID] '!'; -``` -The `Person` in square brackets does not refer to the parser rule `Person` but instead refers to an object of type `Person`. It will successfully parse a document like: -``` -person Bob -Hello Bob ! -``` -but the following: -``` -person Bob -Hello Sara ! -``` -will result in an error message since the cross reference resolution will fail because a `Person` object with the name 'Sara' has not been defined, even though 'Sara' is a valid `ID`. - -#### Unassigned Rule Calls -Parser rules do not necessarily need to create an object, they can also refer to other parser rules which in turn will be responsible for returning the object. -For example, in the [Arithmetics example](https://github.com/eclipse-langium/langium/blob/main/examples/arithmetics/src/language-server/arithmetics.langium): -```langium -AbstractDefinition: - Definition | DeclaredParameter; -``` -The parser rule `AbstractDefinition` will not create an object of type AbstractDefinition. Instead, it calls either the `Definition` or `DeclaredParameter` parser rule which will be responsible for creating an object of a given type (or call other parser rules if they are unassigned rule calls themselves). - -In contrast, an assigned rule call such as `parameter=DeclaredParameter` means that an object is created in the current parser rule and assigns the result of the `DeclaredParameter` parser rule to the specified property `parameter` of that object. - -#### Unordered Groups - -In regular groups, expressions must occur in the exact order they are declared. -```langium -Person: - 'person' name=ID age=INT -``` -Here a `Person` object **needs** to first declare the property `name` then `age`. -``` -person Bob 25 -``` -will successfully be parsed to an object of type `Person` while -``` -person 25 Bob -``` -will throw an error. - -However, it is possible to declare a group of properties in an unordered fashion using the `&` operator -```langium -Person: - 'person' name=ID & age=INT -``` -will now allow `name` and `age` to be declared in any order. -``` -person 25 Bob -``` -will then successfully create an object of type `Person`. - -Cardinality (?,*,+ operators) also applies to unordered group. Please note that assignments with a cardinality of `+` or `*` have to appear continuously and cannot be interrupted by an other assignment and resumed later. - -#### Simple Actions -It is possible for a rule to return different types depending on declaration -```langium -interface TypeOne { - name: string -} -RuleOne returns TypeOne: - 'keywordOne' name=ID | RuleTwo; - -interface TypeTwo extends TypeOne {} -RuleTwo returns TypeTwo: - 'keywordTwo' name=ID; -``` -A rule call is one of the ways to specify the return type. With more complex rules, the readability will be highly impacted. *Actions* allow to improve the readability of the grammar by explicitly defining the return type. Actions are declared inside of curly braces `{}`: -```langium -RuleOne returns TypeOne: - 'keywordOne' name=ID | {TypeTwo} 'keywordTwo' name=ID; -``` - -The example above requires that the return types `TypeOne` and `TypeTwo` are declared separately (see [the next chapter](../semantic-model)). If the type returned by the action is created on-the-fly, the keyword `infer` needs to be added: -```langium -RuleOne infers TypeOne: - 'keywordOne' name=ID | {infer TypeTwo} 'keywordTwo' name=ID; -``` -Now both `TypeOne` and `TypeTwo` are inferred from the rule definition. Note that we use the keyword `infers` (declarative) for the grammar rule, but `infer` (imperative) for the action. - -#### Tree-Rewriting Actions -The parser is built using [Chevrotain](https://github.com/chevrotain/chevrotain) which implements a LL(k) parsing algorithm (left-to-right). Conceptually, a LL(k) grammar cannot have rules containing left recursion. - -Consider the following: -```langium -Addition: - Addition '+' Addition | '(' Addition ')' | value=INT; -``` -The parser rule `Addition` is left-recursive and will not be parseable. We can go around this issue by *left-factoring* the rule, *i.e.* by factoring out the common left-factor. We introduce a new rule `SimpleExpression`: -```langium -Addition: - SimpleExpression ('+' right=SimpleExpression)*; - -SimpleExpression: - '(' Addition ')' | value=INT; -``` -Unfortunately, *left-factoring* does not come without consequences and can lead to the generation of unwanted nodes. It is possible to "clean" the tree by using *tree-rewriting actions*. -```langium -Addition returns Expression: - SimpleExpression ({Addition.left=current} '+' right=SimpleExpression)*; - -SimpleExpression: - '(' Addition ')' | value=INT; -``` -Essentially this means that when a `+` keyword is found, a new object of type `Addition` is created and the current object is assigned to the `left` property of the new object. The `Addition` then becomes the new current object. In imperative pseudo code it may look like this: -```js -function Addition() { - let current = SimpleExpression() - while (nextToken == '+') { - let newObject = new Addition - newObject.left = current - current = newObject - current.right = SimpleExpression() - } -} -``` -Please refer to [this blog post](https://www.typefox.io/blog/parsing-expressions-with-xtext) for further details. - -### Data Type Rules -Data type rules are similar to terminal rules as they match a sequence of characters. However, they are parser rules and are therefore context-dependent. This allows for more flexible parsing, as they can be interspersed with hidden terminals, such as whitespaces or comments. Contrary to terminal rules, they cannot use *regular expressions* to match a stream of characters, so they have to be composed of keywords, terminal rules or other data type rules. - -The following example from the [domain model example](https://github.com/eclipse-langium/langium/blob/main/examples/domainmodel/src/language-server/domain-model.langium) uses the `QualifiedName` data type rule to enable references to other elements using their fully qualified name. -```langium -QualifiedName returns string: - ID ('.' ID)*; -``` -Data type rules need to specify a primitive return type. - -### Rule Fragments -If you are facing repetitive patterns in your grammar definition, you can take advantage of *Rule Fragments* to improve the grammar's maintainability. -```langium -Student: - 'student' firstName=ID lastName=ID address=STRING phoneNumber=STRING grades=Grades; -Teacher: - 'teacher' firstName=ID lastName=ID address=STRING phoneNumber=STRING classes=Classes; -TechnicalStaff: - 'tech' firstName=ID lastName=ID address=STRING phoneNumber=STRING; -``` -The parser rules Student, Teacher, and TechnicalStaff partly share the same syntax. -If, for example, the assignment for `phoneNumber` had to be updated, we would need to make changes everywhere the `phoneNumber` assignment was used. -We can introduce *Rule Fragments* to extract similar patterns and improve maintainability: -```langium -fragment Details: - firstName=ID lastName=ID address=STRING phoneNumber=STRING; - -Student: - 'student' Details grades=Grades; -Teacher: - 'teacher' Details classes=Classes; -TechnicalStaff: - 'tech' Details; -``` - -Fragment rules are not part of the AST and will therefore never create an object, instead they can be understood as being textually inserted where they are referenced. - -### Guard Conditions -It may be useful to group parser rules with small variations inside of a single parser rule. Given the following example: -```langium -entry Model: - element+=RootElement; - -RootElement infers Element: - isPublic?='public'? - 'element' name=ID '{' - elements+=Element* - '}'; - -Element: - 'element' name=ID '{' - elements+=Element* - '}'; -``` -The only difference between `RootElement` and `Element` is that the former has the boolean property `isPublic`. -We can refactor the grammar so that only `Element` is present in the grammar with a *guard condition* that will determine which concrete syntax should be used by the parser: -```langium -entry Model: - element+=Element; - -Element: - ( isPublic?='public')? - 'element' name=ID '{' - elements+=Element* - '}'; -``` -`Element` has the guard `isRoot`, which will determine whether the optional group containing the `isPublic` property is allowed to be parsed. - -The *entry rule* `Model` sets the value of `isRoot` to `true` with `element+=Element`, while `isRoot` is set to `false` inside of the `Element` parser rule with `elements+=Element`. - -In general, a guard condition on a group decides whether the parser is allowed to parse the group or not depending on the result of the evaluated condition. Logical operations can be applied, such as `&` (and), `|` (or) and `!` (not) to fine-tune the exact conditions in which the group is supposed to be parsed. - -Additionally, guard conditions can also be used inside of alternatives. See the following example: -```langium -entry Model: - element+=Element; - -Element: - ( 'root' | 'element') name=ID '{' - elements+=Element* - '}'; -``` - -The parser will always exclude alternatives whose guard conditions evaluate to `false`. All other alternatives remain possible options for the parser to choose from. - - -### More Examples - -Not all parser rules need to be mentioned in the entry rule, as shown in this example: -```langium -entry Model: - (persons+=Person | greetings+=Greeting)*; - -Person: - 'person' name=ID address=Address; - -Greeting: - 'Hello' person=[Person] '!'; - -Address: - street=STRING city=ID postcode=INT; -``` -Here the `Person` parser rule includes a property `address` which matches the parser rule `Address`. We decided that an `Address` will never be present in the input document on its own and will always be parsed in relation to a `Person`. It is therefore not necessary to include an array of `Address` inside of the entry rule. - ---- - -Keywords are meant to provide a visible structure to the language and guide the parser in deciding what type of object needs to be parsed. -Consider the following: -```langium -Student: - name=ID; - -Teacher: - name=ID; - -Person: - Student | Teacher; -``` -In this example, a `Person` can either be a `Student` or a `Teacher`. This grammar is ambiguous because the parser rules `Student` and `Teacher` are identical. The parser will not be able to differentiate between the parser rules for `Student` and `Teacher` when trying to parse a `Person`. -Keywords can help removing such ambiguity and guide the parser in defining if a `Student` or `Teacher` needs to be parsed. -We can add a keyword to the parser rule `Student`, `Teacher`, or to both of them: -```langium -Student: - 'student' name=ID; - -Teacher: - 'teacher' name=ID; - -Person: - Student | Teacher; -``` -Now the ambiguity is resolved and the parser is able to differentiate between the two parser rules. - -Parser rules can have many keywords: -```langium -Person: - 'person' name=ID 'age' age=INT; -``` - ---- - -If an assignment has a cardinality of `+` or `*`, then the expressions belong to a single group and must not be interrupted by other expressions. -```langium -Paragraph: - 'paragraph' (sentences+=STRING)+ id=INT; -``` -Here, the property `sentences` will accept one or many expressions matching the terminal rule `STRING` followed by an `INT`. The parsing of a document containing: -``` -paragraph "The expression group " 3 "was interrupted" -``` -will throw an error since the `STRING` expressions are not continuous. It is however possible to interrupt and resume a sequence of expressions by using [hidden terminal symbols](#hidden-terminal-rules): -``` -paragraph "expression one" /* comment */ "expression two" 3 -``` -The above example will be successfully parsed. - -## More on Terminal Rules - -### Extended Backus-Naur Form Terminals - -*For full disclosure, we recommend using regular expressions when writing your terminals, as EBNF expressions are translated to regular expressions internally anyway. EBNF support is primarily intended for supporting grammars that were originally written in Xtext, but are being ported to Langium.* - -As mentioned earlier, terminal rules can be described using *regular expressions* or *EBNF expressions*. - -EBNF expressions are very similar to [parser rules](#extended-backus-naur-form-expressions), which are described above. In this section, we describe which EBNF expressions are supported for terminals and their equivalent in *Javascript Regular Expressions* where possible. - -#### Terminal Groups -Tokens can be put in sequence specifying the order they have to appear: -```langium -terminal FLIGHT_NUMBER: ('A'..'Z')('A'..'Z')('0'..'9')('0'..'9')('0'..'9')('0'...'9')?; -``` -In this example, the token `FLIGHT_NUMBER` must start with two capital letters followed by three or four digits. - -#### Terminal Alternatives -It is possible to match one of multiple valid options by using the pipe operator `|`. The terminal rule `STRING` can use alternatives to match a sequence of characters between double quotes `""` or single quotes `''`: -```langium -terminal STRING: '"' !('"')* '"' | ''' !(''')* '''; -``` -In regular expression, alternatives are also possible with the pipe operator `|`: -```langium -terminal STRING: /"[^"]*"|'[^']*'/; -``` - -#### Character Range -The operator `..` is used to declare a character range. It is equivalent to the operator `-` within a character class in a regular expression. It matches any character in between the left character and the right character (inclusive on both ends). -```langium -terminal INT returns number: ('0'..'9')+; -``` -is equivalent to the regular expression: -```langium -terminal INT returns number: /[0-9]+/; -``` -Here, `INT` is matched to one or more characters (by using the operand `+`, which defines a [cardinality](#cardinalities) of 'one or many') between `0` and `9` (inclusive on both ends). - -#### Wildcard Token -The operator `.` is used to match any character and is similar in regular expression. -```langium -terminal HASHTAG: '#'.+; -``` -In this example, the terminal rule `HASHTAG` matches a sequence of character starting with `#` followed by one or many ([cardinality](#cardinalities) +) characters. - -Equivalent in regular expression: -```langium -terminal HASHTAG: /#.+/; -``` -#### Until Token -The operator `->` indicates that all characters should be consumed from the left token *until* the right token occurs. For example, the terminal rule for multi-line comment can be implemented as: -```langium -terminal ML_COMMENT: '/*' -> '*/'; -``` -Langium will transform the until token into the regular expression `[\s\S]*?` which matches any character non-greedily: -```langium -terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; -``` - -#### Negated Token -It is possible to negate tokens using the operator `!`. In Langium this produces a *negative lookahead*. I.e., it does *not* consume tokens, but it is a 'guard' for what the following expression can recognize. - -For example, if you want to recognize a word that doesn't start with `no`, then you could write such an expression in EBNF like so: -```langium -terminal NONO: (!'no')('a'..'z'|'A'..'Z')+; -``` - -For reference, this would correspond to the following regular expression: -```langium -terminal NONO: /(?!no)[a-zA-Z]+/; -``` - -Note, if you're coming from Xtext, negated tokens works differently here. In Xtext, negated tokens allow recognizing the *complement* of a set of characters (or anything 'but' what is listed in the negation), very much akin to a negated character class in regular expressions. This is *very* important to keep in mind if you're porting a grammar from Xtext, as Langium's interpretation of negated tokens deviates from that of Xtext. - -#### Terminal Rule Calls -A terminal rule can include other terminal rules in its definition. -```langium -terminal DOUBLE returns number: INT '.' INT; -``` -Note that it is easy to create conflicts between terminal rules when using *terminal rule calls*. See [Data Type Rules](#data-type-rules) for further details. - -### Terminal Fragments -Fragments allow for sub-definition of terminal rules to be extracted. They are not consumed by the lexer and have to be consumed by other terminal rules. -```langium -terminal fragment CAPITAL_LETTER: ('A'..'Z'); -terminal fragment SMALL_LETTER: ('a'..'z'); -terminal NAME: CAPITAL_LETTER SMALL_LETTER+; -``` -In this example, the lexer will not transform a single capital or small letter into a valid token but will match a sequence of one capital letter followed by one or many small letters. diff --git a/hugo/content/old/docs/langium-overview.md b/hugo/content/old/docs/langium-overview.md deleted file mode 100644 index baa5ad93..00000000 --- a/hugo/content/old/docs/langium-overview.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: "Langium Overview" -weight: 0 ---- - -Designing programming languages from the ground up is hard, independent of whether your language is a "simple" domain specific language or a full-fledged general-purpose programming language. -Not only do you have to keep up with the requirements of your domain experts, but you have to deal with all the technical complexity that comes with building a language, including questions such as: - -- How do I get from a string to a semantic model which I can work with? -- How do I resolve references to other parts of my model, even if they are located in a separate file? -- How do I provide a great editing experience to users of my language? - -This is the point where Langium comes into play. Langium aims to lower the barrier to entry for creating a language by removing the technical complexity, allowing you to focus on your domain's requirements. - -In this chapter, you'll get a closer look at the requirements developers usually have to implement by themselves when building a programming language: - -- [Language parsing](#language-parsing) -- [Semantic models](#semantic-models) -- [Cross references and linking](#cross-references-and-linking) -- [Workspace management](#workspace-management) -- [Editing support](#editing-support) - -Langium provides out-of-the-box solutions for these problems, with the ability to fine-tune every part of it to fit your domain requirements. - ---- - -## Language Parsing - -Programming languages and domain specific languages (DSLs) cannot be parsed using simple regular expressions (RegExp). Instead they require a more sophisticated parsing strategy. To define a custom language in Langium, you interact with a high level representation of your context-free grammar using the [Langium grammar language](/docs/grammar-language), in a similar fashion to EBNF. - -Based on the grammar, Langium is then able to construct a parser which transforms an input string into a semantic model representation. Just as the name suggests, this model captures the essential structure to describe your language. - -## Semantic Models - -Langium grammars are not only used to parse your language, but also to generate a semantic model for your Language as TypeScript interfaces. When a program in your language is then parsed, the generated AST will be automatically produced using these interfaces. The following language snippet parses a simple object `{ name: 'John' }`. - -```langium -Person: - 'person' // keyword - name=ID // semantic assignment -; -``` - -To interact with the semantic model in a type safe manner, the `langium-cli` tool generates TypeScript type definitions from your parser rules. The `Person` parser rule generates the following interface: - -```ts -interface Person { - name: String -} -``` - -These interfaces allow you to safely traverse your abstract syntax tree. In case your grammar changes, they will also notify you of any breaking changes which might require you to change your domain logic. - -## Cross References and Linking - -To express any kind of relationship between elements in your language, you will need to **reference** them. -The process of resolving these references, i.e. identifying what element of your language hides behind a certain name, is called _linking_. -Performing the linking process in a deterministic manner with a lot of objects in your project requires sound linking design. - -Langium accomplishes this feat by using the concept of 'scoping'. You likely know scopes from programming, where some variables are only available from certain scopes: - -```ts -let x = 42; -x = 3; // References the `x` defined in the previous line - -if (something) { - let y = 42; -} -y = 3; // Cannot link, `y` isn't in any of the available scopes -``` - -The same occurs in Langium. To enable more complex scoping behavior, you can add custom domain scoping. For example, common object-oriented languages need a more involved scoping mechanism to resolve references to fields and methods of a class: - -```ts -class X { - y(): void { ... } -} - -const instance = new X(); // Symbol `X` is in the local scope -instance.y(); // Symbol `y` exists in the scope of the `X` class -``` - -Once your domain specific scoping rules have been defined, Langium will take care of linking by itself, reporting any errors. - -## Workspace Management - -Like with common modularized programming languages, domain logic written in your DSL will usually be split across multiple files to facilitate ease of use and maintenance. This is also possible using Langium, which automatically tries to pick up any files belonging to your current project. - -When running a Langium based language in a [language server](https://microsoft.github.io/language-server-protocol/), all files in your workspace (the folder containing your current project) belonging to your DSL will automatically be picked up and processed. In addition, any changes in your workspace will be handled as well. Dealing with added, changed or deleted files in a workspace with multiple hundreds of files can become complicated and decrease performance drastically if not done correctly. Langium employs heuristics to only invalidate and recompute what is actually necessary. - -The workspace management also keeps track of the global scope. This allows users of your DSL to reference elements across files within the same workspace. - -## Editing Support - -The Langium framework is deeply integrated with the [language server protocol](https://microsoft.github.io/language-server-protocol/) (LSP). The LSP aims to reduce integration efforts when designing a language by providing an interface that all IDEs can use to provide editing support. This allows Langium based languages to easily interact with common IDEs and editors with LSP support, including Visual Studio Code, Eclipse, IntelliJ and many more. - -The LSP includes commonly used language features, such as code completion, custom validations/diagnostics, finding references, formatting and many more. This allows for deep IDE integration without binding your language to a single IDE. Langium offers out-of-the-box support for most of these language features, with additional extension points for your domain specific requirements. - -## Try it out! - -You can try out most of these features using our [showcase](/showcase/) and [playground](/playground/). The languages shown there are written using Langium and integrated in the monaco-editor. - -If you're interested in Langium, you can check out our [getting started](/docs/getting-started) page next. There you'll learn how to get started writing your first language, and to learn more about how Langium can help you achieve your language designing goals. diff --git a/hugo/content/old/docs/sematic-model.md b/hugo/content/old/docs/sematic-model.md deleted file mode 100644 index de480119..00000000 --- a/hugo/content/old/docs/sematic-model.md +++ /dev/null @@ -1,409 +0,0 @@ ---- -title: "Semantic Model Inference" -weight: 200 ---- - -When AST nodes are created during the parsing of a document, they are given a type. The language grammar dictates the shape of those types and how they might be related to each other. All types form the *semantic model* of your language. There are two ways by which Langium derives semantic model types from the grammar, by **[inference](#inferred-types)** and by **[declaration](#declared-types)**. - -*Inference* is the default behavior in Langium. During the generation of the semantic model types, Langium infers the possible types directly from the grammar rules. While this is a powerful approach for simple languages and prototypes, it is not recommended for more mature languages since minimal changes in the grammar can easily lead to breaking changes. - -To minimize the chance of breaking changes, Langium introduces *declared types* where the semantic model types are explicitly defined by the user in the grammar via a *TypeScript-like* syntax. - -In the following, we detail how grammar rules shape the semantic model via inference and declaration. - -## Inferred Types -*Inferred types* result from letting Langium infer the types of the nodes from the grammar rules. Let's have a look at how various rules shape these type definitions: - -### Parser Rules -The simplest way to write a parser rule is as follows: -```langium -X: name=ID; -``` -With this syntax, Langium will **infer** the type of the node to be generated when parsing the rule. By convention, the type of the node will be named after the name of the rule, resulting in this **TypeScript interface** in the semantic model: -```langium -interface X extends AstNode { - name: string -} -``` -It is also possible to control the naming of the interface by using the following syntax: -```langium -X infers MyType: name=ID; -``` -resulting in the following interface in the semantic model: -```langium -interface MyType extends AstNode { - name: string -} -``` -Please note that an `interface X` is no longer present in the semantic model. - -It is important to understand that the name of the parser rule and the name of the type it infers work on two separate abstraction levels. The name of the parser rule is used at the *parsing level* where types are ignored and only the parsing rule is considered, while the name of the type is used at the *types level* where both the type and the parser rule play a role. This means that the name of the type can be changed without affecting the parsing rules hierarchy, and that the name of the rule can be changed - if it explicitly infers or returns a given type - without affecting the semantic model. - -By inferring types within the grammar, it is also possible to define several parser rules creating the same semantic model type. For example, the following grammar has two rules `X` and `Y` inferring a single semantic model type `MyType`: -```langium -X infers MyType: name=ID; -Y infers MyType: name=ID count=INT; -``` -This result in the creation of a single interface in the semantic model 'merging' the two parser rules with non-common properties made optional: -```langium -interface MyType extends AstNode { - count?: number - name: string -} -``` - -### Terminal Rules -Terminal rules are linked to built-in types in the semantic model. They do not result in semantic model types on their own but determine the type of properties in semantic model types inferred from a parser rule: -```langium -terminal INT returns number: /[0-9]+/; -terminal ID returns string: /[a-zA-Z_][a-zA-Z0-9_]*/; - -X: name=ID count=INT; -``` - -```langium -// generated interface -interface X extends AstNode { - name: string - count: number -} -``` - -The property `name` is of type `string` because the terminal rule `ID` is linked to the built-in type `string`, and the property `count` is of type `number` because the terminal rule `INT` is linked to the built-in type `number`. - -### Data type rules -Data type rules are similar to terminal rules in the sense that they determine the type of properties in semantic model types inferred from parser rules. However, they lead to the creation of type aliases for built-in types in the semantic model: -```langium -QualifiedName returns string: ID '.' ID; - -X: name=QualifiedName; -``` - -```langium -// generated types -type QualifiedName = string; - -interface X extends AstNode { - name: string -} -``` - -### Assignments -There are three available kinds of [assignments](../grammar-language/#assignments) in a parser rule: - -1. `=` for assigning a **single value** to a property, resulting in the property's type to be derived from the right hand side of the assignment. -2. `+=` for assigning **multiple values** to a property, resulting in the property's type to be an array of the right hand side of the assignment. -3. `?=` for assigning a **boolean** to a property, resulting in the property's type to be a `boolean`. - -```langium -X: name=ID numbers+=INT (numbers+=INT)* isValid?='valid'?; -``` - -```langium -// generated interface -interface X extends AstNode { - name: string - numbers: Array - isValid: boolean -} -``` - -The right-hand side of an assignment can be any of the following: -* A terminal rule or a data type rule, which results in the type of the property to be a built-in type. -* A parser rule, which results in the type of the property to be the type of the parser rule. -* A cross-reference, which results in the type of the property to be a *Reference* to the type of the cross-reference. -* An alternative, which results in the type of the property to be a type union of all the types in the alternative. - -```langium -X: 'x' name=ID; - -Y: crossValue=[X:ID] alt=(INT | X | [X:ID]); -``` - -```langium -// generated types -interface X extends AstNode { - name: string -} - -interface Y extends AstNode { - crossValue: Reference - alt: number | X | Reference -} -``` - -### Unassigned Rule Calls - -A parser rule does not necessarily need to have assignments. It may also contain only *unassigned rule calls*. These kind of rules can be used to change the types' hierarchy. - -```langium -X: A | B; - -A: 'A' name=ID; -B: 'B' name=ID count=INT; -``` - -```langium -// generated types -type X = A | B; - -interface A extends AstNode { - name: string -} - -interface B extends AstNode { - name: string - count: number -} -``` - -### Simple Actions - -Actions can be used to change the type of a node **inside** of a parser rule to another semantic model type. For example, they allow you to simplify parser rules which would have to be split into multiple rules. - -```langium -X: - {infer A} 'A' name=ID - | {infer B} 'B' name=ID count=INT; - -// is equivalent to: -X: A | B; -A: 'A' name=ID; -B: 'B' name=ID count=INT; -``` - -```langium -// generated types -type X = A | B; - -interface A extends AstNode { - name: string -} - -interface B extends AstNode { - name: string - count: number -} -``` - -### Assigned actions - -Actions can also be used to control the structure of the semantic model types. This is a more advanced topic, so we recommend getting familiar with the rest of the documentation before diving into this section. - -Let's consider two different grammars derived from the [Arithmetics example](https://github.com/eclipse-langium/langium/blob/main/examples/arithmetics/src/language-server/arithmetics.langium). These grammars are designed to parse a document containing a single definition comprised of a name and an expression assignment, with an expression being any amount of additions or a numerical value. - -The first one does not use assigned actions: - -```langium -Definition: - 'def' name=ID ':' expr=Expression; -Expression: - Addition; -Addition infers Expression: - left=Value ('+' right=Expression)?; - -Primary infers Expression: - '(' Expression ')' | {Literal} value=NUMBER; -``` - -When parsing a document containing `def x: (1 + 2) + 3`, this is the shape of the semantic model node: - -{{}} -graph TD; -expr((expr)) --> left((left)) -expr --> right((right)) -left --> left_left((left)) -left --> left_right((right)) -right --> right_left((left)) -left_left --> left_left_v{1} -left_right --> left_right_{2} -right_left --> right_left_v{3} -{{}} - -We can see that the nested `right -> left` nodes in the tree are unnecessary and we would like to remove one level of nesting from the tree. - -This can be done by refactoring the grammar and adding an assigned action: - -```langium -Definition: - 'def' name=ID ':' expr=Addition ';'; -Expression: - Addition; -Addition infers Expression: - Primary ({infer Addition.left=current} '+' right=Primary)*; - -Primary infers Expression: - '(' Expression ')' | {Literal} value=NUMBER; -``` - -Parsing the same document now leads to this semantic model: - -{{}} -graph TD; -expr((expr)) --> left((left)) -expr --> right((right)) -left --> left_left((left)) -left --> left_right((right)) -right --> right_v{3} -left_left --> left_left_v{1} -left_right --> left_right_{2} -{{}} - -While this is a fairly trivial example, adding more layers of expression types in your grammar massively degrades the quality of your syntax tree as each layer will add another empty `right` property to the tree. Assigned actions alleviate this issue completely. - -## Declared Types - -Because type inference takes into account every entity of a parser rule, even the smallest changes can update your inferred types. This can lead to unwanted changes in your semantic model and incorrect behavior of services that depend on it. *Declared types* are a means to minimize the risk of introducing breaking changes when modifying the grammar. - -In most cases, especially for early language designs, letting the type inference take care of generating your types will be your best choice. As your language starts to mature, it may then be of interest to fix parts of your semantic model using declared types. - -With that aside, declared types can be *especially* helpful for more mature and complex languages, where a stable semantic model is key and breaking changes introduced by inferred types can break your language services. Declared types allow the user to **fix** the type of their parser rules and rely on the power of validation errors to detect breaking changes. - - - -Let's look at the example from the previous section: - -```langium -X infers MyType: name=ID; -Y infers MyType: name=ID count=INT; - -// should be replaced by: -interface MyType { - name: string - count?: number -} - -X returns MyType: name=ID; -Y returns MyType: name=ID count=INT; -``` - -We now explicitly declare `MyType` directly in the grammar with the keyword `interface`. The parser rules `X` and `Y` creating nodes of type `MyType` need to explicitly declare the type of the node they create with the keyword `returns`. - -Contrary to [inferred types](#inferred-types), all properties must be explicitly declared in order to be valid inside of a parser rule. The following syntax: - -```langium -Z returns MyType: name=ID age=INT; -``` - -will show the following validation error `A property 'age' is not expected` because the declaration of `MyType` does not include the property `age`. In short, *declared types* add a layer of safety via validation to the grammar that prevents mismatches between the expected semantic model types and the shape of the parsed nodes. - -A declared type can also extend types, such as other declared types or types inferred from parser rules: - -```langium -interface MyType { - name: string -} - -interface MyOtherType extends MyType { - count: number -} - -Y returns MyOtherType: name=ID count=INT; -``` - -Explicitly declaring union types in the grammar is achieved with the keyword `type`: - -```langium -type X = A | B; -``` - -```langium -// generates: -type X = A | B; -``` - - - -Using `returns` always expects a reference to an already existing type. To create a new type for your rule, use the `infers` keyword or explicitly declare an interface. - -### Cross-references, Arrays, and Alternatives - -Declared types come with special syntax to declare cross-references, arrays, and alternatives: - -```langium -interface A { - reference: @B - array: B[] - alternative: B | C -} - -interface B { - name: string -} - -interface C { - name: string - count: number -} - -X returns A: reference=[B:ID] array+=Y (array+=Y)* alternative=(Y | Z); - -Y returns B: 'Y' name=ID; - -Z returns C: 'Z' name=ID count=INT; -``` - -### Actions - -Actions referring to a declared type have the following syntax: - -```langium -interface A { - name: string -} - -interface B { - name: string - count: number -} - -X: - {A} 'A' name=ID - | {B} 'B' name=ID count=INT; -``` - -Note the absence of the keyword `infer` compared to [actions which infer a type](#simple-actions). - -## Reference Unions - -Trying to reference different types of elements can be an error prone process. Take a look at the following rule which tries to reference either a `Function` or a `Variable`: - -```langium -MemberCall: (element=[Function:ID] | element=[Variable:ID]); -``` - -As both alternatives are only an `ID` from a parser perspective, this grammar is not decidable and the `langium` CLI script will throw an error during generation. Luckily, we can improve on this by adding a layer of indirection using an additional parser rule: - -```langium -NamedElement: Function | Variable; - -MemberCall: element=[NamedElement:ID]; -``` - -This allows us to reference either `Function` or `Variable` using the common rule `NamedElement`. However, we have now introduced a rule which is never actually parsed, but only exists for the purpose of the type system to pick up on the correct target types of the reference. Using declared types, we are able to refactor this unused rule, making our grammar more resilient in the process: - -```langium -// Note the `type` prefix here -type NamedElement = Function | Variable; - -MemberCall: element=[NamedElement:ID]; -``` - -We can also use interfaces in place of union types with similar results: - -```langium -interface NamedElement { - name: string -} - -// Infers an interface `Function` that extends `NamedElement` -Function returns NamedElement: {infer Function} "function" name=ID ...; - -// This also picks up on the `Function` elements -MemberCall: element=[NamedElement:ID]; -``` diff --git a/hugo/content/old/guides/_index.md b/hugo/content/old/guides/_index.md deleted file mode 100644 index 90f8642b..00000000 --- a/hugo/content/old/guides/_index.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -title: "Guides" -weight: 200 ---- - -On this page, you will find guides for specific topics that you often encounter while creating your own language. This includes more advanced help on how to use specific APIs offered by Langium. - -For a more systematic walk-through, consider starting with the [tutorials](/tutorials/). diff --git a/hugo/content/old/guides/builtin-library.md b/hugo/content/old/guides/builtin-library.md deleted file mode 100644 index fb749d5c..00000000 --- a/hugo/content/old/guides/builtin-library.md +++ /dev/null @@ -1,164 +0,0 @@ ---- -title: "Builtin Libraries" -weight: 300 ---- - -Languages usually offer their users some high-level programming features that they do not have to define themselves. -For example, TypeScript provides users with typings for globally accessible variables such as the `window`, `process` or `console` objects. -They are part of the JavaScript runtime, and not defined by any user or a package they might import. -Instead, these features are contributed through what we call builtin libraries. - -Loading a builtin library in Langium is very simple. We first start off with defining the source code of the library using the *hello world* language from the [getting started guide](/docs/getting-started): - -```ts -export const builtinHelloWorld = ` -person Jane -person John -`.trimLeft(); -``` - -Next, we load our builtin library code through the `loadAdditionalDocuments` method provided by the `DefaultWorkspaceManager`: - -```ts -import { - AstNode, - DefaultWorkspaceManager, - LangiumDocument, - LangiumSharedServices -} from "langium"; -import { WorkspaceFolder } from 'vscode-languageserver'; -import { URI } from "vscode-uri"; -import { builtinHelloWorld } from './builtins'; - -export class HelloWorldWorkspaceManager extends DefaultWorkspaceManager { - - private documentFactory: LangiumDocumentFactory; - - constructor(services: LangiumSharedServices) { - super(services); - this.documentFactory = services.workspace.LangiumDocumentFactory; - } - - protected override async loadAdditionalDocuments( - folders: WorkspaceFolder[], - collector: (document: LangiumDocument) => void - ): Promise { - await super.loadAdditionalDocuments(folders, collector); - // Load our library using the `builtin` URI schema - collector(this.documentFactory.fromString(builtinHelloWorld, URI.parse('builtin:///library.hello'))); - } -} -``` - -As a last step, we have to bind our newly created workspace manager: - -```ts -// Add this to the `hello-world-module.ts` included in the yeoman generated project -export type HelloWorldSharedServices = LangiumSharedServices; - -export const HelloWorldSharedModule: Module> = { - workspace: { - WorkspaceManager: (services) => new HelloWorldWorkspaceManager(services) - } -} -``` - -Be aware that this shared module is not injected by default. You have to add it manually to the `inject` call for the shared injection container. - -```ts -export function createHellowWorldServices(context: DefaultSharedModuleContext): { - shared: LangiumSharedServices, - services: HelloWordServices - } { - const shared = inject( - createDefaultSharedModule(context), - HelloWorldGeneratedSharedModule, - HelloWorldSharedModule - ); - const services = inject( - createDefaultModule({ shared }), - HelloWorldGeneratedModule, - HelloWorldModule - ); - shared.ServiceRegistry.register(services); - return { shared, services }; -} -``` - -Once everything is wired together, we are done from the perspective of our DSL. -At startup, our language server will run the `loadAdditionalDocuments` method which makes our library available for any workspace documents of the user. - -However, when trying to navigate to the builtin library elements, vscode will show users an error message, complaining that it cannot find the builtin library file. -This is expected, as the builtin library only lives in memory. -To fix this issue, we need to implement a custom `FileSystemProvider` on the client(`src/extension.ts` in the *hello world* example) that allows navigation to the builtin library files: - -```ts -import * as vscode from 'vscode'; -import { builtinHelloWorld } from './language/builtins'; - -export class DslLibraryFileSystemProvider implements vscode.FileSystemProvider { - - static register(context: vscode.ExtensionContext) { - context.subscriptions.push( - vscode.workspace.registerFileSystemProvider('builtin', new DslLibraryFileSystemProvider(context), { - isReadonly: true, - isCaseSensitive: false - })); - } - - stat(uri: vscode.Uri): vscode.FileStat { - const date = Date.now(); - return { - ctime: date, - mtime: date, - size: Buffer.from(builtinHelloWorld).length, - type: vscode.FileType.File - }; - } - - readFile(uri: vscode.Uri): Uint8Array { - // We could return different libraries based on the URI - // We have only one, so we always return the same - return new Uint8Array(Buffer.from(builtinHelloWorld)); - } - - // The following class members only serve to satisfy the interface - - private readonly didChangeFile = new vscode.EventEmitter(); - onDidChangeFile = this.didChangeFile.event; - - watch() { - return { - dispose: () => {} - }; - } - - readDirectory(): [] { - throw vscode.FileSystemError.NoPermissions(); - } - - createDirectory() { - throw vscode.FileSystemError.NoPermissions(); - } - - writeFile() { - throw vscode.FileSystemError.NoPermissions(); - } - - delete() { - throw vscode.FileSystemError.NoPermissions(); - } - - rename() { - throw vscode.FileSystemError.NoPermissions(); - } -} -... -// register the file system provider on extension activation -export function activate(context: vscode.ExtensionContext) { - DslLibraryFileSystemProvider.register(context); -} -``` - -This registers an in-memory file system for vscode to use for the `builtin` file schema. -Every time vscode is supposed to open a file with this schema, it will invoke the `stat` and `readFile` methods of the registered file system provider. diff --git a/hugo/content/old/guides/code-bundling.md b/hugo/content/old/guides/code-bundling.md deleted file mode 100644 index 29089879..00000000 --- a/hugo/content/old/guides/code-bundling.md +++ /dev/null @@ -1,119 +0,0 @@ ---- -title: "Code Bundling" -weight: 0 ---- - -When you first create a Langium project using the [Yeoman generator](/docs/getting-started/#your-first-example-language), it will only contain a plain TypeScript configuration, without any additional build processes. -However, if you want to make your language available for consumption in a non-development context, you'll want to create a bundle. -It is not absolutely necessary in a Node.js context, since you can always resolve local `node_modules` but it's still recommended [for vscode extensions](https://code.visualstudio.com/api/working-with-extensions/bundling-extension). -It improves performance and decreases file size by minifying your code and only including what you actually need. - -We generally recommend using [esbuild](https://esbuild.github.io/) to bundle Langium based language servers and extensions. To install it, simply run: - -```sh -npm i --save-dev esbuild -``` - -You can see a minimal configuration file below that bundles both your language server and your extension. - -```ts -//@ts-check -import * as esbuild from 'esbuild'; - -const watch = process.argv.includes('--watch'); -const minify = process.argv.includes('--minify'); - -const ctx = await esbuild.context({ - entryPoints: ['src/extension.ts', 'src/language/main.ts'], - outdir: 'out', - bundle: true, - target: "es6", - loader: { '.ts': 'ts' }, - external: ['vscode'], // the vscode-module is created on-the-fly and must be excluded. - platform: 'node', // VSCode extensions run in a node process - sourcemap: !minify, - minify -}); - -if (watch) { - await ctx.watch(); -} else { - await ctx.rebuild(); - ctx.dispose(); -} -``` - -Store it in a module JavaScript file (`.mjs`) and create a corresponding script in your `package.json` file: - -```js -"scripts": { - "build": "node ./esbuild.mjs" -} -``` - -If you want to use a Langium language server in the browser, you can get away with an even smaller setup with the following script: - -```js -"scripts": { - "build:worker": "esbuild ./src/main.ts --bundle --format=iife --outfile=./public/languageServerWorker.js" -} -``` - -If you're more inclined to use [webpack](https://webpack.js.org/), a configuration for an extension bundler can be seen below: - -```js -const path = require('path'); - -const commonConfig = { - target: 'node', - mode: 'none', - devtool: 'nosources-source-map', - externals: { - vscode: 'commonjs vscode' // the vscode-module is created on-the-fly and must be excluded - }, - resolve: { - extensions: ['.ts', '.js'] - }, - module: { - rules: [ - { - test: /\.js$/, - enforce: 'pre', - loader: 'source-map-loader', - exclude: /vscode/ - }, - { - test: /\.ts$/, - exclude: /node_modules/, - use: [ - { - loader: 'ts-loader' - } - ] - } - ] - } -} -const lspConfig = { - ...commonConfig, - entry: './src/language/main.ts', // the entry point of the language server - output: { - path: path.resolve(__dirname, 'out', 'language'), - filename: 'main.js', - libraryTarget: 'commonjs2', - devtoolModuleFilenameTemplate: '../../[resource-path]', - clean: true - } -}; -const vscodeConfig = { - ...commonConfig, - entry: './src/extension.ts', // the entry point of this extension - output: { - path: path.resolve(__dirname, 'out'), - filename: 'extension.js', - libraryTarget: 'commonjs2', - devtoolModuleFilenameTemplate: '../[resource-path]' - } -}; -module.exports = [lspConfig, vscodeConfig]; -``` diff --git a/hugo/content/old/guides/formatting.md b/hugo/content/old/guides/formatting.md deleted file mode 100644 index 5fec2a44..00000000 --- a/hugo/content/old/guides/formatting.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -title: "Formatting" -weight: 300 ---- - -Langium's formatting API allows to easily create formatters for your language. -We start building a custom formatter for our language by creating a new class that inherits from `AbstractFormatter`. - -```ts -import { AbstractFormatter, AstNode, Formatting } from 'langium'; - -export class CustomFormatter extends AbstractFormatter { - protected format(node: AstNode): void { - // This method is called for every AstNode in a document - } -} -... -// Bind the class in your module -export const CustomModule: Module = { - lsp: { - Formatter: () => new CustomFormatter() - } -}; -``` - -The entry point for the formatter is the abstract `format(AstNode)` method. The `AbstractFormatter` calls this method for every node of our model. -To perform custom formatting for every type of node, we will use pattern matching. -In the following example, we will take a closer look at a formatter for the [domain-model](https://github.com/eclipse-langium/langium/tree/main/examples/domainmodel) language. -In particular, we will see how we can format the root of our model (`DomainModel`) and each nested element (`Entity` and `PackageDeclaration`). - -To format each node, we use the `getNodeFormatter` method of the `AbstractFormatter`. The resulting generic `NodeFormatter` provides us with methods to select specific parts of a parsed `AstNode` such as properties or keywords. - -Once we have selected the nodes of our document that we are interested in formatting, we can start applying a specific formatting. -Each formatting option allows to prepend/append whitespace to each note. -The `Formatting` namespace provides a few predefined formatting options which we can use for this: - -* `newLine` Adds one newline character (while preserving indentation). -* `newLines` Adds a specified amount of newline characters. -* `indent` Adds one level of indentation. Automatically also adds a newline character. -* `noIndent` Removes all indentation. -* `oneSpace` Adds one whitespace character. -* `spaces` Adds a specified amount of whitespace characters. -* `noSpace` Removes all spaces. -* `fit` Tries to fit the existing text into one of the specified formattings. - -We first start off by formatting the `Domainmodel` element of our DSL. -It is the root node of every document and just contains a list of other elements. -These elements need to be realigned to the root of the document in case they are indented. -We will use the `Formatting.noIndent` options for that: - -```ts -if (ast.isDomainmodel(node)) { - // Create a new node formatter - const formatter = this.getNodeFormatter(node); - // Select a formatting region which contains all children - const nodes = formatter.nodes(...node.elements); - // Prepend all these nodes with no indent - nodes.prepend(Formatting.noIndent()); -} -``` - -Our other elements, namely `Entity` and `PackageDeclaration`, can be arbitrarily deeply nested, so using `noIndent` is out of the question for them. -Instead we will use `indent` on everything between the `{` and `}` tokens. The formatter internally keeps track of the current indentation level: - -```ts -if (ast.isEntity(node) || isPackageDeclaration(node)) { - const formatter = this.getNodeFormatter(node); - const bracesOpen = formatter.keyword('{'); - const bracesClose = formatter.keyword('}'); - // Add a level of indentation to each element - // between the opening and closing braces. - // This even includes comment nodes - formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent()); - // Also move the newline to a closing brace - bracesClose.prepend(Formatting.newLine()); - // Surround the name property of the element - // With one space to each side - formatter.property("name").surround(Formatting.oneSpace()); -} -``` - -Note that most predefined `Formatting` methods accept additional arguments which make the resulting formatting more lenient. -For example, the `prepend(newLine({ allowMore: true }))` formatting will not apply formatting in case the node is already preceeded by one **or more** newlines. -It will still correctly indent the node in case the indentation is not as expected. - -
-Full Code Sample - -```ts -import { AbstractFormatter, AstNode, Formatting } from 'langium'; -import * as ast from './generated/ast'; - -export class DomainModelFormatter extends AbstractFormatter { - - protected format(node: AstNode): void { - if (ast.isEntity(node) || ast.isPackageDeclaration(node)) { - const formatter = this.getNodeFormatter(node); - const bracesOpen = formatter.keyword('{'); - const bracesClose = formatter.keyword('}'); - formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent()); - bracesClose.prepend(Formatting.newLine()); - formatter.property('name').surround(Formatting.oneSpace()); - } else if (ast.isDomainmodel(node)) { - const formatter = this.getNodeFormatter(node); - const nodes = formatter.nodes(...node.elements); - nodes.prepend(Formatting.noIndent()); - } - } -} -``` - -
diff --git a/hugo/content/old/guides/multiple-languages.md b/hugo/content/old/guides/multiple-languages.md deleted file mode 100644 index 52853e4b..00000000 --- a/hugo/content/old/guides/multiple-languages.md +++ /dev/null @@ -1,447 +0,0 @@ ---- -title: "Multiple dependent languages" -weight: 400 ---- - -This guide is about integrating multiple dependent languages in one Langium project. - -One common situation where it makes sense to create dependent languages is when you only want to read concepts in one language and predefine them in another file (probably also a built-in one). Think of splitting SQL into a defining `CREATE TABLE table (...)`) and a reading part (`SELECT * FROM table`). - -> Notice that for `n` independent languages, you can simply create `n` independent Langium projects. - -If you want to see a living example, I recommend to visit the [`requirements` example](https://github.com/eclipse-langium/langium/tree/main/examples/requirements) of the main [Langium repository](https://github.com/eclipse-langium/langium). - -## Our plan - -The entire change touches several files. Let's summarize what needs to be done: - -1. the **grammar** (the `*.langium` file) needs to be split into the three parts that were discussed above -2. the **Langium configuration** (the `langium-config.json` file in the Langium project root) needs to split the language configuration into three parts -3. the **module file** of your language (`XXX-module.ts`) needs to create the new language services as well. -4. Last, but not least, you have to **cleanup all dependent files**. Here we can give general hints. -5. if you have a **VSCode extension** - 1. the `package.json` needs to be adapted - 2. the extension entry point file (`src/extension/main.ts`) needs to be changed slightly - -## Our scenario - -To keep this guide easy, I will use the [`hello-world` project](/docs/getting-started/). - -Let’s imagine that we have three languages: - -* the first language **defines** persons -* the second language **greets** persons of the first language -* the third language **configures** which person you are - -Just as a finger practice, let's require that you cannot greet yourself. - -{{}} -flowchart - Implementation -->|requires| Definition - Configuration -->|requires| Definition - Implementation -->|requires| Configuration -{{}} - -## Let's start - -### Grammar - -The most relevant change might be in the grammar. Here is the original grammar from the `hello-world` example, which is generated by Langium's Yeoman generator: - -```langium -grammar MultipleLanguages - -entry Model: - (persons+=Person | greetings+=Greeting)*; - -Person: - 'person' name=ID; - -Greeting: - 'Hello' person=[Person:ID] '!'; - -hidden terminal WS: /\s+/; -terminal ID: /[_a-zA-Z][\w_]*/; -terminal INT returns number: /[0-9]+/; -terminal STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/; - -hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; -hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; -``` - -Now, split it into three new files (let's call the entry rules units and the files we can name like `multiple-languages-(configuration|definition|implementation).langium`): - -Our definition grammar: - -```langium -grammar MultiDefinition - -entry DefinitionUnit: - (persons+=Person)*; - -Person: - 'person' name=ID; - -hidden terminal WS: /\s+/; -terminal ID: /[_a-zA-Z][\w_]*/; - -hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; -hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; -``` - -Our configuration grammar (note the import): - -```langium -grammar MultiConfiguration - -import "multiple-languages-definition"; - -entry ConfigurationUnit: 'I' 'am' who=[Person:ID] '.'; -``` - -Our implementation grammar (note the import again): - -```langium -grammar MultiImplementation - -import "multiple-languages-definition"; - -entry ImplementationUnit: - (greetings+=Greeting)*; - -Greeting: - 'Hello' person=[Person:ID] '!'; -``` - -### Langium configuration - -Splitting the grammar alone is not sufficient to generate anything using the CLI. You need to change the `langium-config.json` in the root folder as well. Let's make it happen! - -The initial version of this file was: - -```js -{ - "projectName": "MultipleLanguages", - "languages": [{ - "id": "multiple-languages", - "grammar": "src/language/multiple-languages.langium", - "fileExtensions": [".hello"], - "textMate": { - "out": "syntaxes/multiple-languages.tmLanguage.json" - }, - "monarch": { - "out": "syntaxes/multiple-languages.monarch.ts" - } - }], - "out": "src/language/generated" -} -``` - -The actual change is simple: Triple the object in the `languages` list and fill in reasonable values. Like here: - -```js -{ - "projectName": "MultipleLanguages", - "languages": [{ - "id": "multiple-languages-configuration", - "grammar": "src/language/multiple-languages-configuration.langium", - "fileExtensions": [".me"], - "textMate": { - "out": "syntaxes/multiple-languages-configuration.tmLanguage.json" - }, - "monarch": { - "out": "syntaxes/multiple-languages-configuration.monarch.ts" - } - }, { - "id": "multiple-languages-definition", - "grammar": "src/language/multiple-languages-definition.langium", - "fileExtensions": [".who"], - "textMate": { - "out": "syntaxes/multiple-languages-definition.tmLanguage.json" - }, - "monarch": { - "out": "syntaxes/multiple-languages-definition.monarch.ts" - } - }, { - "id": "multiple-languages-implementation", - "grammar": "src/language/multiple-languages-implementation.langium", - "fileExtensions": [".hello"], - "textMate": { - "out": "syntaxes/multiple-languages-implementation.tmLanguage.json" - }, - "monarch": { - "out": "syntaxes/multiple-languages-implementation.monarch.ts" - } - }], - "out": "src/language/generated" -} -``` - -From now on you are able to run the Langium CLI using the NPM scripts (`npm run langium:generate`). It will generate one file for the abstract syntax tree (AST) containing all languages concepts (it is also a good idea to keep the names of these concepts disjoint). - -For the next step you need to run the Langium generator once: - -```sh -npm run langium:generate -``` - -### Language module file - -The module file describes how your language services are built. -After adding two more languages, some important classes get generated - which need to be registered properly. - -1. Open the module file (`/src/language/multiple-languages-module.ts`). -2. You will notice a wrong import (which is ok, we renamed it in the previous steps and derived new classes by code generation). -3. Import the new generated modules instead. - Replace this line: - - ```ts - import { - MultipleLanguagesGeneratedModule, - MultipleLanguagesGeneratedSharedModule - } from './generated/module.js'; - ``` - - with the following: - - ```ts - import { - MultiConfigurationGeneratedModule, - MultiDefinitionGeneratedModule, - MultiImplementationGeneratedModule, - MultipleLanguagesGeneratedSharedModule - } from './generated/module.js'; - ``` - -4. In the function `createMultipleLanguagesServices` you will notice an error line now, because we deleted the old class name in the previous step. The code there needs to basically be tripled. But before we do this, we need to define the new output type of `createMultipleLanguagesServices`. In the end this should lead to this definition: - - ```ts - export function createMultipleLanguagesServices(context: DefaultSharedModuleContext): { - shared: LangiumSharedServices, - Configuration: MultipleLanguagesServices, - Definition: MultipleLanguagesServices, - Implementation: MultipleLanguagesServices - } { - const shared = inject( - createDefaultSharedModule(context), - MultipleLanguagesGeneratedSharedModule - ); - const Configuration = inject( - createDefaultModule({ shared }), - MultiConfigurationGeneratedModule, - MultipleLanguagesModule - ); - const Definition = inject( - createDefaultModule({ shared }), - MultiDefinitionGeneratedModule, - MultipleLanguagesModule - ); - const Implementation = inject( - createDefaultModule({ shared }), - MultiImplementationGeneratedModule, - MultipleLanguagesModule - ); - shared.ServiceRegistry.register(Configuration); - shared.ServiceRegistry.register(Definition); - shared.ServiceRegistry.register(Implementation); - registerValidationChecks(Configuration); - registerValidationChecks(Definition); - registerValidationChecks(Implementation); - return { shared, Configuration, Definition, Implementation }; - } - ``` - -After this step, Langium is set up correctly. But if you try to build now, the compiler will throw you some errors, because the old concepts of the AST are not existing anymore. - -> Be aware of the fact that we are using `MultipleLanguagesModule` in all three services, three independent services! If you want to avoid this (because of duplicated state etc.), you should put some work into creating instances for each service. - -### Cleanup - -Let's clean up the error lines. Here are some general hints: - -* keep in mind, that you are dealing with three file types now, namely `*.me`, `*.who` and `*.hello` - * you can distinguish them very easily by selecting the right sub service from the result object of `createMultipleLanguagesServices`, which is either `Configuration`, `Definition` or `Implementation`, but not `shared` - * all these services have a sub service with file extensions: `[Configuration,Definition,...].LanguageMetaData.fileExtensions: string[]` - * so, when you are obtaining any documents from the `DocumentBuilder` you can be sure that they are parsed by the matching language service - * to distinguish them on your own, use the AST functions for determining the root type, for example for the Configuration language use `isConfigurationUnit(document.parseResult.value)` - -### VSCode extension - -If you have a VSCode extension, you need to touch two files: `package.json` and `src/extension/main.ts`. - -#### File `package.json` - -In this file we define what services this extension will contribute to VSCode. - -Before the change only one language and grammar was defined: - -```js -//... -"contributes": { - "languages": [ - { - "id": "multiple-languages", - "aliases": [ - "Multiple Languages", - "multiple-languages" - ], - "extensions": [".hello"], - "configuration": "./language-configuration.json" - } - ], - "grammars": [ - { - "language": "multiple-languages", - "scopeName": "source.multiple-languages", - "path": "./syntaxes/multiple-languages.tmLanguage.json" - } - ] -}, -//... -``` - -After the change, we tripled the information. Be aware of that the language ids must match the ids from the Langium configuration. Also make sure that the paths to the syntax files and the language configuration are correct. - -> For the language configuration for VSCode, we reused the old file three times. If you want to make a more precise configuration per language, you should also split this file. But let's use the same for a moment and for simplicity. - -```js -//... -"contributes": { - "languages": [ - { - "id": "multiple-languages-configuration", - "aliases": [ - "Multiple Languages Configuration", - "multiple-languages-configuration" - ], - "extensions": [".me"], - "configuration": "./language-configuration.json" - }, { - "id": "multiple-languages-definition", - "aliases": [ - "Multiple Languages Definition", - "multiple-languages-definition" - ], - "extensions": [".who"], - "configuration": "./language-configuration.json" - }, { - "id": "multiple-languages-implementation", - "aliases": [ - "Multiple Languages Implementation", - "multiple-languages-implementation" - ], - "extensions": [".hello"], - "configuration": "./language-configuration.json" - } - ], - "grammars": [ - { - "language": "multiple-languages-configuration", - "scopeName": "source.multiple-languages-configuration", - "path": "./syntaxes/multiple-languages-configuration.tmLanguage.json" - }, - { - "language": "multiple-languages-definition", - "scopeName": "source.multiple-languages-definition", - "path": "./syntaxes/multiple-languages-definition.tmLanguage.json" - }, - { - "language": "multiple-languages-implementation", - "scopeName": "source.multiple-languages-implementation", - "path": "./syntaxes/multiple-languages-implementation.tmLanguage.json" - } - ] -}, -``` - -#### File `src/extension/main.ts` - -And here is the extension file before the change: - -```ts -// Options to control the language client -const clientOptions: LanguageClientOptions = { - documentSelector: [{ scheme: 'file', language: 'multiple-languages' }] -}; -``` - -After the change, it should look like this (the language IDs should be the same as they are in the Langium configuration): - -```ts -// Options to control the language client -const clientOptions: LanguageClientOptions = { - documentSelector: [ - { scheme: 'file', language: 'multiple-languages-configuration' }, - { scheme: 'file', language: 'multiple-languages-definition' }, - { scheme: 'file', language: 'multiple-languages-implementation' } - ] -}; -``` - -## Test the extension - -Now everything should be executable. **Do not forget to build**! - -Let's run the extension and create some files in our workspace: - -### Definition `people.who` - -```text -person Markus -person Michael -person Frank -``` - -### Configuration `thats.me` - -```text -I am Markus. -``` - -### Implementation `greetings.hello` - -```text -Hello Markus! -Hello Michael! -``` - -## Checklist - -You should be able now...: - -* to see proper syntax highlighting -* to trigger auto completion for keywords -* to jump to the definition by Cmd/Ctrl-clicking on a person's name - -## Add a validator (task) - -As promised, let's add a simple validation rule, that you cannot greet yourself. Therefore we enter our name in the `thats.me` file like we did in the previous step. - -Try to include the following code to our validator. This is meant as task, try to find the missing pieces on your own :-). - -```ts -checkNotGreetingYourself(greeting: Greeting, accept: ValidationAcceptor): void { - const document = getDocument(greeting); - const configFilePath = join(document.uri.fsPath, '..', 'thats.me'); - const configDocument = this.documents.getOrCreateDocument(URI.file(configFilePath)); - if (greeting.person.ref) { - if (configDocument && isConfigurationUnit(configDocument.parseResult.value)) { - if(configDocument.parseResult.value.who.ref === greeting.person.ref) { - accept('warning', 'You cannot greet yourself 🙄!', { node: greeting, property: 'person' }); - } - } - } -} -``` - -After doing so, your name should display a warning, stating that you cannot greet yourself. - -## Troubleshooting - -In this section we will list common mistakes. - -* One prominent mistake is forgetting to build Langium and Typescript files, before running the extension. - -* Since we are basically just copy-pasting given configuration, be aware of what you are pasting. Make sure that the code still makes sense after copying. You probably forgot to adapt the pasted code. - -If you encounter any problems, we are happy to help in our [discussions](https://github.com/eclipse-langium/langium/discussions) page or our [issue tracker](https://github.com/eclipse-langium/langium/issues). diff --git a/hugo/content/old/guides/scoping/_index.md b/hugo/content/old/guides/scoping/_index.md deleted file mode 100644 index e75d086e..00000000 --- a/hugo/content/old/guides/scoping/_index.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: "Scoping" -weight: 100 ---- - -You likely know scopes from programming, where some variables are only available from certain areas (such as blocks) in your program. For example, take the short Typescript snippet below. Based on the block (scope) where a variable is declared, it may or may not be available at another location in the same program. - -```ts -let x = 42; -x = 3; // References the `x` defined in the previous line - -if (condition) { - let y = 42; -} -y = 3; // Cannot link, `y` isn't in any of the available scopes -``` - -This kind of behavior is called lexical scoping. Although this default scoping implementation is suitable for prototyping -- and for some simple languages once finished -- this behavior can be easily modified to fit the needs of your language's domain. - -In general, the way we resolve references is split into three phases of the document lifecycle: -- [Symbol indexing](/docs/document-lifecycle#symbol-indexing) is responsible for making objects globally available for referencing. -- [Scope computation](/docs/document-lifecycle#computing-scopes) determines which elements are reachable from a given position in your document. -- Finally, the [linking phase](/docs/document-lifecycle#linking) eagerly links each reference within a document to its target using your language's scoping rules. - -In this guide, we'll look at different scoping kinds and styles and see how we can achieve them using Langium: - -1. [Qualified Name Scoping](./qualified-name) -2. [Class Member Scoping](./class-member) - -Note that these are just example implementations for commonly used scoping methods. -The scoping API of Langium is designed to be flexible and extensible for any kind of use case. diff --git a/hugo/content/old/guides/scoping/class-member.md b/hugo/content/old/guides/scoping/class-member.md deleted file mode 100644 index bbcce962..00000000 --- a/hugo/content/old/guides/scoping/class-member.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: "Class Member Scoping" -weight: 200 ---- - -In this guide we will take a look at member based scoping. It's a mechanism you are likely familiar with from object oriented languages such as Java, C# and JavaScript: - -```ts -class A { - b: B; -} - -class B { - value: string; -} - -function test(): void { - const a = new A(); - const b = a.b; // Refers to the `b` defined in class `A` - const value = b.value; // Refers to the `value` defined in class `B` -} -``` - -Member based scoping like this requires not only a modification of the default scoping provider, but also some other prerequisites. -This includes adding a member call mechanism in your grammar and a rudimentary type system. -For this guide, we will use excerpts from the [langium-lox](https://github.com/langium/langium-lox) project to demonstrate how you can set this up yourself. -This project implements a strongly-typed version of the [Lox language](https://craftinginterpreters.com/the-lox-language.html) from the popular book [Crafting Interpreters](https://craftinginterpreters.com/). - -We'll first start with the `MemberCall` grammar rule, which references one of our `NamedElements`. These elements could be variable declarations, functions, classes or methods and fields of those classes. Additionally, we want to allow function calls on elements. Note that the grammar has no notion of whether these elements can actually be executed as functions. Instead, we always allow function calls on every named element, and simply provide validation errors in case an element is called erroneously. After parsing the first member call, we continue parsing further members as long as the input text provides us with further references to elements; which are separated by dots. - -```langium -type NamedElement = FunctionDeclaration | VariableDeclaration | MethodMember | FieldMember | Class; - -MemberCall: - // Reference a named element of our grammar - // Variables, functions, etc. - element=[NamedElement:ID] - // Parse an operation call on this element - (explicitOperationCall?='(' ( - // Parse any arguments for the operation call - arguments+=Expression (',' arguments+=Expression)* - )? ')')? - // Create a new `MemberCall` and assign the old one to the `previous` property - // The previous member call can either be the member call that was parsed in the previous section - // Or one that is parsed in the next section due to the repetition at the end of this group - ({infer MemberCall.previous=current} - // We repeat the named element reference - ("." element=[NamedElement:ID] ( - // Parse an operation call again - explicitOperationCall?='(' - ( - arguments+=Expression (',' arguments+=Expression)* - )? - ')')? - // Our language allows to return functions in functions - // So we need to be able to call multiple functions without any element references - | ( - explicitOperationCall?='(' - ( - arguments+=Expression (',' arguments+=Expression)* - )? - ')')) - )*; -``` - -A very important aspect of these chained member calls is the action (`{infer MemberCall.previous=current}`) which rewrites the resulting AST. In this case, it reverses the direction of member call AST nodes. Instead of starting with the first encountered member call and then traversing down to the last, we start with the last and traverse the list of member calls up using the `previous` property. The reason for doing this becomes clear when looking at the scope provider for the Lox language: - -```ts -export class LoxScopeProvider extends DefaultScopeProvider { - - override getScope(context: ReferenceInfo): Scope { - // target element of member calls - if (context.property === 'element' && isMemberCall(context.container)) { - const memberCall = context.container; - const previous = memberCall.previous; - if (!previous) { - return super.getScope(context); - } - const previousType = inferType(previous); - if (isClassType(previousType)) { - return this.scopeClassMembers(previousType.literal); - } - // When the target of our member call isn't a class - // This means it is either a primitive type or a type resolution error - // Simply return an empty scope - return EMPTY_SCOPE; - } - return super.getScope(context); - } - - private scopeClassMembers(classItem: Class): Scope { - // Since Lox allows class-inheritance, - // we also need to look at all members of possible super classes for scoping - const allMembers = getClassChain(classItem).flatMap(e => e.members); - return this.createScopeForNodes(allMembers); - } -} -``` - -When trying to compute the type of an expression, we are only interested in the final piece of the member call. However, to derive the type and scope of the final member call, we have to recursively identify the type of the previous member call. This is done by looking at the member call stored in the `previous` property and inferring its type. See [here for the full implementation of the type inference system in Lox](https://github.com/langium/langium-lox/blob/main/src/language-server/type-system/infer.ts). This kind of type inference requires scoping. - -To illustrate this behavior a bit better, take a look at the following code snippet: - -```ts -class Container { - sub: SubContainer -} - -class SubContainer { - name: string -} - -// Constructor call -var element = Container(); -// Member access -println(element.sub.name); -``` - -We recursively alternate between the scope provider and the type inference system until we arrive at a member call without any previous member call. At this point we resolve the reference using the default lexical scoping which is builtin into Langium. With our scope provider in place, we can visualize how it interacts with Langium's implementation of Lox in the following sequence diagram: - -{{}} -sequenceDiagram - participant R as Language Runtime - participant T as Type System - participant S as Scope Provider - participant L as Lexical Scope - R->>T: Ask for type of expression
`element.sub.name` - T->>S: Ask for `name` node - S->>T: Ask for `sub` type - T->>S: Ask for `sub` node - S->>T: Ask for `element` type - T->>S: Ask for `element` node - S->>L: Ask for `element` node - L->>S: Give `element` node - S->>T: Give `element` node - T->>S: Ask for `Container` node - S->>L: Ask for `Container` node - L->>S: Give `Container` node - S->>T: Give `Container` node - T->>S: Give `Container` type result - S->>T: Give `sub` node - T->>S: Give `SubContainer` type result - S->>T: Give `name` node - T->>R: Give `string` type result -{{
}} - -When trying to infer the type of the expression `element.sub.name`, -we can see that this results in quite a lot of computations throughout the scoping and type systems. It is therefore recommended to cache type inference information as this naive approach to inference can quickly lead to performance issues. diff --git a/hugo/content/old/guides/scoping/qualified-name.md b/hugo/content/old/guides/scoping/qualified-name.md deleted file mode 100644 index 528006d5..00000000 --- a/hugo/content/old/guides/scoping/qualified-name.md +++ /dev/null @@ -1,238 +0,0 @@ ---- -title: "Qualified Name Scoping" -weight: 100 ---- - -Qualified name scoping refers to a style of referencing elements using a fully qualified name. -Such a fully qualified name is usually composed of the original name of the target element and the names of its container elements. -You will usually see this method of scoping in C-like languages using namespaces or in Java using packages. -The following code snippet shows an example of how qualified name scoping works from an end-user perspective, by using a function in a C++ namespace: - -```cpp -namespace Langium { - void getDocumentation(); -} - -void main() { - // Should call the `getDocumentation` function defined in the `Langium` namespace - Langium::getDocumentation(); -} -``` - -As can be seen, using qualified name scoping is quite helpful in this case. It allows us to reference the `getDocumentation` function through the scope computed & made available by the `Langium` namespace, even though it's not directly accessible within the scope of `main` by itself. - -Note that such behavior can also be accomplished using [class member scoping](./class-member). -However, there is one core advantage to using globally available elements: -Compared to member scoping, this type of scoping requires few resources. -The lookup required for qualified name scoping can be done in near constant time with just a bit of additional computation on a **per-document** basis, whereas member scoping needs to do a lot of computation on a **per-reference** basis. -With large workspaces, complex scoping might become a performance bottleneck. - -This behavior can be achieved in Langium by exporting the `getDocumentation` function under the name `Langium::getDocumentation`. To do this, we will first set up a new `ScopeComputation` class that extends the `DefaultScopeComputation`. This class will be responsible for our custom scope computation. Then, we'll want to bind our custom scope computation class in our module: - -```ts -// Scope computation for our C++-like language -export class CppScopeComputation extends DefaultScopeComputation { - - constructor(services: LangiumServices) { - super(services); - } -} - -// Services module for overriding the scope computation -// Your language module is usually placed in your `-module.ts` file -export const CppModule: Module = { - references: { - ScopeComputation: (services) => new CppScopeComputation(services) - } -} -``` - -Next, we can start implementing our custom scoping by overriding the `computeExports` function. This function is particularly important, as it allows us to change export nodes of our model using qualified names: We'll also want to annotate this function with `override`, since there's already a default definition provided. - -```ts -export class CppScopeComputation extends DefaultScopeComputation { - - // Emitting previous implementation for brevity - - /** - * Export all functions using their fully qualified name - */ - override async computeExports(document: LangiumDocument): Promise { - const exportedDescriptions: AstNodeDescription[] = []; - for (const childNode of streamAllContents(document.parseResult.value)) { - if (isFunctionDeclaration(childNode)) { - const fullyQualifiedName = this.getQualifiedName(childNode, childNode.name); - // `descriptions` is our `AstNodeDescriptionProvider` defined in `DefaultScopeComputation` - // It allows us to easily create descriptions that point to elements using a name. - exportedDescriptions.push(this.descriptions.createDescription(modelNode, fullyQualifiedName, document)); - } - } - return exportedDescriptions; - } - - /** - * Build a qualified name for a model node - */ - private getQualifiedName(node: AstNode, name: string): string { - let parent: AstNode | undefined = node.$container; - while (isNamespace(parent)) { - // Iteratively prepend the name of the parent namespace - // This allows us to work with nested namespaces - name = `${parent.name}::${name}`; - parent = parent.$container; - } - return name; - } -``` - -Once we start exporting functions using their fully qualified name, references such as `QualifiedName::target` will start working correctly. We can even nest multiple namespaces to create `Fully::Qualified::Name::target`. However, this leads us to another problem. We can now only reference functions using their fully qualified names, even if they're locally available: - -```cpp -namespace QualifiedName { - void target(); - void test() { - // Will not link correctly - target(); - // Requires the new fully qualified name - QualifiedName::target(); - } -} -``` - -To rectify this problem, we have to override the `computeLocalScopes` method, which provides access to elements that aren't exported globally. We can also use this method to provide secondary access to globally available objects using a local name. - -```ts -export class CppScopeComputation extends DefaultScopeComputation { - - // Emitting previous implementation for brevity - - override async computeLocalScopes(document: LangiumDocument): Promise { - const model = document.parseResult.value as CppProgram; - // This map stores a list of descriptions for each node in our document - const scopes = new MultiMap(); - this.processContainer(model, scopes, document); - return scopes; - } - - private processContainer( - container: CppProgram | Namespace, - scopes: PrecomputedScopes, - document: LangiumDocument - ): AstNodeDescription[] { - const localDescriptions: AstNodeDescription[] = []; - for (const element of container.elements) { - if (isFunctionDeclaration(element)) { - // Create a simple local name for the function - const description = this.descriptions.createDescription(element, element.name, document); - localDescriptions.push(description); - } else if (isNamespace(element)) { - const nestedDescriptions = this.processContainer(element, scopes, document, cancelToken); - for (const description of nestedDescriptions) { - // Add qualified names to the container - // This could also be a partial qualified name - const qualified = this.createQualifiedDescription(element, description, document); - localDescriptions.push(qualified); - } - } - } - scopes.addAll(container, localDescriptions); - return localDescriptions; - } - - private createQualifiedDescription( - container: Namespace, - description: AstNodeDescription, - document: LangiumDocument - ): AstNodeDescription { - // `getQualifiedName` has been implemented in the previous section - const name = this.getQualifiedName(container.name, description.name); - return this.descriptions.createDescription(description.node!, name, document); - } -} -``` - -This new change now allows us to use local names of functions in the local scope, while they are still exported using their fully qualified name to the global scope. -Another example for this style of scoping can be seen in the [domain-model example language](https://github.com/eclipse-langium/langium/tree/main/examples/domainmodel). -Also, click the following note to see the full implementation of the scope computation service. - -
-Full Implementation - -```ts -export class CppScopeComputation extends DefaultScopeComputation { - - /** - * Export all functions using their fully qualified name - */ - override async computeExports(document: LangiumDocument): Promise { - const exportedDescriptions: AstNodeDescription[] = []; - for (const childNode of streamAllContents(document.parseResult.value)) { - if (isFunctionDeclaration(childNode)) { - const fullyQualifiedName = this.getQualifiedName(childNode, childNode.name); - // `descriptions` is our `AstNodeDescriptionProvider` defined in `DefaultScopeComputation` - // It allows us to easily create descriptions that point to elements using a name. - exportedDescriptions.push(this.descriptions.createDescription(modelNode, fullyQualifiedName, document)); - } - } - return exportedDescriptions; - } - - override async computeLocalScopes(document: LangiumDocument): Promise { - const model = document.parseResult.value as CppProgram; - // This multi-map stores a list of descriptions for each node in our document - const scopes = new MultiMap(); - this.processContainer(model, scopes, document); - return scopes; - } - - private processContainer( - container: CppProgram | Namespace, - scopes: PrecomputedScopes, - document: LangiumDocument - ): AstNodeDescription[] { - const localDescriptions: AstNodeDescription[] = []; - for (const element of container.elements) { - if (isFunctionDeclaration(element)) { - // Create a simple local name for the function - const description = this.descriptions.createDescription(element, element.name, document); - localDescriptions.push(description); - } else if (isNamespace(element)) { - const nestedDescriptions = this.processContainer(element, scopes, document, cancelToken); - for (const description of nestedDescriptions) { - // Add qualified names to the container - // This could also be a partially qualified name - const qualified = this.createQualifiedDescription(element, description, document); - localDescriptions.push(qualified); - } - } - } - scopes.addAll(container, localDescriptions); - return localDescriptions; - } - - private createQualifiedDescription( - container: Namespace, - description: AstNodeDescription, - document: LangiumDocument - ): AstNodeDescription { - const name = this.getQualifiedName(container.name, description.name); - return this.descriptions.createDescription(description.node!, name, document); - } - - /** - * Build a qualified name for a model node - */ - private getQualifiedName(node: AstNode, name: string): string { - let parent: AstNode | undefined = node.$container; - while (isNamespace(parent)) { - // Iteratively prepend the name of the parent namespace - // This allows us to work with nested namespaces - name = `${parent.name}::${name}`; - parent = parent.$container; - } - return name; - } -} -``` - -
diff --git a/hugo/content/old/tutorials/_index.md b/hugo/content/old/tutorials/_index.md deleted file mode 100644 index 6295b409..00000000 --- a/hugo/content/old/tutorials/_index.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: "Tutorials" -weight: 200 ---- - -In this section you'll find helpful tutorials aimed at teaching you how to implement Langium for concrete applications. - -These tutorials revolve around the MiniLogo language, implemented in Langium. They describe how to implement MiniLogo from the ground up, and how to customize the various features of MiniLogo. - -By working through each of these tutorials, you'll be learning about: - -- writing a grammar in Langium -- implementing validation for your language -- customizing a CLI for your tooling -- writing up a simple generator -- building a VSCode extension -- running Langium in the web with the Monaco editor -- implementing generation in the web - -By the end of this series, you should be equipped to start working on your own language, and also have a pretty good idea for how you can integrate Langium into other projects as well. - -With that being said, hop on in to the first guide on [Writing a Grammar in Langium](writing_a_grammar)! diff --git a/hugo/content/old/tutorials/building_an_extension/icon.png b/hugo/content/old/tutorials/building_an_extension/icon.png deleted file mode 100644 index 9beea261318ced153fafd3d82823f4ed8d22a723..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163818 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 diff --git a/hugo/content/old/tutorials/building_an_extension/index.md b/hugo/content/old/tutorials/building_an_extension/index.md deleted file mode 100644 index a6d460ea..00000000 --- a/hugo/content/old/tutorials/building_an_extension/index.md +++ /dev/null @@ -1,90 +0,0 @@ ---- -title: "Building an Extension" -weight: 5 ---- - -{{< toc format=html >}} - -In this tutorial we'll be going over how to build a VSIX extension (VSCode extension) for your Langium-based language. This will allow providing LSP support in VSCode for your language. We'll assume that you've already looked at the previous tutorial, and have had time to read the [guide on bundling](/guides/code-bundling/), so that you're ready to build an extension. At this point we assume that your language is also working, and there are no issues running `npm run langium:generate` or `npm run build`. If there are, you'll want to correct those first. - -## Setting up the Scripts - -To get started, you'll want to have a language expressed in Langium, such as [Lox](https://github.com/langium/langium-lox) or [MiniLogo](https://github.com/langium/langium-minilogo). If you have been following along with these tutorials, you should already have something ready. If you don't you can also use the default language generated by the yeoman generator for Langium, presented in the [getting started](/docs/getting-started/) section. - -Regardless of what you're working with, you'll want to make sure you have the following scripts in your **package.json**. - -```json -{ - ... - "vscode:prepublish": "npm run esbuild-base -- --minify && npm run lint", - "esbuild-base": "esbuild ./src/extension/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node", - ... -} -``` - -The `esbuild-base` script is particularly important, as it will be constructing the extension itself. - -You'll also need to install `esbuild` if you haven't already. - -```bash -npm i --save-dev esbuild -``` - -## Generate an Extension - -At this point we're ready to generate an extension. We need the VS Code Extension Manager (`vsce`) to do this, so make sure to download this from npm via `npm install -g @vscode/vsce` (or install locally, as per your preference). Once you have that installed, you can invoke it like so from the root of your project. - -```bash -vsce package -``` - -You should now see a VSIX extension file in the root of your project. The name of this file will correspond with the **name** and **version** properties listed in your **package.json**. For MiniLogo, this produced **minilogo-0.1.0.vsix**. - -{{< figure src="minilogo-vsix.jpg" height="225" >}} - -## Installing - -For installing the extension, you can right click the extension file, and select "Install VSIX Extension" at the bottom of the list. - -{{< figure src="vsix-install.jpg" title="Indication that VSIX extension has been installed" height="400" >}} - -You should see a small indication at the bottom right of your screen that your VSIX extension has been successfully installed, like so: - -![Indication that VSIX extension has been installed](vsix-installed.jpg) - -You can verify this by going to your extensions tab and looking at the enabled extensions, where you should find the name of your language (again corresponding to the **name** property in your package.json). - -{{< figure src="installed-extension.jpg" height="400" >}} - -Assuming the extension is enabled and working correctly, you can open any file that ends in the extensions registered for your language, and you should immediately observe the syntax highlighting kicking in. Interaction with your language should show that syntax errors are recognized, and other LSP functionalities are working as intended (such as renaming of symbols). - -## Adding an Icon - -You may notice that your extension may not have an icon to start with. This is a small thing that we can quickly fix. This is as simple as adding a small PNG icon somewhere in your project repo, such as the root. You'll also want to set the **icon** property in your package.json with the relative path to this icon. - -```json -{ - ... - "name": "minilogo", - "displayName": "minilogo", - "icon": "icon.png", - "publisher": "TypeFox", - ... -} -``` - -In our example, we're using a simple turtle icon from [onlinewebfonts](https://www.onlinewebfonts.com/icon/74548) as a placeholder. - -{{< figure src="icon.png" height="200" >}} - -When you regenerate your extension & reinstall it, you should get an icon that is the same as the one that you packaged it with. - -{{< figure src="minilogo-with-icon.png" height="300" >}} - -## Conclusion - -And that's it, at this point you have an extension for your language that you can use for development. After some testing, and improvements, you could even publish it! - -As a quick aside, it's important to keep the extensions that your language recognizes synchronized in both your **package.json** and your **langium-config.json**. If you do make changes to your extensions, it's a good idea to double check that these are both synced up, and to do a full rebuild to get those changes into your extension. - -And that's it for building an extension. In the next tutorial, we'll be setting up [Langium + Monaco in the web](/tutorials/langium_and_monaco/). diff --git a/hugo/content/old/tutorials/building_an_extension/installed-extension.jpg b/hugo/content/old/tutorials/building_an_extension/installed-extension.jpg deleted file mode 100644 index 235b1aa0b4a26de9c1e28ca960d7958d174614de..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119541 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 H=P~~;OUy3< diff --git a/hugo/content/old/tutorials/building_an_extension/minilogo-vsix.jpg b/hugo/content/old/tutorials/building_an_extension/minilogo-vsix.jpg deleted file mode 100644 index 4407ebdc7e78428120fe9c05edcd57265dc5a11e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33381 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 diff --git a/hugo/content/old/tutorials/building_an_extension/minilogo-with-icon.png b/hugo/content/old/tutorials/building_an_extension/minilogo-with-icon.png deleted file mode 100644 index 71a1d684735699512d09b069207697183fcd9dbc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121740 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 z%0D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 diff --git a/hugo/content/old/tutorials/building_an_extension/vsix-install.jpg b/hugo/content/old/tutorials/building_an_extension/vsix-install.jpg deleted file mode 100644 index cc832f4cbdeec2ca1cc02e870e558a830ba72df9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 114994 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 Wvj`kHw{)@sa<5rdssc0^>irL*dULb@ diff --git a/hugo/content/old/tutorials/building_an_extension/vsix-installed.jpg b/hugo/content/old/tutorials/building_an_extension/vsix-installed.jpg deleted file mode 100644 index f822015c90d26c35d052526a85ef08d34132db60..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23871 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 - -In this tutorial, we'll be talking about customizing the command line interface for your language. We recommend reading through previous tutorials about [writing a grammar](/tutorials/writing_a_grammar) and [validation](/tutorials/validation). Once you have a good grasp on those concepts, then you should be all set for setting up a CLI. We will also continue to use the [MiniLogo](https://github.com/langium/langium-minilogo) language as a motivating example. - -## Overview - -Once you have a grammar and some validation in place, you may want to start configuring a basic CLI for your language. This is an important step where your language begins to become more accessible to other programs. Having a CLI for your language is a powerful way to access functionality that is expressed through Langium, but without having to interact directly with Langium. A well designed CLI can be used by other applications to provide advanced language features, without making those other applications unnecessarily complex. - -## About the Command Line Interface - -If you've been using a language built with the yeoman generator for Langium, you should be able to find your CLI defined in **src/cli/index.ts**. This file describes the general layout of your languages's command line interface, and lets you register specific commands. By default, you're provided with a single command for your CLI, the **generate** command. - -Much like the command implies, it allows you to take a program written in your DSL, parse it, and traverse the AST to produce some sort of generated output. We won't talk about the generator itself in this tutorial (that will come in the [next tutorial on generation](/tutorials/generation)). Instead we'll focus on a simple example for parsing and validating a program, which allows learning more about the CLI itself. - -## Adding a Parse and Validate Action - -To start, let's write up a custom action to allow us to **parse** and **validate** a program in our language. If we've already written up a grammar, and already added some basic validation, then all we have to do is hookup the CLI action here to get this to work. This action will help us verify that our MiniLogo programs have no syntax errors, and also pass our custom validations. - -Feel free to keep (or remove) the existing **generate** action, as we won't be setting that up until the next tutorial. We'll be sure to present example code for that as well, so don't worry about deleting functions that you'll need later. - -In order to add our new command, we need to register it in the default export for the **index.ts** file. In this function, there's a **command** object, which is a collection of commands for our CLI. Let's call our command `parseAndValidate`, and give it some extra details, like: - -- **arguments**: Indicating that it takes a single file -- a **description** detailing what this action does -- an **action** that performs the actual parsing and validation - -We could also add additional options, but we won't be doing that for this action. - -We can register our parse and validate action like so: - -```ts -program - .command('parseAndValidate') - .argument('', 'Source file to parse & validate (ending in ${fileExtensions})') - .description('Indicates where a program parses & validates successfully, but produces no output code') - .action(parseAndValidate) // we'll need to implement this function -``` - -Finally, we need to implement the `parseAndValidate` function itself. This will allow us to be able to parse & validate our programs, but without producing any output. We just want to know when our program is 'correct' by the constraints of our language implementation. - -Using parts of the existing `generateAction` function we got by default, we can do our parsing & validation without having to write too much new code at all. - -```ts -import { extractDocument } from './cli-util'; -... -/** - * Parse and validate a program written in our language. - * Verifies that no lexer or parser errors occur. - * Implicitly also checks for validation errors while extracting the document - * - * @param fileName Program to validate - */ -export const parseAndValidate = async (fileName: string): Promise => { - // retrieve the services for our language - const services = createHelloWorldServices(NodeFileSystem).HelloWorld; - // extract a document for our program - const document = await extractDocument(fileName, services); - // extract the parse result details - const parseResult = document.parseResult; - // verify no lexer, parser, or general diagnostic errors show up - if (parseResult.lexerErrors.length === 0 && - parseResult.parserErrors.length === 0 - ) { - console.log(chalk.green(`Parsed and validated ${fileName} successfully!`)); - } else { - console.log(chalk.red(`Failed to parse and validate ${fileName}!`)); - } -}; -``` - -Some amount of the contents for our custom action are shared with the `generateAction` function. This isn't surprising given that we still need to set up our language's services. - -## Building and Running the CLI - -Now that we have our new action in place, we'll want to build and verify the CLI works for a program written in our language. - -If you've been following along from the hello world example produced by the yeoman generator, then you'll have some errors at this point that need to be corrected as follows. - -If you have errors with regards to any imports of `HelloWorld...`, this is likely related to your `grammar NAME` in your langium file being something different than the original `HelloWorld`. The name of these imports will change based on your grammar file's name after `npm run langium:generate`, so in each case you should be able to change each import to `MyLanguage...` to resolve the issue. - -You may also have build errors related to the generator logic, especially if it was written for the hello-world semantic model. For now, we can comment out the generator function's contents in **src/cli/generator.ts**, return an empty string, and comment/remove the imports to make Typescript happy. In the next tutorial, we'll come back to it and implement an initial version of a generator for our language. - -If you have any other errors while building, double check that the exported & imported names match up. More often than note there's a small discrepancy here, especially when you use a different language name than the default. - -At this point, you should be able to run the following with no errors from the project root. - -```bash -npm run langium:generate -npm run build -``` - -If everything looks good, you should have access to the CLI in **/bin/cli**. We also need a program we can test and validate. For the MiniLogo language we have a simple example program that we can validate: - -```minilogo -def test() { - pen(down) - move(10,10) - pen(up) -} - -test() -``` - -We'll save this under our project root as **test.logo**, and we can test that it's correct using our CLI like so: - -```bash -./bin/cli parseAndValidate test.logo -``` -NOTE: The langium-minilogo repo places `test.logo` in an `examples` subdirectory under the project root. So, for that case, the CLI usage would be: -```bash -./bin/cli parseAndValidate examples/test.logo -``` -It does not matter where you place your .logo files. Organize them as you see fit. - -We should get an output indicating that there were no errors with our program. - -> Parsed and validated test.logo successfully! - -If you get a message that indicates you need to choose a file with a given extension, you'll want to go back and update your list of extensions in your **package.json** and your **langium-config.json** in your project root. Then you'll need to run `npm run langium:generate` followed by `npm run build` to get that change incorporated into your CLI. - -If we wanted to verify that we *can* get errors, we can modify our program a bit to include a duplicate definition (which we should have a validation for, as we implemented in the validation tutorial). - -```minilogo -def test() { - pen(down) - move(10,10) - pen(up) -} - -// redefinition of test, should 'not' validate -def test() { - pen(up) -} - -test() -``` - -Running the CLI again should show that this program has an error, and better yet it will show us exactly the error in question. - -> There are validation errors: -> -> line 7: Def has non-unique name 'test'. [test] - -This is perfect, as we didn't have to implement too much more logic to get validation in our CLI. Since we already hooked up our validation service before, the CLI just handles the interaction with an external program. This separation of concerns makes for a very flexible implementation that is easy to adapt over time. - -That sums up how to add basic CLI functionality. [In the next tutorial, we will be talking about generation in more detail](/tutorials/generation), specifically about techniques that you can use to traverse your AST and produce a generated output. diff --git a/hugo/content/old/tutorials/generation.md b/hugo/content/old/tutorials/generation.md deleted file mode 100644 index adad2497..00000000 --- a/hugo/content/old/tutorials/generation.md +++ /dev/null @@ -1,378 +0,0 @@ ---- -title: "Generation" -weight: 3 ---- - -{{< toc format=html >}} - -In this tutorial we'll be showing how to implement basic generation for your language. When we're talking about generation, we're talking about transforming an AST from your Langium-based language into some output target. This could be another language of similar functionality (transpilation), a lower level language (compilation), or generating some artifacts/data that will be consumed by another application. If you haven't already, make sure to go back over and check out the [tutorial on customizing your CLI](/tutorials/customizing_cli), as it touches on details about how to implement endpoints for your application (like generation). - -Per usual, we'll be using the MiniLogo language as a motivating example here. - -We'll be describing how to write a simple MiniLogo generator to output drawing a JSON array of drawing instructions. This tutorial will give you a general idea of how you can traverse an AST to produce generated output. - -## Setting up the Generator API - -To write the generator, we're going to work in the **src/cli/generator.ts** file. If you're using a language produced by the yeoman generator for Langium, then you should already have a function in here called `generateJavascript`. For MiniLogo, we'll change this to `generateCommands`, which will generate drawing commands to be handled later. We will also change the function signature to take a `Model`, and return a string of the generated file path. - -```ts -// import the 'Model' type from our semantic model -import { Model } from '../language/generated/ast.ts'; - -export function generateCommands(mode: Model, filePath: string, destination: string | undefined): string { - // ... -} -``` - -This function will serve as our generator endpoint. All MiniLogo programs that we want to generate from will be processed from here. - -Now, our objective is to take a program like this: - -```minilogo -def test() { - pen(down) - move(10,10) - pen(up) -} - -test() -``` - -And translate it into a generated JSON-like list of drawing commands like so: - -```json -[ - { cmd: 'penDown' }, - { cmd: 'move', x: 10, y: 10 }, - { cmd: 'penUp' } -] -``` - -## Deciding Output to Generate - -Notice that there's no notion of macros, definitions, for loops, or other constructs that are present in MiniLogo. We only need to produce a generated output that contains information relevant to our *semantic domain*. If you remember this term from the very beginning of writing our grammar, then you'll likely also remember that our semantic domain is a series of transformations performed on a drawing context. With this in mind, we can safely reduce a MiniLogo program to such a series of transformations on the pen, position, and color. We don't need to include anything else. In this context, you could think of it like a form of evaluation. - -To be able to produce this output, we need to be able to traverse through all nodes of our AST. We can perform such a traversal by creating functions that map from our AST to our generated output. This is as simple as accessing the properties stored on a node, and writing functions to process the types of those properties such that generation is defined for every type of node in your AST. - -An example of this would be defining a `generateStatements` function that takes a list of Statements, and produces some generated result from those statements. Anytime we were working with a node that contained statements, we could invoke this function on it, and return the results. - -We can add this function to our `generateCommands` function to begin generation from the top-level statements in our `Model`. - -```ts -export function generateCommands(mode: Model, filePath: string, destination: string | undefined): string { - const result: Object[] = generateStatements(model.stmts); - -} - -... - -function generateStatements(stmts: Stmt[]): Object[] { ... } -``` - -As a side note, to support generation with string content (like for generating file/program contents) we've added a `CompositeGeneratorNode` that is designed to help collect generated output. This is located in our **cli-util.ts**, and provides more structure with constructing textual outputs, without resorting to direct manipulation of strings. - -## Generating from Statements - -Now, let's expand on `generateStatements`. From our grammar, there are 5 types of statements: - -- **pen** -- **move** -- **macro** -- **for** -- **color** - -We we want to expand our function to handle each of these cases. This is easy to do using some special `isTYPE` functions made available from our semantic model. These are automatically generated from our grammar, and allow us to verify the type of a node from our AST at runtime. - -```ts -import { isPen, isMove, isMacro, isFor, isColor } from '../language/generated/ast'; - -... - -if(isPen(stmt)) { - ... -} else if(isMove(stmt)) { - ... -} else if(isMacro(stmt)) { - ... -} else if(isFor(stmt)) { - ... -} else if (isColor(stmt)) { - ... -} -``` - -For `isPen` we have the easiest case where we could emit something like so: - -```ts -{ - cmd: stmt.mode === 'up' ? 'penUp' : 'penDown' -}; -``` - -However, for the rest of the statements, we need to be able to evaluate expressions first. - -## Writing an Expression Evaluator - -We need to *evaluate* our expressions to final values for statements, as we don't want to emit literal expressions like `1 + x * 5`; but rather their evaluated result. We'll handle this in a new `evalExprWithEnv` function. - -```ts -// map of names to values -type MiniLogoGenEnv = Map; - -// evalutes exprs in the context of an env -function evalExprWithEnv(e: Expr, env: MiniLogoGenEnv): number { - ... -} -``` - -As we mentioned before, in order to perform generation in this context, we're also writing an evaluator for our language. Thankfully, MiniLogo is relatively simple, especially since it doesn't have variables outside of definitions and for loops. - -So let's write our expression evaluator. Assuming we have the function declaration from above, our first case to be added into that function is for `Lit`. Again, this is imported from our generated semantic model. - -```ts -if(isLit(e)) { - return e.val; -} -``` - -Pretty easy. A literal returns its value. Now for references. - -```ts -if(isRef(e)) { - const v = env.get(e.val.ref?.name ?? ''); - if (v !== undefined) { - return v; - } - // handle the error case... -} -``` - -Since we have cross references, we can retrieve the node in question (ref), and check if we have a value stored for its name. In the case that we do, we return the value, otherwise we would want to report an error. - -For binary expressions, we can invoke `evalExprWithEnv` recursively on the left & right operands. Since we used actions to restructure our semantic model a bit, we have access to this `isBinExpr` function to find `BinExpr` nodes. It's quite convenient, since we can now handle all 4 cases at once. - -```ts -if(isBinExpr(e)) { - let opval = e.op; - let v1 = evalExprWithEnv(e.e1, env); - let v2 = evalExprWithEnv(e.e2, env); - - switch(opval) { - case '+': return v1 + v2; - case '-': return v1 - v2; - case '*': return v1 * v2; - case '/': return v1 / v2; - default: throw new Error(`Unrecognized bin op passed: ${opval}`); - } -} -``` - -For negated expressions, it's also fairly straight forward. We invert whatever value we would get normally. - -```ts -if (isNegExpr(e)) { - return -1 * evalExprWithEnv(e.ne, env); -} -``` - -Lastly, for groups we extract the 'grouped' value and evaluate it. - -```ts -if(isGroup(e)) { - return evalExprWithEnv(e.ge, env); -} -``` - -Lastly, it's always a good measure to *sanity check* that you aren't missing a case. Throwing an error is often much more desirable than having something silently fail, and produce strange results on generation. This means adding a default for your switches, and a final `else` clause to handle unexpected nodes. - -With all those cases above, we can combine them into a series of `else if` clauses to have a clean case-by-case check. - -## Generating from Statements with the Evaluator - -Now that we can evaluate expressions, we can handle the rest of our statement cases. In order to incorporate our `env`, we'll also want to update our `generateStatements` function, and create a new `evalStmt` function to help out. - -```ts -function generateStatements(stmts: Stmt[]): Object[] { - // minilogo evaluation env - let env : MiniLogoGenEnv = new Map(); - - // generate mini logo cmds off of statements - return stmts.flatMap(s => evalStmt(s,env)).filter(e => e !== undefined) as Object[]; -} - -/** - * Takes an statement, an environment, and produces a list of generated objects - */ -function evalStmt(stmt: Stmt, env: MiniLogoGenEnv) : (Object | undefined)[] { - if (isPen(stmt)) { - return [{ - cmd: stmt.mode === 'up' ? 'penUp' : 'penDown' - }]; - } - - // ... the rest of our cases will follow ... -} -``` - -This gives us an `env` that can be updated by evaluating each statement, and persist from one to another; which is what we want for MiniLogo. Now, for `isMove`, we just need to evaluate the x & y arguments to their values using this env - -```ts -if (isMove(stmt)) { - return [{ - cmd: 'move', - x: evalExprWithEnv(stmt.ex, env), - y: evalExprWithEnv(stmt.ey, env) - }]; -} -``` - -For `isMacro` we need to save and restore our execution environment after the macro has been evaluated. We can do this by generating a new env, setting the parameters from the arguments, and passing that new env to the macro's statements instead. - -*Keep in mind* arguments need to be evaluated before setting them into the env, and we want to carefully do this using the *original* env, not the new one being constructed. If there are names that already exist, and would be shadowed by this macro, then it could change the result of the macro (or even the value of subsequent arguments). - -```ts -// get the cross ref -const macro: Def = stmt.def.ref as Def; - -// copied env -let macroEnv = new Map(env); - -// produce pairs of string & exprs, using a tmp env -// this is important to avoid mixing of params that are only present in the tmp env w/ our actual env -let tmpEnv = new Map(); - -// evalute args independently, staying out of the environment -macro.params.map((elm, idx) => tmpEnv.set(elm.name, evalExprWithEnv(stmt.args[idx], macroEnv))); -// add new params into our copied env -tmpEnv.forEach((v,k) => macroEnv.set(k,v)); - -// evaluate all statements under this macro -return macro.body.flatMap(s => evalStmt(s, macroEnv)); -``` - -For `isFor`, we also use a copied env, so that we don't alter the original env outside of the loop. - -```ts -// compute for loop bounds -// start -let vi = evalExprWithEnv(stmt.e1, env); -// end -let ve = evalExprWithEnv(stmt.e2, env); - -let results : (Object | undefined)[] = []; - -// perform loop -const loopEnv = new Map(env); -while(vi < ve) { - loopEnv.set(stmt.var.name, vi++); - stmt.body.forEach(s => { - results = results.concat(evalStmt(s, new Map(loopEnv))); - }); -} - -return results; -``` - -Lastly, to handle `isColor`, check whether one set of properties is defined or the other (like color vs. any of the r,g,b properties). - -```ts -if (stmt.color) { - // literal color text or hex - return [{cmd:'color', color: stmt.color}] -} else { - // color as rgb - const r = evalExprWithEnv(stmt.r!, env); - const g = evalExprWithEnv(stmt.g!, env); - const b = evalExprWithEnv(stmt.b!, env); - return [{cmd:'color', r, g, b}] -} -``` - -With that, we're effectively done writing the core of our generator! The last changes to make are to write the output to a file, and to connect what we've written here with a command in our CLI. - -## Connecting the Generator to the CLI - -To do this, we can go back to the top of our generator, and update the `generateCommands` function to write the generated result to a file. Most of the structure here is carried over from the original code first setup by the yeoman generator, which makes it convenient to add in. - -```ts -export function generateCommands(model: Model, filePath: string, destination: string | undefined): string { - const data = extractDestinationAndName(filePath, destination); - const generatedFilePath = `${path.join(data.destination, data.name)}.json`; - - if (!fs.existsSync(data.destination)) { - fs.mkdirSync(data.destination, { recursive: true }); - } - - const result = generateStatements(model.stmts); - - fs.writeFileSync(generatedFilePath, JSON.stringify(result, undefined, 2)); - return generatedFilePath; -} -``` - -And to connect it to the CLI, which is setup in **src/cli/index.ts**, we can register it by slightly modifying the existing `generateAction` endpoint that was there by default. - -```ts -export const generateAction = async (fileName: string, opts: GenerateOptions): Promise => { - const services = createHelloWorldServices(NodeFileSystem).HelloWorld; - const model = await extractAstNode(fileName, services); - // now with 'generateCommands' instead - const generatedFilePath = generateCommands(model, fileName, opts.destination); - console.log(chalk.green(`MiniLogo commands generated successfully: ${generatedFilePath}`)); -}; -``` - -Towards the bottom of the same file, we'll modify the description for the logic that registers this action: - -```ts -program - .command('generate') - .argument('', `source file (possible file extensions: ${fileExtensions})`) - .option('-d, --destination

', 'destination directory of generating') - // new description - .description('generates MiniLogo commands that can be used as simple drawing instructions') - .action(generateAction); -``` - -And that's it. Now we can run the following to generate commands from a MiniLogo file of our choice. - -```bash -npm run build -./bin/cli generate test.logo -``` - -This should produce **generated/test.json**, which contains a JSON array of the drawing commands generated by our program. For the following example program: - -```minilogo -def test() { - pen(down) - move(10,10) - pen(up) -} - -test() -``` - -our JSON output should be: - -```json -[ - { - "cmd": "penDown" - }, - { - "cmd": "move", - "x": 10, - "y": 10 - }, - { - "cmd": "penUp" - } -] -``` - -If you're looking at the implementation of [MiniLogo that we've already written in the Langium organization on Github](https://github.com/langium/langium-minilogo), you may notice that the program and output there are *slightly* different. This interpretation of MiniLogo has gone through some iterations, and so there are some slight differences here and there. What's most important is that your version produces the generated output that you expect. - -We could continue to extend on this with new features, and generate new sorts of output using a given input language. In this tutorial, we're able to take a MiniLogo program and convert it into some simple JSON drawing instructions that can be consumed by another program. This opens the door for us to write such a program in another language, such as Python or Javascript, and draw with these results. In later tutorials, we'll be talking about how to run Langium in the web with generation, so that we can immediately verify our results by drawing on an HTML5 canvas. - -We recommend that you next read [the guide on bundling your language with Langium to reduce its size](/guides/code-bundling), before moving onto the tutorial about [bundling an extension](/tutorials/building_an_extension). This is an important step before deployment as an extension for VSCode, and also if you're planning to later deploy your language in the web. diff --git a/hugo/content/old/tutorials/generation_in_the_web.md b/hugo/content/old/tutorials/generation_in_the_web.md deleted file mode 100644 index 46f923de..00000000 --- a/hugo/content/old/tutorials/generation_in_the_web.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -title: "Generation in the Web" -weight: 7 ---- - -{{< toc format=html >}} - -*Updated on Oct. 4th, 2023 for usage with monaco-editor-wrapper 3.1.0 & above.* - -In this tutorial we'll be talking about how to perform generation in the web by listening for document builder notifications. There are multiple ways to hook into Langium to utilize the generator, such as by directly exporting the generator API. However, by listening to notifications from the document builder, we can do this with less code. This lets us quickly integrate new functionality into our existing Langium + Monaco integration, and focus more on what we would want to do with the generated output. - -*(This tutorial previously utilized custom LSP commands to achieve the same goal of generation. This is still a valid approach, but we've found setting up listening for notifications this way is much more straightforward. We've implemented this in our own example languages as well, and would recommend it going forward.)* - -We'll assume that you've already looked over most of the other tutorials at this point. It is particularly important that you have a language with working generation, and have a working instance of Langium + Monaco for your language (or another editor of your choice). In the case that you don't have a language to work with, you can follow along with [MiniLogo](https://github.com/langium/langium-minilogo), which is the example language used throughout many of these tutorials. - -Since we're working with MiniLogo here, we already know that our generated output is in the form of drawing instructions that transform some drawing context. The generated output that we've implemented so far consists of a JSON array of commands, making it very easy to interpret. Now that we're working in a web-based context, this approach lends itself naturally towards manipulating an HTML5 canvas. - -The parts that we still need to setup are: - -- handle document validations, and generate notifications with our generator output -- listen for these notifications in the client, and extract the generated output -- interpret the generated output as drawing commands, and update the canvas - -## Handling Document Validations - -This is the first step we'll need, since without being able to generate notifications in the first place we would have nothing to listen to. - -Thankfully a lot of the groundwork has already been done in previous tutorials, as well as within Langium itself. We just need to setup the an onBuildPhase listener for the document builder in our LS. Using the LS entry point **main-browser.ts** that we setup in the last tutorial on Langium + Monaco, we can add the following code to the end of our `startLanguageServer` function. - -```ts -// modified import from the previous tutorial: Langium + Monaco -import { - BrowserMessageReader, - BrowserMessageWriter, - Diagnostic, - NotificationType, - createConnection -} from 'vscode-languageserver/browser.js'; - -// additional imports -import { Model } from './generated/ast.js'; -import { Command, getCommands } from './minilogo-actions.js'; -import { generateStatements } from '../generator/generator.js'; - -// startLanguageServer... - -// Send a notification with the serialized AST after every document change -type DocumentChange = { uri: string, content: string, diagnostics: Diagnostic[] }; -const documentChangeNotification = new NotificationType('browser/DocumentChange'); -// use the built-in AST serializer -const jsonSerializer = MiniLogo.serializer.JsonSerializer; -// listen on fully validated documents -shared.workspace.DocumentBuilder.onBuildPhase(DocumentState.Validated, documents => { - // perform this for every validated document in this build phase batch - for (const document of documents) { - const model = document.parseResult.value as Model; - let json: Command[] = []; - - // only generate commands if there are no errors - if(document.diagnostics === undefined - || document.diagnostics.filter((i) => i.severity === 1).length === 0 - ) { - json = generateStatements(model.stmts); - } - - // inject the commands into the model - // this is safe so long as you careful to not clobber existing properties - // and is incredibly helpful to enrich the feedback you get from the LS per document - (model as unknown as {$commands: Command[]}).$commands = json; - - // send the notification for this validated document, - // with the serialized AST + generated commands as the content - connection.sendNotification(documentChangeNotification, { - uri: document.uri.toString(), - content: jsonSerializer.serialize(model, { sourceText: true, textRegions: true }), - diagnostics: document.diagnostics ?? [] - }); - } -}); -``` - -And that's it for setting up the onBuildPhase listener itself. We still need to address the usage of `generateMiniLogoCmds`, which is tied to the LS implementation. - -Based on the work done in previous tutorials, we already have set up a working generator with MinLogo. If you haven't already set this up you can go back to the [tutorial on generation](/tutorials/generation) and give it a look over. Ideally, we'll already have setup our `generateStatements` function for MiniLogo, meaning so long as the imported module doesn't have any modules that are browser incompatible, we should be able to use it as is. Based on the previous setup however, we should have a **generator.js** file that is free of such conflicts, as much of them should be separated into the cli directly. - -This saves us quite a bit of time, since we don't need to handle setting up & dispatching a document for validation, we simply tap into the existing workflow and collect the result when it's ready. This is a great example of how Langium's architecture allows us to easily extend existing functionality, and add new features without having to rewrite existing code. - -As a concluding note for this section, don't forget to rebuild your language server bundle! It might not be a bad idea to clean as well, just to be sure everything is working as expected at this step. - -## Listening for Notifications in the Client - -The next step we need to make is to actually listen for these notifications from the client's end. This takes us back to the [Langium + Monaco](/tutorials/langium_and_monaco) setup in the previous tutorial. - -After starting the wrapper successfully, we want to retrieve the MonacoLanguageClient instance (a wrapper around the language client itself) and listen for `browser/DocumentChange` notifications. - -```ts -// wrapper has started... - -// get the language client -const client = wrapper.getLanguageClient(); -if (!client) { - throw new Error('Unable to obtain language client!'); -} - -// listen for document change notifications -client.onNotification('browser/DocumentChange', onDocumentChange); - -function onDocumentChange(resp: any) { - let commands = JSON.parse(resp.content).$commands; - // ... do something with these commands -} -``` - -Now this works, but when do we receive notifications, and how often? Well a good thing you asked, because if you started this up and began editing your program, you would be receiving a notification for every single change! Including whitespace changes. Now that's probably not what we're looking for, but the content is correct, we just want to slow it down a bit. We can do this by setting a timeout and a semaphore to prevent multiple notifications from being processed at once. - -```ts -let running = false; -let timeout: number | null = null; - -function onDocumentChange(resp: any) { - // block until we're finished with a given run - if (running) { - return; - } - - // clear previous timeouts - if (timeout) { - clearTimeout(timeout); - } - - timeout = window.setTimeout(async () => { - running = true; - let commands = JSON.parse(resp.content).$commands; - await updateMiniLogoCanvas(commands); - running = false; - - }, 200); // delay of 200ms is arbitrary, choose what makes the most sense in your use case -} -``` - -And now we have a nice delay where repeated updates are discarded, until we have about 200ms without a subsequent update. That allows us to take the commands we're working with, and start doing something with them. The semaphore will prevent following updates from overriding the current run, allowing it to finish before starting a new execution. - -You may have also noticed we added `updateMiniLogoCanvas` as the action to perform with our commands. This will be implemented in the next step, where we interpret our drawing commands. - -That's it for listening for notifications! Now that we have our commands extracted, we'll can actually perform a series of drawing actions on an HTML5 canvas. - -## Interpreting Draw Commands (Drawing) - -If you've gotten to this point then you're on the final stretch! The last part we need to implement is the actual logic that takes our drawing commands and updates the canvas. This logic will be the content of the `updateMiniLogoCanvas` function, and we'll walk through each step here. - -First, let's get a handle on our canvas, as well as the associated 2D context. - -```ts -const canvas : HTMLCanvasElement | null = document.getElementById('minilogo-canvas') as HTMLCanvasElement | null; -if (!canvas) { - throw new Error('Unable to find canvas element!'); -} - -const context = canvas.getContext('2d'); -if (!context) { - throw new Error('Unable to get canvas context!'); -} -``` - -We'll also want to clean up the context, in case we already drew something there before. This will be relevant when we're updating the canvas multiple times with a new program. - -```ts -context.clearRect(0, 0, canvas.width, canvas.height); -``` - -Next, we want to setup a background grid to display. It's not essential for drawing, but it looks nicer than an empty canvas. - -```ts -context.beginPath(); -context.strokeStyle = '#333'; -for (let x = 0; x <= canvas.width; x+=(canvas.width / 10)) { - context.moveTo(x, 0); - context.lineTo(x, canvas.height); -} -for (let y = 0; y <= canvas.height; y+=(canvas.height / 10)) { - context.moveTo(0, y); - context.lineTo(canvas.width, y); -} -context.stroke(); -``` - -After drawing a grid, let's reset the stroke to a white color. - -```ts -context.strokeStyle = 'white'; -``` - -Let's also setup some initial drawing state. This will be used to keep track of the pen state, and where we are on the canvas. - -```ts -// maintain some state about our drawing context -let drawing = false; -let posX = 0; -let posY = 0; -``` - -And let's begin evaluating each of our commands. To do this, we'll setup an interval that repeatedly shifts the top element from our list of commands, evaluates it, and repeats. Once we're out of commands to evaluate, we'll clear the interval. The whole invocation will be wrapped in a promise, to make it easy to await later on. Feel free to adjust the delay (or remove it entirely) in your version. - -```ts -const doneDrawingPromise = new Promise((resolve) => { - // use the command list to execute each command with a small delay - const id = setInterval(() => { - if (cmds.length > 0) { - dispatchCommand(cmds.shift() as MiniLogoCommand, context); - } else { - // finish existing draw - if (drawing) { - context.stroke(); - } - clearInterval(id); - resolve(''); - } - }, 1); -}); -``` - -`dispatchCommand` itself only needs to handle 4 cases: - -- penUp -- penDown -- move -- color - -Knowing this, and the details about what properties each command type can have, we can evaluate each command and update our context. This can be done with a switch and a case for each command type. - -*Be sure to add this function inside the `updateMiniLogoCanvas` function, otherwise it will not have access to the necessary state!* - -```ts -// dispatches a single command in the current context -function dispatchCommand(cmd: MiniLogoCommand, context: CanvasRenderingContext2D) { - if (cmd.name) { - switch (cmd.name) { - // pen is lifted off the canvas - case 'penUp': - drawing = false; - context.stroke(); - break; - - // pen is put down onto the canvas - case 'penDown': - drawing = true; - context.beginPath(); - context.moveTo(posX, posY); - break; - - // move across the canvas - // will draw only if the pen is 'down' - case 'move': - const x = cmd.args.x; - const y = cmd.args.y; - posX += x; - posY += y; - if (!drawing) { - // move, no draw - context.moveTo(posX, posY); - } else { - // move & draw - context.lineTo(posX, posY); - } - break; - - // set the color of the stroke - case 'color': - if ((cmd.args as { color: string }).color) { - // literal color or hex - context.strokeStyle = (cmd.args as { color: string }).color; - } else { - // literal r,g,b components - const args = cmd.args as { r: number, g: number, b: number }; - context.strokeStyle = `rgb(${args.r},${args.g},${args.b})`; - } - break; - - // fallback in case we missed an instruction - default: - throw new Error('Unrecognized command received: ' + JSON.stringify(cmd)); - - } - } -} -``` - -Now that we can interpret commands into drawing instructions, we're effectively done with setting up the last part of MiniLogo. Since we're listening to document updates, we don't need to do anything other than to just start it up and start with an example program. - -That's it, we're all done writing up our TS file. We should now be able to run the following (assuming the generator script is also executed by `build:web`), and get our results in `localhost:3000`. - -```bash -npm run build:web -npm run serve -``` - -If all went well, you should see a white diamond sketched out on the canvas when the page loads. If not, double check that you receive & use the `code` value correctly in your `createUserConfig` function. You can also add the program yourself from here: - -```minilogo -def test() { - move(100, 0) - pen(down) - move(100, 100) - move(-100, 100) - move(-100, -100) - move(100, -100) - pen(up) -} -color(white) -test() -``` - -Once you have something drawing on the screen, you're all set, congratulations! You've just successfully written your own Langium-based language, deployed it in the web, and hooked up generation to boot. In fact, you've done *quite* a lot if you've gone through all of these tutorials so far. - -- writing your own grammar -- implementing custom validation -- customizing your CLI -- adding generation -- configuring code bundling -- building an extension -- setting up Langium + Monaco in the web -- adding a document build phase listener -- listening for notifications in the client, and using the results - -And the concepts that we've gone over from the beginning to now are not just for MiniLogo of course, they can be easily generalized to work for your own language as well. As you've been going through these tutorials, we hope that you've been thinking about how you could have done things *differently* too. Whether a simple improvement, or another approach, we believe it's this creative kind of thinking that takes an idea of a language and really allows it to grow into something great. - -One easy note is how the example code shown in these tutorials was designed to be easy to demonstrate. It could definitely be improved with better error checking, better logic, generator optimizations, etc; something to keep in mind. - -It's also easy to imagine how one could extend their generator to produce their own functionality besides drawing. For example, imagine that you might have multiple generator targets, as there is no requirement to have a single generator output form like we've done in these tutorials. You could add as many different output forms as you need for each specific target, and even share some functionality between generators. - -We hope that these tutorials have given you a practical demonstration of how to construct a language in Langium, and facilitated further exploration into more advanced topics & customizations. If you're interested about learning more about Langium, you can continue through our other tutorials, reach out to us via discussions on Github, or continue working on your Langium-based language. diff --git a/hugo/content/old/tutorials/langium_and_monaco.md b/hugo/content/old/tutorials/langium_and_monaco.md deleted file mode 100644 index 48111921..00000000 --- a/hugo/content/old/tutorials/langium_and_monaco.md +++ /dev/null @@ -1,619 +0,0 @@ ---- -title: "Langium + Monaco Editor" -weight: 6 ---- - -{{< toc format=html >}} - -*Updated on Oct. 4th, 2023 for usage with monaco-editor-wrapper 3.1.0 & above, as well as Langium 2.0.2* - -In this tutorial we'll be talking about running Langium in the web with the Monaco editor. If you're not familiar with Monaco, it's the editor that powers VS Code. We're quite fond of it at TypeFox, so we've taken the time to write up this tutorial to explain how to integrate Langium in the web with Monaco, no backend required. - -Although we're using Monaco in this tutorial, that does not mean that you cannot use another code editor of your choice. For example, you can use Code Mirror with Langium as well. Generally, if an editor has LSP support, it is very likely you can integrate it easily with Langium, since it's LSP compatible. - -Without further ado, let's jump into getting your web-based Langium experience setup! - -## Technologies You'll Need - -- [Langium](https://www.npmjs.com/package/langium) 2.0.2 or greater -- [Monaco Editor Wrapper](https://www.npmjs.com/package/monaco-editor-wrapper) 3.1.0 or greater -- [ESBuild](https://www.npmjs.com/package/esbuild) 0.18.20 or greater - -## Getting your Language Setup for the Web - -To begin, you're going to need a Langium-based language to work with. We have already written [MiniLogo](https://github.com/langium/langium-minilogo) in Langium as an example for deploying a language in the web. However, if you've been following along with these tutorials so far, you should be ready to move your own language into a web-based context. - -Per usual, we'll be using MiniLogo as the motivating example here. - -## Factoring out File System Dependencies - -In order to build for the browser, we need to create a bundle that is free of any browser-incompatible modules. To do this, let's create a new entry point for our language server in **src/language-server/main-browser.ts**. This will mirror the regular entry point that we use to build already, but will target a browser-based context instead. We'll start with the following content: - -```ts -import { startLanguageServer, EmptyFileSystem } from 'langium'; -import { BrowserMessageReader, BrowserMessageWriter, createConnection } from 'vscode-languageserver/browser.js'; -// your services & module name may differ based on your language's name -import { createMiniLogoServices } from './minilogo-module.js'; - -declare const self: DedicatedWorkerGlobalScope; - -/* browser specific setup code */ -const messageReader = new BrowserMessageReader(self); -const messageWriter = new BrowserMessageWriter(self); - -const connection = createConnection(messageReader, messageWriter); - -// Inject the shared services and language-specific services -const { shared, MiniLogo } = createMiniLogoServices({connection, ...EmptyFileSystem }); - -// Start the language server with the shared services -startLanguageServer(shared); -``` - -Again, this is based on code that was originally produced by the yeoman generator, so it should look familiar. - -Most of this is in line with what's contained in the **main.ts** file. The exceptions being the message readers & writers, and the notion of an `EmptyFileSystem` for the browser. There is a virtual file system API that we could utilize on most modern browsers, but for this tutorial we'll assume we aren't using any file system. Instead we'll have a single source 'file' located in memory. - -We'll also need to include a library to resolve the missing `DedicatedWorkerGlobalScope`, which is normally not accessible until we update our **tsconfig.json** in our project root. We need to supplement the libs entry with `DOM` and `WebWorker`. From the yeoman generator example, the `lib` entry usually has just `["ESNext"]`. - -```json -{ - "compilerOptions": { - ... - "lib": ["ESNext", "DOM", "WebWorker"] - } -} -``` - -Now that we have a new entry point for the browser, we need to add a script to our **package.json** to build a web worker for this language. The bundle this script produces will contain the language server for your language. The following script example is specific to MiniLogo, but should capture the general approach quite nicely: - -```json -{ - ... - "build:worker": "esbuild --minify ./out/language-server/main-browser.js --bundle --format=iife --outfile=./public/minilogo-server-worker.js", -} -``` - -Assuming `esbuild` is installed, and we've properly factored out any modules that are not suitable for a browser-based context, we should be good to go! - -Running `npm run build:worker` we should see the bundle is successfully generated without issue. If you're still having problems building the worker, double check that you're not coupled to `fs` or other file system dependent modules in a related file. - -Note that although our generator is still connected to using the file system, it's not relevant for the worker bundle to function. - -## Setting up Monaco - -Now we're going to setup Monaco, but not with Langium yet, as we want to be sure it's working first before connecting the two. - -For convenience, we're going to use the Monaco Editor Wrapper (MER) to wrap around some of Monaco's core functionality, along with the Monaco Editor Workers package to assist. These packages are both maintained by TypeFox, and are designed to make it easier to use Monaco in a web-based context. We'll be using the following versions of these packages: - -- [Monaco Editor Wrapper](https://www.npmjs.com/package/monaco-editor-wrapper) version **3.1.0** -- [monaco-editor-workers](https://www.npmjs.com/package/monaco-editor-workers) version **0.39.0** - -Both these packages should be installed as dependencies for your language. In particular, this guide will assume that you're using version **3.1.0** or later of the monaco-editor-wrapper package, and version **0.39.0** of the monaco-editor-workers package. - -Additionally, we'll want a way to serve this bundled language server. The choice of how you want to go about this is ultimately up to you. Previously we've recommended `express` as a development dependency (don't forget to also add `@types/express` too), as a powerful & lightweight NodeJS server framework. However, we'll be going with the built-in NodeJS support for standing up a web-server; however again the choice is yours here. - -We'll also want to add some more scripts to our package.json to copy over the necessary files from the monaco-editor-wrapper & monaco-editor-worker into the **public** folder. We'll be referencing these library assets to setup the webpage for Langium + Monaco. - -```json -{ - ... - "prepare:public": "node scripts/prepare-public.mjs", - "build:web": "npm run build && npm run prepare:public && npm run build:worker && node scripts/copy-monaco-assets.mjs", -} -``` - -Both scripts reference *mjs* files that need to be added as well into the scripts folder: - -**scripts/prepare-public.mjs** - -```js -import * as esbuild from 'esbuild' -import shell from 'shelljs' - -// setup & copy over css & html to public -shell.mkdir('-p', './public'); -shell.cp('-fr', './src/static/*.css', './public/'); -shell.cp('-fr', './src/static/*.html', './public'); - -// bundle minilogo.ts, and also copy to public -await esbuild.build({ - entryPoints: ['./src/static/minilogo.ts'], - minify: true, - sourcemap: true, - bundle: true, - outfile: './public/minilogo.js', -}); -``` - -**scripts/copy-monaco-assets.mjs** - -```js -import shell from 'shelljs' - -// copy workers to public -shell.mkdir('-p', './public/monaco-editor-workers/workers'); -shell.cp( - '-fr', - './node_modules/monaco-editor-workers/dist/index.js', - './public/monaco-editor-workers/index.js' -); -shell.cp( - '-fr', - './node_modules/monaco-editor-workers/dist/workers/editorWorker-es.js', - './public/monaco-editor-workers/workers/editorWorker-es.js' -); -shell.cp( - '-fr', - './node_modules/monaco-editor-workers/dist/workers/editorWorker-iife.js', - './public/monaco-editor-workers/workers/editorWorker-iife.js' -); -``` - -This saves us from writing these extra details into our package json, and focusing on the overall goal each step. - -The last script, `build:web` is there to provide a convenient way to invoke all the intermediate build steps in sequence. However you'll want to wait before running the `build:web` script, as we still need to add our **static** assets to make that work; which will come in the next step. - -As a quick note, if you went with another editor you would want to make sure that the assets required for that editor will also be copied into **public** folder as part of your output. - -## Setting up a Static Page - -And now for the actual HTML page itself, plus it's supporting assets. To keep things organized, we're splitting up the JS and CSS. We'll be putting all of these files into a new location from our project root, **src/static/**. - -Here's the raw contents of the HTML content stored in **src/static/index.html**. This will serve as a frame for Monaco to be setup within. - -```html - - - - - - - MiniLogo in Langium - - -

MiniLogo in Langium

- - -
- -
-
-
-
-
- -
- -
-
- - -
- -
- -
-
-
-

Powered by

- Langium -
- - - - -``` - -And here's the associated CSS stored in **src/static/styles.css**. This will style Monaco correctly so it renders as expected. - -```css -html,body { - background: rgb(33,33,33); - font-family: 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif; - color: white; - /* for monaco */ - margin: 0; - padding: 0; - width: 100%; - height: 100%; -} -h1 { - text-align: center; -} -#minilogo-canvas { - display: block; - margin: 8px auto; - text-align: center; -} -#page-wrapper { - display: flex; - max-width: 2000px; - margin: 4px auto; - padding: 4px; - min-height: 75vh; - justify-content: center; -} -#page-wrapper .half { - display: flex; - width: 40vw; -} -.build { - display: block; - margin: 8px auto; - width: 300px; - height: 30px; - background: none; - border: 2px #fff solid; - color: #fff; - transition: 0.3s; - font-size: 1.2rem; - border-radius: 4px; -} -.build:hover { - border-color: #6cf; - color: #6cf; - cursor: pointer; -} -.build:active { - color: #fff; - border-color: #fff; -} -footer { - text-align: center; - color: #444; - font-size: 1.2rem; - margin-bottom: 16px; -} -@media(max-width: 1000px) { - #page-wrapper { - display: block; - } - #page-wrapper .half { - display: block; - width: auto; - } - #minilogo-canvas { - margin-top: 32px; - } - #page-wrapper { - min-height: auto; - } -} - -/* for monaco */ -.wrapper { - display: flex; - flex-direction: column; - height: 100%; - width: 100%; -} - -#monaco-editor-root { - flex-grow: 1; -} - -#status-msg { - color: red; -} -``` - -Finally, there's the actual Javascript setting up our Monaco instance (stored in **src/static/minilogo.ts**), and for setting up Langium as well. This is the most complex part of setting up Langium + Monaco in the web, so we'll walk through the file in parts. - -(*Update on Oct. 4th, 2023: Previously we wrote this as **src/static/setup.js**. This new file can be considered the same, but reworked into TypeScript & updated for the new versions of Langium & the MER.*) - -First, we need to import and setup the worker, as well as some language client wrapper configuration. - -```ts -import { MonacoEditorLanguageClientWrapper, UserConfig } from "monaco-editor-wrapper/bundle"; -import { buildWorkerDefinition } from "monaco-editor-workers"; -import { addMonacoStyles } from 'monaco-editor-wrapper/styles'; - -/** - * Setup Monaco's own workers and also incorporate the necessary styles for the monaco-editor - */ -function setup() { - buildWorkerDefinition( - './monaco-editor-workers/workers', - new URL('', window.location.href).href, - false - ); - addMonacoStyles('monaco-editor-styles'); -} -``` - -Then, we'll want to instantiate our language client wrapper. In previous versions of the `monaco-editor-wrapper` package (before 2.0.0), configuration was performed by manually setting properties on the `MonacoEditorLanguageClientWrapper` instance. However, as of 3.1.0 (at the time of writing this), the constructor for `MonacoEditorLanguageClientWrapper` now takes a configuration object as its first argument. This configuration object allows us to set the same properties as before, but with more fine-grained control over all the properties that are set. - -We're going to walk through the parts that will be used to build up this configuration first, and then joining the actual configuration object together afterwards. - -To start, let's keep in mind that our current language id will be `minilogo`. This should match the id of the language that will be recognized by our language server. - -Then, we'll want to add some static syntax highlighting. To do this we have a couple choices, using a TextMate or a [Monarch grammar](https://microsoft.github.io/monaco-editor/monarch.html). Both will provide us with the ability to parse our language, and apply styling to our tokens. However we have to choose one, we cannot use both simultaneously. This is related to how Monaco itself is configured with regards to whether we're using the VSCode API config, or the classic editor config. This makes sense to a degree, as we can only prepare the editor one way or the other. - -For MiniLogo, our monarch grammar will look like so: - -```ts -/** - * Returns a Monarch grammar definition for MiniLogo - */ -function getMonarchGrammar() { - return { - keywords: [ - 'color','def','down','for','move','pen','to','up' - ], - operators: [ - '-',',','*','/','+','=' - ], - symbols: /-|,|\(|\)|\{|\}|\*|\/|\+|=/, - - tokenizer: { - initial: [ - { regex: /#(\d|[a-fA-F]){3,6}/, action: {"token":"string"} }, - { regex: /[_a-zA-Z][\w_]*/, action: { cases: { '@keywords': {"token":"keyword"}, '@default': {"token":"string"} }} }, - { regex: /(?:(?:-?[0-9]+)?\.[0-9]+)|-?[0-9]+/, action: {"token":"number"} }, - { include: '@whitespace' }, - { regex: /@symbols/, action: { cases: { '@operators': {"token":"operator"}, '@default': {"token":""} }} }, - ], - whitespace: [ - { regex: /\s+/, action: {"token":"white"} }, - { regex: /\/\*/, action: {"token":"comment","next":"@comment"} }, - { regex: /\/\/[^\n\r]*/, action: {"token":"comment"} }, - ], - comment: [ - { regex: /[^\/\*]+/, action: {"token":"comment"} }, - { regex: /\*\//, action: {"token":"comment","next":"@pop"} }, - { regex: /[\/\*]/, action: {"token":"comment"} }, - ], - } - }; -} -``` - -We can produce this Monarch grammar by updating our **langium-config.json** to produce a Monarch file as output. Note that although we're talking about MiniLogo here, we based this example off of the hello-world example produced by the yeoman generator. As such, we still have hello world names here and there, and for this tutorial we'll just use the same name again as for the TextMate grammar. - -```json -... -"textMate": { - "out": "syntaxes/minilogo.tmLanguage.json" -}, -"monarch": { - "out": "syntaxes/minilogo.monarch.ts" -} -``` - -To generate this file, run `npm run langium:generate`. You can then copy over the definition of the grammar from **syntaxes/hello-world.monarch.ts** (or whatever other name you have given this file). Keep in mind that this generated monarch grammar is *very* simple. If you want more complex highlighting, we recommend writing your own custom monarch grammar, and storing it somewhere else to prevent it from being overridden. If you're interested, you can find more details about the [Monarch grammar highlighting language here](https://microsoft.github.io/monaco-editor/monarch.html). - -Then, we want to setup the code that shows up by default. The following is a fixed MiniLogo program that should display a white diamond in the top left corner of the screen. - -```ts -/** - * Retrieves the program code to display, either a default or from local storage - */ -function getMainCode() { - let mainCode = ` - def test() { - move(100, 0) - pen(down) - move(100, 100) - move(-100, 100) - move(-100, -100) - move(100, -100) - pen(up) - } - color(white) - test() - - `; - - // optionally: use local storage to save the code - // and seek to restore any previous code from our last session - if (window.localStorage) { - const storedCode = window.localStorage.getItem('mainCode'); - if (storedCode !== null) { - mainCode = storedCode; - } - } - - return mainCode; -} -``` - -Since we're planning to use a language server with Monaco, we'll need to setup a language client config too. To do this we'll also need to generate a worker using our language server worker file, but that's fairly straightforward to setup here. Keep in mind that you'll need to have access to the bundle produced from your **main-browser.ts** from before. Here the built result is copied over as **public/minilogo-server-worker.js**. - -```ts -/** - * Creates & returns a fresh worker using the MiniLogo language server - */ -function getWorker() { - const workerURL = new URL('minilogo-server-worker.js', window.location.href); - return new Worker(workerURL.href, { - type: 'module', - name: 'MiniLogoLS' - }); -} -``` - -By creating the worker in advance, we give ourselves the ability to directly interact with the worker/LS independent of the wrapper itself, and to even pre-configure it before use. This can be hugely beneficial, especially if we expect to customize our LS on the fly. - -Lastly, let's setup the user config, which will be used to startup the wrapper. - -```ts -type WorkerUrl = string; - -/** - * Classic configuration for the monaco editor (for use with a Monarch grammar) - */ -interface ClassicConfig { - code: string, - htmlElement: HTMLElement, - languageId: string, - worker: WorkerUrl | Worker, - monarchGrammar: any; -} - -/** - * Generates a valid UserConfig for a given Langium example - * - * @param config An extended or classic editor config to generate a UserConfig from - * @returns A completed UserConfig - */ -function createUserConfig(config: ClassicConfig): UserConfig { - // setup urls for config & grammar - const id = config.languageId; - - // generate langium config - return { - htmlElement: config.htmlElement, - wrapperConfig: { - editorAppConfig: { - $type: 'classic', - languageId: id, - useDiffEditor: false, - code: config.code, - theme: 'vs-dark', - languageDef: config.monarchGrammar - }, - serviceConfig: { - enableModelService: true, - configureConfigurationService: { - defaultWorkspaceUri: '/tmp/' - }, - enableKeybindingsService: true, - enableLanguagesService: true, - debugLogging: false - } - }, - languageClientConfig: { - options: { - $type: 'WorkerDirect', - worker: config.worker as Worker, - name: `${id}-language-server-worker` - } - } - }; -} -``` - -This particular UserConfig will be for configuring a classic editor, rather than a VSCode extension-based editor. This is because we're using a Monarch grammar, which is not supported by the extension configuration. However, if we wanted to use a TextMate grammar, we could use the extension based configuration instead. - -```json -editorAppConfig: { - $type: 'vscodeApi', - languageId: id, - useDiffEditor: false, - code: config.code, - ... -} -``` - -You would just need to fill in the rest of the details for associating a TextMate grammar & such. [Here's an example from the monaco-components repo](https://github.com/TypeFox/monaco-components/blob/4f301445eca943b9775166704304637cf5e8bd00/packages/examples/src/langium/config/wrapperLangiumVscode.ts#L37). - -Regardless of how the user config is setup, we can now invoke that helper function with a handful of configuration details, and have a working UserConfig to pass to the wrapper. - -```ts -// create a wrapper instance -const wrapper = new MonacoEditorLanguageClientWrapper(); - -// start up with a user config -await wrapper.start(createUserConfig({ - htmlElement: document.getElementById("monaco-editor-root")!, - languageId: 'minilogo', - code: getMainCode(), - worker: getWorker(), - monarchGrammar: getMonarchGrammar() -})); -``` - -That's it! Now if everything was configured correctly, we should have a valid wrapper that will display the code we want in our browser. - -## Serving via NodeJS - -Now that we have our files all setup, and our build process prepared, we can put together a mini server application to make viewing our public assets easy. We'll do this by adding **src/web/app.ts** to our project, and giving it the following contents: - -```ts -/** - * Simple server app for serving generated examples locally - * Based on: https://developer.mozilla.org/en-US/docs/Learn/Server-side/Node_server_without_framework - */ -import * as fs from "node:fs"; -import * as http from "node:http"; -import * as path from "node:path"; - -const port = 3000; - -const MIME_TYPES: Record = { - default: "application/octet-stream", - html: "text/html; charset=UTF-8", - js: "application/javascript", - css: "text/css", -}; - -const STATIC_PATH = path.join(process.cwd(), "./public"); - -const toBool = [() => true, () => false]; - -const prepareFile = async (url: string) => { - const paths = [STATIC_PATH, url]; - if (url.endsWith("/")) { - paths.push("index.html"); - } - const filePath = path.join(...paths); - const pathTraversal = !filePath.startsWith(STATIC_PATH); - const exists = await fs.promises.access(filePath).then(...toBool); - const found = !pathTraversal && exists; - // there's no 404, just redirect to index.html in all other cases - const streamPath = found ? filePath : STATIC_PATH + "/index.html"; - const ext = path.extname(streamPath).substring(1).toLowerCase(); - const stream = fs.createReadStream(streamPath); - return { found, ext, stream }; -}; - -http - .createServer(async (req, res) => { - const file = await prepareFile(req.url!); - const statusCode = file.found ? 200 : 404; - const mimeType: string = MIME_TYPES[file.ext] || MIME_TYPES.default; - res.writeHead(statusCode, { "Content-Type": mimeType }); - file.stream.pipe(res); - console.log(`${req.method} ${req.url} ${statusCode}`); - }) - .listen(port); - -console.log(`Server for MiniLogo assets listening on http://localhost:${port}`); -``` - -If you would like to compact this, and don't mind adding additional deps to your project, you can include `express` and `@types/express` to your project, and use the following code instead: - -```ts -/** - * Simple express app for serving generated examples - */ - -import express from 'express'; -const app = express(); -const port = 3000; -app.use(express.static('./public')); -app.listen(port, () => { -console.log(`Server for MiniLogo assets listening on http://localhost:${port}`); -}); -``` - -And to invoke the server, we need to add one more script to our package.json. - -```json -{ - ... - "serve": "node ./out/web/app.js" -} -``` - -That's it! Now we can build all the assets, and run express to be able to view our demo of Langium in the web from **localhost:3000**. - -```bash -npm run build:web -npm run serve -``` - -You should be greeted with a page that contains a working Monaco instance and a small MiniLogo program in the editor. This editor has the highlighting we would expect, and also is fully connected to the language server for our language. This means we have full LSP support for operations that we would expect to have in a native IDE, such as VSCode. - -And that's it, we have successfully implemented Langium + Monaco in the web for our language. It's not doing much at this time besides presenting us with an editor, but in the next tutorial we'll talk about [using the same setup to add generation in the web](/tutorials/generation_in_the_web). Since our generation has already been configured natively in prior tutorials, we can use what we've written to quickly implement a web application that translates MiniLogo programs into drawing instructions for an HTML5 canvas. diff --git a/hugo/content/old/tutorials/validation.md b/hugo/content/old/tutorials/validation.md deleted file mode 100644 index b41015bd..00000000 --- a/hugo/content/old/tutorials/validation.md +++ /dev/null @@ -1,153 +0,0 @@ ---- -title: "Validation" -weight: 1 ---- - -{{< toc format=html >}} - -In this tutorial, we will be talking about implementing validation for your Langium-based language. We recommend first reading the previous tutorial about [writing a grammar](/tutorials/writing_a_grammar/), as we will assume you're familiar with the topics covered there. We'll also assume that you have a working language to add validation to, so double check that `npm run langium:generate` succeeds without errors before you proceed. - -For this tutorial, we'll be implementing validation for the [MiniLogo language](https://github.com/langium/langium-minilogo), but you can use your own language to follow along as well. - -## Overview - -Adding validation is an important step to building a language, as there are often invalid cases that cannot be filtered out through your grammar alone. - -Consider the case of having unique names for identifiers. In MiniLogo we have definitions with names, and we also have parameters that are identified by name. One problem here is if we have several definitions that share the same name. We could also have a similar problem with parameters, where perhaps the same name is used multiple times in the same definition. In the second case, this is most certainly undesirable, but in the first it depends on how you want your language to handle redefinitions. - -Let's consider the case where you want to allow redeclaring a previous definition. This opens the door to allowing redeclaring or shadowing of definitions. If you ever wanted to extend your language down the road, such as by adding the ability to import other programs (along with their definitions) then you might consider allowing a definition to be redefined. However, it could also lead to unintended redeclarations that may be harder to track down. Ultimately, this choice depends on the desired semantics for your language, and is something you should consider carefully. - -In this example we're going to *disallow* names that are non-unique for definitions, and we'll be doing the same for arguments of a definition as well. - -## The Validation Registry - -In order to express these constraints, we need to modify our language's **validator**. By default, this can be found in **src/language/YOUR-LANGUAGE-validator.ts**; with a name that corresponds to your language. This file begins with a validation registry that extends the default validation registry. The validation registry allows us to register validation checks for our language. - -The constructor for the registry is of particular interest, as it allows associating validation functions with *specific* nodes in your AST. Here you can see an example of the constructor below for the default hello world language from the yeoman generator. - -```ts -/** - * Registry for validation checks. - */ -export class HelloWorldValidationRegistry extends ValidationRegistry { - constructor(services: HelloWorldServices) { - super(services); - const validator = services.validation.HelloWorldValidator; - const checks: ValidationChecks = { - // we want to add checks here... - Person: validator.checkPersonStartsWithCapital - }; - this.register(checks, validator); - } -} -``` - -From this example, we have a single validation for the `Person` node. - -```ts -Person: validator.checkPersonStartsWithCapital -``` - -Before we changed our grammar in the last tutorial, the `Person` node corresponded with a parser rule named `Person`. Similarly, most nodes that we can validate will share the name of the parser rule that instantiates them. However, there are a couple cases where this is different: - -- when `Rule infers AnotherName` (or uses `return`), the node's type will be `AnotherName` -- when the body of a parser rule has an action (like `{AnotherName}`, possibly starting with `infer`) this new name will exist instead for this *part* of the rule body - -## Finding Nodes to Validate - -With this in mind, we can look back at our grammar that we've written for MiniLogo (from the last tutorial), and find the parser rules that refer to the nodes we want to validate. For this language we have a pair of cases to check, as mentioned above: - -- Validate that definitions have unique names in a Model -- Validate that arguments have unique names in a Definition - -In order to perform a validation, we need to know the type of that node to validate. Beyond checking our grammar to find this, we can also check the semantic model (akin to the abstract syntax) of our language. This was generated while running `npm run langium:generate`, and is located in **src/language/generated/ast.ts**. Peeking into this model, we can see that our rule for `Model` was written like so: - -```langium -entry Model: (stmts+=Stmt | defs+=Def)*; -``` - -which produces the following node type in our semantic model: - -```ts -export interface Model extends AstNode { - defs: Array - stmts: Array -} -``` - -## Registering Validations - -So, we can register a validation on all nodes of type `Model` (which should be just the root), like so. Note the import coming from the generated file, which contains the definitions that compose our semantic model. The name **ast.ts** reflects it's usage as identifying node types that constitute an AST in our language (akin to an abstract syntax). - -```ts -import { Model } from './generated/ast'; -... -const checks: ValidationChecks = { - Model: (m: Model, accept: ValidationAcceptor) => { - // and validate the model 'm' here - } -}; -``` - -We also have a perfectly good validator class that's just below this part of the file that we can use, but it's still setup to perform validation on the old `Person` node. We can safely remove the old function, add our custom validation there, and associate it back with our validation registry checks. - -The updated validator class looks like so: - -```ts -/** - * Implementation of custom validations. - */ -export class HelloWorldValidator { - - // our new validation function for defs - checkUniqueDefs(model: Model, accept: ValidationAcceptor): void { - // create a set of visited functions - // and report an error when we see one we've already seen - const reported = new Set(); - model.defs.forEach(d => { - if (reported.has(d.name)) { - accept('error', `Def has non-unique name '${d.name}'.`, {node: d, property: 'name'}); - } - reported.add(d.name); - }); - } - -} -``` - -To call this validator in our registry, we can modify the check that is listed in our registry like so (removing the previously written lambda/arrow function). - -```ts -const checks: ValidationChecks = { - Model: validator.checkUniqueDefs, -}; -``` - -Great! Now we have a simple validation in place to guard against duplicate definitions in MiniLogo. - -Now that we've shown how this can be done, we can implement this for parameters as well. Looking at our grammar, we can see params are contained as part of a Definition, so we'll register validation for Definition nodes and report if any parameter are duplicated. - -```ts -const checks: ValidationChecks = { - Model: validator.checkUniqueDefs, - Def: validator.checkUniqueParams -}; -``` - -And we can define this new function in our validator class, which is very close in structure to our first function. - -```ts -checkUniqueParams(def: Def, accept: ValidationAcceptor): void { - const reported = new Set(); - def.params.forEach(p => { - if (reported.has(p.name)) { - accept('error', `Param ${p.name} is non-unique for Def '${def.name}'`, {node: p, property: 'name'}); - } - reported.add(p.name); - }); -} -``` - -Although we've only implemented a pair of validations, hopefully this demonstrates the flexibility of the validator API. The validator can help enforce constraints or features of your language, and ensure that your programs are correct. You could also explore more customized validations for specific cases, perhaps where a parameter and a definition share the same name -- which is not handled here. So long as you can identify the AST node type that you need to validate, you can implement the logic here. - -That's all for validation. Next we'll be talking about how we can [customize our CLI](/tutorials/customizing_cli). diff --git a/hugo/content/old/tutorials/writing_a_grammar.md b/hugo/content/old/tutorials/writing_a_grammar.md deleted file mode 100644 index e971bf9b..00000000 --- a/hugo/content/old/tutorials/writing_a_grammar.md +++ /dev/null @@ -1,312 +0,0 @@ ---- -title: "Writing a Grammar" -weight: 0 ---- - -{{< toc format=html >}} - -In this tutorial we will be talking about writing a grammar for your language in Langium. As a motivating example, we'll be describing how to write a grammar for the MiniLogo language. If you're not familiar with MiniLogo, it's a smaller implementation of the Logo programming language. Logo itself is a lot like Turtle from Python. Ultimately, we'll be using MiniLogo to express drawing instructions that can be used to draw on a canvas. - -We've already written an implementation of [MiniLogo on Github using Langium](https://github.com/langium/langium-minilogo). This tutorial will be following along with this project, by walking through the grammar implementation step by step. Later tutorials will also follow along with MiniLogo to create an easy to follow series. - -## Planning - -Before we get started writing the grammar, we'll want to first identify a couple important aspects of our language. Namely, these are: - -- The Semantic Domain -- The Concrete Syntax - -The Semantic Domain describes the types of values that will be produced by evaluating our language. In the case of MiniLogo our semantic domain is going to have a single part, an updated drawing state that contains information on: - -- position -- whether we're drawing or not -- color of the drawing stroke - -We'll also be producing values and updating an environment as well, which are important to keep in mind. - -Basically, a MiniLogo program can be considered equivalent to a series of transformations on some drawing context. This goal for MiniLogo will guide our design throughout these tutorials. - -In addition, we'll want to get an idea of what our concrete syntax will be. This step can be done on paper if you like, but the overall goal is to get a feel for how you want the language to look. Your choice of concrete syntax will also drive your grammar's design. If your design is chosen well, it can simplify the way your grammar is constructed. If your syntax is complex, the grammar may also be complex as well. Not only this, but it's also important to try and strike a balance between syntax that is special to your language, and syntax that is at least somewhat shared with other languages. The more unfamiliar the language appears, the more likely your users will struggle trying to pick it up. - -In our case, we're going to use a C-like concrete syntax. This will make it easy to understand the structure of our programs for most users. This is also chosen because it allows us to use curly braces to delimit blocks of code, which is quite easy to implement in Langium. You could also go for a Python style language, where whitespace has significance in determining which block some code belongs to. Unfortunately, this is not as easy to do out of the box with Langium, due to it ignoring whitespace by default, but it can be configured to work for such languages. - -## Sketching the Grammar - -Now that we have an idea of our semantics and our concrete syntax, we can then start writing out a grammar. Conveniently, MiniLogo already has a grammar and concrete syntax described, and that in turn is based off of the [Logo programming language](https://el.media.mit.edu/logo-foundation/what_is_logo/logo_programming.html). [MiniLogo](https://web.engr.oregonstate.edu/~walkiner/teaching/cs381-wi21/minilogo.html) itself was designed by Eric Walkingshaw at Oregon State University, and was used to teach students. It's not something that we've created, but rather something that we found to be an ideal demonstration of Langium's capabilities, while also remaining friendly for newcomers. - -As an aside, our version of MiniLogo will be an *approximation* of Dr. Walkingshaw's version. We won't adhere to it completely, and we won't be incorporating some elements, such as variable declarations. - -To get started sketching the grammar we'll be using the **Hello World** example from the yeoman generator. You can read about how to get this setup in the [Getting Started](/docs/getting-started/) section of our docs. We'll be working with a fresh from the generator using only the defaults, and building up from that. We'll begin by modifying the default grammar file, and updating it to work for MiniLogo. You can find this file under **src/language/hello-world.langium** in your new project. If you used a name other than the default, the file will still be there, but using your custom name instead. - -We'll be overriding the existing langium grammar file completely, so delete the old contents before we begin. - -The first line that we'll then add is the declaration of our grammar. - -```langium -grammar MiniLogo -``` - -This simply describes the name of the grammar that will be proceeding, and is required. - -Next, we'll need to describe an entry rule. This will be a parser rule that must be matched first when recognizing a MiniLogo program. This rule is particularly special, because it will become the root of the resulting abstract syntax tree, which captures the essential structure of our program. For MiniLogo, our entry rule Will be `Model`. You could also make it `Program`, but whatever you choose it should capture the same notion. Regardless of your choice, this rule should match any number of Statements and/or Definitions to follow the MiniLogo specification. - -```langium -entry Model: (stmts+=Stmt | defs+=Def)*; -``` - -Each instance of a statement will be stored under the `stmts` property as an element of an Array. The same will be done for Definitions using `defs` as well. Note the trailing `*` after the grouping, which means technically a program containing *nothing* is also a valid MiniLogo program. - -To iterate on this a little bit further we'll need to describe what a Statement (Stmt) and a Definition (Def) are in the context of MiniLogo. - -First, let's talk about **Definitions**. A definition corresponds to: - -- a name -- a list of parameters -- a block of *statements* - -And we want definitions to look like so in our concrete syntax: - -```minilogo -def myDef() { - ... -} -... -def anotherDef(x,y,z) { - ... -} -``` - -We can recognize this concrete syntax, and capture the relevant information for our AST, with the following rule: - -```langium -Def: 'def' name=ID '(' (params+=Param (',' params+=Param)*)? ')' Block; -``` - -As an additional note, much like regular expressions we use modifiers in our grammar to indicate that definitions can take any number of comma separated parameters. - -You may be wondering what `Block` is as well. Block corresponds to a rule *fragment*, which is akin to a reusable rule body. It's not a rule itself, but an reusable piece that can be reused to complete rules. It's particularly handy when you find yourself writing the same pattern repeatedly, and want to factor it out. - -```langium -fragment Block: '{' body+=Stmt* '}'; -``` - -Then we have **Statements**, which consist of Commands or Macros. - -```langium -Stmt: Cmd | Macro; -``` - -A **Command** describes an action that transforms the drawing state (which connects to our semantic domain from before). The commands in MiniLogo can be expressed like so: - -```langium -Cmd: Pen | Move | Color | For; -``` - -Where each command is also a separate rule: - -- **Pen**: Corresponds to a command that turns on/off drawing -- **Move**: Updates the position of the pen (relatively) -- **Color**: Sets the stroke color of what is drawn -- **For**: A standard for loop control flow - -These commands describe the essential drawing instructions that we will be representing. We'll go over those in a moment. - -A statement can also be a **Macro**. A Macro has 2 distinct parts: - -- a reference to a Definition (more on this shortly, think of it like a 'function' for now) -- a list of arguments to apply this definition to - -In our concrete syntax, we want macros to look like this: - -```minilogo -myMacro() -... -anotherMacro(1, 2, 3 * 3) -``` - -We can encode this in MiniLogo like so: - -```langium -Macro: def=[Def:ID] '(' (args+=Expr (',' args+=Expr)*)? ')'; -``` - -In this case `def` will be a **Cross Reference** to an existing Definition. This is a special syntax that says *def will be assigned to a Definition object at runtime identified by an ID terminal token*. Although we haven't introduced this terminal yet, it's a simple rule that captures literal strings as tokens. It's also important to note that cross references implicitly utilize the `name` property to hookup the cross reference to the target object. - -We also want to add the notion of a Parameter, which is quite simple to write in: - -```langium -Param: name=ID; -``` - -As you may have guessed, by using the `name` property for a parameter, we're allowing Langium to automatically setup cross references for parameters as well. - -## Adding Commands - -For the commands, we'll go through each one, and show examples of the concrete syntax we're trying to capture: - -**Pen** needs to have two modes, up and down. So it should capture syntax like this: - -```minilogo -pen(up) -... -pen(down) -``` - -We can express this with the following parser rule. - -```langium -Pen: 'pen' '(' mode=('up' | 'down') ')'; -``` - -**Move** commands will take a pair of expressions, corresponding to the x and y components, and can look like so: - -```minilogo -move(1,5) -... -move(x * 10, y * 10) -``` - -We haven't defined it yet, but we can use an **Expr** rule to represent where our expressions will go, and capture this command like this: - -```langium -Move: 'move' '(' ex=Expr ',' ey=Expr ')'; -``` - -We'll define expressions shortly. - -Simple for loops can be defined too, which should look like this: - -```minilogo -for x = 0 to 10 { - ... -} -``` - -Again, we don't have **Expr** defined yet, but we can still use it here. Also, since we have a block of statements, we can reuse that `Block` fragment that was defined earlier. - -```langium -For: 'for' var=Param '=' e1=Expr 'to' e2=Expr Block; -``` - -**Color** commands are the last one to add, and they'll change the stroke color in a few ways. The first is by setting the RGB components as integers directly: - -```minilogo -color(128,64,255) -``` - -The second is by passing in the name of a stroke color: - -```minilogo -color(blue) -``` - -The last is by passing a hexadecimal value: - -```minilogo -color(#66CCFF) -... -color(#6cf) -``` - -The corresponding rule for this syntax is a special case where we have 3 different overloaded forms of the same command. To capture all of these forms, we can use two different sets of properties: - -- r,g,b values for each color -- a single color value that can be either an ID or HEX - -We can encode this like so: - -```langium -Color: 'color' '(' ((r = Expr ',' g=Expr ',' b=Expr) | color=ID | color=HEX) ')'; -``` - -What's interesting here is that the color & r,g,b properties are *both* optional. Since in either case only one or the other will be defined. With the two forms, this is enough information to quickly determine what kind of color command we have, and to handle it correctly later on. - -## Adding Expressions - -Now we're at the core of our language, **Expressions**. In MiniLogo we want to be able to express not only literal values, but also references and arithmetic operations such as addition, subtraction, multiplication, and division. When implementing expressions, we need to keep in mind that Langium is based off of Chevrotain, which produces top-down parsers. This means we have to watch out for cases that lead to left-recursion. In order to avoid this, we need to be careful not to define a rule with itself on the left-hand side. For example, something like `Expr: e1=Expr ...` would not work, because the parser would infinitely try to parse another expression forever. - -However, we can work around this. We can introduce expressions and avoid left-recursion by writing them from the bottom up in terms of order of operations. We'll start with `Add` (which also includes subtraction): - -```langium -Expr: Add; -``` - -Then writing a rule to handle the addition (and subtraction) case. - -```langium -Add infers Expr: - Mult ({infer BinExpr.e1=current} op=('+'|'-') e2=Mult)*; -``` - -To explain a bit, the `Add` rule introduces: - -- a parser rule that produces an **Expr** instance (that's what the infers is doing here) -- starts by recognizing a `Mult` instance -- *then* if there's a binary operator to parse - - rewrite this parsed object into a **BinExpr** that will *extend* **Expr** (that's what the second `{infer ...}` is doing) - - also capture the first `Mult` under the `e1` property (that's what the `current` keyword refers to) - - capture the operand +/- - - capture the following `Mult` instance (the right hand side of our binary expression) -- *else* simply returns the result of `Mult` (the case where we don't have a binary expression) - -We can then repeat this pattern with the `Mult` rule: - -```langium -Mult infers Expr: - PrimExpr ({infer BinExpr.e1=current} op=('*'|'/') e2=PrimExpr)*; -``` - -Lastly we can then introduce `Primary` expressions, or `PrimExpr`. This rule will match all the primitive cases, such as literals, references, groupings, and negation. - -```langium -PrimExpr: Lit | Ref | Group | NegExpr; - -// literal int -Lit: val=INT; -// cross-reference to a parameter -Ref: val=[Param:ID]; -// grouped expression with parentheses -Group: '(' ge=Expr ')'; -// negated expression -NegExpr: '-' ne=Expr; -``` - -By writing our parser rules first for Addition & Subtraction, and then later for Multiplication and Division, we can construct an abstract syntax text tree that will correctly preserve order of operations. - -As a note, we could also write these rules *without using actions to rewrite our parse tree*. When we're talking about actions, we're talking about those cases of `{infer ...}`. However, then we'll get nodes like `Add` and `Mult`, instead of `Expr` and `BinaryExpr`. This is a tradeoff that is a bit tough to grasp at first in the grammar, but translates to a more sensible AST to work on later. This is especially helpful when we get to generation. - -## Adding Terminals - -Now that we're almost done with our grammar, we need to add in the terminal rules. Conveniently, the body of a terminal rule can be defined as a Javascript regular expression; sharing the same syntax. This makes it very clear to determine what our terminals should recognize. - -```langium -// recognize a hexadecimal sequence, used to recognize colors for the 'Color' command -terminal HEX returns string: /#(\d|[a-fA-F])+/; - -// recognize an identifier -terminal ID returns string: /[_a-zA-Z][\w_]*/; - -// recognize an Integer (but represented via a 'number' type) -terminal INT returns number: /-?[0-9]+/; -``` - -Then, lastly, we want to add *hidden terminals*. These will describe tokens that we want to parse and *discard* while parsing any input. Since we're adding whitespace & comments as hidden terminals, it's the same as saying we do *not* care about these tokens while parsing, but we do recognize that they are tokens; they just don't play a role in capturing the structure of our language. - -```langium -hidden terminal WS: /\s+/; -hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; -hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; -``` - -And that's it, we're all set writing up the grammar for MiniLogo. To verify that we correctly implemented the grammar with no problems, we can run the following command in the project root: - -```bash -npm run langium:generate -``` - -The generation should finish successfully, indicating that our grammar doesn't have any errors in it. In some cases, you may get warnings -- such as from unreachable rules in your grammar -- but these won't prevent the generation from completing successfully. Also, when we're referring to the generation, we're talking about the construction of the following from your grammar: - -- a semantic model (that ASTs can be mapped onto) -- a parser that recognizes our language - -With that, we have the beginnings of our very own language! Hopefully this gives a good idea of how to express a grammar in Langium, particularly with consideration to your concrete syntax & semantic domain. You can also consider the ways we can express cases that are left-recursive, like expressions, in an alternative fashion. Overall, our grammar should now be ready for the next step of [validation in the following tutorial](/tutorials/validation). From c8880c9e69291ae949e4797be1a6594c6fd634c2 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 15 Apr 2024 16:46:33 +0200 Subject: [PATCH 11/19] Apply review notes of Johannes --- hugo/content/docs/_index.md | 3 +- hugo/content/docs/introduction/_index.md | 20 +++++++ hugo/content/docs/introduction/features.md | 1 + hugo/content/docs/learn/workflow/_index.md | 54 ++++++++++++++----- .../docs/learn/workflow/create_validations.md | 2 +- .../docs/learn/workflow/generate_ast.md | 2 +- .../learn/workflow/generate_everything.md | 2 +- hugo/content/docs/learn/workflow/install.md | 2 +- .../workflow/resolve_cross_references.md | 2 +- hugo/content/docs/learn/workflow/scaffold.md | 2 +- .../docs/learn/workflow/write_grammar.md | 2 +- hugo/content/docs/recipes/builtin-library.md | 2 +- hugo/content/docs/recipes/code-bundling.md | 2 +- hugo/content/docs/recipes/scoping/_index.md | 2 +- 14 files changed, 75 insertions(+), 23 deletions(-) diff --git a/hugo/content/docs/_index.md b/hugo/content/docs/_index.md index 21039921..e8aaead5 100644 --- a/hugo/content/docs/_index.md +++ b/hugo/content/docs/_index.md @@ -1,4 +1,5 @@ --- title: "Documentation" weight: 0 ---- \ No newline at end of file +--- + \ No newline at end of file diff --git a/hugo/content/docs/introduction/_index.md b/hugo/content/docs/introduction/_index.md index 06bc2e11..5ab517e8 100644 --- a/hugo/content/docs/introduction/_index.md +++ b/hugo/content/docs/introduction/_index.md @@ -3,3 +3,23 @@ title: "What is Langium?" weight: -100 --- Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. + +## Where to go? + +### Features + +If you need a more detailed list of Langium features, you can find them in the [features section](/docs/features). + +### Try it out + +If you want to see Langium in action, you can follow the [showcases](/showcase) or event the [playground](/playground). + +### Learn Langium + +If you are convinced with Langium and want to learn more about it, you can start with the [learn section](/docs/learn). + +### More details + +If you are looking for more details about Langium, you can find them in the [reference section](/docs/reference). + +If you are searching for a certain guide or recipe, you can find them in the [recipes section](/docs/recipes). diff --git a/hugo/content/docs/introduction/features.md b/hugo/content/docs/introduction/features.md index eafe4339..14c41d0e 100644 --- a/hugo/content/docs/introduction/features.md +++ b/hugo/content/docs/introduction/features.md @@ -1,6 +1,7 @@ --- title: "Features" weight: 200 +url: /docs/features --- Designing programming languages from the ground up is hard, independent of whether your language is a "simple" domain specific language or a full-fledged general-purpose programming language. Not only do you have to keep up with the requirements of your domain experts, but you have to deal with all the technical complexity that comes with building a language, including questions such as: diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index 9da47498..01052b9e 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -1,23 +1,25 @@ --- -title: "Our workflow" +title: "Langium's workflow" weight: 0 url: /docs/learn/worflow --- + + ## Workflow diagram {{}} flowchart TD - A(["1. Install Yeoman generator"]); + A(["1. Install Yeoman"]); B(["2. Scaffold a Langium project"]); C(["3. Write the grammar"]); - D(["4. Generate AST files"]); + D(["4. Generate the AST"]); E(["5. Resolve cross-references"]); F(["6. Create validations"]); - G(["7. Generate what you want"]); - H(["8. Find advanced topics"]); - A --> B --> C --> D --> E --> F --> G --> H; - G -- reiterate --> C; + G(["7. Generate your artifacts"]); + H(["Find advanced topics"]); + A --> B --> C --> D --> E --> F --> G ~~~ H; + G -- for each feature --> C; click A "/docs/learn/workflow/install" click B "/docs/learn/workflow/scaffold" @@ -42,10 +44,38 @@ This simple introduction can be seen as three main parts: While the first part is straight-forward. The last part is about advanced topics that differ from project to project. The middle part will be explained briefly in the following section. +## Initial setup + +### [1. Install Yeoman](/docs/learn/workflow/install) + +This step ensures that you start a Langium project with the Yeoman generator. Yeoman is a scaffolding tool that helps you to start a new project with a predefined structure. + +### [2. Scaffold a Langium project](/docs/learn/workflow/scaffold) + +After installing Yeoman, you can scaffold a new Langium project. + ## Core workflow -3. [_changing the grammar_](/docs/learn/workflow/write_grammar): The first step in the core workflow starts from the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. -4. [_generating the AST_](/docs/learn/workflow/generate_ast): The AST is the backbone of your language. It is used to represent the structure of your language elements. The AST is generated from the grammar. One important part of the AST are the _cross-references_. They are used to resolve references between language elements. If you have cross-references in your language, you need to _resolve_ them, after this step. The actual generation is done by a call of the Langium CLI. -5. [_resolving cross-references_](/docs/learn/workflow/resolve_cross_references): The cross-references are used to resolve references between language elements (between different sub trees of one file or even elements of other files(!)). This step is quite important, because it is the basis for the next steps. You can also see it like this: Step 4 will generate an AST with gaps, this fifth step will fill these gaps. -6. [_create validations_](/docs/learn/workflow/create_validations): From here we have a fully utilized AST. Now every input file that matches the syntax will be accepted. But we want to have more control over the input. We want to check if the input is semantically correct. This is done by creating _validations_. They are used to check the input against a set of rules. If the input does not match the rules, an error will be thrown. -7. [_generate what you want_](/docs/learn/workflow/generate_everything): Now you have a fully working language. You can generate whatever you want from the input. This can be code, documentation, or anything else. You can use the AST to traverse the input and generate the output. +### [3. Write the grammar](/docs/learn/workflow/write_grammar) + +The first step in the core workflow starts from the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. + +### [4. Generate the AST](/docs/learn/workflow/generate_ast) + +The AST is the backbone of your language. It is used to represent the structure of your language elements. The AST is generated from the grammar. One important part of the AST are the _cross-references_. They are used to resolve references between language elements. If you have cross-references in your language, you need to _resolve_ them, after this step. The actual generation is done by a call of the Langium CLI. + +### [5. Resolve cross-references](/docs/learn/workflow/resolve_cross_references) + +The cross-references are used to resolve references between language elements (between different sub trees of one file or even elements of other files(!)). This step is quite important, because it is the basis for the next steps. You can also see it like this: Step 4 will generate an AST with gaps, this fifth step will fill these gaps. + +### [6. Create validations](/docs/learn/workflow/create_validations) + +From here we have a fully utilized AST. Now every input file that matches the syntax will be accepted. But we want to have more control over the input. We want to check if the input is semantically correct. This is done by creating _validations_. They are used to check the input against a set of rules. If the input does not match the rules, an error will be thrown. + +### [7. Generate your artifacts](/docs/learn/workflow/generate_everything) + +Now you have a fully working language. You can generate whatever you want from the input. This can be code, documentation, or anything else. You can use the AST to traverse the input and generate the output. + +## [Find advanced topics](/docs/recipes) + +Everything that is out of the scope of the common workflow is covered in the recipes. Here you can find answers to specific questions or problems that you might encounter during the development of your language. diff --git a/hugo/content/docs/learn/workflow/create_validations.md b/hugo/content/docs/learn/workflow/create_validations.md index d732bfd4..0ae78669 100644 --- a/hugo/content/docs/learn/workflow/create_validations.md +++ b/hugo/content/docs/learn/workflow/create_validations.md @@ -1,5 +1,5 @@ --- -title: "Create validations" +title: "6. Create validations" weight: 700 url: /docs/learn/workflow/create_validations --- diff --git a/hugo/content/docs/learn/workflow/generate_ast.md b/hugo/content/docs/learn/workflow/generate_ast.md index 02095d84..c206a842 100644 --- a/hugo/content/docs/learn/workflow/generate_ast.md +++ b/hugo/content/docs/learn/workflow/generate_ast.md @@ -1,5 +1,5 @@ --- -title: "Generate the AST" +title: "4. Generate the AST" weight: 500 url: /docs/learn/workflow/generate_ast --- diff --git a/hugo/content/docs/learn/workflow/generate_everything.md b/hugo/content/docs/learn/workflow/generate_everything.md index 349c88e6..e774cd06 100644 --- a/hugo/content/docs/learn/workflow/generate_everything.md +++ b/hugo/content/docs/learn/workflow/generate_everything.md @@ -1,5 +1,5 @@ --- -title: "Generate your artifacts" +title: "7. Generate your artifacts" weight: 800 url: /docs/learn/workflow/generate_everything --- diff --git a/hugo/content/docs/learn/workflow/install.md b/hugo/content/docs/learn/workflow/install.md index f23cb46d..cd369234 100644 --- a/hugo/content/docs/learn/workflow/install.md +++ b/hugo/content/docs/learn/workflow/install.md @@ -1,5 +1,5 @@ --- -title: "Install Yeoman" +title: "1. Install Yeoman" weight: 200 url: /docs/learn/workflow/install --- diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index 8519bbce..1854ca27 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -1,5 +1,5 @@ --- -title: "Resolve cross-references" +title: "5. Resolve cross-references" weight: 600 url: /docs/learn/workflow/resolve_cross_references --- diff --git a/hugo/content/docs/learn/workflow/scaffold.md b/hugo/content/docs/learn/workflow/scaffold.md index c30c486d..071b69c9 100644 --- a/hugo/content/docs/learn/workflow/scaffold.md +++ b/hugo/content/docs/learn/workflow/scaffold.md @@ -1,5 +1,5 @@ --- -title: "Scaffold a Langium project" +title: "2. Scaffold a Langium project" weight: 300 url: /docs/learn/workflow/scaffold --- diff --git a/hugo/content/docs/learn/workflow/write_grammar.md b/hugo/content/docs/learn/workflow/write_grammar.md index 099addae..9dce5bff 100644 --- a/hugo/content/docs/learn/workflow/write_grammar.md +++ b/hugo/content/docs/learn/workflow/write_grammar.md @@ -1,5 +1,5 @@ --- -title: "Write the grammar" +title: "3. Write the grammar" weight: 400 url: /docs/learn/workflow/write_grammar --- diff --git a/hugo/content/docs/recipes/builtin-library.md b/hugo/content/docs/recipes/builtin-library.md index fb749d5c..73a78bae 100644 --- a/hugo/content/docs/recipes/builtin-library.md +++ b/hugo/content/docs/recipes/builtin-library.md @@ -1,6 +1,6 @@ --- title: "Builtin Libraries" -weight: 300 +weight: 100 --- Languages usually offer their users some high-level programming features that they do not have to define themselves. diff --git a/hugo/content/docs/recipes/code-bundling.md b/hugo/content/docs/recipes/code-bundling.md index 29089879..a7a09f27 100644 --- a/hugo/content/docs/recipes/code-bundling.md +++ b/hugo/content/docs/recipes/code-bundling.md @@ -1,6 +1,6 @@ --- title: "Code Bundling" -weight: 0 +weight: 900 --- When you first create a Langium project using the [Yeoman generator](/docs/getting-started/#your-first-example-language), it will only contain a plain TypeScript configuration, without any additional build processes. diff --git a/hugo/content/docs/recipes/scoping/_index.md b/hugo/content/docs/recipes/scoping/_index.md index e75d086e..42afe56a 100644 --- a/hugo/content/docs/recipes/scoping/_index.md +++ b/hugo/content/docs/recipes/scoping/_index.md @@ -1,6 +1,6 @@ --- title: "Scoping" -weight: 100 +weight: 0 --- You likely know scopes from programming, where some variables are only available from certain areas (such as blocks) in your program. For example, take the short Typescript snippet below. Based on the block (scope) where a variable is declared, it may or may not be available at another location in the same program. From 219f0844c95ca919584454806ee8454602ce9237 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 15 Apr 2024 17:02:15 +0200 Subject: [PATCH 12/19] Add intro sentence for Langium's workflow --- hugo/content/docs/learn/workflow/_index.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index 01052b9e..abc24704 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -4,9 +4,8 @@ weight: 0 url: /docs/learn/worflow --- - - -## Workflow diagram +Langium's workflow can be expressed as a flow chart diagram, which boils down to the following steps in the diagram. +Be aware of the fact that the possibilities go beyond this simple workflow. For more advanced topics, you can find answers in the [recipes](/docs/recipes). {{}} flowchart TD From aec997feaee73d20e7202e38691bbd9c43744593 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Thu, 18 Apr 2024 16:44:07 +0200 Subject: [PATCH 13/19] Add testing code for user verification --- .../docs/learn/workflow/create_validations.md | 37 ++++++++++++++++++- .../docs/learn/workflow/generate_ast.md | 36 ++++++++++++++++++ .../learn/workflow/generate_everything.md | 5 ++- .../workflow/resolve_cross_references.md | 33 +++++++++++++++++ 4 files changed, 109 insertions(+), 2 deletions(-) diff --git a/hugo/content/docs/learn/workflow/create_validations.md b/hugo/content/docs/learn/workflow/create_validations.md index 0ae78669..5022506d 100644 --- a/hugo/content/docs/learn/workflow/create_validations.md +++ b/hugo/content/docs/learn/workflow/create_validations.md @@ -6,7 +6,9 @@ url: /docs/learn/workflow/create_validations After resolving the cross-references, you can assume that the syntax tree is complete. Now you can start with the validation of the input files. The validation process is a crucial part of the language engineering workflow. The parser ensures the syntactic correctness of the input files. The validation process ensures the semantic correctness of the input files. -As an example, let's consider the Hello-World example from the Yeoman generator. One semantic of this language could be that each declared person must be greeted at most once. To be clear, the following input file is invalid, we are greeting John twice: +## Example + +Let's consider the Hello-World example from the Yeoman generator. One semantic of this language could be that each declared person must be greeted at most once. To be clear, the following input file is invalid, we are greeting John twice: ```text person John @@ -17,6 +19,8 @@ Hello Jane! Hello John! //should throw: You can great each person at most once! This is the 2nd greeting to John. ``` +## Implementation + To accomplish this, you need to implement a validator. The validator is a visitor that traverses a certain part of the syntax tree and checks for semantic errors. The following code snippet shows how you can implement a validator for the Hello-World example. Mind that the Hello-World already has a validator, you just need to add the following one. ```ts @@ -59,3 +63,34 @@ export class HelloWorldValidator { } } ``` + +## How to test the validator? + +To test the validator, we can simply use the `parseHelper` again. The following code snippet shows how you can test the validator: + +```ts +import { createHelloWorldServices } from "./your-project//hello-world-module.js"; +import { EmptyFileSystem } from "langium"; +import { parseHelper } from "langium/test"; +import { Model } from "../../src/language/generated/ast.js"; + +//arrange +const services = createHelloWorldServices(EmptyFileSystem); +const parse = parseHelper(services.HelloWorld); + +//act +const document = await parse(` + person John + person Jane + + Hello John! + Hello Jane! + Hello John! +`, { validation: true }); //enable validation, otherwise the validator will not be called! + +//assert +expect(document.diagnostics).toHaveLength(1); +expect(document.diagnostics![0].message).toBe('You can great each person at most once! This is the 2nd greeting to John.'); +``` + +The `expect` function can be any assertion library you like. The `Hello world` example uses Vitest. diff --git a/hugo/content/docs/learn/workflow/generate_ast.md b/hugo/content/docs/learn/workflow/generate_ast.md index c206a842..4fc7b3a2 100644 --- a/hugo/content/docs/learn/workflow/generate_ast.md +++ b/hugo/content/docs/learn/workflow/generate_ast.md @@ -65,3 +65,39 @@ graph TB {{}} Mind the gaps (question marks) for the cross-references inside the greetings. This job has to be done by the developer. Fortunately Langium provides a default implementation for cross-reference resolution. You can also implement your own resolution strategy. + +## How to test the parser? + +You can test the parser by comparing the generated AST with the expected AST. Here is an example: + +```typescript +import { createHelloWorldServices } from "./your-project//hello-world-module.js"; +import { EmptyFileSystem } from "langium"; +import { parseHelper } from "langium/test"; +import { Model } from "../../src/language/generated/ast.js"; + +//arrange +const services = createHelloWorldServices(EmptyFileSystem); +const parse = parseHelper(services.HelloWorld); + +//act +const document = await parse(` + person John + person Jane + + Hello John! + Hello Jane! +`); + +//assert +const model = document.parseResult.value; +expect(model.persons).toHaveLength(2); +expect(model.persons[0].name).toBe("John"); +expect(model.persons[1].name).toBe("Jane"); +expect(model.greetings).toHaveLength(2); +//be aware of the fact that the following checks will fail, because the cross-references are not resolved yet +expect(model.greetings[0].person.ref?.name).toBe("John"); +expect(model.greetings[1].person.ref?.name).toBe("Jane"); +``` + +The `expect` function can be any assertion library you like. The `Hello world` example uses Vitest. diff --git a/hugo/content/docs/learn/workflow/generate_everything.md b/hugo/content/docs/learn/workflow/generate_everything.md index e774cd06..edd27a93 100644 --- a/hugo/content/docs/learn/workflow/generate_everything.md +++ b/hugo/content/docs/learn/workflow/generate_everything.md @@ -34,18 +34,21 @@ import { createHelloWorldServices } from "./your-project/hello-world-module.js"; import { Model } from "./your-project/generated/ast.js"; import { generateJavaScript } from "./your-project/generator.js"; +//arrange const services = createHelloWorldServices(EmptyFileSystem); const parse = parseHelper(services.HelloWorld); const document = await parse(` person Langium Hello Langium! `, {validation: true}); - expect(document.parseResult.lexerErrors).toHaveLength(0); expect(document.parseResult.parserErrors).toHaveLength(0); expect(document.diagnostics ?? []).toHaveLength(0); +//act const javaScript = generateJavaScript(document.parseResult.value); + +//assert expect(javaScript).toBe(`"use strict"; console.log('Hello, Langium!');`); ``` diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index 1854ca27..65dc2fdc 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -194,3 +194,36 @@ export const HelloWorldModule: Module(services.HelloWorld); + +//act +const document = await parse(` + person John + person Jane + + Hello John! + Hello Jane! +`); + +//assert +const model = document.parseResult.value; +expect(model.persons).toHaveLength(2); +expect(model.greetings).toHaveLength(2); +expect(model.greetings[0].person.ref).toBe(model.persons[0]); +expect(model.greetings[1].person.ref).toBe(model.persons[1]); +``` + +The `expect` function can be any assertion library you like. The `Hello world` example uses Vitest. From fb94a5b05abb5cd67924936c9e9aae3a8e2f1490 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Thu, 18 Apr 2024 17:00:05 +0200 Subject: [PATCH 14/19] Fill further empty sites with life --- hugo/content/docs/introduction/_index.md | 2 +- hugo/content/docs/recipes/_index.md | 5 ++++- hugo/content/docs/reference/_index.md | 22 ++++++++++++++++++- .../docs/reference/configuration-services.md | 2 +- .../docs/reference/document-lifecycle.md | 2 +- .../{sematic-model.md => semantic-model.md} | 2 +- 6 files changed, 29 insertions(+), 6 deletions(-) rename hugo/content/docs/reference/{sematic-model.md => semantic-model.md} (99%) diff --git a/hugo/content/docs/introduction/_index.md b/hugo/content/docs/introduction/_index.md index 5ab517e8..5b90020a 100644 --- a/hugo/content/docs/introduction/_index.md +++ b/hugo/content/docs/introduction/_index.md @@ -4,7 +4,7 @@ weight: -100 --- Langium is an open source language engineering tool with first-class support for the Language Server Protocol, written in TypeScript and running in Node.js. -## Where to go? +## Where to go from here? ### Features diff --git a/hugo/content/docs/recipes/_index.md b/hugo/content/docs/recipes/_index.md index 61c1254b..3f26ac3b 100644 --- a/hugo/content/docs/recipes/_index.md +++ b/hugo/content/docs/recipes/_index.md @@ -3,4 +3,7 @@ title: "Recipes" weight: 400 url: "/docs/recipes" --- -TODO \ No newline at end of file + +## Where to go from here? + +Take your time to study the recipes within the navigation on the left. They are designed to help you with common tasks and challenges you might face when working with Langium. If you have any questions or suggestions, feel free to [create an issue](https://github.com/eclipse-langium/langium/issues) or [start a discussion](https://github.com/eclipse-langium/langium/discussions). diff --git a/hugo/content/docs/reference/_index.md b/hugo/content/docs/reference/_index.md index 384a2ea8..775871fc 100644 --- a/hugo/content/docs/reference/_index.md +++ b/hugo/content/docs/reference/_index.md @@ -1,4 +1,24 @@ --- title: "Reference" weight: 300 ---- \ No newline at end of file +--- + +This section contains the reference documentation for Langium. + +## Where to go from here? + +### Glossary + +If you are looking for a specific term or concept, you can find it in the [glossary](/docs/reference/glossary). + +### Grammar language + +If you are looking for a specific grammar language feature, you can find it in the [grammar language](/docs/reference/grammar-language). + +### Architecture + +If you are looking for a specific architecture feature, here are some nice readings: + +* [Configuration via services](/docs/reference/configuration-services) +* [Document lifecycle](/docs/reference/document-lifecycle) +* [Semantic model](/docs/reference/semantic-model) \ No newline at end of file diff --git a/hugo/content/docs/reference/configuration-services.md b/hugo/content/docs/reference/configuration-services.md index 8dbad125..56ffb0e8 100644 --- a/hugo/content/docs/reference/configuration-services.md +++ b/hugo/content/docs/reference/configuration-services.md @@ -1,6 +1,6 @@ --- title: "Configuration via Services" -weight: 300 +weight: 200 --- Langium supports the configuration of most aspects of your language and language server via a set of *services*. Those services are configured by *modules*, which are essentially mappings from a service name to its implementation. diff --git a/hugo/content/docs/reference/document-lifecycle.md b/hugo/content/docs/reference/document-lifecycle.md index 3672e486..1a99770e 100644 --- a/hugo/content/docs/reference/document-lifecycle.md +++ b/hugo/content/docs/reference/document-lifecycle.md @@ -1,6 +1,6 @@ --- title: 'Document Lifecycle' -weight: 400 +weight: 300 --- `LangiumDocument` is the central data structure in Langium that represents a text file of your DSL. Its main purpose is to hold the parsed Abstract Syntax Tree (AST) plus additional information derived from it. After its creation, a `LangiumDocument` must be "built" before it can be used in any way. The service responsible for building documents is called `DocumentBuilder`. diff --git a/hugo/content/docs/reference/sematic-model.md b/hugo/content/docs/reference/semantic-model.md similarity index 99% rename from hugo/content/docs/reference/sematic-model.md rename to hugo/content/docs/reference/semantic-model.md index de480119..56df2bca 100644 --- a/hugo/content/docs/reference/sematic-model.md +++ b/hugo/content/docs/reference/semantic-model.md @@ -1,6 +1,6 @@ --- title: "Semantic Model Inference" -weight: 200 +weight: 400 --- When AST nodes are created during the parsing of a document, they are given a type. The language grammar dictates the shape of those types and how they might be related to each other. All types form the *semantic model* of your language. There are two ways by which Langium derives semantic model types from the grammar, by **[inference](#inferred-types)** and by **[declaration](#declared-types)**. From 31cd790de0cddd1fafa557df14c7ebfdcd16c7c8 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 13 May 2024 10:38:27 +0200 Subject: [PATCH 15/19] Add latest review comments --- hugo/content/docs/introduction/_index.md | 4 ++-- hugo/content/docs/learn/workflow/_index.md | 6 +++--- .../content/docs/learn/workflow/resolve_cross_references.md | 4 ++-- hugo/content/docs/learn/workflow/write_grammar.md | 2 +- hugo/content/docs/recipes/_index.md | 2 +- hugo/content/docs/reference/glossary.md | 2 +- hugo/content/docs/reference/grammar-language.md | 3 +++ 7 files changed, 13 insertions(+), 10 deletions(-) diff --git a/hugo/content/docs/introduction/_index.md b/hugo/content/docs/introduction/_index.md index 5b90020a..8bb8600b 100644 --- a/hugo/content/docs/introduction/_index.md +++ b/hugo/content/docs/introduction/_index.md @@ -12,11 +12,11 @@ If you need a more detailed list of Langium features, you can find them in the [ ### Try it out -If you want to see Langium in action, you can follow the [showcases](/showcase) or event the [playground](/playground). +If you want to see Langium in action, you can follow the [showcases](/showcase) or even the [playground](/playground). ### Learn Langium -If you are convinced with Langium and want to learn more about it, you can start with the [learn section](/docs/learn). +If you are convinced by Langium and want to learn more about it, you can start with the [learn section](/docs/learn). ### More details diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index abc24704..927253cc 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -38,9 +38,9 @@ This simple introduction can be seen as three main parts: * setting up your project environment (1.+2.): this is only done once * specifying the language features (3.-7.): this cycle you need to reiterate for each new language feature -* everything advanced (8.): here the limit of the common workflow is reached, for specific questions you can find answers in the [recipes](/docs/recipes). +* everything advanced (8.): The limit of the common workflow is reached here. For specific questions you can find answers in the [recipes](/docs/recipes). -While the first part is straight-forward. The last part is about advanced topics that differ from project to project. +While the first part is straight-forward, the last part is about advanced topics that differ from project to project. The middle part will be explained briefly in the following section. ## Initial setup @@ -57,7 +57,7 @@ After installing Yeoman, you can scaffold a new Langium project. ### [3. Write the grammar](/docs/learn/workflow/write_grammar) -The first step in the core workflow starts from the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. +The first step in the core workflow starts with the grammar. You will have some language feature in mind that you want to implement. The grammar is used to nail down the syntax of your features. You can use our Langium VS Code extension to get syntax highlighting and code completion for `.langium` files. If your grammar is free of errors, you can generate the files for the _abstract syntax tree (AST)_. ### [4. Generate the AST](/docs/learn/workflow/generate_ast) diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index 65dc2fdc..d2903490 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -118,11 +118,11 @@ export interface Scope { #### Purpose -So, what is the purpose of the scope provider? As mentioned above: it visits each cross-reference and tries to find the corresponding AST nodes over the entire workspace, that can be a candidate for the cross-reference's place. It is important to understand that we do not decide here which of these nodes is the perfect match! That decision is part of the so-called linker of the Langium architecture. +So, what is the purpose of the scope provider? As mentioned above: it visits each cross-reference and tries to find the corresponding AST nodes over the entire workspace that can be a candidate for the cross-reference's place. It is important to understand that we do not decide here which of these nodes is the perfect match! That decision is part of the so-called linker of the Langium architecture. If your cross-reference's `$refText` contains the name `Jane` does not matter here. We need to provide all nodes that are possible at this position. So in the result, you would return `Jane` and `John` AST nodes - for both cross-references! -The background for this behavior is, that this mechanism can be used for two things: the cross-reference resolution and the code completion. The code completion needs to know all possible candidates for a given cross-reference. The resolution of the cross-reference is done by the linker: Given a scope for a certain cross-reference, the linker decides which of the candidates is the right one - for example the first candidate with the same name. +The background for this behavior is that this mechanism can be used for two things: the cross-reference resolution and the code completion. The code completion needs to know all possible candidates for a given cross-reference. The resolution of the cross-reference is done by the linker: Given a scope for a certain cross-reference, the linker decides which of the candidates is the right one - for example the first candidate with the same name. ### Scope computation diff --git a/hugo/content/docs/learn/workflow/write_grammar.md b/hugo/content/docs/learn/workflow/write_grammar.md index 9dce5bff..8bebf921 100644 --- a/hugo/content/docs/learn/workflow/write_grammar.md +++ b/hugo/content/docs/learn/workflow/write_grammar.md @@ -35,7 +35,7 @@ hidden terminal WS: /\s+/; terminal ID: /[_a-zA-Z][\w]*/; ``` -Here we define our two needed terminals for this grammar: The whitespace `WS` and identifier `ID` terminals. Terminals parse a part of our document by matching it against their regular expression. The `WS` terminal parses any whitespace characters with the regex `/\s+/`. This allows us consume whitespaces in our document. As the terminal is declared as `hidden`, the parser will parse any whitespace and discard the results. That way, we don't have to care about how many whitespaces a user uses in their document. Secondly, we define our `ID` terminal. It parses any string that starts with an underscore or letter and continues with any amount of characters that match the `\w` regex token. It will match `Alice`, `_alice`, or `_al1c3` but not `4lice` or `#alice`. Langium is using the JS regex dialect for terminal definitions. +Here we define our two needed terminals for this grammar: The whitespace `WS` and identifier `ID` terminals. Terminals parse a part of our document by matching it against their regular expression. The `WS` terminal parses any whitespace characters with the regex `/\s+/`. This allows us to consume whitespaces in our document. As the terminal is declared as `hidden`, the parser will parse any whitespace and discard the results. That way, we don't have to care about how many whitespaces a user uses in their document. Secondly, we define our `ID` terminal. It parses any string that starts with an underscore or letter and continues with any amount of characters that match the `\w` regex token. It will match `Alice`, `_alice`, or `_al1c3` but not `4lice` or `#alice`. Langium is using the JS regex dialect for terminal definitions. ```langium entry Model: (persons+=Person | greetings+=Greeting)*; diff --git a/hugo/content/docs/recipes/_index.md b/hugo/content/docs/recipes/_index.md index 3f26ac3b..105b28bf 100644 --- a/hugo/content/docs/recipes/_index.md +++ b/hugo/content/docs/recipes/_index.md @@ -6,4 +6,4 @@ url: "/docs/recipes" ## Where to go from here? -Take your time to study the recipes within the navigation on the left. They are designed to help you with common tasks and challenges you might face when working with Langium. If you have any questions or suggestions, feel free to [create an issue](https://github.com/eclipse-langium/langium/issues) or [start a discussion](https://github.com/eclipse-langium/langium/discussions). +Take your time to study the recipes within the navigation on the left. They are designed to help you with common tasks and challenges you might face when working with Langium. If you have any questions or suggestions, feel free to [create an issue](https://github.com/eclipse-langium/langium/issues) or [start a discussion](https://github.com/eclipse-langium/langium/discussions) on the Github repository. diff --git a/hugo/content/docs/reference/glossary.md b/hugo/content/docs/reference/glossary.md index 5c953e84..b84a435d 100644 --- a/hugo/content/docs/reference/glossary.md +++ b/hugo/content/docs/reference/glossary.md @@ -15,6 +15,6 @@ _parser_: A program that takes a _document_ as its input and computes an _abstra _parser rule_: A parser rule describes how a certain _AST_ element is supposed to be parsed. This is done by invoking other _parser rules_ or _terminals_. -_terminal_: A terminal is the smallest parseable part of a document. It usually represents small pieces of text like names, numbers, keywords or comments. +_terminal_: A terminal is the smallest parsable part of a document. It usually represents small pieces of text like names, numbers, keywords or comments. _token_: A token is a substring of the _document_ that matches a certain _terminal_. It contains information about which kind of _terminal_ it represents as well as its location in the document. \ No newline at end of file diff --git a/hugo/content/docs/reference/grammar-language.md b/hugo/content/docs/reference/grammar-language.md index 587afefd..17266f9e 100644 --- a/hugo/content/docs/reference/grammar-language.md +++ b/hugo/content/docs/reference/grammar-language.md @@ -2,6 +2,9 @@ title: "Grammar Language" weight: 100 --- + +{{< toc format=html >}} + The grammar language describes the syntax and structure of your language. The [Langium grammar language](https://github.com/eclipse-langium/langium/blob/main/packages/langium/src/grammar/langium-grammar.langium) is implemented using Langium itself and therefore follows the same syntactic rules as any language created with Langium. The grammar language will define the structure of the *abstract syntax tree* (AST) which in Langium is a collection of *TypeScript types* describing the content of a parsed document and organized hierarchically. The individual nodes of the tree are then represented with JavaScript objects at runtime. In the following, we describe the Langium syntax and document structure. From 25c248c5be3641c0673f2080b0fc23ac75f66310 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 13 May 2024 13:12:51 +0200 Subject: [PATCH 16/19] Another iteration of resolving comments from the PR --- hugo/content/docs/learn/workflow/_index.md | 6 +++--- hugo/content/docs/learn/workflow/generate_ast.md | 4 ++-- hugo/content/docs/learn/workflow/generate_everything.md | 2 +- .../content/docs/learn/workflow/resolve_cross_references.md | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index 927253cc..153db796 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -15,7 +15,7 @@ flowchart TD D(["4. Generate the AST"]); E(["5. Resolve cross-references"]); F(["6. Create validations"]); - G(["7. Generate your artifacts"]); + G(["7. Generate artifacts"]); H(["Find advanced topics"]); A --> B --> C --> D --> E --> F --> G ~~~ H; G -- for each feature --> C; @@ -37,7 +37,7 @@ This is the workflow we recommend for developing a language with Langium. It is This simple introduction can be seen as three main parts: * setting up your project environment (1.+2.): this is only done once -* specifying the language features (3.-7.): this cycle you need to reiterate for each new language feature +* specifying the language features (3.-7.): this cycle you need to reiterate for each new language feature or grammar change iteration * everything advanced (8.): The limit of the common workflow is reached here. For specific questions you can find answers in the [recipes](/docs/recipes). While the first part is straight-forward, the last part is about advanced topics that differ from project to project. @@ -71,7 +71,7 @@ The cross-references are used to resolve references between language elements (b From here we have a fully utilized AST. Now every input file that matches the syntax will be accepted. But we want to have more control over the input. We want to check if the input is semantically correct. This is done by creating _validations_. They are used to check the input against a set of rules. If the input does not match the rules, an error will be thrown. -### [7. Generate your artifacts](/docs/learn/workflow/generate_everything) +### [7. Generate artifacts](/docs/learn/workflow/generate_everything) Now you have a fully working language. You can generate whatever you want from the input. This can be code, documentation, or anything else. You can use the AST to traverse the input and generate the output. diff --git a/hugo/content/docs/learn/workflow/generate_ast.md b/hugo/content/docs/learn/workflow/generate_ast.md index 4fc7b3a2..22f540bc 100644 --- a/hugo/content/docs/learn/workflow/generate_ast.md +++ b/hugo/content/docs/learn/workflow/generate_ast.md @@ -22,7 +22,7 @@ It will create the following files (depending on your given Langium configuratio An AST of your language is now ready to be get parsed. One important concept in Langium are _cross-references_. With them you can reference other elements in your language. For example, you can reference a variable in a function call. The AST will contain a reference to the variable. This is useful for code analysis and transformation. Technologies like ANTLR or other parser-only generators do not support this feature. For them you are forced to resolve these references in-place everytime the developer is confronted with them. -After this generation steps, cross-references are not resolved yet. This is done in the next step. +After these generation steps, cross-references are not resolved yet. This is done in the next step. ## Example @@ -95,7 +95,7 @@ expect(model.persons).toHaveLength(2); expect(model.persons[0].name).toBe("John"); expect(model.persons[1].name).toBe("Jane"); expect(model.greetings).toHaveLength(2); -//be aware of the fact that the following checks will fail, because the cross-references are not resolved yet +//be aware of the fact that the following checks will fail at this point, because the cross-references are not resolved yet expect(model.greetings[0].person.ref?.name).toBe("John"); expect(model.greetings[1].person.ref?.name).toBe("Jane"); ``` diff --git a/hugo/content/docs/learn/workflow/generate_everything.md b/hugo/content/docs/learn/workflow/generate_everything.md index edd27a93..39644153 100644 --- a/hugo/content/docs/learn/workflow/generate_everything.md +++ b/hugo/content/docs/learn/workflow/generate_everything.md @@ -1,5 +1,5 @@ --- -title: "7. Generate your artifacts" +title: "7. Generate artifacts" weight: 800 url: /docs/learn/workflow/generate_everything --- diff --git a/hugo/content/docs/learn/workflow/resolve_cross_references.md b/hugo/content/docs/learn/workflow/resolve_cross_references.md index d2903490..593c8d02 100644 --- a/hugo/content/docs/learn/workflow/resolve_cross_references.md +++ b/hugo/content/docs/learn/workflow/resolve_cross_references.md @@ -84,7 +84,7 @@ graph TB ## Resolution of cross-references -As already hinted, you can implement a scope provider and a scope computation. Fortunately, Langium comes with default implementations for both. But eventually as your language grows, you might want to implement your own strategy because the default is not sufficient. In the follwoing sections I will sketch how to interpret their interfaces. +As already hinted, you can implement a scope provider and a scope computation. Fortunately, Langium comes with default implementations for both. But eventually as your language grows, you might want to implement your own strategy because the default is not sufficient. In the following sections the interpretation of the involved interfaces will be sketched. ### Scope provider @@ -96,7 +96,7 @@ A _scope_ is a collection of AST nodes that are represented by the `AstNodeDescr The _description_ is like a (string) path through the AST of a document. It can be also seen as a tuple of document URI, JSON path, name and type of the AST node. -A _reference info_ contains the concrete AST reference (which points to nothing yet). The info also has a the parent AST node (a so-called container) of the reference and the property name under which you can find the reference under its container. In the form of this tuple (`container`, `property`, `reference`) Langium visits all cross-references using the scope providers `getScope` method. +A _reference info_ contains the concrete AST reference (which points to nothing yet). The info also has a the parent AST node (a so-called container) of the reference and the property name under which you can find the reference under its container. In the form of this tuple (`container`, `property`, `reference`) Langium visits all cross-references using the scope provider's `getScope` method. ```ts export interface ScopeProvider { From ada8c9b0d62ad42ba9b0b4f090d42d4a1772e3a6 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 13 May 2024 14:59:18 +0200 Subject: [PATCH 17/19] Update workflow documentation to reflect grammar change iteration --- hugo/content/docs/learn/workflow/_index.md | 4 ++-- hugo/content/docs/reference/_index.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index 153db796..e8f5063f 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -18,7 +18,7 @@ flowchart TD G(["7. Generate artifacts"]); H(["Find advanced topics"]); A --> B --> C --> D --> E --> F --> G ~~~ H; - G -- for each feature --> C; + G -- for each grammar change --> C; click A "/docs/learn/workflow/install" click B "/docs/learn/workflow/scaffold" @@ -37,7 +37,7 @@ This is the workflow we recommend for developing a language with Langium. It is This simple introduction can be seen as three main parts: * setting up your project environment (1.+2.): this is only done once -* specifying the language features (3.-7.): this cycle you need to reiterate for each new language feature or grammar change iteration +* specifying the language features (3.-7.): this cycle you need to go through for each grammar change * everything advanced (8.): The limit of the common workflow is reached here. For specific questions you can find answers in the [recipes](/docs/recipes). While the first part is straight-forward, the last part is about advanced topics that differ from project to project. diff --git a/hugo/content/docs/reference/_index.md b/hugo/content/docs/reference/_index.md index 775871fc..b6ab5a27 100644 --- a/hugo/content/docs/reference/_index.md +++ b/hugo/content/docs/reference/_index.md @@ -21,4 +21,4 @@ If you are looking for a specific architecture feature, here are some nice readi * [Configuration via services](/docs/reference/configuration-services) * [Document lifecycle](/docs/reference/document-lifecycle) -* [Semantic model](/docs/reference/semantic-model) \ No newline at end of file +* [Semantic model](/docs/reference/semantic-model) From a46f042822d21570dcfe3a4d52c7f8574f9de8c0 Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 13 May 2024 15:01:14 +0200 Subject: [PATCH 18/19] Add missing comma --- hugo/content/docs/recipes/multiple-languages.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugo/content/docs/recipes/multiple-languages.md b/hugo/content/docs/recipes/multiple-languages.md index 52853e4b..74789c7c 100644 --- a/hugo/content/docs/recipes/multiple-languages.md +++ b/hugo/content/docs/recipes/multiple-languages.md @@ -260,7 +260,7 @@ After this step, Langium is set up correctly. But if you try to build now, the c Let's clean up the error lines. Here are some general hints: * keep in mind, that you are dealing with three file types now, namely `*.me`, `*.who` and `*.hello` - * you can distinguish them very easily by selecting the right sub service from the result object of `createMultipleLanguagesServices`, which is either `Configuration`, `Definition` or `Implementation`, but not `shared` + * you can distinguish them very easily by selecting the right sub service from the result object of `createMultipleLanguagesServices`, which is either `Configuration`, `Definition`, or `Implementation`, but not `shared` * all these services have a sub service with file extensions: `[Configuration,Definition,...].LanguageMetaData.fileExtensions: string[]` * so, when you are obtaining any documents from the `DocumentBuilder` you can be sure that they are parsed by the matching language service * to distinguish them on your own, use the AST functions for determining the root type, for example for the Configuration language use `isConfigurationUnit(document.parseResult.value)` From 2fdb85af3236200c5ba3eee97ec8531b24b9823b Mon Sep 17 00:00:00 2001 From: Markus Rudolph Date: Mon, 13 May 2024 15:47:00 +0200 Subject: [PATCH 19/19] Add "additional" --- hugo/content/docs/learn/workflow/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hugo/content/docs/learn/workflow/_index.md b/hugo/content/docs/learn/workflow/_index.md index e8f5063f..0b4ae27b 100644 --- a/hugo/content/docs/learn/workflow/_index.md +++ b/hugo/content/docs/learn/workflow/_index.md @@ -18,7 +18,7 @@ flowchart TD G(["7. Generate artifacts"]); H(["Find advanced topics"]); A --> B --> C --> D --> E --> F --> G ~~~ H; - G -- for each grammar change --> C; + G -- for each additional\ngrammar change --> C; click A "/docs/learn/workflow/install" click B "/docs/learn/workflow/scaffold"