diff --git a/CHANGELOG.md b/CHANGELOG.md index 71dff4e..dc34cea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,18 @@ ## [Unreleased] +### Changed + +- Reworked the lexer and parser to be more generic, which should make it a bit easier to support future changes to the + Structurizr DSL +- Syntax highlighting is now mostly annotator based instead of lexer based + +### Added + +- Matching curly braces are now highlighted in the editor +- Code can now be commented with the "Comment with line/block comment" commands +- Code is automatically indented correctly while editing + ## [0.2.1] - 2023-03-31 ### Changed diff --git a/README.md b/README.md index 1d60c1c..190af29 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,8 @@ using [Simon Brown](https://twitter.com/simonbrown)'s [C4 model](https://c4model * Basic syntax highlighting for the Structurizr DSL language. Files with the `.dsl` extension are considered to be Structurizr DSL files. * Automatically indent and normalize spacing with IntelliJ's "Reformat Code" command. +* Automatically indent new code while typing +* Comment code using the "Comment with line/block comment" commands * More to come! Please refer to the [TODO section](https://github.com/dirkgroot/structurizr-dsl-intellij-plugin#todo) of the README for a list of features that will likely be added. @@ -42,9 +44,8 @@ using [Simon Brown](https://twitter.com/simonbrown)'s [C4 model](https://c4model - For now, arguments of statements are all treated as (un)quoted strings, so "true", "false", integers, (un)quoted text will all get the same syntax highlighting. - The following blocks are treated as property blocks, containing (un)quoted string pairs: - - branding - - terminology - - configuration + - perspectives + - properties - users - All arguments of view declarations are highlighted as (un)quoted strings. Correct highlighting of these arguments will most likely be implemented using @@ -68,11 +69,11 @@ Search for "Structurizr" in the marketplace, and install the plugin. Please refe ### Features -- ☑️ syntax highlighting +- ✅ syntax highlighting - ✅ token based - - 🔳 annotator based + - ✅ annotator based - ✅ reformat code -- 🔳 auto indentation +- ✅ auto indentation - 🔳 go to definition - 🔳 rename refactoring for identifiers - 🔳 code validation diff --git a/build.gradle.kts b/build.gradle.kts index 7165c0a..855535a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -49,6 +49,7 @@ koverReport { sourceSets["main"].java.srcDirs("src/main/gen") dependencies { + testImplementation(kotlin("test")) testImplementation("io.kotest:kotest-runner-junit5:5.6.2") testImplementation("io.kotest:kotest-assertions-core:5.6.2") testImplementation("com.willowtreeapps.assertk:assertk-jvm:0.25") diff --git a/gradle.properties b/gradle.properties index 3049315..e34df1d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ pluginGroup = nl.dirkgroot.structurizr-dsl-plugin pluginName = Structurizr DSL Language Support pluginRepositoryUrl = https://github.com/dirkgroot/structurizr-dsl-intellij-plugin # SemVer format -> https://semver.org -pluginVersion = 0.2.2 +pluginVersion = 0.3.1 # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html pluginSinceBuild = 223 diff --git a/src/main/gen/nl/dirkgroot/structurizr/dsl/StructurizrDSLParser.java b/src/main/gen/nl/dirkgroot/structurizr/dsl/StructurizrDSLParser.java index 5363ffd..2c34e76 100644 --- a/src/main/gen/nl/dirkgroot/structurizr/dsl/StructurizrDSLParser.java +++ b/src/main/gen/nl/dirkgroot/structurizr/dsl/StructurizrDSLParser.java @@ -21,7 +21,7 @@ public ASTNode parse(IElementType t, PsiBuilder b) { public void parseLight(IElementType t, PsiBuilder b) { boolean r; - b = adapt_builder_(t, b, this, null); + b = adapt_builder_(t, b, this, EXTENDS_SETS_); Marker m = enter_section_(b, 0, _COLLAPSE_, null); r = parse_root_(t, b); exit_section_(b, 0, m, t, r, true, TRUE_CONDITION); @@ -35,311 +35,319 @@ static boolean parse_root_(IElementType t, PsiBuilder b, int l) { return structurizrDSLFile(b, l + 1); } + public static final TokenSet[] EXTENDS_SETS_ = new TokenSet[] { + create_token_set_(ANIMATION_STATEMENT, BLOCK_COMMENT_STATEMENT, BLOCK_STATEMENT, EXPLICIT_RELATIONSHIP_STATEMENT, + IDENTIFIER_ASSIGNMENT_STATEMENT, IDENTIFIER_REFERENCES_STATEMENT, IMPLICIT_RELATIONSHIP_STATEMENT, LINE_COMMENT_STATEMENT, + PROPERTIES_STATEMENT, SCRIPT_STATEMENT, SINGLE_LINE_STATEMENT), + }; + /* ********************************************************** */ - // text - public static boolean argument(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "argument")) return false; - if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; + // 'animation' + public static boolean animationKeyword(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "animationKeyword")) return false; boolean r; - Marker m = enter_section_(b, l, _NONE_, ARGUMENT, ""); - r = text(b, l + 1); + Marker m = enter_section_(b, l, _NONE_, ANIMATION_KEYWORD, ""); + r = consumeToken(b, "animation"); exit_section_(b, l, m, r, false, null); return r; } /* ********************************************************** */ - // identifierAssignment? keywordWithArguments '{' CRLF statement* '}' lf_eof - public static boolean blockStatement(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "blockStatement")) return false; + // animationKeyword '{' CRLF (identifierReferencesStatement | lineCommentStatement | blockCommentStatement)* '}' lf_eof + public static boolean animationStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "animationStatement")) return false; boolean r; - Marker m = enter_section_(b, l, _NONE_, BLOCK_STATEMENT, ""); - r = blockStatement_0(b, l + 1); - r = r && keywordWithArguments(b, l + 1); + Marker m = enter_section_(b, l, _NONE_, ANIMATION_STATEMENT, ""); + r = animationKeyword(b, l + 1); r = r && consumeTokens(b, 0, BRACE1, CRLF); - r = r && blockStatement_4(b, l + 1); + r = r && animationStatement_3(b, l + 1); r = r && consumeToken(b, BRACE2); r = r && lf_eof(b, l + 1); exit_section_(b, l, m, r, false, null); return r; } - // identifierAssignment? - private static boolean blockStatement_0(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "blockStatement_0")) return false; - identifierAssignment(b, l + 1); - return true; - } - - // statement* - private static boolean blockStatement_4(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "blockStatement_4")) return false; + // (identifierReferencesStatement | lineCommentStatement | blockCommentStatement)* + private static boolean animationStatement_3(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "animationStatement_3")) return false; while (true) { int c = current_position_(b); - if (!statement(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "blockStatement_4", c)) break; + if (!animationStatement_3_0(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "animationStatement_3", c)) break; } return true; } - /* ********************************************************** */ - // singleLineStatement | blockStatement | propertyBlockStatement | CRLF - static boolean elementDefinition(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "elementDefinition")) return false; + // identifierReferencesStatement | lineCommentStatement | blockCommentStatement + private static boolean animationStatement_3_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "animationStatement_3_0")) return false; boolean r; - r = singleLineStatement(b, l + 1); - if (!r) r = blockStatement(b, l + 1); - if (!r) r = propertyBlockStatement(b, l + 1); - if (!r) r = consumeToken(b, CRLF); + r = identifierReferencesStatement(b, l + 1); + if (!r) r = lineCommentStatement(b, l + 1); + if (!r) r = blockCommentStatement(b, l + 1); return r; } /* ********************************************************** */ - // identifierName '->' identifierName argument* - public static boolean explicitRelationship(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "explicitRelationship")) return false; - if (!nextTokenIs(b, IDENTIFIER)) return false; + // text + public static boolean argument(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "argument")) return false; + if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; boolean r; - Marker m = enter_section_(b); - r = identifierName(b, l + 1); - r = r && consumeToken(b, RELATIONSHIP_KEYWORD); - r = r && identifierName(b, l + 1); - r = r && explicitRelationship_3(b, l + 1); - exit_section_(b, m, EXPLICIT_RELATIONSHIP, r); + Marker m = enter_section_(b, l, _NONE_, ARGUMENT, ""); + r = text(b, l + 1); + exit_section_(b, l, m, r, false, null); return r; } - // argument* - private static boolean explicitRelationship_3(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "explicitRelationship_3")) return false; + /* ********************************************************** */ + // '{' CRLF expr* '}' + public static boolean block(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "block")) return false; + boolean r, p; + Marker m = enter_section_(b, l, _NONE_, BLOCK, ""); + r = consumeTokens(b, 1, BRACE1, CRLF); + p = r; // pin = 1 + r = r && report_error_(b, block_2(b, l + 1)); + r = p && consumeToken(b, BRACE2) && r; + exit_section_(b, l, m, r, p, StructurizrDSLParser::blockRecover); + return r || p; + } + + // expr* + private static boolean block_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "block_2")) return false; while (true) { int c = current_position_(b); - if (!argument(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "explicitRelationship_3", c)) break; + if (!expr(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "block_2", c)) break; } return true; } /* ********************************************************** */ - // identifierName '=' - static boolean identifierAssignment(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "identifierAssignment")) return false; - if (!nextTokenIs(b, IDENTIFIER)) return false; + // BLOCK_COMMENT lf_eof + public static boolean blockCommentStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "blockCommentStatement")) return false; + if (!nextTokenIs(b, BLOCK_COMMENT)) return false; boolean r; Marker m = enter_section_(b); - r = identifierName(b, l + 1); - r = r && consumeToken(b, EQUALS); - exit_section_(b, m, null, r); + r = consumeToken(b, BLOCK_COMMENT); + r = r && lf_eof(b, l + 1); + exit_section_(b, m, BLOCK_COMMENT_STATEMENT, r); return r; } /* ********************************************************** */ - // IDENTIFIER - public static boolean identifierName(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "identifierName")) return false; - if (!nextTokenIs(b, IDENTIFIER)) return false; + // !(text | lf_eof) + static boolean blockRecover(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "blockRecover")) return false; boolean r; - Marker m = enter_section_(b); - r = consumeToken(b, IDENTIFIER); - exit_section_(b, m, IDENTIFIER_NAME, r); + Marker m = enter_section_(b, l, _NOT_); + r = !blockRecover_0(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + // text | lf_eof + private static boolean blockRecover_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "blockRecover_0")) return false; + boolean r; + r = text(b, l + 1); + if (!r) r = lf_eof(b, l + 1); return r; } /* ********************************************************** */ - // identifierName+ lf_eof - public static boolean identifierReferences(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "identifierReferences")) return false; - if (!nextTokenIs(b, IDENTIFIER)) return false; + // keyword argument* block lf_eof + public static boolean blockStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "blockStatement")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; boolean r; Marker m = enter_section_(b); - r = identifierReferences_0(b, l + 1); + r = keyword(b, l + 1); + r = r && blockStatement_1(b, l + 1); + r = r && block(b, l + 1); r = r && lf_eof(b, l + 1); - exit_section_(b, m, IDENTIFIER_REFERENCES, r); + exit_section_(b, m, BLOCK_STATEMENT, r); return r; } - // identifierName+ - private static boolean identifierReferences_0(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "identifierReferences_0")) return false; - boolean r; - Marker m = enter_section_(b); - r = identifierName(b, l + 1); - while (r) { + // argument* + private static boolean blockStatement_1(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "blockStatement_1")) return false; + while (true) { int c = current_position_(b); - if (!identifierName(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "identifierReferences_0", c)) break; + if (!argument(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "blockStatement_1", c)) break; } - exit_section_(b, m, null, r); - return r; + return true; } /* ********************************************************** */ - // '->' identifierName argument* - public static boolean implicitRelationship(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "implicitRelationship")) return false; - if (!nextTokenIs(b, RELATIONSHIP_KEYWORD)) return false; + // relationshipSource relationshipKeyword relationshipDestination argument* block? lf_eof + public static boolean explicitRelationshipStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "explicitRelationshipStatement")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; boolean r; Marker m = enter_section_(b); - r = consumeToken(b, RELATIONSHIP_KEYWORD); - r = r && identifierName(b, l + 1); - r = r && implicitRelationship_2(b, l + 1); - exit_section_(b, m, IMPLICIT_RELATIONSHIP, r); + r = relationshipSource(b, l + 1); + r = r && relationshipKeyword(b, l + 1); + r = r && relationshipDestination(b, l + 1); + r = r && explicitRelationshipStatement_3(b, l + 1); + r = r && explicitRelationshipStatement_4(b, l + 1); + r = r && lf_eof(b, l + 1); + exit_section_(b, m, EXPLICIT_RELATIONSHIP_STATEMENT, r); return r; } // argument* - private static boolean implicitRelationship_2(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "implicitRelationship_2")) return false; + private static boolean explicitRelationshipStatement_3(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "explicitRelationshipStatement_3")) return false; while (true) { int c = current_position_(b); if (!argument(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "implicitRelationship_2", c)) break; + if (!empty_element_parsed_guard_(b, "explicitRelationshipStatement_3", c)) break; } return true; } + // block? + private static boolean explicitRelationshipStatement_4(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "explicitRelationshipStatement_4")) return false; + block(b, l + 1); + return true; + } + /* ********************************************************** */ - // text - public static boolean key(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "key")) return false; - if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; + // scriptStatement + // | explicitRelationshipStatement + // | implicitRelationshipStatement + // | animationStatement + // | propertiesStatement + // | identifierAssignmentStatement + // | blockStatement + // | singleLineStatement + // | lineCommentStatement + // | blockCommentStatement + static boolean expr(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "expr")) return false; boolean r; - Marker m = enter_section_(b, l, _NONE_, KEY, ""); - r = text(b, l + 1); - exit_section_(b, l, m, r, false, null); + r = scriptStatement(b, l + 1); + if (!r) r = explicitRelationshipStatement(b, l + 1); + if (!r) r = implicitRelationshipStatement(b, l + 1); + if (!r) r = animationStatement(b, l + 1); + if (!r) r = propertiesStatement(b, l + 1); + if (!r) r = identifierAssignmentStatement(b, l + 1); + if (!r) r = blockStatement(b, l + 1); + if (!r) r = singleLineStatement(b, l + 1); + if (!r) r = lineCommentStatement(b, l + 1); + if (!r) r = blockCommentStatement(b, l + 1); return r; } /* ********************************************************** */ - // key value CRLF - public static boolean keyValuePair(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "keyValuePair")) return false; - if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; - boolean r; - Marker m = enter_section_(b, l, _NONE_, KEY_VALUE_PAIR, ""); - r = key(b, l + 1); - r = r && value(b, l + 1); - r = r && consumeToken(b, CRLF); - exit_section_(b, l, m, r, false, null); + // identifierReference '=' (blockStatement | singleLineStatement) + public static boolean identifierAssignmentStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "identifierAssignmentStatement")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; + boolean r; + Marker m = enter_section_(b); + r = identifierReference(b, l + 1); + r = r && consumeToken(b, EQUALS); + r = r && identifierAssignmentStatement_2(b, l + 1); + exit_section_(b, m, IDENTIFIER_ASSIGNMENT_STATEMENT, r); + return r; + } + + // blockStatement | singleLineStatement + private static boolean identifierAssignmentStatement_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "identifierAssignmentStatement_2")) return false; + boolean r; + r = blockStatement(b, l + 1); + if (!r) r = singleLineStatement(b, l + 1); return r; } /* ********************************************************** */ - // '!adrs' | 'animation' | 'autoLayout' | 'background' | 'border' | 'color' | 'colour' | 'component' | - // '!constant' | 'containerInstance' | 'container' | 'custom' | 'deploymentEnvironment' | 'deploymentGroup' | - // 'deployment' | 'deploymentNode' | 'description' | '!docs' | 'dynamic' | 'element' | 'enterprise' | - // 'exclude' | 'extends' | 'filtered' | 'fontSize' | 'group' | 'healthCheck' | 'height' | 'icon' | - // '!identifiers' | '!impliedRelationships' | 'include' | '!include' | 'infrastructureNode' | 'instances' | - // 'metadata' | 'model' | 'opacity' | 'person' | 'perspectives' | '!plugin' | 'position' | '!ref' | '->' | - // 'routing' | '!script' | 'shape' | 'softwareSystemInstance' | 'softwareSystem' | 'stroke' | 'strokeWidth' | - // 'style' | 'styles' | 'systemContext' | 'systemLandscape' | 'tags' | 'technology' | 'theme' | 'thickness' | - // 'title' | 'url' | 'views' | 'width' | 'workspace' - public static boolean keyword(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "keyword")) return false; + // UNQUOTED_TEXT + public static boolean identifierReference(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "identifierReference")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, UNQUOTED_TEXT); + exit_section_(b, m, IDENTIFIER_REFERENCE, r); + return r; + } + + /* ********************************************************** */ + // identifierReference* CRLF + public static boolean identifierReferencesStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "identifierReferencesStatement")) return false; + if (!nextTokenIs(b, "", CRLF, UNQUOTED_TEXT)) return false; boolean r; - Marker m = enter_section_(b, l, _NONE_, KEYWORD, ""); - r = consumeToken(b, ADRS_KEYWORD); - if (!r) r = consumeToken(b, ANIMATION_KEYWORD); - if (!r) r = consumeToken(b, AUTO_LAYOUT_KEYWORD); - if (!r) r = consumeToken(b, BACKGROUND_KEYWORD); - if (!r) r = consumeToken(b, BORDER_KEYWORD); - if (!r) r = consumeToken(b, COLOR_KEYWORD); - if (!r) r = consumeToken(b, COLOUR_KEYWORD); - if (!r) r = consumeToken(b, COMPONENT_KEYWORD); - if (!r) r = consumeToken(b, CONSTANT_KEYWORD); - if (!r) r = consumeToken(b, CONTAINER_INSTANCE); - if (!r) r = consumeToken(b, CONTAINER_KEYWORD); - if (!r) r = consumeToken(b, CUSTOM_KEYWORD); - if (!r) r = consumeToken(b, DEPLOYMENT_ENVIRONMENT_KEYWORD); - if (!r) r = consumeToken(b, DEPLOYMENT_GROUP_KEYWORD); - if (!r) r = consumeToken(b, DEPLOYMENT_KEYWORD); - if (!r) r = consumeToken(b, DEPLOYMENT_NODE_KEYWORD); - if (!r) r = consumeToken(b, DESCRIPTION_KEYWORD); - if (!r) r = consumeToken(b, DOCS_KEYWORD); - if (!r) r = consumeToken(b, DYNAMIC_KEYWORD); - if (!r) r = consumeToken(b, ELEMENT_KEYWORD); - if (!r) r = consumeToken(b, ENTERPRISE_KEYWORD); - if (!r) r = consumeToken(b, EXCLUDE_ELEMENT_KEYWORD); - if (!r) r = consumeToken(b, EXTENDS_KEYWORD); - if (!r) r = consumeToken(b, FILTERED_KEYWORD); - if (!r) r = consumeToken(b, FONTSIZE_KEYWORD); - if (!r) r = consumeToken(b, GROUP_KEYWORD); - if (!r) r = consumeToken(b, HEALTH_CHECK_KEYWORD); - if (!r) r = consumeToken(b, HEIGHT_KEYWORD); - if (!r) r = consumeToken(b, ICON_KEYWORD); - if (!r) r = consumeToken(b, IDENTIFIERS_KEYWORD); - if (!r) r = consumeToken(b, IMPLIED_RELATIONSHIPS_KEYWORD); - if (!r) r = consumeToken(b, INCLUDE_ELEMENT_KEYWORD); - if (!r) r = consumeToken(b, INCLUDE_FILE_KEYWORD); - if (!r) r = consumeToken(b, INFRASTRUCTURE_NODE_KEYWORD); - if (!r) r = consumeToken(b, INSTANCES_KEYWORD); - if (!r) r = consumeToken(b, METADATA_KEYWORD); - if (!r) r = consumeToken(b, MODEL_KEYWORD); - if (!r) r = consumeToken(b, OPACITY_KEYWORD); - if (!r) r = consumeToken(b, PERSON_KEYWORD); - if (!r) r = consumeToken(b, PERSPECTIVES_KEYWORD); - if (!r) r = consumeToken(b, PLUGIN_KEYWORD); - if (!r) r = consumeToken(b, POSITION_KEYWORD); - if (!r) r = consumeToken(b, REF_KEYWORD); - if (!r) r = consumeToken(b, RELATIONSHIP_KEYWORD); - if (!r) r = consumeToken(b, ROUTING_KEYWORD); - if (!r) r = consumeToken(b, SCRIPT_KEYWORD); - if (!r) r = consumeToken(b, SHAPE_KEYWORD); - if (!r) r = consumeToken(b, SOFTWARE_SYSTEM_INSTANCE_KEYWORD); - if (!r) r = consumeToken(b, SOFTWARE_SYSTEM_KEYWORD); - if (!r) r = consumeToken(b, STROKE_KEYWORD); - if (!r) r = consumeToken(b, STROKEWIDTH_KEYWORD); - if (!r) r = consumeToken(b, STYLE_KEYWORD); - if (!r) r = consumeToken(b, STYLES_KEYWORD); - if (!r) r = consumeToken(b, SYSTEM_CONTEXT_KEYWORD); - if (!r) r = consumeToken(b, SYSTEM_LANDSCAPE_KEYWORD); - if (!r) r = consumeToken(b, TAGS_KEYWORD); - if (!r) r = consumeToken(b, TECHNOLOGY_KEYWORD); - if (!r) r = consumeToken(b, THEME_KEYWORD); - if (!r) r = consumeToken(b, THICKNESS_KEYWORD); - if (!r) r = consumeToken(b, TITLE_KEYWORD); - if (!r) r = consumeToken(b, URL_KEYWORD); - if (!r) r = consumeToken(b, VIEWS_KEYWORD); - if (!r) r = consumeToken(b, WIDTH_KEYWORD); - if (!r) r = consumeToken(b, WORKSPACE_KEYWORD); + Marker m = enter_section_(b, l, _NONE_, IDENTIFIER_REFERENCES_STATEMENT, ""); + r = identifierReferencesStatement_0(b, l + 1); + r = r && consumeToken(b, CRLF); exit_section_(b, l, m, r, false, null); return r; } + // identifierReference* + private static boolean identifierReferencesStatement_0(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "identifierReferencesStatement_0")) return false; + while (true) { + int c = current_position_(b); + if (!identifierReference(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "identifierReferencesStatement_0", c)) break; + } + return true; + } + /* ********************************************************** */ - // keyword argument* - static boolean keywordWithArguments(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "keywordWithArguments")) return false; + // relationshipKeyword relationshipDestination argument* block? lf_eof + public static boolean implicitRelationshipStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "implicitRelationshipStatement")) return false; + if (!nextTokenIs(b, ARROW)) return false; boolean r; Marker m = enter_section_(b); - r = keyword(b, l + 1); - r = r && keywordWithArguments_1(b, l + 1); - exit_section_(b, m, null, r); + r = relationshipKeyword(b, l + 1); + r = r && relationshipDestination(b, l + 1); + r = r && implicitRelationshipStatement_2(b, l + 1); + r = r && implicitRelationshipStatement_3(b, l + 1); + r = r && lf_eof(b, l + 1); + exit_section_(b, m, IMPLICIT_RELATIONSHIP_STATEMENT, r); return r; } // argument* - private static boolean keywordWithArguments_1(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "keywordWithArguments_1")) return false; + private static boolean implicitRelationshipStatement_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "implicitRelationshipStatement_2")) return false; while (true) { int c = current_position_(b); if (!argument(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "keywordWithArguments_1", c)) break; + if (!empty_element_parsed_guard_(b, "implicitRelationshipStatement_2", c)) break; } return true; } + // block? + private static boolean implicitRelationshipStatement_3(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "implicitRelationshipStatement_3")) return false; + block(b, l + 1); + return true; + } + /* ********************************************************** */ - // 'branding' | 'configuration' | 'properties' | 'terminology' | 'users' - public static boolean keywordWithPropertyBlock(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "keywordWithPropertyBlock")) return false; - boolean r; - Marker m = enter_section_(b, l, _NONE_, KEYWORD_WITH_PROPERTY_BLOCK, ""); - r = consumeToken(b, BRANDING_KEYWORD); - if (!r) r = consumeToken(b, CONFIGURATION_KEYWORD); - if (!r) r = consumeToken(b, PROPERTIES_KEYWORD); - if (!r) r = consumeToken(b, TERMINOLOGY_KEYWORD); - if (!r) r = consumeToken(b, USERS_KEYWORD); - exit_section_(b, l, m, r, false, null); + // UNQUOTED_TEXT + public static boolean keyword(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "keyword")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, UNQUOTED_TEXT); + exit_section_(b, m, KEYWORD, r); return r; } @@ -356,114 +364,223 @@ static boolean lf_eof(PsiBuilder b, int l) { } /* ********************************************************** */ - // keywordWithPropertyBlock '{' CRLF keyValuePair* '}' - public static boolean propertyBlockStatement(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "propertyBlockStatement")) return false; + // LINE_COMMENT lf_eof + public static boolean lineCommentStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "lineCommentStatement")) return false; + if (!nextTokenIs(b, LINE_COMMENT)) return false; boolean r; - Marker m = enter_section_(b, l, _NONE_, PROPERTY_BLOCK_STATEMENT, ""); - r = keywordWithPropertyBlock(b, l + 1); - r = r && consumeTokens(b, 0, BRACE1, CRLF); - r = r && propertyBlockStatement_3(b, l + 1); + Marker m = enter_section_(b); + r = consumeToken(b, LINE_COMMENT); + r = r && lf_eof(b, l + 1); + exit_section_(b, m, LINE_COMMENT_STATEMENT, r); + return r; + } + + /* ********************************************************** */ + // '{' CRLF propertyDefinition* '}' + public static boolean propertiesBlock(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertiesBlock")) return false; + if (!nextTokenIs(b, BRACE1)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, BRACE1, CRLF); + r = r && propertiesBlock_2(b, l + 1); r = r && consumeToken(b, BRACE2); - exit_section_(b, l, m, r, false, null); + exit_section_(b, m, PROPERTIES_BLOCK, r); return r; } - // keyValuePair* - private static boolean propertyBlockStatement_3(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "propertyBlockStatement_3")) return false; + // propertyDefinition* + private static boolean propertiesBlock_2(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertiesBlock_2")) return false; while (true) { int c = current_position_(b); - if (!keyValuePair(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "propertyBlockStatement_3", c)) break; + if (!propertyDefinition(b, l + 1)) break; + if (!empty_element_parsed_guard_(b, "propertiesBlock_2", c)) break; } return true; } /* ********************************************************** */ - // '!script' argument* '{' scriptContents '}' - public static boolean scriptBlock(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "scriptBlock")) return false; - if (!nextTokenIs(b, SCRIPT_KEYWORD)) return false; + // 'perspectives' | 'properties' | 'users' + public static boolean propertiesKeyword(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertiesKeyword")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, PROPERTIES_KEYWORD, ""); + r = consumeToken(b, "perspectives"); + if (!r) r = consumeToken(b, "properties"); + if (!r) r = consumeToken(b, "users"); + exit_section_(b, l, m, r, false, null); + return r; + } + + /* ********************************************************** */ + // propertiesKeyword propertiesBlock lf_eof + public static boolean propertiesStatement(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertiesStatement")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, PROPERTIES_STATEMENT, ""); + r = propertiesKeyword(b, l + 1); + r = r && propertiesBlock(b, l + 1); + r = r && lf_eof(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + /* ********************************************************** */ + // propertyKey propertyValue CRLF + public static boolean propertyDefinition(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertyDefinition")) return false; + if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, PROPERTY_DEFINITION, ""); + r = propertyKey(b, l + 1); + r = r && propertyValue(b, l + 1); + r = r && consumeToken(b, CRLF); + exit_section_(b, l, m, r, false, null); + return r; + } + + /* ********************************************************** */ + // text + public static boolean propertyKey(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertyKey")) return false; + if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, PROPERTY_KEY, ""); + r = text(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + /* ********************************************************** */ + // text + public static boolean propertyValue(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "propertyValue")) return false; + if (!nextTokenIs(b, "", QUOTED_TEXT, UNQUOTED_TEXT)) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, PROPERTY_VALUE, ""); + r = text(b, l + 1); + exit_section_(b, l, m, r, false, null); + return r; + } + + /* ********************************************************** */ + // UNQUOTED_TEXT + public static boolean relationshipDestination(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "relationshipDestination")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; boolean r; Marker m = enter_section_(b); - r = consumeToken(b, SCRIPT_KEYWORD); - r = r && scriptBlock_1(b, l + 1); - r = r && consumeToken(b, BRACE1); - r = r && scriptContents(b, l + 1); - r = r && consumeToken(b, BRACE2); - exit_section_(b, m, SCRIPT_BLOCK, r); + r = consumeToken(b, UNQUOTED_TEXT); + exit_section_(b, m, RELATIONSHIP_DESTINATION, r); return r; } - // argument* - private static boolean scriptBlock_1(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "scriptBlock_1")) return false; - while (true) { - int c = current_position_(b); - if (!argument(b, l + 1)) break; - if (!empty_element_parsed_guard_(b, "scriptBlock_1", c)) break; - } - return true; + /* ********************************************************** */ + // ARROW + public static boolean relationshipKeyword(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "relationshipKeyword")) return false; + if (!nextTokenIs(b, ARROW)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeToken(b, ARROW); + exit_section_(b, m, RELATIONSHIP_KEYWORD, r); + return r; } /* ********************************************************** */ - // SCRIPT_TEXT+ - public static boolean scriptContents(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "scriptContents")) return false; - if (!nextTokenIs(b, SCRIPT_TEXT)) return false; + // UNQUOTED_TEXT + public static boolean relationshipSource(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "relationshipSource")) return false; + if (!nextTokenIs(b, UNQUOTED_TEXT)) return false; boolean r; Marker m = enter_section_(b); - r = consumeToken(b, SCRIPT_TEXT); - while (r) { - int c = current_position_(b); - if (!consumeToken(b, SCRIPT_TEXT)) break; - if (!empty_element_parsed_guard_(b, "scriptContents", c)) break; - } - exit_section_(b, m, SCRIPT_CONTENTS, r); + r = consumeToken(b, UNQUOTED_TEXT); + exit_section_(b, m, RELATIONSHIP_SOURCE, r); return r; } /* ********************************************************** */ - // identifierAssignment? keywordWithArguments lf_eof - public static boolean singleLineStatement(PsiBuilder b, int l) { - if (!recursion_guard_(b, l, "singleLineStatement")) return false; + // '{' SCRIPT_TEXT '}' + public static boolean scriptBlock(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "scriptBlock")) return false; + if (!nextTokenIs(b, BRACE1)) return false; + boolean r; + Marker m = enter_section_(b); + r = consumeTokens(b, 0, BRACE1, SCRIPT_TEXT, BRACE2); + exit_section_(b, m, SCRIPT_BLOCK, r); + return r; + } + + /* ********************************************************** */ + // '!script' + public static boolean scriptKeyword(PsiBuilder b, int l) { + if (!recursion_guard_(b, l, "scriptKeyword")) return false; + boolean r; + Marker m = enter_section_(b, l, _NONE_, SCRIPT_KEYWORD, "