首页 文章

AntLR4:为Dockefile编写语法

提问于
浏览
3

我正在尝试编写一个可以识别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 回答

  • 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 指令有两种形式:

    ADD <src>... <dest>
    ADD ["<src>",... "<dest>"] # (this form is required for paths containing whitespace)
    

    COPY

    COPY 指令有两种形式:

    COPY <src>... <dest>
    COPY ["<src>",... "<dest>"] # (this form is required for paths containing whitespace)
    

    ENTRYPOINT

    ENTRYPOINT 指令有两种形式:

    ENTRYPOINT ["executable", "param1", "param2"] # (exec form, preferred)
    ENTRYPOINT command param1 param2              # (shell form)
    

    HEALTHCHECK

    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 指令有三种形式:

    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/

相关问题