我正在尝试编写一个可以识别dockerfile的语法 . (无上下文语法)长话短说,dockerfiles是由命令组成的文本文件 . 命令可以是单行或多行,并由其名称标识 .
最简单的dockerfile命令示例:
FROM anImageNameThatCanContainsPrettyMuchAnythingButWS
EXPOSE aNumber
有一些更复杂的命令,例如:
ADD aPath anotherPath
COPY aPath anotherPath
ENV aKey=aValue
这是 RUN
命令中最复杂的命令 . RUN
命令基本上可以是任何shell命令,因此可以是任何东西 . 我尝试实现的唯一一件事就是 &&
1174051 RUN
.
到目前为止我做了什么:
grammar Dockerfile;
dockerfile: ((COMMENT | command))+ EOF;
COMMENT
: ( '#' ~[\r\n]* '\r'? '\n'
| '/*' .*? '*/'
) -> skip
;
command: one_line | run;
one_line: (from | env | entrypoint | maintainer | workdir | add | copy | expose) (NEWLINE)*;
from: FROM ANYKEYS;
maintainer: MAINTAINER ANYKEYS ANYKEYS;
env: ENV ANYKEYS '=' ANYKEYS;
entrypoint: ENTRYPOINT ANYKEYS;
workdir: WORKDIR ANYKEYS;
add: ADD .*?;
copy: COPY src dest;
src: ANYKEYS | '.';
dest: ANYKEYS | '.';
expose: EXPOSE NUMBER;
run: RUN body NEWLINE;
body: shellCmd (SHELLAND shellCmd)* ;
shellCmd: ANYKEYS+;
SHARP: '#';
FROM: [fF][rR][oO][mM];
ENV: [eE][nN][vV];
RUN: [rR][uU][nN];
ENTRYPOINT: [eE][nN][tT][rR][yY][pP][oO][iI][nN][tT];
MAINTAINER: [mM][aA][iI][nN][tT][aA][iI][nN][eE][rR];
WORKDIR: [wW][oO][rR][kK][dD][iI][rR];
SHELLAND: '&&' | ('\\' NEWLINE '&&');
ADD: [aA][dD][dD];
COPY: [cC][oO][pP][yY];
EXPOSE: [eE][xX][pP][oO][sS][eE];
NUMBER: [0-9]+;
LETTER: [a-zA-Z];
ANYKEYS: (LETTER | NUMBER | ':' | '_' | '-' | '/' | '|' | '"' | '=' | '*' | '\\' | '\'' | '+' | ']' | '[' | '{' | '}' | ';' | '!' | '~' | '.' | '–' | '$' | '<' | '>' | '@' | ',')+;
NEWLINE: ('\n' | '\r')+;
WS : ((' ' | '\t')+) -> skip;
那有什么不对?首先, ANYKEYS
规则是ulgy但我可以找到如何以更好的方式执行此操作..接下来, RUN exit 9000
将无法工作,产生 extraneous input '9000' expecting {SHELLAND, ANYKEYS, NEWLINE}
错误,我不明白,因为 ANYKEYS
应该与 ANYKEY
规则中的 NUMBER
匹配
我有点迷茫,不明白为什么它不匹配这样的输入,并且不知道如何以更好的方式做到这一点
感谢您的帮助和建议!
1 回答
我不熟悉AntLR4,但是对于你的语法来说,包含一些指令的多种形式是很重要的 .
以下说明有两种形式:
以下说明有三种形式:
跑
RUN
指令有两种形式:ADD
ADD
指令有两种形式:COPY
COPY
指令有两种形式:ENTRYPOINT
ENTRYPOINT
指令有两种形式:HEALTHCHECK
HEALTHCHECK
指令有两种形式:CMD
CMD
指令有三种形式:有关每个命令的更多信息和示例,请参阅:https://docs.docker.com/engine/reference/builder/