2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
42
package org.netbeans.modules.languages;
44
import java.util.ArrayList;
45
import java.util.Arrays;
46
import java.util.Collections;
47
import java.util.HashMap;
48
import java.util.HashSet;
49
import java.util.Iterator;
50
import java.util.List;
54
import org.netbeans.api.languages.ParseException;
55
import org.netbeans.api.languages.ASTToken;
56
import org.netbeans.api.languages.ParseException;
57
import org.netbeans.modules.languages.parser.LLSyntaxAnalyser;
58
import org.netbeans.modules.languages.parser.Parser;
59
import org.netbeans.modules.languages.parser.Pattern;
66
public class NBSLanguage {
68
static final String NBS_MIME_TYPE = "text/x-nbs";
70
public static int WHITESPACE_ID;
71
public static int COMMENT_ID;
72
public static int IDENTIFIER_ID;
75
private static Language nbsLanguage;
77
static Language getNBSLanguage () {
78
if (nbsLanguage == null) {
80
List<TokenType> tokenTypes = new ArrayList<TokenType> ();
81
tokenTypes.add (new TokenType (
103
"'SEMANTIC_CONTEXT' | " +
104
"'SEMANTIC_DECLARATION' | " +
105
"'SEMANTIC_USAGE' | " +
116
tokenTypes.add (new TokenType (
119
"['a'-'z' 'A'-'Z'] ['a'-'z' 'A'-'Z' '0'-'9' '_']*"
127
tokenTypes.add (new TokenType (
130
"':' | '*' | '?' | '+' | '-' | '[' | ']' | '<' | " +
131
"'>' | '^' | '|' | '{' | '}' | '(' | ')' | ',' | " +
132
"'=' | ';' | '.' | '$'"
140
tokenTypes.add (new TokenType (
145
"[^'\\\"' '\\\\' '\\r' '\\n'] |" +
146
"('\\\\' ['r' 'n' 't' '\\\\' '\\\'' '\\\"']) |" +
147
"('\\\\' 'u' ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'])" +
157
tokenTypes.add (new TokenType (
162
"[^'\\\'' '\\\\' '\\r' '\\n'] |" +
163
"('\\\\' ['r' 'n' 't' '\\\\' '\\\'' '\\\"']) |" +
164
"('\\\\' 'u' ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'] ['0'-'9' 'a'-'f' 'A'-'F'])" +
174
tokenTypes.add (new TokenType (
176
Pattern.create ("'#' [^'\\n' '\\r']* ['\\n' '\\r']+"),
183
tokenTypes.add (new TokenType (
185
Pattern.create ("'/#' - '#/'"),
192
tokenTypes.add (new TokenType (
194
Pattern.create ("['\\n' '\\r' ' ' '\\t']+"),
202
Map<Integer,String> tokensMap = new HashMap<Integer,String> ();
203
Iterator<TokenType> it = tokenTypes.iterator ();
204
while (it.hasNext ()) {
205
TokenType tokenType = it.next ();
206
tokensMap.put (tokenType.getTypeID (), tokenType.getType ());
208
nbsLanguage = Language.create (
211
Collections.<Feature>emptyList (),
212
Parser.create (tokenTypes)
215
int OPERATOR_ID = nbsLanguage.getTokenID ("operator");
216
ASTToken COLON = ASTToken.create (nbsLanguage, OPERATOR_ID, ":", 0);
217
ASTToken PARENTHESIS = ASTToken.create (nbsLanguage, OPERATOR_ID, "(", 0);
218
ASTToken PARENTHESIS2 = ASTToken.create (nbsLanguage, OPERATOR_ID, ")", 0);
219
ASTToken BRACE = ASTToken.create (nbsLanguage, OPERATOR_ID, "{", 0);
220
ASTToken BRACE2 = ASTToken.create (nbsLanguage, OPERATOR_ID, "}", 0);
221
ASTToken LT = ASTToken.create (nbsLanguage, OPERATOR_ID, "<", 0);
222
ASTToken GT = ASTToken.create (nbsLanguage, OPERATOR_ID, ">", 0);
223
ASTToken DOT = ASTToken.create (nbsLanguage, OPERATOR_ID, ".", 0);
224
ASTToken PLUS = ASTToken.create (nbsLanguage, OPERATOR_ID, "+", 0);
225
ASTToken QUESTION = ASTToken.create (nbsLanguage, OPERATOR_ID, "?", 0);
226
ASTToken MULTIPLY = ASTToken.create (nbsLanguage, OPERATOR_ID, "*", 0);
227
ASTToken OR = ASTToken.create (nbsLanguage, OPERATOR_ID, "|", 0);
228
ASTToken MINUS = ASTToken.create (nbsLanguage, OPERATOR_ID, "-", 0);
229
ASTToken BRACKET = ASTToken.create (nbsLanguage, OPERATOR_ID, "[", 0);
230
ASTToken BRACKET2 = ASTToken.create (nbsLanguage, OPERATOR_ID, "]", 0);
231
ASTToken UPP = ASTToken.create (nbsLanguage, OPERATOR_ID, "^", 0);
232
ASTToken EQUAL = ASTToken.create (nbsLanguage, OPERATOR_ID, "=", 0);
233
ASTToken SEMICOLON = ASTToken.create (nbsLanguage, OPERATOR_ID, ";", 0);
234
ASTToken COMMA = ASTToken.create (nbsLanguage, OPERATOR_ID, ",", 0);
235
int KEYWORD_ID = nbsLanguage.getTokenID ("keyword");
236
ASTToken KEYWORD = ASTToken.create (nbsLanguage, KEYWORD_ID, null, 0);
237
ASTToken KEYWORD_TOKEN = ASTToken.create (nbsLanguage, KEYWORD_ID, "TOKEN", 0);
238
IDENTIFIER_ID = nbsLanguage.getTokenID ("identifier");
239
ASTToken IDENTIFIER = ASTToken.create (nbsLanguage, IDENTIFIER_ID, null, 0);
240
ASTToken IDENTIFIER_I = ASTToken.create (nbsLanguage, IDENTIFIER_ID, "i", 0);
241
int STRING_ID = nbsLanguage.getTokenID ("string");
242
ASTToken STRING = ASTToken.create (nbsLanguage, STRING_ID, null, 0);
243
WHITESPACE_ID = nbsLanguage.getTokenID ("whitespace");
244
COMMENT_ID = nbsLanguage.getTokenID ("comment");
246
List<Rule> rules = new ArrayList<Rule> ();
247
rules.add (rule ("S", new Object[] {"token", "S"}));
248
rules.add (rule ("S", new Object[] {"tokenState", "S"}));
249
rules.add (rule ("S", new Object[] {"grammarRule", "S"}));
250
rules.add (rule ("S", new Object[] {"command", "S"}));
251
rules.add (rule ("S", new Object[] {}));
253
rules.add (rule ("tokenState", new Object[] {"state", "tokenState1"}));
254
rules.add (rule ("tokenState1", new Object[] {COLON, "token"}));
255
rules.add (rule ("tokenState1", new Object[] {BRACE, "tokenGroup"}));
256
rules.add (rule ("token", new Object[] {KEYWORD_TOKEN, COLON, IDENTIFIER, COLON, "token2"}));
257
rules.add (rule ("token2", new Object[] {PARENTHESIS, "regularExpression", PARENTHESIS2, "token3"}));
258
rules.add (rule ("token2", new Object[] {BRACE, "properties", BRACE2}));
259
rules.add (rule ("token3", new Object[] {COLON, "state"}));
260
rules.add (rule ("token3", new Object[] {}));
261
rules.add (rule ("state", new Object[] {LT, IDENTIFIER, GT}));
262
rules.add (rule ("tokenGroup", new Object[] {"tokensInGroup", BRACE2}));
263
rules.add (rule ("tokensInGroup", new Object[] {"token", "tokensInGroup"}));
264
rules.add (rule ("tokensInGroup", new Object[] {}));
266
rules.add (rule ("regularExpression", new Object[] {"reChoice", "regularExpression1"}));
267
rules.add (rule ("regularExpression1", new Object[] {OR, "reChoice", "regularExpression1"}));
268
rules.add (rule ("regularExpression1", new Object[] {}));
269
rules.add (rule ("reChoice", new Object[] {"rePart", "reChoice1"}));
270
rules.add (rule ("reChoice1", new Object[] {"rePart", "reChoice1"}));
271
rules.add (rule ("reChoice1", new Object[] {}));
272
rules.add (rule ("rePart", new Object[] {STRING, "rePartOperatorOrMinus"}));
273
rules.add (rule ("rePart", new Object[] {STRING, IDENTIFIER_I, "rePartOperatorOrMinus"}));
274
rules.add (rule ("rePart", new Object[] {DOT, "rePartOperator"}));
275
rules.add (rule ("rePart", new Object[] {"reClass", "rePartOperator"}));
276
rules.add (rule ("rePart", new Object[] {PARENTHESIS, "regularExpression", PARENTHESIS2, "rePartOperator"}));
277
rules.add (rule ("rePartOperator", new Object[] {}));
278
rules.add (rule ("rePartOperator", new Object[] {PLUS}));
279
rules.add (rule ("rePartOperator", new Object[] {QUESTION}));
280
rules.add (rule ("rePartOperator", new Object[] {MULTIPLY}));
281
rules.add (rule ("rePartOperatorOrMinus", new Object[] {MINUS, STRING}));
282
rules.add (rule ("rePartOperatorOrMinus", new Object[] {"rePartOperator"}));
283
rules.add (rule ("reClass", new Object[] {BRACKET, "reInClassNegation", "reInClass", BRACKET2}));
284
rules.add (rule ("reInClassNegation", new Object[] {UPP}));
285
rules.add (rule ("reInClassNegation", new Object[] {}));
286
rules.add (rule ("reInClass", new Object[] {STRING, "reInClassMinus", "reInClass1"}));
287
rules.add (rule ("reInClass1", new Object[] {STRING, "reInClassMinus", "reInClass1"}));
288
rules.add (rule ("reInClass1", new Object[] {}));
289
rules.add (rule ("reInClassMinus", new Object[] {MINUS, STRING}));
290
rules.add (rule ("reInClassMinus", new Object[] {}));
292
rules.add (rule ("grammarRule", new Object[] {IDENTIFIER, EQUAL, "grRightSide", SEMICOLON}));
293
rules.add (rule ("grRightSide", new Object[] {"grChoice", "grRightSide1"}));
294
rules.add (rule ("grRightSide1", new Object[] {OR, "grChoice", "grRightSide1"}));
295
rules.add (rule ("grRightSide1", new Object[] {}));
296
rules.add (rule ("grChoice", new Object[] {"grPart", "grChoice"}));
297
rules.add (rule ("grChoice", new Object[] {}));
298
rules.add (rule ("grPart", new Object[] {IDENTIFIER, "grOperator"}));
299
rules.add (rule ("grPart", new Object[] {"tokenDef", "grOperator"}));
300
rules.add (rule ("grPart", new Object[] {STRING, "grOperator"}));
301
rules.add (rule ("grPart", new Object[] {BRACKET, "grRightSide", BRACKET2}));
302
rules.add (rule ("grPart", new Object[] {PARENTHESIS, "grRightSide", PARENTHESIS2, "grOperator"}));
303
rules.add (rule ("grOperator", new Object[] {PLUS}));
304
rules.add (rule ("grOperator", new Object[] {MULTIPLY}));
305
rules.add (rule ("grOperator", new Object[] {QUESTION}));
306
rules.add (rule ("grOperator", new Object[] {}));
307
rules.add (rule ("tokenDef", new Object[] {LT, IDENTIFIER, "tokenDef1", GT}));
308
rules.add (rule ("tokenDef1", new Object[] {COMMA, STRING}));
309
rules.add (rule ("tokenDef1", new Object[] {}));
311
rules.add (rule ("command", new Object[] {KEYWORD, "command0"}));
312
rules.add (rule ("command0", new Object[] {COLON, "selector", "command1"}));
313
rules.add (rule ("command0", new Object[] {"value"}));
314
rules.add (rule ("command1", new Object[] {COLON, "value"}));
315
rules.add (rule ("command1", new Object[] {}));
316
rules.add (rule ("value", new Object[] {"class"}));
317
rules.add (rule ("value", new Object[] {STRING}));
318
rules.add (rule ("value", new Object[] {BRACE, "properties", BRACE2}));
319
rules.add (rule ("value", new Object[] {PARENTHESIS, "regularExpression", PARENTHESIS2}));
320
rules.add (rule ("properties", new Object[] {"property", "properties"}));
321
rules.add (rule ("properties", new Object[] {}));
322
rules.add (rule ("property", new Object[] {IDENTIFIER, COLON, "propertyValue", SEMICOLON}));
323
rules.add (rule ("propertyValue", new Object[] {STRING}));
324
rules.add (rule ("propertyValue", new Object[] {"class"}));
325
rules.add (rule ("propertyValue", new Object[] {PARENTHESIS, "regularExpression", PARENTHESIS2}));
326
rules.add (rule ("selector", new Object[] {"class", "selector1"}));
327
rules.add (rule ("selector1", new Object[] {COMMA, "class", "selector1"}));
328
rules.add (rule ("selector1", new Object[] {}));
329
rules.add (rule ("class", new Object[] {IDENTIFIER, "class1"}));
330
rules.add (rule ("class1", new Object[] {DOT, IDENTIFIER, "class1"}));
331
rules.add (rule ("class1", new Object[] {}));
333
Set<Integer> skipTokenIDs = new HashSet<Integer> ();
334
skipTokenIDs.add (nbsLanguage.getTokenID ("whitespace"));
335
skipTokenIDs.add (nbsLanguage.getTokenID ("comment"));
337
nbsLanguage.setAnalyser (LLSyntaxAnalyser.create (
338
nbsLanguage, rules, skipTokenIDs
340
} catch (ParseException ex) {
341
Utils.message (ex.getMessage ());
348
private static Rule rule (String nt, Object[] right) {
351
Arrays.asList (right)