justfile grammar
Justfiles are processed by a mildly context-sensitive tokenizer and a recursive descent parser. The grammar is mostly LL(1), although an extra token of lookahead is used to distinguish between export assignments and recipes with parameters.
tokens
BACKTICK = `[^`\n\r]*`COMMENT = #([^!].*)?$DEDENT = emitted when indentation decreasesEOF = emitted at the end of the fileINDENT = emitted when indentation increasesLINE = emitted before a recipe lineNAME = [a-zA-Z_][a-zA-Z0-9_-]*NEWLINE = \n|\r\nRAW_STRING = '[^'\r\n]*'STRING = "[^"]*" # also processes \n \r \t \" \\ escapesTEXT = recipe text, only matches in a recipe body
grammar syntax
| alternation() grouping_? option (0 or 1 times)_* repetition (0 or more times)_+ repetition (1 or more times)
grammar
justfile : item* EOFitem : recipe| alias| assignment| export| eoleol : NEWLINE| COMMENT NEWLINEalias : 'alias' NAME ':=' NAMEassignment : NAME ':=' expression eolexport : 'export' assignmentexpression : value '+' expression| valuevalue : NAME '(' sequence? ')'| STRING| RAW_STRING| BACKTICK| NAME| '(' expression ')'sequence : expression ',' sequence| expression ','?recipe : '@'? NAME parameter* ('+' parameter)? ':' dependencies? body?parameter : NAME| NAME '=' valuedependencies : NAME+body : INDENT line+ DEDENTline : LINE (TEXT | interpolation)+ NEWLINE| NEWLINEinterpolation : '{{' expression '}}'
