%{ (* Grammar for a Dockerfile: a sequence of instruction lines and comments. The lexer has already joined continuations and isolated each logical line, so the grammar's job is to collect them in order; the keyword dispatch and argument interpretation happen in {!Dockerfile.of_string}. *) %} %token INSTR %token COMMENT %token EOF %start <(Raw.t * (Lexing.position * Lexing.position)) list> file %% file: | items = list(item); EOF { items } item: | s = INSTR { (Raw.Instr s, ($startpos, $endpos)) } | s = COMMENT { (Raw.Comment s, ($startpos, $endpos)) }