{ parserClass = 'com.intellij.json.JsonParser' parserUtilClass = "com.intellij.json.psi.JsonParserUtil" psiPackage = 'com.intellij.json.psi' psiImplPackage = 'com.intellij.json.psi.impl' elementTypeHolderClass = 'com.intellij.json.JsonElementTypes' elementTypeClass = 'com.intellij.json.JsonElementType' psiClassPrefix = "Json" psiVisitorName = "JsonElementVisitor" psiImplUtilClass = 'com.intellij.json.psi.impl.JsonPsiImplUtils' tokenTypeClass = 'com.intellij.json.JsonTokenType' implements("value") = "com.intellij.json.psi.JsonElement" extends("value") = "com.intellij.json.psi.impl.JsonElementImpl" tokens = [ L_CURLY='{' R_CURLY='}' L_BRACKET='[' R_BRACKET=']' COMMA=',' COLON=':' LINE_COMMENT='regexp://.*' // "/*" ([^*]|\*+[^*/])* (\*+"/")? BLOCK_COMMENT='regexp:/\*([^*]|\*+[^*/])*(\*+/)?' // else /\*(?:[^*]|\*[^/])*\*+/ // unclosed string literal matches till the line's end // any escape sequences included, illegal escapes are indicated by SyntaxHighlighter // and JsonStringLiteralAnnotator DOUBLE_QUOTED_STRING="regexp:\"([^\\\"\r\n]|\\[^\r\n])*\"?" SINGLE_QUOTED_STRING="regexp:'([^\\\'\r\n]|\\[^\r\n])*'?" // STRING='regexp:"([^\\"\r\n]|\\([\\"/bfnrt]|u[a-fA-F0-9]{4}))*"?' NUMBER='regexp:-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d*)?' TRUE='true' FALSE='false' NULL='null' // Actually not defined in RFC 4627, but may be used for JSON5 and helps with // auto completion of keywords. Semantically, it represents "bad word" type // of tokens // Could be as loose as [^\s\[\]{}:,\"\']+, but is slightly more restricted // for the time being to match most forms of npm package names and semver versions // in package.json. // See https://github.com/npm/validate-npm-package-name IDENTIFIER="regexp:[[:jletterdigit:]~!()*\-./@\^<>=]+" ] extends("container|literal|reference_expression")=value extends("array|object")=container extends("string_literal|number_literal|boolean_literal|null_literal")=literal implements("property")=[ "com.intellij.json.psi.JsonElement" "com.intellij.psi.PsiNamedElement" ] } // For compatibility we allow any value at root level (see JsonStandardComplianceAnnotator) json ::= value+ object ::= '{' object_element* '}' { pin=1 methods=[ findProperty getPresentation ] mixin="com.intellij.json.psi.impl.JsonObjectMixin" } // Hackity-hack to parse array elements and properties even if separating commas are missing, // TODO: Find out if there is any simpler way to do so in GrammarKit private object_element ::= property (','|&'}') { recoverWhile = not_brace_or_next_value pin = 1 } property ::= property_name (':' value) { methods=[ getName getNameElement getValue // suppress getValueList() accessor value="" getPresentation ] mixin="com.intellij.json.psi.impl.JsonPropertyMixin" pin(".*")=1 } private property_name ::= literal | reference_expression array ::= '[' array_element* ']' { methods=[ getPresentation ] pin=1 } private array_element ::= value (','|&']') { recoverWhile = not_bracket_or_next_value pin=1 } string_literal ::= SINGLE_QUOTED_STRING | DOUBLE_QUOTED_STRING { methods=[ getTextFragments getValue isPropertyName SINGLE_QUOTED_STRING="" DOUBLE_QUOTED_STRING="" ] mixin="com.intellij.json.psi.impl.JsonStringLiteralMixin" } number_literal ::= NUMBER { methods=[ NUMBER="" getValue ] } boolean_literal ::= TRUE | FALSE { methods=[ getValue ] } null_literal ::= NULL literal ::= string_literal | number_literal | boolean_literal | null_literal { methods=[ isQuotedString ] mixin="com.intellij.json.psi.impl.JsonLiteralMixin" } fake container ::= reference_expression ::= IDENTIFIER value ::= object | array | literal | reference_expression // Recoveries private not_bracket_or_next_value ::= !(']'|value) private not_brace_or_next_value ::= !('}'|value)