extracted method to use in language plugins
[idea/community.git] / json / json.bnf
1 {
2   parserClass = 'com.intellij.json.JsonParser'
3   parserUtilClass = "com.intellij.json.psi.JsonParserUtil"
4   psiPackage = 'com.intellij.json.psi'
5   psiImplPackage = 'com.intellij.json.psi.impl'
6
7   elementTypeHolderClass = 'com.intellij.json.JsonElementTypes'
8   elementTypeClass = 'com.intellij.json.JsonElementType'
9   psiClassPrefix = "Json"
10   psiVisitorName = "JsonElementVisitor"
11
12   psiImplUtilClass = 'com.intellij.json.psi.impl.JsonPsiImplUtils'
13   tokenTypeClass = 'com.intellij.json.JsonTokenType'
14
15   implements("value") = "com.intellij.json.psi.JsonElement"
16   extends("value") = "com.intellij.json.psi.impl.JsonElementImpl"
17
18     tokens = [
19         L_CURLY='{'
20         R_CURLY='}'
21         L_BRACKET='['
22         R_BRACKET=']'
23
24         COMMA=','
25         COLON=':'
26         LINE_COMMENT='regexp://.*'
27         // "/*" ([^*]|\*+[^*/])* (\*+"/")?
28         BLOCK_COMMENT='regexp:/\*([^*]|\*+[^*/])*(\*+/)?'
29         // else /\*(?:[^*]|\*[^/])*\*+/
30
31         // unclosed string literal matches till the line's end
32         // any escape sequences included, illegal escapes are indicated by SyntaxHighlighter
33         // and JsonStringLiteralAnnotator
34         DOUBLE_QUOTED_STRING="regexp:\"([^\\\"\r\n]|\\[^\r\n])*\"?"
35         SINGLE_QUOTED_STRING="regexp:'([^\\\'\r\n]|\\[^\r\n])*'?"
36 //        STRING='regexp:"([^\\"\r\n]|\\([\\"/bfnrt]|u[a-fA-F0-9]{4}))*"?'
37
38         NUMBER='regexp:-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d*)?'
39         TRUE='true'
40         FALSE='false'
41         NULL='null'
42         // Actually not defined in RFC 4627, but may be used for JSON5 and helps with
43         // auto completion of keywords.
44         IDENTIFIER='regexp:[:jletter:] [:jletterdigit:]*'
45     ]
46
47     extends("container|literal|reference_expression")=value
48     extends("array|object")=container
49     extends("string_literal|number_literal|boolean_literal|null_literal")=literal
50     implements("property")=[
51       "com.intellij.json.psi.JsonElement"
52       "com.intellij.psi.PsiNamedElement"
53     ]
54 }
55
56 // For compatibility we allow any value at root level (see JsonStandardComplianceAnnotator)
57 json ::= value+
58
59 object ::= '{' object_element* '}' {
60   pin=1
61   methods=[
62     findProperty
63     getPresentation
64   ]
65   mixin="com.intellij.json.psi.impl.JsonObjectMixin"
66 }
67
68 // Hackity-hack to parse array elements and properties even if separating commas are missing,
69 // TODO: Find out if there is any simpler way to do so in GrammarKit
70 private object_element ::= property (','|&'}') {
71   recoverWhile = not_brace_or_next_value
72   pin = 1
73 }
74
75 property ::= property_name (':' value) {
76   methods=[
77     getName
78     getNameElement
79     getValue
80     // suppress getValueList() accessor
81     value=""
82     getPresentation
83   ]
84   mixin="com.intellij.json.psi.impl.JsonPropertyMixin"
85   pin(".*")=1
86 }
87
88 private property_name ::= literal | reference_expression
89
90 array ::= '[' array_element* ']' {
91   methods=[
92     getPresentation
93   ]
94   pin=1
95 }
96
97 private array_element ::= value (','|&']') {
98   recoverWhile = not_bracket_or_next_value
99   pin=1
100 }
101
102 string_literal ::= SINGLE_QUOTED_STRING | DOUBLE_QUOTED_STRING {
103   methods=[
104     getTextFragments
105     getValue
106     SINGLE_QUOTED_STRING=""
107     DOUBLE_QUOTED_STRING=""
108   ]
109   mixin="com.intellij.json.psi.impl.JsonStringLiteralMixin"
110 }
111 number_literal ::= NUMBER {
112   methods=[
113     NUMBER=""
114     getValue
115   ]
116 }
117 boolean_literal ::= TRUE | FALSE {
118   methods=[
119     getValue
120   ]
121 }
122 null_literal ::= NULL
123
124 literal ::= string_literal | number_literal | boolean_literal | null_literal {
125   methods=[
126     isQuotedString
127   ]
128   mixin="com.intellij.json.psi.impl.JsonLiteralMixin"
129 }
130
131 fake container ::=
132
133 reference_expression ::= IDENTIFIER
134
135 value ::= object | array | literal | reference_expression
136
137 // Recoveries
138 private not_bracket_or_next_value ::= !(']'|value)
139 private not_brace_or_next_value ::= !('}'|value)