Handling Hashbang/Shebang
In a Unix environment, a shell script often has its first line marked by a hashbang or a shebang, #!
. A common example is a utility intended to be executed by Node.js, which may look like the following:
- #!/usr/bin/env node
- console.log('Hello from Node.js!');
If Esprima parser is being used to process the content of the above file, the parser will throw an exception. This is because that hashbang is not valid in JavaScript. A quick Node.js REPL session to illustrate the point:
- $ node
- > var esprima = require('esprima')
- > var src = ['#!/usr/bin/env node', 'answer = 42'].join('\n')
- > esprima.parseScript(src)
- Error: Line 1: Unexpected token ILLEGAL
The workaround for this problem is to remove the first line completely before passing it to the parser. One way to do that is to use a regular expression, as shown below:
- $ node
- > var esprima = require('esprima')
- > var src = ['#!/usr/bin/env node', 'answer = 42'].join('\n')
- > src = src.replace(/^#!(.*\n)/, '')
- 'answer = 42'
- > esprima.parseScript(src)
- Script {
- type: 'Program',
- body: [ ExpressionStatement { type: 'ExpressionStatement', expression: [Object] } ],
- sourceType: 'script' }
Note that the above approach will shorten the source string. If the string length needs to be preserved, e.g. to facilitate an exact location mapping to the original version, then a series of whitespaces need to be padded to the beginning. A modified approach looks like the following:
- $ node
- > var esprima = require('esprima')
- > var src = ['#!/usr/bin/env node', 'answer = 42'].join('\n')
- > src = src.replace(/(^#!.*)/, function(m) { return Array(m.length + 1).join(' ') });
- > esprima.parseScript(src, { range: true })
- Script {
- type: 'Program',
- body:
- [ ExpressionStatement {
- type: 'ExpressionStatement',
- expression: [Object],
- range: [Object] } ],
- sourceType: 'script',
- range: [ 15, 26 ] }