From 3271ca514c9243877df5a62cbe8650860da27d7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20H=C3=B6lting?= <87192362+moritz-hoelting@users.noreply.github.com> Date: Wed, 13 Aug 2025 09:37:18 +0200 Subject: [PATCH] add script for extracting EBNF grammar from doccomments --- grammar.md | 528 ++++++++++++++---- scripts/update_grammar_md.py | 136 +++++ src/lexical/token.rs | 10 + src/syntax/syntax_tree/declaration.rs | 18 +- src/syntax/syntax_tree/expression.rs | 9 +- src/syntax/syntax_tree/mod.rs | 6 +- src/syntax/syntax_tree/program.rs | 7 + src/syntax/syntax_tree/statement.rs | 22 +- .../syntax_tree/statement/execute_block.rs | 43 +- 9 files changed, 619 insertions(+), 160 deletions(-) create mode 100644 scripts/update_grammar_md.py diff --git a/grammar.md b/grammar.md index a17cc85..fc9549d 100644 --- a/grammar.md +++ b/grammar.md @@ -1,63 +1,145 @@ # Grammar of the Shulkerscript language -## Table of contents +## Program -### Program ```ebnf -Program: Namespace Declaration*; +Program: + Namespace + Declaration* + ; ``` -### Namespace +## Declaration + ```ebnf -Namespace: 'namespace' StringLiteral; +Declaration: + Function + | Import + | TagDeclaration + | ('pub'? VariableDeclaration ';') + ; ``` -### StringLiteral +## Namespace + ```ebnf -StringLiteral: '"' TEXT '"'; +Namespace: + 'namespace' StringLiteral ';' ; ``` -### MacroStringLiteral -```ebnf -MacroStringLiteral: '`' ( TEXT | '$(' [a-zA-Z0-9_]+ ')' )* '`'; -``` +## Function -### AnyStringLiteral -```ebnf -AnyStringLiteral: StringLiteral | MacroStringLiteral; -``` - -### Declaration -```ebnf -Declaration: FunctionDeclaration | Import | TagDeclaration; -``` - -### Import -```ebnf -Import: 'from' StringLiteral 'import' Identifier; -``` - -### TagDeclaration -```ebnf -TagDeclaration: 'tag' StringLiteral ('of' StringLiteral)? 'replace'? '[' (StringLiteral (',' StringLiteral)*)? ']'; -``` - -### FunctionDeclaration ```ebnf Function: - Annotation* 'pub'? 'fn' Identifier '(' ParameterList? ')' Block - ; -ParameterList: - Identifier (',' Identifier)* ','? + Annotation* 'pub'? 'fn' Identifier '(' FunctionParameterList? ')' Block ; + ``` -### Annotation +## Import + ```ebnf -Annotation: '#[' Identifier ('=' StringLiteral)? ']'; +Import: + 'from' StringLiteral 'import' ('*' | Identifier (',' Identifier)*) ';' + ; ``` -### Statement +## TagDeclaration + +```ebnf +TagDeclaration: + 'tag' ('<' StringLiteral '>')? StringLiteral 'replace'? '[' (StringLiteral (',' StringLiteral)*)? ']' + ; +``` + +## VariableDeclaration + +```ebnf +VariableDeclaration: + SingleVariableDeclaration + | ArrayVariableDeclaration + | ScoreVariableDeclaration + | TagVariableDeclaration + | ComptimeValueDeclaration + ; +``` + +## StringLiteral + +```ebnf +StringLiteral: + '"' TEXT '"'; +``` + +## Annotation + +```ebnf +Annotation: + '#[' AnnotationAssignment ']' + ; +``` + +## Block + +```ebnf +Block: + '{' Statement* '}' + ; +``` + +## FunctionParameterList + +```ebnf +FunctionParameterList: + FunctionArgument (',' FunctionArgument)* ','? + ; +``` + +## ArrayVariableDeclaration + +```ebnf +ArrayVariableDeclaration: + ('int' | 'bool') identifier '[' integer ']' VariableDeclarationAssignment? +``` + +## ComptimeValueDeclaration + +```ebnf +ComptimeValueDeclaration: + 'val' identifier VariableDeclarationAssignment? +``` + +## ScoreVariableDeclaration + +```ebnf +ScoreVariableDeclaration: + 'int' ('<' StringLiteral '>')? identifier '[' AnyStringLiteral? ']' VariableDeclarationAssignment? +``` + +## SingleVariableDeclaration + +```ebnf +SingleVariableDeclaration: + ('int' | 'bool') identifier VariableDeclarationAssignment? +``` + +## TagVariableDeclaration + +```ebnf +TagVariableDeclaration: + 'bool' identifier '[' AnyStringLiteral? ']' VariableDeclarationAssignment? +``` + +## AnnotationAssignment + +```ebnf +AnnotationAssignment: + Identifier AnnotationValue + ; +``` + +## Statement + ```ebnf Statement: Block @@ -65,115 +147,345 @@ Statement: | Conditional | Grouping | DocComment + | ExecuteBlock | Semicolon - | Run ; ``` -### Block -```ebnf -Block: '{' Statement* '}'; -``` +## FunctionArgument -### Run ```ebnf -Run: - 'run' Expression ';' +FunctionArgument: + FunctionVariableType Identifier ; ``` -### Conditional +## VariableDeclarationAssignment + +```ebnf +VariableDeclarationAssignment: + '=' Expression +``` + +## AnyStringLiteral + +```ebnf +AnyStringLiteral: StringLiteral | MacroStringLiteral ; +``` + +## AnnotationValue + +```ebnf +AnnotationValue: + '=' Expression + | '(' AnnotationAssignment ( ',' AnnotationAssignment )* ')' + ; +``` + +## Conditional + ```ebnf Conditional: - 'if' ParenthizedCondition Block ('else' Block)? - ; +'if' Parenthized +; ``` -### Condition +## ExecuteBlock + ```ebnf -Condition: - PrimaryCondition - BinaryCondition - ; +ExecuteBlock: + (ExecuteBlockHead ExecuteBlockTail) + | (Conditional Block Else) + ; ``` -#### PrimaryCondition +## Grouping + ```ebnf -PrimaryCondition: - ConditionalPrefix - | ParenthesizedCondition - | AnyStringLiteral - ; +Grouping: + 'group' Block +; ``` -#### ConditionalPrefix +## Semicolon + ```ebnf -ConditionalPrefix: - ConditionalPrefixOperator PrimaryCondition +Semicolon: + SemicolonStatement ';' + ; +``` + +## FunctionVariableType + +```ebnf +FunctionVariableType: + 'macro' | 'int' | 'bool' ; ``` -#### ConditionalPrefixOperator -``` ebnf -ConditionalPrefixOperator: '!'; +## Expression + +```ebnf +Expression: + Primary | Binary ; ``` -#### BinaryCondition -``` ebnf -BinaryCondition: - Condition ConditionalBinaryOperator Condition +## MacroStringLiteral + +```ebnf +MacroStringLiteral: + '`' ( TEXT | '$(' [a-zA-Z0-9_]+ ')' )* '`'; +``` + +## Else + +```ebnf +Else: + 'else' Block ; ``` -#### ConditionalBinaryOperator -``` ebnf -ConditionalBinaryOperator: - '&&' +## ExecuteBlockHead + +```ebnf +ExecuteBlockHead: + Conditional + | Align + | Anchored + | As + | AsAt + | At + | Facing + | In + | On + | Positioned + | Rotated + | Store + | Summon +; +``` + +## ExecuteBlockTail + +```ebnf +ExecuteBlockTail: + ExecuteBlock +| Block +; +``` + +## SemicolonStatement + +```ebnf +SemicolonStatement: + (Expression | VariableDeclaration | Assignment | ReturnStatement) + ';' + ; +``` + +## Binary + +```ebnf +Binary: + Expression BinaryOperator Expression + ; +``` + +## Primary + +```ebnf +Primary: + Identifier + | Prefix + | Parenthesized + | Indexed + | Integer + | Boolean + | StringLiteral + | FunctionCall + | MemberAccess + | MacroStringLiteral + | LuaCode +``` + +## Align + +```ebnf +Align: + 'align' '(' AnyStringLiteral ')' ; +``` + +## Anchored + +```ebnf +Anchored: + 'anchored' '(' AnyStringLiteral ')' ; +``` + +## As + +```ebnf +As: + 'as' '(' AnyStringLiteral ')' ; +``` + +## AsAt + +```ebnf +AsAt: + 'asat' '(' AnyStringLiteral ')' ; +``` + +## At + +```ebnf +At: + 'at' '(' AnyStringLiteral ')' ; +``` + +## Facing + +```ebnf +Facing: + 'facing' '(' AnyStringLiteral ')' ; +``` + +## In + +```ebnf +In: + 'in' '(' AnyStringLiteral ')' ; +``` + +## On + +```ebnf +On: + 'on' '(' AnyStringLiteral ')' ; +``` + +## Positioned + +```ebnf +Positioned: + 'positioned' '(' AnyStringLiteral ')' ; +``` + +## Rotated + +```ebnf +Rotated: + 'rotated' '(' AnyStringLiteral ')' ; +``` + +## Store + +```ebnf +Store: + 'store' '(' AnyStringLiteral ')' ; +``` + +## Summon + +```ebnf +Summon: + 'summon' '(' AnyStringLiteral ')' ; +``` + +## Assignment + +```ebnf +Assignment: + AssignmentDestination '=' Expression +``` + +## ReturnStatement + +```ebnf +ReturnStatement: + `return` Expression ; +``` + +## BinaryOperator + +```ebnf +BinaryOperator: + '+' + | '-' + | '*' + | '/' + | '%' + | '==' + | '!=' + | '<' + | '<=' + | '>' + | '>=' + | '&&' | '||' ; ``` -#### ParenthizedCondition -```ebnf -ParenthizedCondition: - '(' Condition ')' - ; -``` +## FunctionCall - -### Grouping -``` ebnf -Grouping: - 'group' Block - ; -``` - -### Expression -```ebnf -Expression: - Primary - ; -``` - -### Primary -```ebnf -Primary: - FunctionCall - | AnyStringLiteral - | LuaCode - ; -``` - -### FunctionCall ```ebnf FunctionCall: Identifier '(' (Expression (',' Expression)*)? ')' ; ``` -### LuaCode +## Indexed + +```ebnf +Indexed: + PrimaryExpression '[' Expression ']' + ; +``` + +## LuaCode + ```ebnf LuaCode: 'lua' '(' (Expression (',' Expression)*)? ')' '{' (.*?)* '}' +``` + +## MemberAccess + +```ebnf +MemberAccess: + Primary '.' Identifier +``` + +## Parenthesized + +```ebnf +Parenthesized: + '(' Expression ')' ; -``` \ No newline at end of file +``` + +## Prefix + +```ebnf +Prefix: + PrefixOperator Primary + ; +``` + +## AssignmentDestination + +```ebnf +AssignmentDestination: + Identifier + | Identifier '[' Expression ']' + ; +``` + +## PrefixOperator + +```ebnf +PrefixOperator: + '!' | '-' | 'run' + ; +``` + diff --git a/scripts/update_grammar_md.py b/scripts/update_grammar_md.py new file mode 100644 index 0000000..839c77d --- /dev/null +++ b/scripts/update_grammar_md.py @@ -0,0 +1,136 @@ +#!/usr/bin/env python3 + +import re +import os +from pathlib import Path +from collections import defaultdict, deque + +ebnf_blocks = [] +rule_defs = {} +rule_deps = defaultdict(set) + +ebnf_fence_start = re.compile(r"^\s*///\s*```\s*ebnf\s*$") +ebnf_fence_end = re.compile(r"^\s*///\s*```\s*$") +doc_comment_prefix = re.compile(r"^\s*///\s?(.*)$") + +rule_start_pattern = re.compile(r"^\s*([A-Za-z_]\w*)\s*:") +rule_ref_pattern = re.compile(r"\b([A-Za-z_]\w*)\b") + + +def find_project_root() -> Path | None: + current = Path.cwd() + while current != current.parent: + cargo_toml = current / "Cargo.toml" + if cargo_toml.exists(): + text = cargo_toml.read_text(encoding="utf-8") + if re.search(r'(?m)^\s*name\s*=\s*"shulkerscript"\s*$', text): + return current + current = current.parent + return None + + +root_dir = find_project_root() +if not root_dir: + raise SystemExit( + "Could not find Cargo.toml of package 'shulkerscript' in this or any parent directory." + ) + +if Path.cwd() != root_dir: + os.chdir(root_dir) + print(f"Changed working directory to {root_dir}") + +previous_rules = set() + +with open("grammar.md", "r", encoding="utf-8") as f: + rule_header_pattern = re.compile(r"## (\w+)") + for line in f: + m = rule_header_pattern.match(line) + if m: + previous_rules.add(m.group(1)) + +for path in Path(".").rglob("*.rs"): + with path.open(encoding="utf-8") as f: + in_block = False + current_block_lines = [] + + for line in f: + if not in_block and ebnf_fence_start.match(line): + in_block = True + current_block_lines = [] + continue + if in_block: + if ebnf_fence_end.match(line): + block_text = "\n".join(current_block_lines) + + ebnf_blocks.append(block_text) + + current_rule_name = None + current_rule_lines = [] + for ln in current_block_lines: + m = rule_start_pattern.match(ln) + if m: + if current_rule_name: + full_def = "\n".join(current_rule_lines) + rule_defs[current_rule_name] = full_def + refs = set(rule_ref_pattern.findall(full_def)) + refs.discard(current_rule_name) + rule_deps[current_rule_name].update(refs) + current_rule_name = m.group(1) + current_rule_lines = [ln] + else: + if current_rule_name: + current_rule_lines.append(ln) + + if current_rule_name: + full_def = "\n".join(current_rule_lines) + + rule_defs[current_rule_name] = full_def + refs = set(rule_ref_pattern.findall(full_def)) + refs.discard(current_rule_name) + rule_deps[current_rule_name].update(refs) + + in_block = False + continue + + m = doc_comment_prefix.match(line) + if m: + current_block_lines.append(m.group(1)) + +if "Program" not in rule_defs: + raise SystemExit("Root rule 'Program' not found in EBNF definitions") + +visited = set() +order = [] +queue = deque(["Program"]) + +while queue: + rule = queue.popleft() + if rule not in visited and rule in rule_defs: + visited.add(rule) + order.append(rule) + for dep in sorted(rule_deps[rule]): + if dep not in visited: + queue.append(dep) + +unused_rules = sorted(set(rule_defs.keys()) - visited) + +if len(unused_rules) > 0: + print( + f"Appending {len(unused_rules)} unused rules to the end: {', '.join(unused_rules)}" + ) + +order.extend(unused_rules) + +with open("grammar.md", "w", encoding="utf-8") as out: + out.write("# Grammar of the Shulkerscript language\n\n") + + for rule in order: + out.write(f"## {rule}\n\n```ebnf\n{rule_defs[rule]}\n```\n\n") + +print(f"Wrote grammar.md with {len(order)} rules.") +added_rules = set(rule_defs.keys()) - previous_rules +if len(added_rules) > 0: + print(f"Added rules for: {', '.join(added_rules)}") +removed_rules = previous_rules - set(rule_defs.keys()) +if len(removed_rules) > 0: + print(f"Removed rules for: {', '.join(removed_rules)}") diff --git a/src/lexical/token.rs b/src/lexical/token.rs index 3c902ac..6eee5e9 100644 --- a/src/lexical/token.rs +++ b/src/lexical/token.rs @@ -310,6 +310,11 @@ impl Debug for Boolean { } /// Represents a hardcoded string literal value in the source code. +/// +/// ```ebnf +/// StringLiteral: +/// '"' TEXT '"'; +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct StringLiteral { @@ -344,6 +349,11 @@ impl SourceElement for StringLiteral { } /// Represents a hardcoded macro string literal value in the source code. +/// +/// ```ebnf +/// MacroStringLiteral: +/// '`' ( TEXT | '$(' [a-zA-Z0-9_]+ ')' )* '`'; +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct MacroStringLiteral { diff --git a/src/syntax/syntax_tree/declaration.rs b/src/syntax/syntax_tree/declaration.rs index 0292f84..9086595 100644 --- a/src/syntax/syntax_tree/declaration.rs +++ b/src/syntax/syntax_tree/declaration.rs @@ -32,11 +32,11 @@ use super::{ /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Declaration: /// Function /// | Import -/// | Tag +/// | TagDeclaration /// | ('pub'? VariableDeclaration ';') /// ; /// ``` @@ -97,12 +97,12 @@ impl Declaration { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Function: -/// Annotation* 'pub'? 'fn' Identifier '(' ParameterList? ')' Block +/// Annotation* 'pub'? 'fn' Identifier '(' FunctionParameterList? ')' Block /// ; /// -/// ParameterList: +/// FunctionParameterList: /// FunctionArgument (',' FunctionArgument)* ','? /// ; /// ``` @@ -176,7 +176,7 @@ impl SourceElement for Function { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// FunctionVariableType: /// 'macro' | 'int' | 'bool' /// ; @@ -193,7 +193,7 @@ pub enum FunctionVariableType { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// FunctionArgument: /// FunctionVariableType Identifier /// ; @@ -211,7 +211,7 @@ pub struct FunctionParameter { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Import: /// 'from' StringLiteral 'import' ('*' | Identifier (',' Identifier)*) ';' /// ; @@ -266,7 +266,7 @@ impl SourceElement for Import { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// TagDeclaration: /// 'tag' ('<' StringLiteral '>')? StringLiteral 'replace'? '[' (StringLiteral (',' StringLiteral)*)? ']' /// ; diff --git a/src/syntax/syntax_tree/expression.rs b/src/syntax/syntax_tree/expression.rs index 5b358b6..a8b602f 100644 --- a/src/syntax/syntax_tree/expression.rs +++ b/src/syntax/syntax_tree/expression.rs @@ -143,7 +143,7 @@ impl SourceElement for Binary { /// /// ```ebnf /// Expression: -/// Primary | Binary +/// Primary | Binary ; /// ``` #[allow(missing_docs)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -166,11 +166,12 @@ impl SourceElement for Expression { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Primary: /// Identifier /// | Prefix /// | Parenthesized +/// | Indexed /// | Integer /// | Boolean /// | StringLiteral @@ -307,7 +308,7 @@ impl SourceElement for Indexed { /// Syntax Synopsis: /// ```ebnf /// PrefixOperator: -/// '!' | '-' +/// '!' | '-' | 'run' /// ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -359,7 +360,7 @@ impl SourceElement for Prefix { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// FunctionCall: /// Identifier '(' (Expression (',' Expression)*)? ')' /// ; diff --git a/src/syntax/syntax_tree/mod.rs b/src/syntax/syntax_tree/mod.rs index b38dc51..a66d443 100644 --- a/src/syntax/syntax_tree/mod.rs +++ b/src/syntax/syntax_tree/mod.rs @@ -96,7 +96,7 @@ impl SourceElement for AnyStringLiteral { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Annotation: /// '#[' AnnotationAssignment ']' /// ; @@ -149,7 +149,7 @@ impl SourceElement for Annotation { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// AnnotationValue: /// '=' Expression /// | '(' AnnotationAssignment ( ',' AnnotationAssignment )* ')' @@ -200,7 +200,7 @@ impl SourceElement for AnnotationValue { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// AnnotationAssignment: /// Identifier AnnotationValue /// ; diff --git a/src/syntax/syntax_tree/program.rs b/src/syntax/syntax_tree/program.rs index 4f027ed..29f3333 100644 --- a/src/syntax/syntax_tree/program.rs +++ b/src/syntax/syntax_tree/program.rs @@ -20,6 +20,13 @@ use crate::{ use super::declaration::Declaration; /// Program is a collection of declarations preceeded by a namespace selector. +/// +/// ```ebnf +/// Program: +/// Namespace +/// Declaration* +/// ; +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] pub struct ProgramFile { diff --git a/src/syntax/syntax_tree/statement.rs b/src/syntax/syntax_tree/statement.rs index 821dd32..8a245e6 100644 --- a/src/syntax/syntax_tree/statement.rs +++ b/src/syntax/syntax_tree/statement.rs @@ -35,13 +35,14 @@ use super::{expression::Expression, Annotation, AnyStringLiteral}; /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Statement: /// Block /// | LiteralCommand /// | Conditional /// | Grouping /// | DocComment +/// | ExecuteBlock /// | Semicolon /// ; /// ``` @@ -131,7 +132,7 @@ impl Statement { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Block: /// '{' Statement* '}' /// ; @@ -171,11 +172,11 @@ impl SourceElement for Block { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Grouping: -/// 'group' Block +/// 'group' Block /// ; -/// ```` +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] pub struct Grouping { @@ -207,9 +208,9 @@ impl SourceElement for Grouping { /// Represents a statement that ends with a semicolon in the syntax tree. /// /// Syntax Synopsis: -/// ``` ebnf +/// ```ebnf /// Semicolon: -/// SemicolonStatement ';' +/// SemicolonStatement ';' /// ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -243,10 +244,10 @@ impl Semicolon { /// Represents a statement that ends with a semicolon in the syntax tree. /// /// Syntax Synopsis: -/// ``` ebnf +/// ```ebnf /// SemicolonStatement: -/// (Expression | VariableDeclaration | Assignment) -/// ';' +/// (Expression | VariableDeclaration | Assignment | ReturnStatement) +/// ';' /// ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -318,6 +319,7 @@ impl ReturnStatement { /// | ArrayVariableDeclaration /// | ScoreVariableDeclaration /// | TagVariableDeclaration +/// | ComptimeValueDeclaration /// ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] diff --git a/src/syntax/syntax_tree/statement/execute_block.rs b/src/syntax/syntax_tree/statement/execute_block.rs index e085e46..bb68988 100644 --- a/src/syntax/syntax_tree/statement/execute_block.rs +++ b/src/syntax/syntax_tree/statement/execute_block.rs @@ -73,6 +73,7 @@ impl SourceElement for ExecuteBlock { /// | Store /// | Summon /// ; +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, EnumAsInner, From)] #[allow(missing_docs)] @@ -120,6 +121,7 @@ impl SourceElement for ExecuteBlockHead { /// ExecuteBlock /// | Block /// ; +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, EnumAsInner, From)] #[allow(missing_docs)] @@ -144,7 +146,7 @@ impl SourceElement for ExecuteBlockTail { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Conditional: /// 'if' Parenthized /// ; @@ -181,7 +183,7 @@ impl SourceElement for Conditional { /// /// Syntax Synopsis: /// -/// ``` ebnf +/// ```ebnf /// Else: /// 'else' Block /// ; @@ -217,8 +219,7 @@ impl SourceElement for Else { /// /// ```ebnf /// As: -/// 'as' '(' AnyStringLiteral ')' -/// ; +/// 'as' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -263,8 +264,8 @@ impl As { /// Syntax Synopsis: /// ```ebnf /// Align: -/// 'align' '(' AnyStringLiteral ')' -/// ; +/// 'align' '(' AnyStringLiteral ')' ; +/// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] pub struct Align { @@ -309,8 +310,7 @@ impl Align { /// Syntax Synopsis: /// ```ebnf /// Anchored: -/// 'anchored' '(' AnyStringLiteral ')' -/// ; +/// 'anchored' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -354,8 +354,7 @@ impl Anchored { /// Syntax Synopsis: /// ```ebnf /// AsAt: -/// 'asat' '(' AnyStringLiteral ')' -/// ; +/// 'asat' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -399,8 +398,7 @@ impl AsAt { /// Syntax Synopsis: /// ```ebnf /// At: -/// 'at' '(' AnyStringLiteral ')' -/// ; +/// 'at' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -444,8 +442,7 @@ impl At { /// Syntax Synopsis: /// ```ebnf /// Facing: -/// 'facing' '(' AnyStringLiteral ')' -/// ; +/// 'facing' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -489,8 +486,7 @@ impl Facing { /// Syntax Synopsis: /// ```ebnf /// In: -/// 'in' '(' AnyStringLiteral ')' -/// ; +/// 'in' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -534,8 +530,7 @@ impl In { /// Syntax Synopsis: /// ```ebnf /// On: -/// 'on' '(' AnyStringLiteral ')' -/// ; +/// 'on' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -579,8 +574,7 @@ impl On { /// Syntax Synopsis: /// ```ebnf /// Positioned: -/// 'positioned' '(' AnyStringLiteral ')' -/// ; +/// 'positioned' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -624,8 +618,7 @@ impl Positioned { /// Syntax Synopsis: /// ```ebnf /// Rotated: -/// 'rotated' '(' AnyStringLiteral ')' -/// ; +/// 'rotated' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -669,8 +662,7 @@ impl Rotated { /// Syntax Synopsis: /// ```ebnf /// Store: -/// 'store' '(' AnyStringLiteral ')' -/// ; +/// 'store' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)] @@ -714,8 +706,7 @@ impl Store { /// Syntax Synopsis: /// ```ebnf /// Summon: -/// 'summon' '(' AnyStringLiteral ')' -/// ; +/// 'summon' '(' AnyStringLiteral ')' ; /// ``` #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Getters)]