我试图写一个能识别 dockerfile 的语法。 (无上下文语法) 长话短说,dockerfiles是由命令组成的文本文件。 命令可以是单行或多行,并由其名称标识。
最简单的dockerfile命令示例:
FROM anImageNameThatCanContainsPrettyMuchAnythingButWS
EXPOSE aNumber
有一些更复杂的命令,例如:
ADD aPath anotherPath
COPY aPath anotherPath
ENV aKey=aValue
这是RUN
命令中最复杂的命令。
RUN
命令基本上可以是任何 shell 命令,因此可以是任何命令。我唯一想要实现的是分裂' RUN
的{{1}}个命令。
到目前为止我做了什么:
&&
那有什么不对?
首先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;
规则是ulgy但我可以找到更好的方法来做到这一点。
接下来,ANYKEYS
无法正常工作,产生RUN exit 9000
错误,因为extraneous input '9000' expecting {SHELLAND, ANYKEYS, NEWLINE}
应与ANYKEYS
规则中的NUMBER
匹配,所以我无法理解
我有点迷失,不明白为什么它不符合这样的输入,并且不知道如何以更好的方式做到这一点
感谢您的帮助和建议!
答案 0 :(得分:0)
我不熟悉AntLR4,但是对于你的语法来说,包含一些指令的多种形式是很重要的。
以下说明有两种形式:
RUN
ADD
COPY
ENTRYPOINT
HEALTHCHECK
以下说明有三种形式:
CMD
RUN
指令有两种形式:
RUN <command> # (shell form, the command is run in a shell
# which by default is /bin/sh -c on Linux
# or cmd /S /C on Windows)
RUN ["executable", "param1", "param2"] # (exec form)
ADD
指令有两种形式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] # (this form is required for paths containing whitespace)
COPY
指令有两种形式:
COPY <src>... <dest>
COPY ["<src>",... "<dest>"] # (this form is required for paths containing whitespace)
ENTRYPOINT
指令有两种形式:
ENTRYPOINT ["executable", "param1", "param2"] # (exec form, preferred)
ENTRYPOINT command param1 param2 # (shell form)
HEALTHCHECK
指令有两种形式:
HEALTHCHECK [OPTIONS] CMD command # (check container health by running a command inside the container)
HEALTHCHECK NONE # (disable any healthcheck inherited from the base image)
CMD
指令有三种形式:
CMD ["executable","param1","param2"] # (exec form, this is the preferred form)
CMD ["param1","param2"] # (as default parameters to ENTRYPOINT)
CMD command param1 param2 # (shell form)
有关每个命令的更多信息和示例,请参阅:https://docs.docker.com/engine/reference/builder/