|
| 1 | +// language spec: https://jsonnet.org/ref/spec.html |
| 2 | +// language tutorial: https://jsonnet.org/learning/tutorial.html |
| 3 | +// grammar from: https://gist.github.com/ironchefpython/84380aa60871853dc86719dd598c35e4 |
| 4 | +// slightly changed the slice rule |
| 5 | +grammar Jsonnet; |
| 6 | + |
| 7 | +jsonnet |
| 8 | + : expr EOF |
| 9 | + ; |
| 10 | + |
| 11 | +expr |
| 12 | + : value=(NULL | TRUE | FALSE | SELF | DOLLAR | STRING | NUMBER ) # Value |
| 13 | + | '(' expr ')' # Parens |
| 14 | + | '{' objinside? '}' # Object |
| 15 | + | '[' ( elems+=expr (',' elems+=expr)* )? ','? ']' # Array |
| 16 | + | '[' expr ','? forspec+ ']' # ArrayComp |
| 17 | + | expr '.' ID # Index |
| 18 | + | expr '[' expr ']' # Index |
| 19 | + | expr '[' startIdx=expr? ':' endIdx=expr? (':' step=expr? )? ']' # Slice |
| 20 | + | SUPER . ID # IndexSuper |
| 21 | + | SUPER '[' expr ']' # IndexSuper |
| 22 | + | expr '(' args? ')' TAILSTRICT? # Apply |
| 23 | + | ID # Var |
| 24 | + | IF expr THEN expr ( ELSE expr )? # IfThenElse |
| 25 | + | op=(PLUS | MINUS | NOT | BITNOT) expr # UnaryExpr |
| 26 | + | expr op=(MULTIPLY | DIVIDE | MODULUS) expr # BinaryExpr |
| 27 | + | expr op=(PLUS | MINUS) expr # BinaryExpr |
| 28 | + | expr op=(SHIFTLEFT | SHIFTRIGHT) expr # BinaryExpr |
| 29 | + | expr op=(GT | GE | LT | LE | IN) expr # BinaryExpr |
| 30 | + | expr op=(EQUALS | NOTEQUALS) expr # BinaryExpr |
| 31 | + | expr op=BITAND expr # BinaryExpr |
| 32 | + | expr op=BITXOR expr # BinaryExpr |
| 33 | + | expr op=BITOR expr # BinaryExpr |
| 34 | + | expr op=AND expr # BinaryExpr |
| 35 | + | expr op=OR expr # BinaryExpr |
| 36 | + | expr '{' objinside? '}' # ApplyBrace |
| 37 | + | FUNCTION '(' params? ')' expr # Function |
| 38 | + | assertion ';' expr # Assert |
| 39 | + | IMPORT STRING # Import |
| 40 | + | IMPORTSTR STRING # Import |
| 41 | + | ERROR expr # ErrorExpr |
| 42 | + | expr IN SUPER # InSuper |
| 43 | + | LOCAL binds+=bind (',' binds+=bind)* ';' expr # LocalBind |
| 44 | + ; |
| 45 | + |
| 46 | + |
| 47 | +objinside |
| 48 | + : members+=member (',' members+=member)* ','? # Members |
| 49 | + | ( objlocal ',' )* '[' key=expr ']' ':' value=expr ( ',' objlocal )* ','? forspec+ |
| 50 | + # ObjectComp |
| 51 | + ; |
| 52 | + |
| 53 | +member |
| 54 | + : objlocal | assertion | field |
| 55 | + ; |
| 56 | + |
| 57 | +field |
| 58 | + : fieldname PLUS? visibility expr # ValueField |
| 59 | + | fieldname '(' params? ')' visibility expr # FunctionField |
| 60 | + ; |
| 61 | + |
| 62 | +visibility |
| 63 | + : ':' |
| 64 | + | ':' ':' |
| 65 | + | ':' ':' ':' |
| 66 | + ; |
| 67 | + |
| 68 | +objlocal |
| 69 | + : LOCAL bind |
| 70 | + ; |
| 71 | + |
| 72 | +forspec |
| 73 | + : FOR ID IN expr ifspec* |
| 74 | + ; |
| 75 | + |
| 76 | +ifspec |
| 77 | + : IF expr |
| 78 | + ; |
| 79 | + |
| 80 | +fieldname |
| 81 | + : ID |
| 82 | + | STRING |
| 83 | + | '[' expr ']' |
| 84 | + ; |
| 85 | + |
| 86 | +assertion |
| 87 | + : ASSERT condition=expr (':' message=expr)? |
| 88 | + ; |
| 89 | + |
| 90 | + |
| 91 | +bind |
| 92 | + : ID '=' expr # ValueBind |
| 93 | + | ID '(' params? ')' '=' expr # FunctionBind |
| 94 | + ; |
| 95 | + |
| 96 | + |
| 97 | +args |
| 98 | + : pos+=expr ( ',' pos+=expr )* ( ',' names+=ID '=' named+=expr )* ','? |
| 99 | + | names+=ID '=' named+=expr ( ',' names+=ID '=' named+=expr )* ','? |
| 100 | + ; |
| 101 | + |
| 102 | +params |
| 103 | + : pos+=ID ( ',' pos+=ID )* ( ',' names+=ID '=' defaults+=expr )* ','? |
| 104 | + | names+=ID '=' defaults+=expr ( ',' names+=ID '=' defaults+=expr )* ','? |
| 105 | + ; |
| 106 | + |
| 107 | + |
| 108 | +DOLLAR : '$'; |
| 109 | + |
| 110 | +ASSERT : 'assert'; |
| 111 | +ELSE : 'else'; |
| 112 | +ERROR : 'error'; |
| 113 | +FALSE : 'false'; |
| 114 | +FOR : 'for'; |
| 115 | +FUNCTION : 'function'; |
| 116 | +IF : 'if'; |
| 117 | +IMPORT : 'import'; |
| 118 | +IMPORTSTR : 'importstr'; |
| 119 | +LOCAL : 'local'; |
| 120 | +NULL : 'null'; |
| 121 | +SELF : 'self'; |
| 122 | +SUPER : 'super'; |
| 123 | +TAILSTRICT: 'tailstrict'; |
| 124 | +THEN : 'then'; |
| 125 | +TRUE : 'true'; |
| 126 | + |
| 127 | +EQUALS : '==' ; |
| 128 | +NOTEQUALS : '!='; |
| 129 | +PLUS : '+'; |
| 130 | +MINUS : '-'; |
| 131 | +MULTIPLY : '*'; |
| 132 | +DIVIDE : '/'; |
| 133 | +MODULUS : '%'; |
| 134 | +AND : '&&'; |
| 135 | +OR : '||'; |
| 136 | +NOT : '!'; |
| 137 | +GT : '>'; |
| 138 | +GE : '>='; |
| 139 | +LT : '<'; |
| 140 | +LE : '<='; |
| 141 | +IN : 'in'; |
| 142 | +SHIFTLEFT : '<<'; |
| 143 | +SHIFTRIGHT: '>>'; |
| 144 | +BITNOT : '~'; |
| 145 | +BITAND : '&'; |
| 146 | +BITXOR : '^'; |
| 147 | +BITOR : '|'; |
| 148 | + |
| 149 | +STRING |
| 150 | + : '"' (ESCAPES | UNICODE | ~["\\\u0000-\u001F])* '"' |
| 151 | + | '\'' (ESCAPES | UNICODE | ~['\\\u0000-\u001F])* '\'' |
| 152 | + | '@' '"' ('""' | ~["])* '"' |
| 153 | + | '@' '\'' ('\'\'' | ~['])* '\'' |
| 154 | + | '@' '\'' ('\'\'' | ~['])* '\'' |
| 155 | + | '|||' ( ~'|' | '|' ~'|' | '||' ~'|' )* '|||' |
| 156 | + ; |
| 157 | + |
| 158 | +NUMBER: INT ( '.' DIGIT+ )? EXP?; |
| 159 | + |
| 160 | +ID: ALPHA (ALPHA | DIGIT)*; |
| 161 | + |
| 162 | +fragment ESCAPES: '\\' ["'\\/bfnrt]; |
| 163 | +fragment DIGIT: [0-9]; |
| 164 | +fragment ALPHA: [_a-zA-Z]; |
| 165 | +fragment UNICODE: 'u' HEX HEX HEX HEX; |
| 166 | +fragment HEX: [0-9a-fA-F]; |
| 167 | +fragment INT: '0' | [1-9] DIGIT*; |
| 168 | +fragment EXP: [Ee] [+\-]? DIGIT+; |
| 169 | +
|
| 170 | +Whitespace |
| 171 | + : [ \t]+ -> skip |
| 172 | + ; |
| 173 | +
|
| 174 | +Newline |
| 175 | + : ( '\r' '\n'? | '\n' ) -> skip |
| 176 | + ; |
| 177 | +
|
| 178 | +BlockComment |
| 179 | + : '/*' .*? '*/' -> skip |
| 180 | + ; |
| 181 | +
|
| 182 | +LineComment |
| 183 | + : ('//'|'#') ~[\r\n]* -> skip |
| 184 | + ; |
0 commit comments