Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
478 lines (449 sloc) 8.5 KB
// node node_modules/.bin/jacob -t Dockerfile.jacoblex -l dockerlex.js
%moduleName DockerfileLexer
%%
directive = (FROM|MAINTAINER|ENV|ARG|ADD|ENTRYPOINT|EXPOSE|RUN|CMD|COPY|ENTRYPOINT|VOLUME|USER|WORKDIR|ONBUILD|LABEL|STOPSIGNAL)
%%
/********************************************************************
* Eat Comments in default state
*/
<>#.* {
return 'COMMENT';
}
/********************************************************************
* Parse quoted strings
*/
<STARTQUOTEDSTRING>["'] {
this.quote = this.jjtext;
this.popState();
this.pushState('QUOTEDSTRING');
return null;
}
<QUOTEDSTRING>["'] {
if (this.jjtext !== this.quote) {
return (this.stringAs || 'STRING');
}
this.quote = null;
this.stringAs = null;
this.popState();
var s = this.getState();
if (!this.input.more()) {
if (s.match(/^(ENV|ARG|LABEL)$/)) {
this.popState();
}
}
return null;
}
<QUOTEDSTRING>(\n|\r|\\.|.) {
if (!this.input.more() && this.jjtext != '\\') {
this.popState();
//return 'ERROR';
}
return (this.stringAs || 'STRING');
}
/********************************************************************
* Parse unquoted strings, supporting escaped new-lines and comments
*/
<UNQUOTEDSTRING>#.* { // comment
this.popState();
this.stringAs = null;
var s = this.getState();
if (s.match(/^(ENV|ARG)$/)) {
this.popState();
}
return 'COMMENT';
}
<UNQUOTEDSTRING>\\ { // escaped eol, continue string
return (this.stringAs || 'STRING');
}
<UNQUOTEDSTRING>[^\\#]+|\\. {
var tok = (this.stringAs || 'STRING');
if (!this.input.more()) {
this.popState();
this.stringAs = null;
var s = this.getState();
if (s.match(/^(ENV|ARG)$/)) {
this.popState();
}
}
return tok;
}
/********************************************************************
* Parse unquoted strings, up to whitespace, supporting escaped
* new-lines and comments
*/
<UNQUOTEDSTRING2SPACE>#.* { // comment
this.popState();
this.stringAs = null;
var s = this.getState();
if (s.match(/^(ENV|ARG)$/)) {
this.popState();
}
return 'COMMENT';
}
<UNQUOTEDSTRING2SPACE>\\ { // escaped eol, continue string
return (this.stringAs || 'STRING');
}
<UNQUOTEDSTRING2SPACE>[^\\#]|\\. {
var tok = (this.stringAs || 'STRING');
if (!this.input.more()) {
this.popState();
this.stringAs = null;
var s = this.getState();
if (s.match(/^(ENV|ARG)$/)) {
this.popState();
}
}
if (this.jjtext.match(/^[ \t]$/)) {
this.less(1);
this.popState();
this.stringAs = null;
var s = this.getState();
}
return tok;
}
/********************************************************************
* ENV directive
*/
<ENV>\s+ {
if (this.input.more()) {
this.pushState('ENVDEF');
} else {
this.popState()
}
return null;
}
<ENV>\s*#.* {
this.popState();
return 'COMMENT';
}
<ENV>\\. {
this.popState();
return 'ERROR';
}
<ENV>\\ {
return null;
}
<ENV>. {
this.less(1);
if (!this.input.sol()) {
this.popState();
return 'ERROR';
}
this.pushState('ENVDEF');
return null;
}
<ENVDEF>\w+ {
this.popState();
if (this.input.more()) {
this.pushState('ENVASSIGN');
} else {
// pop out of ENV
this.popState();
}
return 'DEF';
}
<ENVDEF>. {
this.less(1);
this.popState();
return 'ERROR';
}
<ENVASSIGN>\s*=\s* {
this.popState();
if (this.input.more()) {
this.pushState('ENVVAL');
} else {
// pop out of ENV
this.popState();
}
return null;
}
<ENVASSIGN>\s+ {
this.popState();
if (this.input.more()) {
this.pushState('UNQUOTEDSTRING');
} else {
// pop out of ENV
this.popState();
}
return null;
}
<ENVASSIGN>. {
return 'ERROR';
}
<ENVVAL>["'] {
this.less(1);
this.popState();
this.pushState('STARTQUOTEDSTRING');
return null;
}
<ENVVAL>[^"'] {
this.less(1);
this.popState();
this.pushState('UNQUOTEDSTRING2SPACE');
return 'STRING';
}
/********************************************************************
* ARG directive
*/
<ARG>\s+ {
if (this.input.more()) {
this.pushState('ARGDEF');
} else {
this.popState()
}
return null;
}
<ARG>\s*#.* {
this.popState();
return 'COMMENT';
}
<ARG>\\. {
this.popState();
return 'ERROR';
}
<ARG>\\ {
return null;
}
<ARG>. {
this.less(1);
if (!this.input.sol()) {
this.popState();
return 'ERROR';
}
this.pushState('ARGDEF');
return null;
}
<ARGDEF>\w+ {
this.popState();
if (this.input.more()) {
this.pushState('ARGASSIGN');
} else {
// pop out of ARG
this.popState();
}
return 'DEF';
}
<ARGDEF>. {
this.less(1);
this.popState();
return 'ERROR';
}
<ARGASSIGN>\s*=\s* {
this.popState();
if (this.input.more()) {
this.pushState('ARGVAL');
} else {
// pop out of ARG
this.popState();
}
return null;
}
<ARGASSIGN>\s+ {
this.popState();
if (this.input.more()) {
this.pushState('UNQUOTEDSTRING');
} else {
// pop out of ARG
this.popState();
}
return null;
}
<ARGASSIGN>. {
return 'ERROR';
}
<ARGVAL>["'] {
this.less(1);
this.popState();
this.pushState('STARTQUOTEDSTRING');
return null;
}
<ARGVAL>[^"'] {
this.less(1);
this.popState();
this.pushState('UNQUOTEDSTRING2SPACE');
return 'STRING';
}
/********************************************************************
* LABEL directive
*/
<LABEL>\s+ {
if (this.input.more()) {
this.pushState('LABELDEF');
} else {
this.popState()
}
return null;
}
<LABEL>\s*#.* {
this.popState();
return 'COMMENT';
}
<LABEL>\\. {
this.popState();
return 'ERROR';
}
<LABEL>\\ {
return null;
}
<LABEL>. {
this.less(1);
if (!this.input.sol()) {
this.popState();
return 'ERROR';
}
this.pushState('LABELDEF');
return null;
}
<LABELDEF>[\w\.\-]+ {
this.popState();
if (this.input.more()) {
this.pushState('LABELASSIGN');
} else {
// pop out of LABEL
this.popState();
}
return 'DEF';
}
<LABELDEF>['"] {
this.less(1);
this.stringAs = 'def';
this.popState();
this.pushState('LABELASSIGN');
this.pushState('STARTQUOTEDSTRING');
return null;
}
<LABELDEF>. {
this.less(1);
this.popState();
return 'ERROR';
}
<LABELASSIGN>\s*=\s* {
this.popState();
if (this.input.more()) {
this.pushState('LABELVAL');
} else {
// pop out of LABEL
this.popState();
}
return null;
}
<LABELASSIGN>\s+ {
this.popState();
if (this.input.more()) {
this.pushState('UNQUOTEDSTRING');
} else {
// pop out of LABEL
this.popState();
}
return null;
}
<LABELASSIGN>. {
return 'ERROR';
}
<LABELVAL>["'] {
this.less(1);
this.popState();
this.pushState('STARTQUOTEDSTRING');
return null;
}
<LABELVAL>[^"'] {
this.less(1);
this.popState();
this.pushState('UNQUOTEDSTRING2SPACE');
return 'STRING';
}
/********************************************************************
* EXPOSE directive
*/
<EXPOSE>\s+ {
if (this.input.more()) {
this.pushState('EXPOSEDEF');
}
return null;
}
<EXPOSE>\s*#.* {
this.popState();
return 'COMMENT';
}
<EXPOSE>. {
this.less(1);
this.popState();
return 'ERROR';
}
<EXPOSEDEF>[\w${}]+ {
this.popState();
return 'EXPOSE';
}
<EXPOSEDEF>. {
this.less(1);
this.popState();
this.popState();
return 'ERROR';
}
/********************************************************************
* STOPSIGNAL directive
*/
<STOPSIGNAL>\s+ {
if (this.input.more()) {
this.pushState('STOPSIGNALDEF');
}
return null;
}
<STOPSIGNAL>\s*#.* {
this.popState();
return 'COMMENT';
}
<STOPSIGNAL>. {
this.less(1);
this.popState();
return 'ERROR';
}
<STOPSIGNALDEF>\w+ {
this.popState();
return 'STOPSIGNAL';
}
<STOPSIGNALDEF>. {
this.less(1);
this.popState();
this.popState();
return 'ERROR';
}
/********************************************************************
* Match all directives and enter respective states
*/
<>{directive} {
var d = this.jjtext.match(/(\w+)/)[1];
this.jjval = d;
if (d.match(/RUN|CMD/i)) {
this.localMode = this.bashMode;
this.localState = this.bashMode.startState();
} else if (d.match(/ONBUILD/)) {
this.popState();
} else {
if (d.match(/FROM|MAINTAINER|EXPOSE|STOPSIGNAL/i)) {
this.stringAs = d.toLowerCase();
} else {
this.stringAs = null;
}
if (!d.match(/ENV|ARG|LABEL|EXPOSE|STOPSIGNAL/i)) {
d = 'DOCKDIR';
}
this.pushState(d.toUpperCase());
}
return 'DOCKDIR';
}
<DOCKDIR>\s+ {
this.jjval = this.jjtext.trim();
this.popState();
this.pushState('UNQUOTEDSTRING');
return null;
}
<DOCKDIR>. {
return 'ERROR';
}
// Catchalls
<>\s+ {
} // remaining whitespace
<>. {
return 'ERROR';
} // anything else unexpected