Skip to content

Commit

Permalink
Add main langium LS example
Browse files Browse the repository at this point in the history
  • Loading branch information
kaisalmen committed Jul 28, 2023
1 parent fb941be commit ff9f804
Show file tree
Hide file tree
Showing 16 changed files with 870 additions and 9 deletions.
4 changes: 3 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ <h1>Examples</h1>
Please execute <b><code>npm run start:example:server</code></b> beforehand:<br>
<a href="packages/examples/main/client.html">Web Client for Node.js Language Server</a>
<br><br>
<a href="packages/examples/main/langium_wwls.html">Web Client & Langium Web Worker Language Server Example</a>
<a href="packages/examples/main/langium_client.html">Web Client & Langium LS (Web Worker)</a>
<br><br>
<a href="packages/examples/main/statemachine_client.html">Web Client & Statemachine LS (Web Worker)</a>
<br><br>
<a href="packages/examples/main/browser.html">Browser Example</a>
<br><br>
Expand Down
12 changes: 12 additions & 0 deletions packages/client/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// this file is required for VSCode to work properly
{
"extends": "./tsconfig.src.json",
"compilerOptions": {
"noEmit": true,
"rootDir": "."
},
"include": [
"src/**/*",
"test/**/*"
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<body>
<h2>Monaco Language Client & Langium Web Worker Language Server Example</h2>
<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>
<script type="module" src="./src/langium/main.ts"></script>
<script type="module" src="./src/langium/langiumClient.ts"></script>
<div id="panel"></div>
</body>

Expand Down
10 changes: 5 additions & 5 deletions packages/examples/main/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@
"clean": "shx rm -fr dist *.tsbuildinfo",
"compile": "tsc --build tsconfig.src.json",
"build:msg": "echo Building main examples:",
"build:worker:vite": "vite --config vite.langium-worker.ts build",
"build:worker": "esbuild ../../../node_modules/langium-statemachine-dsl/out/language-server/main-browser.js --bundle --tree-shaking=true --minify --format=iife --outfile=./dist/worker/statemachineServerWorker.js",
"build": "npm run build:msg && npm run clean && npm run compile && npm run build:worker",
"build:worker:vite": "vite --config vite.statemachine-worker.ts build",
"build:worker:statemachine": "esbuild ../../../node_modules/langium-statemachine-dsl/out/language-server/main-browser.js --bundle --tree-shaking=true --minify --format=iife --outfile=./dist/worker/statemachineServerWorker.js",
"build:worker:langium": "esbuild ./src/langium/langiumServerWorker.js --bundle --tree-shaking=true --minify --format=iife --outfile=./dist/worker/langiumServerWorker.js",
"build": "npm run build:msg && npm run clean && npm run compile && npm run build:worker:statemachine && npm run build:worker:langium",
"start": "node --loader ts-node/esm src/server/main.ts",
"start:ext": "node --loader ts-node/esm src/server/main.ts --external",
"fetch:themes": "node resources/fetchThemes.mjs"
"start:ext": "node --loader ts-node/esm src/server/main.ts --external"
}
}
215 changes: 215 additions & 0 deletions packages/examples/main/src/langium/example.langium
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
grammar LangiumGrammar

entry Grammar:
(
isDeclared?='grammar' name=ID ('with' usedGrammars+=[Grammar:ID] (',' usedGrammars+=[Grammar:ID])*)?
(definesHiddenTokens?='hidden' '(' (hiddenTokens+=[AbstractRule:ID] (',' hiddenTokens+=[AbstractRule:ID])*)? ')')?
)?
imports+=GrammarImport*
(rules+=AbstractRule | interfaces+=Interface | types+=Type)+;

Interface:
'interface' name=ID
('extends' superTypes+=[AbstractType:ID] (',' superTypes+=[AbstractType:ID])*)?
SchemaType;

fragment SchemaType:
'{' attributes+=TypeAttribute* '}' ';'?;

TypeAttribute:
name=FeatureName (isOptional?='?')? ':' type=TypeDefinition ';'?;

TypeDefinition: UnionType;

UnionType infers TypeDefinition:
ArrayType ({infer UnionType.types+=current} ('|' types+=ArrayType)+)?;

ArrayType infers TypeDefinition:
ReferenceType ({infer ArrayType.elementType=current} '[' ']')? ;

ReferenceType infers TypeDefinition:
SimpleType |
{infer ReferenceType} '@' referenceType=SimpleType;

SimpleType infers TypeDefinition:
'(' TypeDefinition ')' |
{infer SimpleType} (typeRef=[AbstractType:ID] | primitiveType=PrimitiveType | stringType=STRING);

PrimitiveType returns string:
'string' | 'number' | 'boolean' | 'Date' | 'bigint';

type AbstractType = Interface | Type | Action | ParserRule;

Type:
'type' name=ID '=' type=TypeDefinition ';'?;

AbstractRule:
ParserRule | TerminalRule;

GrammarImport:
'import' path=STRING ';'?;

ParserRule:
(entry?='entry' | fragment?='fragment')?
RuleNameAndParams
(wildcard?='*' | ('returns' (returnType=[AbstractType:ID] | dataType=PrimitiveType)) | inferredType=InferredType<false>)?
(definesHiddenTokens?='hidden' '(' (hiddenTokens+=[AbstractRule:ID] (',' hiddenTokens+=[AbstractRule:ID])*)? ')')? ':'
definition=Alternatives ';';

InferredType<imperative>:
(<imperative> 'infer' | <!imperative> 'infers') name=ID;

fragment RuleNameAndParams:
name=ID ('<' (parameters+=Parameter (',' parameters+=Parameter)*)? '>')?;

Parameter:
name=ID;

Alternatives infers AbstractElement:
ConditionalBranch ({infer Alternatives.elements+=current} ('|' elements+=ConditionalBranch)+)?;

ConditionalBranch infers AbstractElement:
UnorderedGroup
| {infer Group} '<' guardCondition=Disjunction '>' (elements+=AbstractToken)+;

UnorderedGroup infers AbstractElement:
Group ({infer UnorderedGroup.elements+=current} ('&' elements+=Group)+)?;

Group infers AbstractElement:
AbstractToken ({infer Group.elements+=current} elements+=AbstractToken+)?;

AbstractToken infers AbstractElement:
AbstractTokenWithCardinality |
Action;

AbstractTokenWithCardinality infers AbstractElement:
(Assignment | AbstractTerminal) cardinality=('?'|'*'|'+')?;

Action infers AbstractElement:
{infer Action} '{' (type=[AbstractType:ID] | inferredType=InferredType<true>) ('.' feature=FeatureName operator=('='|'+=') 'current')? '}';

AbstractTerminal infers AbstractElement:
Keyword |
RuleCall |
ParenthesizedElement |
PredicatedKeyword |
PredicatedRuleCall |
PredicatedGroup;

Keyword:
value=STRING;

RuleCall:
rule=[AbstractRule:ID] ('<' arguments+=NamedArgument (',' arguments+=NamedArgument)* '>')?;

NamedArgument:
( parameter=[Parameter:ID] calledByName?='=')?
( value=Disjunction );

LiteralCondition:
true?='true' | 'false';

Disjunction infers Condition:
Conjunction ({infer Disjunction.left=current} '|' right=Conjunction)*;

Conjunction infers Condition:
Negation ({infer Conjunction.left=current} '&' right=Negation)*;

Negation infers Condition:
Atom | {infer Negation} '!' value=Negation;

Atom infers Condition:
ParameterReference | ParenthesizedCondition | LiteralCondition;

ParenthesizedCondition infers Condition:
'(' Disjunction ')';

ParameterReference:
parameter=[Parameter:ID];

PredicatedKeyword infers Keyword:
('=>' | '->') value=STRING;

PredicatedRuleCall infers RuleCall:
('=>' | '->') rule=[AbstractRule:ID] ('<' arguments+=NamedArgument (',' arguments+=NamedArgument)* '>')?;

Assignment infers AbstractElement:
{infer Assignment} ('=>' | '->')? feature=FeatureName operator=('+='|'='|'?=') terminal=AssignableTerminal;

AssignableTerminal infers AbstractElement:
Keyword | RuleCall | ParenthesizedAssignableElement | CrossReference;

ParenthesizedAssignableElement infers AbstractElement:
'(' AssignableAlternatives ')';

AssignableAlternatives infers AbstractElement:
AssignableTerminal ({infer Alternatives.elements+=current} ('|' elements+=AssignableTerminal)+)?;

CrossReference infers AbstractElement:
{infer CrossReference} '[' type=[AbstractType] ((deprecatedSyntax?='|' | ':') terminal=CrossReferenceableTerminal )? ']';

CrossReferenceableTerminal infers AbstractElement:
Keyword | RuleCall;

ParenthesizedElement infers AbstractElement:
'(' Alternatives ')';

PredicatedGroup infers Group:
('=>' | '->') '(' elements+=Alternatives ')';

ReturnType:
name=(PrimitiveType | ID);

TerminalRule:
hidden?='hidden'? 'terminal' (fragment?='fragment' name=ID | name=ID ('returns' type=ReturnType)?) ':'
definition=TerminalAlternatives
';';

TerminalAlternatives infers AbstractElement:
TerminalGroup ({infer TerminalAlternatives.elements+=current} '|' elements+=TerminalGroup)*;

TerminalGroup infers AbstractElement:
TerminalToken ({infer TerminalGroup.elements+=current} elements+=TerminalToken+)?;

TerminalToken infers AbstractElement:
TerminalTokenElement cardinality=('?'|'*'|'+')?;

TerminalTokenElement infers AbstractElement:
CharacterRange | TerminalRuleCall | ParenthesizedTerminalElement | NegatedToken | UntilToken | RegexToken | Wildcard;

ParenthesizedTerminalElement infers AbstractElement:
'(' (lookahead=('?='|'?!'))? TerminalAlternatives ')';

TerminalRuleCall infers AbstractElement:
{infer TerminalRuleCall} rule=[TerminalRule:ID];

NegatedToken infers AbstractElement:
{infer NegatedToken} '!' terminal=TerminalTokenElement;

UntilToken infers AbstractElement:
{infer UntilToken} '->' terminal=TerminalTokenElement;

RegexToken infers AbstractElement:
{infer RegexToken} regex=RegexLiteral;

Wildcard infers AbstractElement:
{infer Wildcard} '.';

CharacterRange infers AbstractElement:
{infer CharacterRange} left=Keyword ('..' right=Keyword)?;

FeatureName returns string:
'current' | 'entry' | 'extends' | 'false' | 'fragment' | 'grammar' | 'hidden' | 'import' | 'interface' | 'returns' | 'terminal' | 'true' | 'type' | 'infer' | 'infers' | 'with' | PrimitiveType | ID;

terminal ID: /\^?[_a-zA-Z][\w_]*/;
terminal STRING: /"(\\.|[^"\\])*"|'(\\.|[^'\\])*'/;
terminal RegexLiteral returns string: /\/(?![*+?])(?:[^\r\n\[/\\]|\\.|\[(?:[^\r\n\]\\]|\\.)*\])+\//;

hidden terminal WS: /\s+/;
hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//;
hidden terminal SL_COMMENT: /\/\/[^\n\r]*/;
Loading

0 comments on commit ff9f804

Please sign in to comment.