From 7e997af41028674f51dbcfe7d5618ba04303857f Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 10:37:11 +0100 Subject: [PATCH 1/8] wip: buggy case statement --- src/language-server/st.langium | 35 ++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/language-server/st.langium b/src/language-server/st.langium index 236f935..4857d67 100644 --- a/src/language-server/st.langium +++ b/src/language-server/st.langium @@ -43,9 +43,6 @@ Real_type_name returns number: Real_literal_or_signed_int returns number: (Real_type_name '#')? Signed_Integer ('.' Integer (Exponent)?)?; -Exponent returns number: -Exponent_prefix ('+'|'-')? Integer; - /* Boolean literals */ Boolean_literal returns boolean: // should be ((BOOL '#')? ( 1 | 0)) | 'TRUE' | 'FALSE' @@ -181,7 +178,7 @@ Statement_list: statements=Statement ';' (Statement ';')*; Statement: -Function_invoke_or_assign_statement | Action_call_statement ; +Selection_statement | Function_invoke_or_assign_statement | Action_call_statement ; Action_call_statement: action=Identifier; @@ -207,6 +204,31 @@ Invoke_subrule: Param_assignment: (ParamName=Variable_name ':=')? ParamValue=Expression; +/* Selection statements */ +//selection_statement = if_statement | case_statement; +Selection_statement: +Case_statement; + +//if_statement = "IF" expression "THEN" statement_list {"ELSIF" expression "THEN" statement_list} ["ELSE" statement_list] "END_IF"; + + +//case_statement = "CASE" expression "OF" case_element {case_element} ["ELSE" statement_list] "END_CASE"; +Case_statement: +'CASE' Expression 'OF' Case_element (Case_element)* ('ELSE' Statement_list)? 'END_CASE'; + +//case_element = case_list ":" statement_list; +Case_element: +Case_list ':' statements=Statement_list; + +//case_list = case_list_element {"," case_list_element}; +Case_list: +caseList+=Case_list_element (',' caseList+=Case_list_element)*; + +//case_list_element = subrange | signed_integer | enumerated_value; +Case_list_element: +(numCase=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=Identifier); + + /* Derived typename */ //variable = direct_variable | symbolic_variable; @@ -236,13 +258,14 @@ Subscript_list: '[' Subscript (',' Subscript)* ']'; //subscript = expression; -Subscript: +Subscript infers Expression: Expression; // numeric tokens -terminal Exponent_prefix : /[Ee]/; +terminal fragment Exponent_prefix : /[Ee]/; +terminal Exponent: Exponent_prefix ('+'|'-')? Integer; terminal Binary_integer: /\b2#(0|1)(0|1|(_))*\b/; terminal Hex_integer: /\b16#([0-9aAbBcCdDeEfF])([0-9aAbBcCdDeEfF]|(_))*\b/; terminal Octal_integer: /\b8#([0-7])([0-7]|(_))*\b/; From f39315c66f52ba475d819ab9e76d12d4bda862ec Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 12:16:43 +0100 Subject: [PATCH 2/8] wip: buggy case grammar snippet --- .../grammar-snippets/case.langium | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 src/language-server/grammar-snippets/case.langium diff --git a/src/language-server/grammar-snippets/case.langium b/src/language-server/grammar-snippets/case.langium new file mode 100644 index 0000000..84f1d5c --- /dev/null +++ b/src/language-server/grammar-snippets/case.langium @@ -0,0 +1,81 @@ +grammar StructuredText + +entry Document: + (stStatements+=Statement_list); + +/* Numerics declarations */ +Signed_Integer returns number: +('+'|'-')? Integer; + +/* Structured Text */ +Statement_list: +statements=Statement ';' (Statement ';')*; + +Statement: +Selection_statement | Action_call_statement ; + +Action_call_statement: +action=Identifier | 'RETURN'; + +/* Selection statements */ +//selection_statement = if_statement | case_statement; +Selection_statement: +Case_statement; + +//case_statement = "CASE" expression "OF" case_element {case_element} ["ELSE" statement_list] "END_CASE"; +Case_statement: +'CASE' Identifier 'OF' Case_element (Case_element)* ('ELSE' Statement_list)? 'END_CASE'; +//case_element = case_list ":" statement_list; +Case_element: +Case_list ':' statements=Statement_list; +//case_list = case_list_element {"," case_list_element}; +Case_list: +caseList+=Case_list_element (',' caseList+=Case_list_element)*; +//case_list_element = subrange | signed_integer | enumerated_value; +Case_list_element: +(numCase=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=Identifier); + +// identifier characters +terminal fragment Underscore: /_/; +terminal fragment Letters: /[a-zA-Z]+/; +terminal fragment Digits: /[0-9]+/; +terminal Integer: Digits ((Underscore)? Digits)*; +terminal Identifier: ((Underscore (Digits | Letters))| Letters) ((Underscore)? (Digits | Letters))*; + +// hidden +hidden terminal WS: /\s+/; +hidden terminal ML_COMMENT: /\/\*[\s\S]*?\*\//; +hidden terminal ML_COMMENT_ST: /\(\*[\s\S]*?\*\)/; +hidden terminal SL_COMMENT: /\/\/[^\n\r]*/; + +/* Example input + +CASE example OF + +foo: + RETURN; + dummyAction; + +10: + RETURN; + dummyAction; + +20,30: + RETURN; + dummyAction; + +40..50, 60..80: + RETURN; + dummyAction; + +bar: // failing here at bar, because it expects action call statement. + RETURN; + dummyAction; + +ELSE + RETURN; + dummyAction; + +END_CASE; + +*/ \ No newline at end of file From bceff2c8ed7d83c48bc13a224c58fd2038a41449 Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 18:43:04 +0100 Subject: [PATCH 3/8] bugfix: added terminal IdentifierEnumeratedCase to prevent matching identifier in a case statement --- src/language-server/st.langium | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/language-server/st.langium b/src/language-server/st.langium index 4857d67..3ffa2f5 100644 --- a/src/language-server/st.langium +++ b/src/language-server/st.langium @@ -226,7 +226,7 @@ caseList+=Case_list_element (',' caseList+=Case_list_element)*; //case_list_element = subrange | signed_integer | enumerated_value; Case_list_element: -(numCase=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=Identifier); +(numCase=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=IdentifierEnumeratedCase); /* Derived typename */ @@ -272,8 +272,6 @@ terminal Octal_integer: /\b8#([0-7])([0-7]|(_))*\b/; // string tokens terminal Single_byte_character_string: /(')(\\.|[^'])*(')/; terminal Double_byte_character_string: /(")(\\.|[^"])*(")/; -// hack - only match if its followed by a letter D/H/M/S/MS in a time expression - // time tokens terminal TMilliseconds: (Underscore)? Fixed_point /[mM][sS]/; terminal TMinutes: (Underscore)? Fixed_point /[mM]/; @@ -290,6 +288,10 @@ terminal fragment Location_prefix: ('I' | 'Q' | 'M'); terminal fragment Size_prefix: ('X' | 'B' | 'W' | 'D' | 'L'); terminal Direct_variable_prefix: '%' Location_prefix Size_prefix; terminal Integer: Digits ((Underscore)? Digits)*; +// hack - IdentifierEnumeratedCase uses positive lookahead for "," and ":" +terminal IdentifierEnumeratedCase: ((Underscore (Digits | Letters))| Letters) ((Underscore)? (Digits | Letters))* +/(?=(,\s*([_A-Za-z]\w*|([+\-]?[0-9][0-9_]*\s*(\.\.\s*[+\-]?[0-9][0-9_]*)?))\s*)*\:\s+)/; + terminal Identifier: ((Underscore (Digits | Letters))| Letters) ((Underscore)? (Digits | Letters))*; // hidden From e93dd9a24cd6000a556c6276c25c72d3cc998f69 Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 18:59:44 +0100 Subject: [PATCH 4/8] added: if_statement rule --- src/language-server/st.langium | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/language-server/st.langium b/src/language-server/st.langium index 3ffa2f5..706956e 100644 --- a/src/language-server/st.langium +++ b/src/language-server/st.langium @@ -207,10 +207,11 @@ Param_assignment: /* Selection statements */ //selection_statement = if_statement | case_statement; Selection_statement: -Case_statement; +if=If_statement| case=Case_statement; //if_statement = "IF" expression "THEN" statement_list {"ELSIF" expression "THEN" statement_list} ["ELSE" statement_list] "END_IF"; - +If_statement: +'IF' ifCondition=Expression 'THEN' ifStatement=Statement_list ('ELSIF' elsifConditions+=Expression 'THEN' elsifStatements=Statement_list)* ('ELSE' elseStatement=Statement_list)? 'END_IF'; //case_statement = "CASE" expression "OF" case_element {case_element} ["ELSE" statement_list] "END_CASE"; Case_statement: From a84ae8c172f80b1beae29e16fb81472cd845d8b0 Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 19:05:41 +0100 Subject: [PATCH 5/8] test: added assignments to grammar rules --- src/language-server/st.langium | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/language-server/st.langium b/src/language-server/st.langium index 706956e..427318e 100644 --- a/src/language-server/st.langium +++ b/src/language-server/st.langium @@ -7,7 +7,7 @@ Program: 'PROGRAM' name=Identifier 'END_PROGRAM'; Constant: - constant= Prefixed_integer_literal | Prefixed_bit_string_literal | Real_literal_or_signed_int | Nonprefix_integer_literal | Boolean_literal | Character_string | Time_literal; + constant= (Prefixed_integer_literal | Prefixed_bit_string_literal | Real_literal_or_signed_int | Nonprefix_integer_literal | Boolean_literal | Character_string | Time_literal); /* Numeric constants declarations */ Signed_Integer returns number: @@ -169,19 +169,19 @@ Unary_expression infers Expression: // primary_expression = constant | enumerated_value | variable | "(" expression ")" | function_name "(" param_assignment {"," param_assignment} ")"; Primary_Expression infers Expression: value = Constant -| '(' Expression ')' -| (name=Function_name params+=Invoke_subrule) -| Variable; +| '(' Expression=Expression ')' +| (name=Function_name params=Invoke_subrule) +| variable=Variable; /* ST statements */ Statement_list: -statements=Statement ';' (Statement ';')*; +statements+=Statement ';' (statements+=Statement ';')*; Statement: -Selection_statement | Function_invoke_or_assign_statement | Action_call_statement ; +statement=(Selection_statement | Function_invoke_or_assign_statement | Action_call_statement) ; Action_call_statement: -action=Identifier; +actionName=Identifier; Function_name returns string: Identifier; @@ -193,13 +193,13 @@ Function_invoke_or_assign: id=Variable (assign=Assignment_subrule | params+=Invoke_subrule); Assignment_statement: -statement=Variable ':=' Expression ';'; +statement=Variable ':=' expression=Expression ';'; Assignment_subrule: -':=' Expression; +':=' expression=Expression; Invoke_subrule: -'(' (Param_assignment (',' Param_assignment)*)? ')'; +'(' (parameters+=Param_assignment (',' parameters+=Param_assignment)*)? ')'; Param_assignment: (ParamName=Variable_name ':=')? ParamValue=Expression; @@ -215,26 +215,26 @@ If_statement: //case_statement = "CASE" expression "OF" case_element {case_element} ["ELSE" statement_list] "END_CASE"; Case_statement: -'CASE' Expression 'OF' Case_element (Case_element)* ('ELSE' Statement_list)? 'END_CASE'; +'CASE' caseExpression=Expression 'OF' caseElements+=Case_element (caseElements+=Case_element)* ('ELSE' elseStatements=Statement_list)? 'END_CASE'; //case_element = case_list ":" statement_list; Case_element: -Case_list ':' statements=Statement_list; +caseList=Case_list ':' statements=Statement_list; //case_list = case_list_element {"," case_list_element}; Case_list: -caseList+=Case_list_element (',' caseList+=Case_list_element)*; +caseListElement+=Case_list_element (',' caseListElement+=Case_list_element)*; //case_list_element = subrange | signed_integer | enumerated_value; Case_list_element: -(numCase=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=IdentifierEnumeratedCase); +(numCaseStart=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=IdentifierEnumeratedCase); /* Derived typename */ //variable = direct_variable | symbolic_variable; Variable: -Direct_variable | Variable_any_symbolic; +variable=(Direct_variable | Variable_any_symbolic); //location_prefix = "I" | "Q" | "M"; //size_prefix = NIL | "X" | "B" | "W" | "D" | "L"; @@ -245,10 +245,10 @@ Direct_variable_prefix Integer ('.' Integer)?; // symbolic_variable = variable_name | multi_element_variable; // Variable_any_symbolic parses Multi-element variables and variable_name Variable_any_symbolic: -Variable_basic ('.' Variable_basic)*; +variable=Variable_basic ('.' structureMember=Variable_basic)*; Variable_basic: -Identifier (Subscript_list)?; +variable=Identifier (subscript=Subscript_list)?; //variable_name = identifier; Variable_name returns string: From 93cbafdfada15768ae0c07c035be374bae0f3530 Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 19:18:22 +0100 Subject: [PATCH 6/8] added: iteration statements --- src/language-server/st.langium | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/language-server/st.langium b/src/language-server/st.langium index 427318e..7ce2b90 100644 --- a/src/language-server/st.langium +++ b/src/language-server/st.langium @@ -178,7 +178,7 @@ Statement_list: statements+=Statement ';' (statements+=Statement ';')*; Statement: -statement=(Selection_statement | Function_invoke_or_assign_statement | Action_call_statement) ; +statement=(Selection_statement | Function_invoke_or_assign_statement | Action_call_statement | Iteration_statement)? ; Action_call_statement: actionName=Identifier; @@ -229,6 +229,22 @@ caseListElement+=Case_list_element (',' caseListElement+=Case_list_element)*; Case_list_element: (numCaseStart=Signed_Integer ('..' numericCaseEnd+=Signed_Integer)?) | (enumCase=IdentifierEnumeratedCase); +/* Iteration statements */ +Iteration_statement: +statement=(For_statement | While_statement | Repeat_statement | 'EXIT'); + +For_statement: +'FOR' controlVariable=Identifier ':=' forList=For_list 'DO' statementList=Statement_list 'END_FOR'; + +For_list: +forExpr=Expression 'TO' toExpr=Expression ('BY' byExpr=Expression)?; + +While_statement: +'WHILE' whileExpr=Expression 'DO' statementList=Statement_list 'END_WHILE'; + +Repeat_statement: +'REPEAT' statementList=Statement_list 'UNTIL' untilExpr=Expression 'END_REPEAT'; + /* Derived typename */ From b1bf0068f2ad7ff5fc256ac1f17afc0bf9c35f68 Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 19:23:02 +0100 Subject: [PATCH 7/8] change: isolated semicolon from statement_list to allow empty statements --- src/language-server/st.langium | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/language-server/st.langium b/src/language-server/st.langium index 7ce2b90..47ff72f 100644 --- a/src/language-server/st.langium +++ b/src/language-server/st.langium @@ -175,10 +175,10 @@ value = Constant /* ST statements */ Statement_list: -statements+=Statement ';' (statements+=Statement ';')*; +statements+=Statement (statements+=Statement)*; Statement: -statement=(Selection_statement | Function_invoke_or_assign_statement | Action_call_statement | Iteration_statement)? ; +((Selection_statement | Function_invoke_or_assign_statement | Action_call_statement | Iteration_statement) ';' )? ; Action_call_statement: actionName=Identifier; From b3f9b17b141e6186c32d938fd00f85ada046df7a Mon Sep 17 00:00:00 2001 From: Jidost Date: Sun, 27 Nov 2022 19:27:51 +0100 Subject: [PATCH 8/8] updated: generated langium files --- src/language-server/generated/ast.ts | 345 +++++-- src/language-server/generated/grammar.ts | 1203 ++++++++++++++++++---- 2 files changed, 1277 insertions(+), 271 deletions(-) diff --git a/src/language-server/generated/ast.ts b/src/language-server/generated/ast.ts index 85779c2..3e10167 100644 --- a/src/language-server/generated/ast.ts +++ b/src/language-server/generated/ast.ts @@ -7,20 +7,10 @@ /* eslint-disable @typescript-eslint/no-empty-interface */ import { AstNode, AstReflection, ReferenceInfo, isAstNode, TypeMetaData } from 'langium'; -export type Assignment_subrule = Expression; - -export const Assignment_subrule = 'Assignment_subrule'; - -export function isAssignment_subrule(item: unknown): item is Assignment_subrule { - return reflection.isInstance(item, Assignment_subrule); -} - export type Bit_string_type_name = 'BYTE' | 'DWORD' | 'LWORD' | 'WORD'; export type Boolean_literal = boolean; -export type Character_string = string; - export type Data_type_name = string; export type Date_and_time = string; @@ -49,26 +39,18 @@ export type Duration = string; export type Elementary_type_name = string; -export type Exponent = number; - export type Function_name = string; export type Generic_type_name = 'ANY' | 'ANY_BIT' | 'ANY_DATE' | 'ANY_DERIVED' | 'ANY_ELEMENTARY' | 'ANY_INT' | 'ANY_MAGNITUDE' | 'ANY_NUM' | 'ANY_REAL' | 'ANY_STRING'; export type Hours = string; +export type Character_string = string; + export type Integer_type_name = number; export type Interval = string; -export type Invoke_subrule = Param_assignment; - -export const Invoke_subrule = 'Invoke_subrule'; - -export function isInvoke_subrule(item: unknown): item is Invoke_subrule { - return reflection.isInstance(item, Invoke_subrule); -} - export type Milliseconds = string; export type Minutes = string; @@ -95,7 +77,7 @@ export type Signed_Integer = number; export type Signed_integer_type_name = 'DINT' | 'INT' | 'LINT' | 'SINT'; -export type Statement = Action_call_statement | Function_invoke_or_assign_statement; +export type Statement = Action_call_statement | Function_invoke_or_assign_statement | Iteration_statement | Selection_statement; export const Statement = 'Statement'; @@ -103,15 +85,7 @@ export function isStatement(item: unknown): item is Statement { return reflection.isInstance(item, Statement); } -export type Subscript = Expression; - -export const Subscript = 'Subscript'; - -export function isSubscript(item: unknown): item is Subscript { - return reflection.isInstance(item, Subscript); -} - -export type Subscript_list = Subscript; +export type Subscript_list = Expression; export const Subscript_list = 'Subscript_list'; @@ -127,37 +101,13 @@ export type Unsigned_Integer = number; export type Unsigned_integer_type_name = 'UDINT' | 'UINT' | 'ULINT' | 'USINT'; -export type Variable = Direct_variable | Variable_any_symbolic; - -export const Variable = 'Variable'; - -export function isVariable(item: unknown): item is Variable { - return reflection.isInstance(item, Variable); -} - -export type Variable_any_symbolic = Variable_basic; - -export const Variable_any_symbolic = 'Variable_any_symbolic'; - -export function isVariable_any_symbolic(item: unknown): item is Variable_any_symbolic { - return reflection.isInstance(item, Variable_any_symbolic); -} - -export type Variable_basic = Subscript_list; - -export const Variable_basic = 'Variable_basic'; - -export function isVariable_basic(item: unknown): item is Variable_basic { - return reflection.isInstance(item, Variable_basic); -} - export type Variable_name = string; export type Year = string; export interface Action_call_statement extends AstNode { readonly $container: Statement_list; - action: string + actionName: string } export const Action_call_statement = 'Action_call_statement'; @@ -167,6 +117,7 @@ export function isAction_call_statement(item: unknown): item is Action_call_stat } export interface Assignment_statement extends AstNode { + expression: Expression statement: Variable } @@ -176,8 +127,19 @@ export function isAssignment_statement(item: unknown): item is Assignment_statem return reflection.isInstance(item, Assignment_statement); } +export interface Assignment_subrule extends AstNode { + readonly $container: Function_invoke_or_assign; + expression: Expression +} + +export const Assignment_subrule = 'Assignment_subrule'; + +export function isAssignment_subrule(item: unknown): item is Assignment_subrule { + return reflection.isInstance(item, Assignment_subrule); +} + export interface BinaryExpression extends Expression { - readonly $container: Assignment_statement | BinaryExpression | Function_invoke_or_assign | Param_assignment; + readonly $container: Assignment_statement | Assignment_subrule | BinaryExpression | Case_statement | Expression | For_list | If_statement | Param_assignment | Repeat_statement | Variable_basic | While_statement; left: Expression operator: '&' | '*' | '**' | '+' | '-' | '/' | '<' | '<=' | '<>' | '=' | '>' | '>=' | 'AND' | 'MOD' | 'NOT' | 'OR' | 'XOR' right: Expression @@ -189,9 +151,58 @@ export function isBinaryExpression(item: unknown): item is BinaryExpression { return reflection.isInstance(item, BinaryExpression); } +export interface Case_element extends AstNode { + readonly $container: Case_statement; + caseList: Case_list + statements: Statement_list +} + +export const Case_element = 'Case_element'; + +export function isCase_element(item: unknown): item is Case_element { + return reflection.isInstance(item, Case_element); +} + +export interface Case_list extends AstNode { + readonly $container: Case_element; + caseListElement: Array +} + +export const Case_list = 'Case_list'; + +export function isCase_list(item: unknown): item is Case_list { + return reflection.isInstance(item, Case_list); +} + +export interface Case_list_element extends AstNode { + readonly $container: Case_list; + enumCase?: string + numCaseStart?: Signed_Integer + numericCaseEnd: Array +} + +export const Case_list_element = 'Case_list_element'; + +export function isCase_list_element(item: unknown): item is Case_list_element { + return reflection.isInstance(item, Case_list_element); +} + +export interface Case_statement extends AstNode { + readonly $container: Selection_statement; + caseElements: Array + caseExpression: Expression + elseStatements?: Statement_list +} + +export const Case_statement = 'Case_statement'; + +export function isCase_statement(item: unknown): item is Case_statement { + return reflection.isInstance(item, Case_statement); +} + export interface Constant extends AstNode { readonly $container: Expression; - constant: Prefixed_integer_literal + constant: Boolean_literal | Character_string | Nonprefix_integer_literal | Prefixed_bit_string_literal | Prefixed_integer_literal | Real_literal_or_signed_int | Time_literal } export const Constant = 'Constant'; @@ -211,10 +222,12 @@ export function isDocument(item: unknown): item is Document { } export interface Expression extends AstNode { - readonly $container: Assignment_statement | BinaryExpression | Function_invoke_or_assign | Param_assignment; + readonly $container: Assignment_statement | Assignment_subrule | BinaryExpression | Case_statement | Expression | For_list | If_statement | Param_assignment | Repeat_statement | Variable_basic | While_statement; + Expression?: Expression name?: Function_name - params: Array + params?: Invoke_subrule value?: Constant + variable?: Variable } export const Expression = 'Expression'; @@ -223,6 +236,32 @@ export function isExpression(item: unknown): item is Expression { return reflection.isInstance(item, Expression); } +export interface For_list extends AstNode { + readonly $container: For_statement; + byExpr?: Expression + forExpr: Expression + toExpr: Expression +} + +export const For_list = 'For_list'; + +export function isFor_list(item: unknown): item is For_list { + return reflection.isInstance(item, For_list); +} + +export interface For_statement extends AstNode { + readonly $container: Iteration_statement; + controlVariable: string + forList: For_list + statementList: Statement_list +} + +export const For_statement = 'For_statement'; + +export function isFor_statement(item: unknown): item is For_statement { + return reflection.isInstance(item, For_statement); +} + export interface Function_invoke_or_assign extends AstNode { readonly $container: Function_invoke_or_assign_statement; assign?: Assignment_subrule @@ -247,8 +286,45 @@ export function isFunction_invoke_or_assign_statement(item: unknown): item is Fu return reflection.isInstance(item, Function_invoke_or_assign_statement); } -export interface Param_assignment extends AstNode { +export interface If_statement extends AstNode { + readonly $container: Selection_statement; + elseStatement?: Statement_list + elsifConditions: Array + elsifStatements?: Statement_list + ifCondition: Expression + ifStatement: Statement_list +} + +export const If_statement = 'If_statement'; + +export function isIf_statement(item: unknown): item is If_statement { + return reflection.isInstance(item, If_statement); +} + +export interface Invoke_subrule extends AstNode { readonly $container: Expression | Function_invoke_or_assign; + parameters: Array +} + +export const Invoke_subrule = 'Invoke_subrule'; + +export function isInvoke_subrule(item: unknown): item is Invoke_subrule { + return reflection.isInstance(item, Invoke_subrule); +} + +export interface Iteration_statement extends AstNode { + readonly $container: Statement_list; + statement: 'EXIT' | For_statement | Repeat_statement | While_statement +} + +export const Iteration_statement = 'Iteration_statement'; + +export function isIteration_statement(item: unknown): item is Iteration_statement { + return reflection.isInstance(item, Iteration_statement); +} + +export interface Param_assignment extends AstNode { + readonly $container: Invoke_subrule; ParamName?: Variable_name ParamValue: Expression } @@ -269,9 +345,33 @@ export function isProgram(item: unknown): item is Program { return reflection.isInstance(item, Program); } +export interface Repeat_statement extends AstNode { + readonly $container: Iteration_statement; + statementList: Statement_list + untilExpr: Expression +} + +export const Repeat_statement = 'Repeat_statement'; + +export function isRepeat_statement(item: unknown): item is Repeat_statement { + return reflection.isInstance(item, Repeat_statement); +} + +export interface Selection_statement extends AstNode { + readonly $container: Statement_list; + case?: Case_statement + if?: If_statement +} + +export const Selection_statement = 'Selection_statement'; + +export function isSelection_statement(item: unknown): item is Selection_statement { + return reflection.isInstance(item, Selection_statement); +} + export interface Statement_list extends AstNode { - readonly $container: Document; - statements: Statement + readonly $container: Case_element | Case_statement | Document | For_statement | If_statement | Repeat_statement | While_statement; + statements: Array } export const Statement_list = 'Statement_list'; @@ -280,12 +380,59 @@ export function isStatement_list(item: unknown): item is Statement_list { return reflection.isInstance(item, Statement_list); } -export type StAstType = 'Action_call_statement' | 'Assignment_statement' | 'Assignment_subrule' | 'BinaryExpression' | 'Constant' | 'Document' | 'Expression' | 'Function_invoke_or_assign' | 'Function_invoke_or_assign_statement' | 'Invoke_subrule' | 'Param_assignment' | 'Program' | 'Statement' | 'Statement_list' | 'Subscript' | 'Subscript_list' | 'Variable' | 'Variable_any_symbolic' | 'Variable_basic'; +export interface Variable extends AstNode { + readonly $container: Assignment_statement | Expression | Function_invoke_or_assign; + variable: Direct_variable | Variable_any_symbolic +} + +export const Variable = 'Variable'; + +export function isVariable(item: unknown): item is Variable { + return reflection.isInstance(item, Variable); +} + +export interface Variable_any_symbolic extends AstNode { + readonly $container: Variable; + structureMember?: Variable_basic + variable: Variable_basic +} + +export const Variable_any_symbolic = 'Variable_any_symbolic'; + +export function isVariable_any_symbolic(item: unknown): item is Variable_any_symbolic { + return reflection.isInstance(item, Variable_any_symbolic); +} + +export interface Variable_basic extends AstNode { + readonly $container: Variable_any_symbolic; + subscript?: Subscript_list + variable: string +} + +export const Variable_basic = 'Variable_basic'; + +export function isVariable_basic(item: unknown): item is Variable_basic { + return reflection.isInstance(item, Variable_basic); +} + +export interface While_statement extends AstNode { + readonly $container: Iteration_statement; + statementList: Statement_list + whileExpr: Expression +} + +export const While_statement = 'While_statement'; + +export function isWhile_statement(item: unknown): item is While_statement { + return reflection.isInstance(item, While_statement); +} + +export type StAstType = 'Action_call_statement' | 'Assignment_statement' | 'Assignment_subrule' | 'BinaryExpression' | 'Case_element' | 'Case_list' | 'Case_list_element' | 'Case_statement' | 'Constant' | 'Document' | 'Expression' | 'For_list' | 'For_statement' | 'Function_invoke_or_assign' | 'Function_invoke_or_assign_statement' | 'If_statement' | 'Invoke_subrule' | 'Iteration_statement' | 'Param_assignment' | 'Program' | 'Repeat_statement' | 'Selection_statement' | 'Statement' | 'Statement_list' | 'Subscript_list' | 'Variable' | 'Variable_any_symbolic' | 'Variable_basic' | 'While_statement'; export class StAstReflection implements AstReflection { getAllTypes(): string[] { - return ['Action_call_statement', 'Assignment_statement', 'Assignment_subrule', 'BinaryExpression', 'Constant', 'Document', 'Expression', 'Function_invoke_or_assign', 'Function_invoke_or_assign_statement', 'Invoke_subrule', 'Param_assignment', 'Program', 'Statement', 'Statement_list', 'Subscript', 'Subscript_list', 'Variable', 'Variable_any_symbolic', 'Variable_basic']; + return ['Action_call_statement', 'Assignment_statement', 'Assignment_subrule', 'BinaryExpression', 'Case_element', 'Case_list', 'Case_list_element', 'Case_statement', 'Constant', 'Document', 'Expression', 'For_list', 'For_statement', 'Function_invoke_or_assign', 'Function_invoke_or_assign_statement', 'If_statement', 'Invoke_subrule', 'Iteration_statement', 'Param_assignment', 'Program', 'Repeat_statement', 'Selection_statement', 'Statement', 'Statement_list', 'Subscript_list', 'Variable', 'Variable_any_symbolic', 'Variable_basic', 'While_statement']; } isInstance(node: unknown, type: string): boolean { @@ -298,31 +445,17 @@ export class StAstReflection implements AstReflection { } switch (subtype) { case Action_call_statement: - case Function_invoke_or_assign_statement: { + case Function_invoke_or_assign_statement: + case Iteration_statement: + case Selection_statement: { return this.isSubtype(Statement, supertype); } - case BinaryExpression: - case Variable: { + case BinaryExpression: { return this.isSubtype(Expression, supertype); } case Expression: { - return this.isSubtype(Assignment_subrule, supertype) || this.isSubtype(Subscript, supertype); - } - case Param_assignment: { - return this.isSubtype(Invoke_subrule, supertype); - } - case Subscript: { return this.isSubtype(Subscript_list, supertype); } - case Subscript_list: { - return this.isSubtype(Variable_basic, supertype); - } - case Variable_any_symbolic: { - return this.isSubtype(Variable, supertype); - } - case Variable_basic: { - return this.isSubtype(Variable_any_symbolic, supertype); - } default: { return false; } @@ -340,11 +473,27 @@ export class StAstReflection implements AstReflection { getTypeMetaData(type: string): TypeMetaData { switch (type) { - case 'BinaryExpression': { + case 'Case_list': { return { - name: 'BinaryExpression', + name: 'Case_list', mandatory: [ - { name: 'params', type: 'array' } + { name: 'caseListElement', type: 'array' } + ] + }; + } + case 'Case_list_element': { + return { + name: 'Case_list_element', + mandatory: [ + { name: 'numericCaseEnd', type: 'array' } + ] + }; + } + case 'Case_statement': { + return { + name: 'Case_statement', + mandatory: [ + { name: 'caseElements', type: 'array' } ] }; } @@ -356,19 +505,35 @@ export class StAstReflection implements AstReflection { ] }; } - case 'Expression': { + case 'Function_invoke_or_assign': { return { - name: 'Expression', + name: 'Function_invoke_or_assign', mandatory: [ { name: 'params', type: 'array' } ] }; } - case 'Function_invoke_or_assign': { + case 'If_statement': { return { - name: 'Function_invoke_or_assign', + name: 'If_statement', mandatory: [ - { name: 'params', type: 'array' } + { name: 'elsifConditions', type: 'array' } + ] + }; + } + case 'Invoke_subrule': { + return { + name: 'Invoke_subrule', + mandatory: [ + { name: 'parameters', type: 'array' } + ] + }; + } + case 'Statement_list': { + return { + name: 'Statement_list', + mandatory: [ + { name: 'statements', type: 'array' } ] }; } diff --git a/src/language-server/generated/grammar.ts b/src/language-server/generated/grammar.ts index a1d3b57..7555540 100644 --- a/src/language-server/generated/grammar.ts +++ b/src/language-server/generated/grammar.ts @@ -72,63 +72,63 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "$type": "ParserRule", "name": "Constant", "definition": { - "$type": "Alternatives", - "elements": [ - { - "$type": "Assignment", - "feature": "constant", - "operator": "=", - "terminal": { + "$type": "Assignment", + "feature": "constant", + "operator": "=", + "terminal": { + "$type": "Alternatives", + "elements": [ + { "$type": "RuleCall", "rule": { "$refText": "Prefixed_integer_literal" }, "arguments": [] - } - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Prefixed_bit_string_literal" }, - "arguments": [] - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Real_literal_or_signed_int" + { + "$type": "RuleCall", + "rule": { + "$refText": "Prefixed_bit_string_literal" + }, + "arguments": [] }, - "arguments": [] - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Nonprefix_integer_literal" + { + "$type": "RuleCall", + "rule": { + "$refText": "Real_literal_or_signed_int" + }, + "arguments": [] }, - "arguments": [] - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Boolean_literal" + { + "$type": "RuleCall", + "rule": { + "$refText": "Nonprefix_integer_literal" + }, + "arguments": [] }, - "arguments": [] - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Character_string" + { + "$type": "RuleCall", + "rule": { + "$refText": "Boolean_literal" + }, + "arguments": [] }, - "arguments": [] - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Time_literal" + { + "$type": "RuleCall", + "rule": { + "$refText": "Character_string" + }, + "arguments": [] }, - "arguments": [] - } - ] + { + "$type": "RuleCall", + "rule": { + "$refText": "Time_literal" + }, + "arguments": [] + } + ] + } }, "definesHiddenTokens": false, "entry": false, @@ -574,50 +574,6 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "parameters": [], "wildcard": false }, - { - "$type": "ParserRule", - "name": "Exponent", - "dataType": "number", - "definition": { - "$type": "Group", - "elements": [ - { - "$type": "RuleCall", - "rule": { - "$refText": "Exponent_prefix" - }, - "arguments": [] - }, - { - "$type": "Alternatives", - "elements": [ - { - "$type": "Keyword", - "value": "+" - }, - { - "$type": "Keyword", - "value": "-" - } - ], - "cardinality": "?" - }, - { - "$type": "RuleCall", - "rule": { - "$refText": "Integer" - }, - "arguments": [] - } - ] - }, - "definesHiddenTokens": false, - "entry": false, - "fragment": false, - "hiddenTokens": [], - "parameters": [], - "wildcard": false - }, { "$type": "ParserRule", "name": "Boolean_literal", @@ -2211,11 +2167,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "value": "(" }, { - "$type": "RuleCall", - "rule": { - "$refText": "Expression" - }, - "arguments": [] + "$type": "Assignment", + "feature": "Expression", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } }, { "$type": "Keyword", @@ -2241,7 +2202,7 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar { "$type": "Assignment", "feature": "params", - "operator": "+=", + "operator": "=", "terminal": { "$type": "RuleCall", "rule": { @@ -2253,11 +2214,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar ] }, { - "$type": "RuleCall", - "rule": { - "$refText": "Variable" - }, - "arguments": [] + "$type": "Assignment", + "feature": "variable", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Variable" + }, + "arguments": [] + } } ] }, @@ -2277,7 +2243,7 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar { "$type": "Assignment", "feature": "statements", - "operator": "=", + "operator": "+=", "terminal": { "$type": "RuleCall", "rule": { @@ -2287,24 +2253,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar } }, { - "$type": "Keyword", - "value": ";" - }, - { - "$type": "Group", - "elements": [ - { - "$type": "RuleCall", - "rule": { - "$refText": "Statement" - }, - "arguments": [] + "$type": "Assignment", + "feature": "statements", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement" }, - { - "$type": "Keyword", - "value": ";" - } - ], + "arguments": [] + }, "cardinality": "*" } ] @@ -2320,23 +2278,47 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "$type": "ParserRule", "name": "Statement", "definition": { - "$type": "Alternatives", + "$type": "Group", "elements": [ { - "$type": "RuleCall", - "rule": { - "$refText": "Function_invoke_or_assign_statement" - }, - "arguments": [] + "$type": "Alternatives", + "elements": [ + { + "$type": "RuleCall", + "rule": { + "$refText": "Selection_statement" + }, + "arguments": [] + }, + { + "$type": "RuleCall", + "rule": { + "$refText": "Function_invoke_or_assign_statement" + }, + "arguments": [] + }, + { + "$type": "RuleCall", + "rule": { + "$refText": "Action_call_statement" + }, + "arguments": [] + }, + { + "$type": "RuleCall", + "rule": { + "$refText": "Iteration_statement" + }, + "arguments": [] + } + ] }, { - "$type": "RuleCall", - "rule": { - "$refText": "Action_call_statement" - }, - "arguments": [] + "$type": "Keyword", + "value": ";" } - ] + ], + "cardinality": "?" }, "definesHiddenTokens": false, "entry": false, @@ -2350,7 +2332,7 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "name": "Action_call_statement", "definition": { "$type": "Assignment", - "feature": "action", + "feature": "actionName", "operator": "=", "terminal": { "$type": "RuleCall", @@ -2495,11 +2477,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "value": ":=" }, { - "$type": "RuleCall", - "rule": { - "$refText": "Expression" - }, - "arguments": [] + "$type": "Assignment", + "feature": "expression", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } }, { "$type": "Keyword", @@ -2525,11 +2512,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "value": ":=" }, { - "$type": "RuleCall", - "rule": { - "$refText": "Expression" - }, - "arguments": [] + "$type": "Assignment", + "feature": "expression", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } } ] }, @@ -2554,11 +2546,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "$type": "Group", "elements": [ { - "$type": "RuleCall", - "rule": { - "$refText": "Param_assignment" - }, - "arguments": [] + "$type": "Assignment", + "feature": "parameters", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Param_assignment" + }, + "arguments": [] + } }, { "$type": "Group", @@ -2568,11 +2565,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "value": "," }, { - "$type": "RuleCall", - "rule": { - "$refText": "Param_assignment" - }, - "arguments": [] + "$type": "Assignment", + "feature": "parameters", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Param_assignment" + }, + "arguments": [] + } } ], "cardinality": "*" @@ -2644,23 +2646,667 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar }, { "$type": "ParserRule", - "name": "Variable", + "name": "Selection_statement", "definition": { "$type": "Alternatives", "elements": [ { - "$type": "RuleCall", - "rule": { - "$refText": "Direct_variable" + "$type": "Assignment", + "feature": "if", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "If_statement" + }, + "arguments": [] + } + }, + { + "$type": "Assignment", + "feature": "case", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Case_statement" + }, + "arguments": [] + } + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "If_statement", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "IF" + }, + { + "$type": "Assignment", + "feature": "ifCondition", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "THEN" + }, + { + "$type": "Assignment", + "feature": "ifStatement", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "ELSIF" + }, + { + "$type": "Assignment", + "feature": "elsifConditions", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "THEN" + }, + { + "$type": "Assignment", + "feature": "elsifStatements", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + } + ], + "cardinality": "*" + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "ELSE" + }, + { + "$type": "Assignment", + "feature": "elseStatement", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + }, + { + "$type": "Keyword", + "value": "END_IF" + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "Case_statement", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "CASE" + }, + { + "$type": "Assignment", + "feature": "caseExpression", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "OF" + }, + { + "$type": "Assignment", + "feature": "caseElements", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Case_element" + }, + "arguments": [] + } + }, + { + "$type": "Assignment", + "feature": "caseElements", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Case_element" + }, + "arguments": [] + }, + "cardinality": "*" + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "ELSE" + }, + { + "$type": "Assignment", + "feature": "elseStatements", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + }, + { + "$type": "Keyword", + "value": "END_CASE" + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "Case_element", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Assignment", + "feature": "caseList", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Case_list" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": ":" + }, + { + "$type": "Assignment", + "feature": "statements", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "Case_list", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Assignment", + "feature": "caseListElement", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Case_list_element" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "," + }, + { + "$type": "Assignment", + "feature": "caseListElement", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Case_list_element" + }, + "arguments": [] + } + } + ], + "cardinality": "*" + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "Case_list_element", + "definition": { + "$type": "Alternatives", + "elements": [ + { + "$type": "Group", + "elements": [ + { + "$type": "Assignment", + "feature": "numCaseStart", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Signed_Integer" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": ".." + }, + { + "$type": "Assignment", + "feature": "numericCaseEnd", + "operator": "+=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Signed_Integer" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + } + ] + }, + { + "$type": "Assignment", + "feature": "enumCase", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "IdentifierEnumeratedCase" + }, + "arguments": [] + } + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "Iteration_statement", + "definition": { + "$type": "Assignment", + "feature": "statement", + "operator": "=", + "terminal": { + "$type": "Alternatives", + "elements": [ + { + "$type": "RuleCall", + "rule": { + "$refText": "For_statement" + }, + "arguments": [] }, - "arguments": [] + { + "$type": "RuleCall", + "rule": { + "$refText": "While_statement" + }, + "arguments": [] + }, + { + "$type": "RuleCall", + "rule": { + "$refText": "Repeat_statement" + }, + "arguments": [] + }, + { + "$type": "Keyword", + "value": "EXIT" + } + ] + } + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "For_statement", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "FOR" + }, + { + "$type": "Assignment", + "feature": "controlVariable", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Identifier" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": ":=" + }, + { + "$type": "Assignment", + "feature": "forList", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "For_list" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "DO" + }, + { + "$type": "Assignment", + "feature": "statementList", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "END_FOR" + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "For_list", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Assignment", + "feature": "forExpr", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "TO" + }, + { + "$type": "Assignment", + "feature": "toExpr", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "BY" + }, + { + "$type": "Assignment", + "feature": "byExpr", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + } + ], + "cardinality": "?" + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "While_statement", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "WHILE" + }, + { + "$type": "Assignment", + "feature": "whileExpr", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "DO" + }, + { + "$type": "Assignment", + "feature": "statementList", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "END_WHILE" + } + ] + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, + { + "$type": "ParserRule", + "name": "Repeat_statement", + "definition": { + "$type": "Group", + "elements": [ + { + "$type": "Keyword", + "value": "REPEAT" }, { - "$type": "RuleCall", - "rule": { - "$refText": "Variable_any_symbolic" - }, - "arguments": [] + "$type": "Assignment", + "feature": "statementList", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Statement_list" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "UNTIL" + }, + { + "$type": "Assignment", + "feature": "untilExpr", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Expression" + }, + "arguments": [] + } + }, + { + "$type": "Keyword", + "value": "END_REPEAT" } ] }, @@ -2671,6 +3317,40 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "parameters": [], "wildcard": false }, + { + "$type": "ParserRule", + "name": "Variable", + "definition": { + "$type": "Assignment", + "feature": "variable", + "operator": "=", + "terminal": { + "$type": "Alternatives", + "elements": [ + { + "$type": "RuleCall", + "rule": { + "$refText": "Direct_variable" + }, + "arguments": [] + }, + { + "$type": "RuleCall", + "rule": { + "$refText": "Variable_any_symbolic" + }, + "arguments": [] + } + ] + } + }, + "definesHiddenTokens": false, + "entry": false, + "fragment": false, + "hiddenTokens": [], + "parameters": [], + "wildcard": false + }, { "$type": "ParserRule", "name": "Direct_variable", @@ -2725,11 +3405,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "$type": "Group", "elements": [ { - "$type": "RuleCall", - "rule": { - "$refText": "Variable_basic" - }, - "arguments": [] + "$type": "Assignment", + "feature": "variable", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Variable_basic" + }, + "arguments": [] + } }, { "$type": "Group", @@ -2739,11 +3424,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "value": "." }, { - "$type": "RuleCall", - "rule": { - "$refText": "Variable_basic" - }, - "arguments": [] + "$type": "Assignment", + "feature": "structureMember", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Variable_basic" + }, + "arguments": [] + } } ], "cardinality": "*" @@ -2764,18 +3454,28 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "$type": "Group", "elements": [ { - "$type": "RuleCall", - "rule": { - "$refText": "Identifier" - }, - "arguments": [] + "$type": "Assignment", + "feature": "variable", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Identifier" + }, + "arguments": [] + } }, { - "$type": "RuleCall", - "rule": { - "$refText": "Subscript_list" + "$type": "Assignment", + "feature": "subscript", + "operator": "=", + "terminal": { + "$type": "RuleCall", + "rule": { + "$refText": "Subscript_list" + }, + "arguments": [] }, - "arguments": [], "cardinality": "?" } ] @@ -2855,6 +3555,10 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar { "$type": "ParserRule", "name": "Subscript", + "inferredType": { + "$type": "InferredType", + "name": "Expression" + }, "definition": { "$type": "RuleCall", "rule": { @@ -2871,11 +3575,54 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar }, { "$type": "TerminalRule", + "fragment": true, "name": "Exponent_prefix", "definition": { "$type": "RegexToken", "regex": "[Ee]" }, + "hidden": false + }, + { + "$type": "TerminalRule", + "name": "Exponent", + "definition": { + "$type": "TerminalGroup", + "elements": [ + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Exponent_prefix" + } + }, + { + "$type": "TerminalAlternatives", + "elements": [ + { + "$type": "CharacterRange", + "left": { + "$type": "Keyword", + "value": "+" + } + }, + { + "$type": "CharacterRange", + "left": { + "$type": "Keyword", + "value": "-" + } + } + ], + "cardinality": "?" + }, + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Integer" + } + } + ] + }, "fragment": false, "hidden": false }, @@ -3292,6 +4039,90 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar "fragment": false, "hidden": false }, + { + "$type": "TerminalRule", + "name": "IdentifierEnumeratedCase", + "definition": { + "$type": "TerminalGroup", + "elements": [ + { + "$type": "TerminalAlternatives", + "elements": [ + { + "$type": "TerminalGroup", + "elements": [ + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Underscore" + } + }, + { + "$type": "TerminalAlternatives", + "elements": [ + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Digits" + } + }, + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Letters" + } + } + ] + } + ] + }, + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Letters" + } + } + ] + }, + { + "$type": "TerminalGroup", + "elements": [ + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Underscore" + }, + "cardinality": "?" + }, + { + "$type": "TerminalAlternatives", + "elements": [ + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Digits" + } + }, + { + "$type": "TerminalRuleCall", + "rule": { + "$refText": "Letters" + } + } + ] + } + ], + "cardinality": "*" + }, + { + "$type": "RegexToken", + "regex": "(?=(,\\\\s*([_A-Za-z]\\\\w*|([+\\\\-]?[0-9][0-9_]*\\\\s*(\\\\.\\\\.\\\\s*[+\\\\-]?[0-9][0-9_]*)?))\\\\s*)*\\\\:\\\\s+)" + } + ] + }, + "fragment": false, + "hidden": false + }, { "$type": "TerminalRule", "name": "Identifier", @@ -3392,6 +4223,16 @@ export const StructuredTextGrammar = (): Grammar => loadedStructuredTextGrammar }, "fragment": false }, + { + "$type": "TerminalRule", + "hidden": true, + "name": "ML_COMMENT_ST", + "definition": { + "$type": "RegexToken", + "regex": "\\\\(\\\\*[\\\\s\\\\S]*?\\\\*\\\\)" + }, + "fragment": false + }, { "$type": "TerminalRule", "hidden": true,