antlr3 1.6.3 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -24,8 +24,9 @@ lib/antlr3/template.rb
24
24
  lib/antlr3/dfa.rb
25
25
  lib/antlr3/profile.rb
26
26
  lib/antlr3/template/parameter.rb
27
- lib/antlr3/template/group-lexer.rb
28
- lib/antlr3/template/group-parser.rb
27
+ lib/antlr3/template/group-file.rb
28
+ lib/antlr3/template/group-file-parser.rb
29
+ lib/antlr3/template/group-file-lexer.rb
29
30
  lib/antlr3/tree/visitor.rb
30
31
  lib/antlr3/tree/debug.rb
31
32
  lib/antlr3/tree/wizard.rb
@@ -87,7 +88,6 @@ samples/ANTLRv3Grammar.g
87
88
  README.txt
88
89
  ANTLR-LICENSE.txt
89
90
  History.txt
90
- Manifest.txt
91
91
  java/antlr-full-3.2.1.jar
92
92
  java/RubyTarget.java
93
93
  Manifest.txt
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  [The "BSD licence"]
3
- Copyright (c) 2005 Martin Traverso
3
+ Copyright (c) 2010 Martin Traverso
4
4
  All rights reserved.
5
5
 
6
6
  Redistribution and use in source and binary forms, with or without
@@ -36,377 +36,387 @@ import org.antlr.stringtemplate.*;
36
36
  import org.antlr.tool.Grammar;
37
37
 
38
38
  public class RubyTarget
39
- extends Target
39
+ extends Target
40
40
  {
41
- public static final Set rubyKeywords =
42
- new HashSet() {
43
- {
44
- add("alias"); add("end"); add("retry");
45
- add("and"); add("ensure"); add("return");
46
- add("BEGIN"); add("false"); add("self");
47
- add("begin"); add("for"); add("super");
48
- add("break"); add("if"); add("then");
49
- add("case"); add("in"); add("true");
50
- add("class"); add("module"); add("undef");
51
- add("def"); add("next"); add("unless");
52
- add("defined"); add("nil"); add("until");
53
- add("do"); add("not"); add("when");
54
- add("else"); add("or"); add("while");
55
- add("elsif"); add("redo"); add("yield");
56
- add("END"); add("rescue");
57
- }
58
- };
59
-
60
- public class RubyRenderer
61
- implements AttributeRenderer
62
- {
63
- public String toString(Object o) {
64
- return o.toString();
65
- }
66
-
67
- public String toString(Object o, String formatName) {
68
- String idString = o.toString();
69
-
70
- if (idString.isEmpty()) return idString;
71
-
72
- if (formatName.equals("snakecase")) {
73
- return snakecase(idString);
74
- } else if (formatName.equals("camelcase")) {
75
- return camelcase(idString);
76
- } else if (formatName.equals("subcamelcase")) {
77
- return subcamelcase(idString);
78
- } else if (formatName.equals("constant")) {
79
- return constantcase(idString);
80
- } else if (formatName.equals("platform")) {
81
- return platform(idString);
82
- } else if (formatName.equals("lexerRule")) {
83
- return lexerRule(idString);
84
- } else if (formatName.equals("constantPath")) {
85
- return constantPath(idString);
86
- } else if (formatName.equals("label")) {
87
- return label(idString);
88
- } else if (formatName.equals("symbol")) {
89
- return symbol(idString);
90
- } else {
91
- throw new IllegalArgumentException("Unsupported format name");
92
- }
93
- }
94
- /** given an input string, which is presumed
95
- * to contain a word, which may potentially be camelcased,
96
- * and convert it to snake_case underscore style.
97
- *
98
- * algorithm --
99
- * iterate through the string with a sliding window 3 chars wide
100
- *
101
- * example -- aGUIWhatNot
102
- * c c+1 c+2 action
103
- * a G << 'a' << '_' // a lower-upper word edge
104
- * G U I << 'g'
105
- * U I W << 'w'
106
- * I W h << 'i' << '_' // the last character in an acronym run of uppers
107
- * W h << 'w'
108
- * ... and so on
109
- */
110
- private String snakecase(String value) {
111
- StringBuilder output_buffer = new StringBuilder();
112
- int l = value.length();
113
- int cliff = l - 1;
114
- char cur;
115
- char next;
116
- char peek;
117
-
118
- if (value.isEmpty()) return value;
119
- if (l == 1) return value.toLowerCase();
120
-
121
- for (int i = 0; i < cliff; i++) {
122
- cur = value.charAt(i);
123
- next = value.charAt(i + 1);
124
-
125
- if ( Character.isLetter( cur ) ) {
126
- output_buffer.append( Character.toLowerCase( cur ) );
127
-
128
- if ( Character.isDigit( next ) || Character.isWhitespace( next ) ) {
129
- output_buffer.append( '_' );
130
- } else if ( Character.isLowerCase( cur ) && Character.isUpperCase( next ) ) {
131
- // at camelcase word edge
132
- output_buffer.append( '_' );
133
- } else if ( (i < cliff - 1) && Character.isUpperCase( cur ) && Character.isUpperCase( next ) ) {
134
- // cur is part of an acronym
135
-
136
- peek = value.charAt(i + 2);
137
- if ( Character.isLowerCase( peek ) ) {
138
- /* if next is the start of word (indicated when peek is lowercase)
139
- then the acronym must be completed by appending an underscore */
140
- output_buffer.append('_');
141
- }
142
- }
143
- } else if( Character.isDigit( cur ) ) {
144
- output_buffer.append( cur );
145
- if ( Character.isLetter( next ) ) {
146
- output_buffer.append('_');
147
- }
148
- } else if (Character.isWhitespace( cur )) {
149
- // do nothing
150
- } else {
151
- output_buffer.append( cur );
152
- }
153
-
154
- }
155
-
156
- cur = value.charAt(cliff);
157
- if (! Character.isWhitespace(cur) ) {
158
- output_buffer.append( Character.toLowerCase( cur ) );
159
- }
160
-
161
- return output_buffer.toString();
162
- }
163
- private String constantcase(String value) {
164
- return snakecase(value).toUpperCase();
165
- }
166
- private String platform(String value) {
167
- return ("__" + value + "__");
168
- }
169
- private String symbol(String value) {
170
- if (value.matches("[a-zA-Z_]\\w*[\\?\\!\\=]?")) {
171
- return (":" + value);
172
- } else {
173
- return ("%s(" + value + ")");
174
- }
175
- }
176
- private String lexerRule(String value) {
177
- if (value.equals("Tokens")) {
178
- return "token!";
179
- } else {
180
- return (snakecase(value) + "!");
181
- }
182
- }
183
- private String constantPath(String value) {
184
- return value.replaceAll("\\.", "::");
185
- }
186
- private String camelcase(String value) {
187
- StringBuilder output_buffer = new StringBuilder();
188
- int cliff = value.length();
189
- char cur;
190
- char next;
191
- boolean at_edge = true;
192
-
193
- if (value.isEmpty()) return value;
194
- if (cliff == 1) return value.toUpperCase();
195
-
196
- for (int i = 0; i < cliff; i++) {
197
- cur = value.charAt(i);
198
-
199
- if ( Character.isWhitespace( cur ) ) {
200
- at_edge = true;
201
- continue;
202
- } else if ( cur == '_' ) {
203
- at_edge = true;
204
- continue;
205
- } else if ( Character.isDigit( cur ) ) {
206
- output_buffer.append( cur );
207
- at_edge = true;
208
- continue;
209
- }
210
-
211
- if (at_edge) {
212
- output_buffer.append( Character.toUpperCase( cur ) );
213
- if ( Character.isLetter( cur ) ) at_edge = false;
214
- } else {
215
- output_buffer.append( cur );
216
- }
217
- }
218
-
219
- return output_buffer.toString();
220
- }
221
- private String label(String value) {
222
- if (rubyKeywords.contains(value)) {
223
- return platform(value);
224
- } else if (Character.isUpperCase(value.charAt(0)) &&
225
- (!value.equals("FILE")) &&
226
- (!value.equals("LINE"))) {
227
- return platform(value);
228
- } else if (value.equals("FILE")) {
229
- return "_FILE_";
230
- } else if (value.equals("LINE")) {
231
- return "_LINE_";
232
- } else {
233
- return value;
234
- }
235
- }
236
- private String subcamelcase(String value) {
237
- value = camelcase(value);
238
- if (value.isEmpty())
239
- return value;
240
- Character head = Character.toLowerCase( value.charAt(0) );
241
- String tail = value.substring(1);
242
- return head.toString().concat(tail);
243
- }
244
- }
245
-
246
- protected void genRecognizerFile(Tool tool,
247
- CodeGenerator generator,
248
- Grammar grammar,
249
- StringTemplate outputFileST)
250
- throws IOException
251
- {
252
- StringTemplateGroup group = generator.getTemplates();
253
- RubyRenderer renderer = new RubyRenderer();
254
- try {
255
- group.registerRenderer(Class.forName("java.lang.String"), renderer);
256
- } catch (ClassNotFoundException e) {
257
- // this shouldn't happen
258
- System.err.println("ClassNotFoundException: " + e.getMessage());
259
- e.printStackTrace(System.err);
260
- }
261
- String fileName =
262
- generator.getRecognizerFileName(grammar.name, grammar.type);
263
- generator.write(outputFileST, fileName);
264
- }
265
-
266
- public String getTargetCharLiteralFromANTLRCharLiteral(
267
- CodeGenerator generator,
268
- String literal)
269
- {
270
- literal = literal.substring(1, literal.length() - 1);
271
-
272
- String result = "?";
273
-
274
- if (literal.equals("\\")) {
275
- result += "\\\\";
276
- }
277
- else if (literal.equals(" ")) {
278
- result += "\\s";
279
- }
280
- else if (literal.startsWith("\\u")) {
281
- result = "0x" + literal.substring(2);
282
- }
283
- else {
284
- result += literal;
285
- }
286
-
287
- return result;
288
- }
289
-
290
- public int getMaxCharValue(CodeGenerator generator)
291
- {
292
- // Versions before 1.9 do not support unicode
293
- return 0xFF;
294
- }
295
-
296
- public String getTokenTypeAsTargetLabel(CodeGenerator generator, int ttype)
297
- {
298
- String name = generator.grammar.getTokenDisplayName(ttype);
299
- // If name is a literal, return the token type instead
300
- if ( name.charAt(0)=='\'' ) {
301
- return generator.grammar.computeTokenNameFromLiteral(ttype, name);
302
- }
303
- return name;
304
- }
305
-
306
- /** Is scope in @scope::name {action} valid for this kind of grammar?
307
- * Targets like C++ may want to allow new scopes like headerfile or
308
- * some such. The action names themselves are not policed at the
309
- * moment so targets can add template actions w/o having to recompile
310
- * ANTLR.
311
- */
312
- public boolean isValidActionScope(int grammarType, String scope) {
313
- switch (grammarType) {
314
- case Grammar.LEXER:
315
- if (scope.equals("lexer")) {
316
- return true;
317
- }
318
- if (scope.equals("token")) {
319
- return true;
320
- }
321
- if (scope.equals("module")) {
322
- return true;
323
- }
324
- if (scope.equals("overrides")) {
325
- return true;
326
- }
327
- break;
328
- case Grammar.PARSER:
329
- if (scope.equals("parser")) {
330
- return true;
331
- }
332
- if (scope.equals("token")) {
333
- return true;
334
- }
335
- if (scope.equals("module")) {
336
- return true;
337
- }
338
- if (scope.equals("overrides")) {
339
- return true;
340
- }
341
- break;
342
- case Grammar.COMBINED:
343
- if (scope.equals("parser")) {
344
- return true;
345
- }
346
- if (scope.equals("lexer")) {
347
- return true;
348
- }
349
- if (scope.equals("token")) {
350
- return true;
351
- }
352
- if (scope.equals("module")) {
353
- return true;
354
- }
355
- if (scope.equals("overrides")) {
356
- return true;
357
- }
358
- break;
359
- case Grammar.TREE_PARSER:
360
- if (scope.equals("treeparser")) {
361
- return true;
362
- }
363
- if (scope.equals("token")) {
364
- return true;
365
- }
366
- if (scope.equals("module")) {
367
- return true;
368
- }
369
- if (scope.equals("overrides")) {
370
- return true;
371
- }
372
- break;
373
- }
374
- return false;
375
- }
376
-
377
- /*
378
- public String getTargetStringLiteralFromString(String s)
41
+ /** A set of ruby keywords which are used to escape labels and method names
42
+ * which will cause parse errors in the ruby source
43
+ */
44
+ public static final Set rubyKeywords =
45
+ new HashSet() {
46
+ {
47
+ add( "alias" ); add( "END" ); add( "retry" );
48
+ add( "and" ); add( "ensure" ); add( "return" );
49
+ add( "BEGIN" ); add( "false" ); add( "self" );
50
+ add( "begin" ); add( "for" ); add( "super" );
51
+ add( "break" ); add( "if" ); add( "then" );
52
+ add( "case" ); add( "in" ); add( "true" );
53
+ add( "class" ); add( "module" ); add( "undef" );
54
+ add( "def" ); add( "next" ); add( "unless" );
55
+ add( "defined?" ); add( "nil" ); add( "until" );
56
+ add( "do" ); add( "not" ); add( "when" );
57
+ add( "else" ); add( "or" ); add( "while" );
58
+ add( "elsif" ); add( "redo" ); add( "yield" );
59
+ add( "end" ); add( "rescue" );
60
+ }
61
+ };
62
+
63
+ public static HashMap sharedActionBlocks = new HashMap();
64
+
65
+ public class RubyRenderer
66
+ implements AttributeRenderer
379
67
  {
380
- System.out.print(s + "\n");
381
- return super.getTargetStringLiteralFromString(s);
68
+ public String toString( Object o ) {
69
+ return o.toString();
70
+ }
71
+
72
+ public String toString( Object o, String formatName ) {
73
+ String idString = o.toString();
74
+
75
+ if ( idString.isEmpty() ) return idString;
76
+
77
+ if ( formatName.equals( "snakecase" ) ) {
78
+ return snakecase( idString );
79
+ } else if ( formatName.equals( "camelcase" ) ) {
80
+ return camelcase( idString );
81
+ } else if ( formatName.equals( "subcamelcase" ) ) {
82
+ return subcamelcase( idString );
83
+ } else if ( formatName.equals( "constant" ) ) {
84
+ return constantcase( idString );
85
+ } else if ( formatName.equals( "platform" ) ) {
86
+ return platform( idString );
87
+ } else if ( formatName.equals( "lexerRule" ) ) {
88
+ return lexerRule( idString );
89
+ } else if ( formatName.equals( "constantPath" ) ) {
90
+ return constantPath( idString );
91
+ } else if ( formatName.equals( "label" ) ) {
92
+ return label( idString );
93
+ } else if ( formatName.equals( "symbol" ) ) {
94
+ return symbol( idString );
95
+ } else {
96
+ throw new IllegalArgumentException( "Unsupported format name" );
97
+ }
98
+ }
99
+
100
+ /** given an input string, which is presumed
101
+ * to contain a word, which may potentially be camelcased,
102
+ * and convert it to snake_case underscore style.
103
+ *
104
+ * algorithm --
105
+ * iterate through the string with a sliding window 3 chars wide
106
+ *
107
+ * example -- aGUIWhatNot
108
+ * c c+1 c+2 action
109
+ * a G << 'a' << '_' // a lower-upper word edge
110
+ * G U I << 'g'
111
+ * U I W << 'w'
112
+ * I W h << 'i' << '_' // the last character in an acronym run of uppers
113
+ * W h << 'w'
114
+ * ... and so on
115
+ */
116
+ private String snakecase( String value ) {
117
+ StringBuilder output_buffer = new StringBuilder();
118
+ int l = value.length();
119
+ int cliff = l - 1;
120
+ char cur;
121
+ char next;
122
+ char peek;
123
+
124
+ if ( value.isEmpty() ) return value;
125
+ if ( l == 1 ) return value.toLowerCase();
126
+
127
+ for ( int i = 0; i < cliff; i++ ) {
128
+ cur = value.charAt( i );
129
+ next = value.charAt( i + 1 );
130
+
131
+ if ( Character.isLetter( cur ) ) {
132
+ output_buffer.append( Character.toLowerCase( cur ) );
133
+
134
+ if ( Character.isDigit( next ) || Character.isWhitespace( next ) ) {
135
+ output_buffer.append( '_' );
136
+ } else if ( Character.isLowerCase( cur ) && Character.isUpperCase( next ) ) {
137
+ // at camelcase word edge
138
+ output_buffer.append( '_' );
139
+ } else if ( ( i < cliff - 1 ) && Character.isUpperCase( cur ) && Character.isUpperCase( next ) ) {
140
+ // cur is part of an acronym
141
+
142
+ peek = value.charAt( i + 2 );
143
+ if ( Character.isLowerCase( peek ) ) {
144
+ /* if next is the start of word (indicated when peek is lowercase)
145
+ then the acronym must be completed by appending an underscore */
146
+ output_buffer.append( '_' );
147
+ }
148
+ }
149
+ } else if ( Character.isDigit( cur ) ) {
150
+ output_buffer.append( cur );
151
+ if ( Character.isLetter( next ) ) {
152
+ output_buffer.append( '_' );
153
+ }
154
+ } else if ( Character.isWhitespace( cur ) ) {
155
+ // do nothing
156
+ } else {
157
+ output_buffer.append( cur );
158
+ }
159
+
160
+ }
161
+
162
+ cur = value.charAt( cliff );
163
+ if ( ! Character.isWhitespace( cur ) ) {
164
+ output_buffer.append( Character.toLowerCase( cur ) );
165
+ }
166
+
167
+ return output_buffer.toString();
168
+ }
169
+
170
+ private String constantcase( String value ) {
171
+ return snakecase( value ).toUpperCase();
172
+ }
173
+
174
+ private String platform( String value ) {
175
+ return ( "__" + value + "__" );
176
+ }
177
+
178
+ private String symbol( String value ) {
179
+ if ( value.matches( "[a-zA-Z_]\\w*[\\?\\!\\=]?" ) ) {
180
+ return ( ":" + value );
181
+ } else {
182
+ return ( "%s(" + value + ")" );
183
+ }
184
+ }
185
+
186
+ private String lexerRule( String value ) {
187
+ // System.out.print( "lexerRule( \"" + value + "\") => " );
188
+ if ( value.equals( "Tokens" ) ) {
189
+ // System.out.println( "\"token!\"" );
190
+ return "token!";
191
+ } else {
192
+ // String result = snakecase( value ) + "!";
193
+ // System.out.println( "\"" + result + "\"" );
194
+ return ( snakecase( value ) + "!" );
195
+ }
196
+ }
197
+
198
+ private String constantPath( String value ) {
199
+ return value.replaceAll( "\\.", "::" );
200
+ }
201
+
202
+ private String camelcase( String value ) {
203
+ StringBuilder output_buffer = new StringBuilder();
204
+ int cliff = value.length();
205
+ char cur;
206
+ char next;
207
+ boolean at_edge = true;
208
+
209
+ if ( value.isEmpty() ) return value;
210
+ if ( cliff == 1 ) return value.toUpperCase();
211
+
212
+ for ( int i = 0; i < cliff; i++ ) {
213
+ cur = value.charAt( i );
214
+
215
+ if ( Character.isWhitespace( cur ) ) {
216
+ at_edge = true;
217
+ continue;
218
+ } else if ( cur == '_' ) {
219
+ at_edge = true;
220
+ continue;
221
+ } else if ( Character.isDigit( cur ) ) {
222
+ output_buffer.append( cur );
223
+ at_edge = true;
224
+ continue;
225
+ }
226
+
227
+ if ( at_edge ) {
228
+ output_buffer.append( Character.toUpperCase( cur ) );
229
+ if ( Character.isLetter( cur ) ) at_edge = false;
230
+ } else {
231
+ output_buffer.append( cur );
232
+ }
233
+ }
234
+
235
+ return output_buffer.toString();
236
+ }
237
+
238
+ private String label( String value ) {
239
+ if ( rubyKeywords.contains( value ) ) {
240
+ return platform( value );
241
+ } else if ( Character.isUpperCase( value.charAt( 0 ) ) &&
242
+ ( !value.equals( "FILE" ) ) &&
243
+ ( !value.equals( "LINE" ) ) ) {
244
+ return platform( value );
245
+ } else if ( value.equals( "FILE" ) ) {
246
+ return "_FILE_";
247
+ } else if ( value.equals( "LINE" ) ) {
248
+ return "_LINE_";
249
+ } else {
250
+ return value;
251
+ }
252
+ }
253
+
254
+ private String subcamelcase( String value ) {
255
+ value = camelcase( value );
256
+ if ( value.isEmpty() )
257
+ return value;
258
+ Character head = Character.toLowerCase( value.charAt( 0 ) );
259
+ String tail = value.substring( 1 );
260
+ return head.toString().concat( tail );
261
+ }
382
262
  }
383
263
 
384
- public String getTargetStringLiteralFromString(String s, boolean quoted)
264
+ protected void genRecognizerFile(
265
+ Tool tool,
266
+ CodeGenerator generator,
267
+ Grammar grammar,
268
+ StringTemplate outputFileST
269
+ ) throws IOException
385
270
  {
386
- // System.out.print(s + "\n");
387
- String ret_value = super.getTargetStringLiteralFromString(s, quoted);
388
- System.out.print(ret_value + "\n");
389
- return(ret_value);
271
+ /*
272
+ Below is an experimental attempt at providing a few named action blocks
273
+ that are printed in both lexer and parser files from combined grammars.
274
+ ANTLR appears to first generate a parser, then generate an independent lexer,
275
+ and then generate code from that. It keeps the combo/parser grammar object
276
+ and the lexer grammar object, as well as their respective code generator and
277
+ target instances, completely independent. So, while a bit hack-ish, this is
278
+ a solution that should work without having to modify Terrence Parr's
279
+ core tool code.
280
+
281
+ - sharedActionBlocks is a class variable containing a hash map
282
+ - if this method is called with a combo grammar, and the action map
283
+ in the grammar contains an entry for the named scope "all",
284
+ add an entry to sharedActionBlocks mapping the grammar name to
285
+ the "all" action map.
286
+ - if this method is called with an `implicit lexer'
287
+ (one that's extracted from a combo grammar), check to see if
288
+ there's an entry in sharedActionBlocks for the lexer's grammar name.
289
+ - if there is an action map entry, place it in the lexer's action map
290
+ - the recognizerFile template has code to place the
291
+ "all" actions appropriately
292
+
293
+ problems:
294
+ - This solution assumes that the parser will be generated
295
+ before the lexer. If that changes at some point, this will
296
+ not work.
297
+ - I have not investigated how this works with delegation yet
298
+
299
+ Kyle Yetter - March 25, 2010
300
+ */
301
+
302
+ if ( grammar.type == Grammar.COMBINED ) {
303
+ Map actions = grammar.getActions();
304
+ if ( actions.containsKey( "all" ) ) {
305
+ sharedActionBlocks.put( grammar.name, actions.get( "all" ) );
306
+ }
307
+ } else if ( grammar.implicitLexer ) {
308
+ if ( sharedActionBlocks.containsKey( grammar.name ) ) {
309
+ Map actions = grammar.getActions();
310
+ actions.put( "all", sharedActionBlocks.get( grammar.name ) );
311
+ }
312
+ }
313
+
314
+ StringTemplateGroup group = generator.getTemplates();
315
+ RubyRenderer renderer = new RubyRenderer();
316
+ try {
317
+ group.registerRenderer( Class.forName( "java.lang.String" ), renderer );
318
+ } catch ( ClassNotFoundException e ) {
319
+ // this shouldn't happen
320
+ System.err.println( "ClassNotFoundException: " + e.getMessage() );
321
+ e.printStackTrace( System.err );
322
+ }
323
+ String fileName =
324
+ generator.getRecognizerFileName( grammar.name, grammar.type );
325
+ generator.write( outputFileST, fileName );
390
326
  }
391
327
 
392
- public String getTarget64BitStringFromValue(long word)
328
+ public String getTargetCharLiteralFromANTLRCharLiteral(
329
+ CodeGenerator generator,
330
+ String literal
331
+ )
393
332
  {
394
- System.out.print(((Long)word).toString() + "\n");
395
- String result = super.getTarget64BitStringFromValue(word);
396
- System.out.print(result + "\n");
333
+ literal = literal.substring( 1, literal.length() - 1 );
334
+
335
+ String result = "?";
336
+
337
+ if ( literal.equals( "\\" ) ) {
338
+ result += "\\\\";
339
+ }
340
+ else if ( literal.equals( " " ) ) {
341
+ result += "\\s";
342
+ }
343
+ else if ( literal.startsWith( "\\u" ) ) {
344
+ result = "0x" + literal.substring( 2 );
345
+ }
346
+ else {
347
+ result += literal;
348
+ }
349
+
397
350
  return result;
398
351
  }
399
- */
400
-
401
- public String encodeIntAsCharEscape(final int v) {
402
- final int intValue;
403
-
404
- if ( v == 65535 ) {
405
- intValue = -1;
406
- } else {
407
- intValue = v;
408
- }
409
-
410
- return String.valueOf( intValue );
411
- }
352
+
353
+ public int getMaxCharValue( CodeGenerator generator )
354
+ {
355
+ // Versions before 1.9 do not support unicode
356
+ return 0xFF;
357
+ }
358
+
359
+ public String getTokenTypeAsTargetLabel( CodeGenerator generator, int ttype )
360
+ {
361
+ String name = generator.grammar.getTokenDisplayName( ttype );
362
+ // If name is a literal, return the token type instead
363
+ if ( name.charAt( 0 )=='\'' ) {
364
+ return generator.grammar.computeTokenNameFromLiteral( ttype, name );
365
+ }
366
+ return name;
367
+ }
368
+
369
+ public boolean isValidActionScope( int grammarType, String scope ) {
370
+ if ( scope.equals( "all" ) ) {
371
+ return true;
372
+ }
373
+ if ( scope.equals( "token" ) ) {
374
+ return true;
375
+ }
376
+ if ( scope.equals( "module" ) ) {
377
+ return true;
378
+ }
379
+ if ( scope.equals( "overrides" ) ) {
380
+ return true;
381
+ }
382
+
383
+ switch ( grammarType ) {
384
+ case Grammar.LEXER:
385
+ if ( scope.equals( "lexer" ) ) {
386
+ return true;
387
+ }
388
+ break;
389
+ case Grammar.PARSER:
390
+ if ( scope.equals( "parser" ) ) {
391
+ return true;
392
+ }
393
+ break;
394
+ case Grammar.COMBINED:
395
+ if ( scope.equals( "parser" ) ) {
396
+ return true;
397
+ }
398
+ if ( scope.equals( "lexer" ) ) {
399
+ return true;
400
+ }
401
+ break;
402
+ case Grammar.TREE_PARSER:
403
+ if ( scope.equals( "treeparser" ) ) {
404
+ return true;
405
+ }
406
+ break;
407
+ }
408
+ return false;
409
+ }
410
+
411
+ public String encodeIntAsCharEscape( final int v ) {
412
+ final int intValue;
413
+
414
+ if ( v == 65535 ) {
415
+ intValue = -1;
416
+ } else {
417
+ intValue = v;
418
+ }
419
+
420
+ return String.valueOf( intValue );
421
+ }
412
422
  }