blob: 701015ec6aa5fc0cf5fa7eed2401e112c7a02c0b [file] [log] [blame]
{
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
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)