@@ -254,11 +254,19 @@ engine.TypeSpecifier = function(ctx, parentData, node) {
254
254
} ;
255
255
256
256
engine . ExternalConstantTerm = function ( ctx , parentData , node ) {
257
- var extConstant = node . children [ 0 ] ;
258
- var identifier = extConstant . children [ 0 ] ;
259
- var varName = engine . Identifier ( ctx , parentData , identifier ) [ 0 ] ;
257
+ let varName ;
258
+ const extConstant = node . children [ 0 ] ;
259
+ // externalConstant(variable name) is defined in the grammar as:
260
+ // '%' ( identifier | STRING )
261
+ if ( extConstant . terminalNodeText . length === 2 ) {
262
+ // if the variable name is a STRING
263
+ varName = getStringLiteralVal ( extConstant . terminalNodeText [ 1 ] ) ;
264
+ } else {
265
+ // otherwise, it is an identifier
266
+ varName = getIdentifierVal ( extConstant . children [ 0 ] . text ) ;
267
+ }
260
268
261
- var value ;
269
+ let value ;
262
270
// Check the user-defined environment variables first as the user can override
263
271
// the "context" variable like we do in unit tests. In this case, the user
264
272
// environment variable can replace the system environment variable in "processedVars".
@@ -315,28 +323,36 @@ engine.LiteralTerm = function(ctx, parentData, node) {
315
323
} ;
316
324
317
325
engine . StringLiteral = function ( ctx , parentData , node ) {
318
- // Remove the beginning and ending quotes.
319
- var rtn = node . text . replace ( / ( ^ ' | ' $ ) / g, "" ) ;
320
- rtn = rtn . replace ( / \\ ( u \d { 4 } | .) / g, function ( match , submatch ) {
321
- switch ( match ) {
322
- case '\\r' :
323
- return '\r' ;
324
- case '\\n' :
325
- return "\n" ;
326
- case '\\t' :
327
- return '\t' ;
328
- case '\\f' :
329
- return '\f' ;
330
- default :
331
- if ( submatch . length > 1 )
332
- return String . fromCharCode ( '0x' + submatch . slice ( 1 ) ) ;
333
- else
334
- return submatch ;
335
- }
336
- } ) ;
337
- return [ rtn ] ;
326
+ return [ getStringLiteralVal ( node . text ) ] ;
338
327
} ;
339
328
329
+ /**
330
+ * Removes the beginning and ending single-quotes and replaces string escape
331
+ * sequences.
332
+ * @param {string } str - string literal
333
+ * @return {string }
334
+ */
335
+ function getStringLiteralVal ( str ) {
336
+ return str . replace ( / ( ^ ' | ' $ ) / g, "" )
337
+ . replace ( / \\ ( u \d { 4 } | .) / g, function ( match , submatch ) {
338
+ switch ( match ) {
339
+ case '\\r' :
340
+ return '\r' ;
341
+ case '\\n' :
342
+ return "\n" ;
343
+ case '\\t' :
344
+ return '\t' ;
345
+ case '\\f' :
346
+ return '\f' ;
347
+ default :
348
+ if ( submatch . length > 1 )
349
+ return String . fromCharCode ( '0x' + submatch . slice ( 1 ) ) ;
350
+ else
351
+ return submatch ;
352
+ }
353
+ } ) ;
354
+ }
355
+
340
356
engine . BooleanLiteral = function ( ctx , parentData , node ) {
341
357
if ( node . text === "true" ) {
342
358
return [ true ] ;
@@ -372,9 +388,18 @@ engine.NumberLiteral = function(ctx, parentData, node) {
372
388
} ;
373
389
374
390
engine . Identifier = function ( ctx , parentData , node ) {
375
- return [ node . text . replace ( / ( ^ ` | ` $ ) / g , "" ) ] ;
391
+ return [ getIdentifierVal ( node . text ) ] ;
376
392
} ;
377
393
394
+ /**
395
+ * Removes the beginning and ending back-quotes.
396
+ * @param {string } str - identifier string
397
+ * @return {string }
398
+ */
399
+ function getIdentifierVal ( str ) {
400
+ return str . replace ( / ( ^ ` | ` $ ) / g, "" ) ;
401
+ }
402
+
378
403
engine . InvocationTerm = function ( ctx , parentData , node ) {
379
404
return engine . doEval ( ctx , parentData , node . children [ 0 ] ) ;
380
405
} ;
0 commit comments