Compare commits

...

12 Commits

Author SHA1 Message Date
Kevin
36d3d4214c Add initial support for block statements
We needed to add `end` versions of the block identifiers or else the
lexer would identify them as generic tokens.
2024-05-21 17:05:47 -04:00
Kevin
eeaeeec591 Support context management on imports 2024-05-21 15:50:03 -04:00
Kevin
7095e47d33 Fix bug where multiple imports were required 2024-05-21 15:45:31 -04:00
Kevin
bb4749db36 Add support for from ... import ... as 2024-05-21 15:42:46 -04:00
Kevin
249d551e5e Adding basic import statement support 2024-05-21 15:25:54 -04:00
Kevin
38d2923eae Support variable names in literals 2024-05-21 15:09:25 -04:00
Kevin
ba0d6e64a1 Fix single quote string handling 2024-05-21 14:48:07 -04:00
Kevin
80cd1833a6 Support list literals for templates
Because lists can be dynamic this needs to be handled in the grammar
instead of in the lexer.
2024-05-21 14:45:22 -04:00
Kevin
af3a219111 Require template name/list for include statement 2024-05-21 14:45:08 -04:00
Kevin
ca1593eabc Add optional modifiers for include statement 2024-05-21 14:24:44 -04:00
Kevin
2c164b0caa Testing out include syntax 2024-05-21 14:21:20 -04:00
Kevin
04588e2e1c Initial version of the ANTLR grammar
Specifically using ANTLR because it aligns very well with the standard
grammars out there and has a lot better tooling for validating the
grammars and lexers themselves.
2024-05-21 12:09:27 -04:00
3 changed files with 202 additions and 0 deletions

3
.gitignore vendored
View File

@ -8,3 +8,6 @@ dist/
htmlcov/
.tox/
docs/_build/
.antlr/
*.input.txt

99
grammar/JinjaGrammar.g4 Normal file
View File

@ -0,0 +1,99 @@
parser grammar JinjaGrammar;
options {
tokenVocab=JinjaLexer;
}
start : expressions;
expression
: inline_statement
| block_statement
;
expressions : expression*;
list_literal : LSQB SP? list_literal_values? SP? RSQB;
list_literal_values
:
(list_literal_value SP? COMMA SP?)*
list_literal_value
;
list_literal_value
: STRING_LITERAL
| variable_name
;
variable_name : IDENTIFIER;
statement_block
:
STATEMENT_ID_BLOCK SP IDENTIFIER
;
statement_include_template
: STRING_LITERAL
| list_literal
| variable_name
;
statement_include_context
: STATEMENT_INCLUDE_WITH_CONTEXT
| STATEMENT_INCLUDE_WITHOUT_CONTEXT
;
statement_include
: STATEMENT_ID_INCLUDE
(SP statement_include_template)
(SP STATEMENT_INCLUDE_IGNORE_MISSING)?
(SP statement_include_context)?
;
statement_import_file
: STRING_LITERAL
| variable_name
;
statement_import_variable
: variable_name (SP STATEMENT_ID_IMPORT_AS SP variable_name)?
;
statement_import_variable_list
: (statement_import_variable SP? COMMA SP?)* statement_import_variable
;
statement_import
: STATEMENT_ID_IMPORT SP statement_import_file SP STATEMENT_ID_IMPORT_AS SP variable_name (SP statement_include_context)?
| STATEMENT_ID_FROM SP statement_import_file SP STATEMENT_ID_IMPORT SP statement_import_variable_list (SP statement_include_context)?
;
block_end_statement_id
: STATEMENT_END_ID_BLOCK
| STATEMENT_END_ID_SET
;
// block_statement_with_parameters
// : block_statement_id
// | block_statement_id
// ;
block_statement_without_parameters
: statement_block
;
block_statement_start_content
: block_statement_without_parameters
// | block_statement_with_parameters
;
inline_statement_content
: statement_include
| statement_import
;
inline_statement : STATEMENT_OPEN inline_statement_content STATEMENT_CLOSE;
block_statement_start : STATEMENT_OPEN block_statement_start_content STATEMENT_CLOSE;
block_statement_end : STATEMENT_OPEN block_end_statement_id STATEMENT_CLOSE;
block_statement : block_statement_start expressions block_statement_end;

100
grammar/JinjaLexer.g4 Normal file
View File

@ -0,0 +1,100 @@
lexer grammar JinjaLexer;
TRUE_LOWER : 'true';
TRUE_PY : 'True';
TRUE
: TRUE_LOWER
| TRUE_PY
;
FALSE_LOWER : 'false';
FALSE_PY : 'False';
FALSE
: FALSE_LOWER
| FALSE_PY
;
BOOLEAN
: TRUE
| FALSE
;
NONE_LOWER : 'none';
NONE_PY : 'None';
NONE
: NONE_LOWER
| NONE_PY
;
LPAR : '(';
LSQB : '[';
LBRACE : '{';
RPAR : ')';
RSQB : ']';
RBRACE : '}';
DOT : '.';
COLON : ':';
COMMA : ',';
SEMI : ';';
PLUS : '+';
MINUS : '-';
STAR : '*';
SLASH : '/';
VBAR : '|';
AMPER : '&';
LESS : '<';
GREATER : '>';
EQUAL : '=';
PERCENT : '%';
EQEQUAL : '==';
NOTEQUAL : '!=';
LESSEQUAL : '<=';
GREATEREQUAL : '>=';
TILDE : '~';
CIRCUMFLEX : '^';
LEFTSHIFT : '<<';
RIGHTSHIFT : '>>';
DOUBLESTAR : '**';
DOUBLESLASH : '//';
AT : '@';
RARROW : '->';
ELLIPSIS : '...';
EXCLAMATION : '!';
STATEMENT_OPEN : '{%' SP?;
STATEMENT_CLOSE : SP? '%}';
EXPRESSION_OPEN : '{{';
EXPRESSION_CLOSE : '}}';
COMMENT_OPEN : '{#';
COMMENT_CLOSE : '#}';
STRING_LITERAL : STRING_LITERAL_SINGLE_QUOTE | STRING_LITERAL_DOUBLE_QUOTE;
fragment STRING_LITERAL_SINGLE_QUOTE : '\'' (~[\\\r\n'])* '\'';
fragment STRING_LITERAL_DOUBLE_QUOTE : '"' (~[\\\r\n"])* '"';
SP : [ \t\f]+;
// Statement identifiers for built-in statements
STATEMENT_ID_BLOCK : 'block';
STATEMENT_END_ID_BLOCK : 'endblock';
STATEMENT_ID_FROM : 'from';
STATEMENT_ID_IMPORT : 'import';
STATEMENT_ID_INCLUDE : 'include';
STATEMENT_ID_RAW : 'raw';
STATEMENT_ID_SET : 'set';
STATEMENT_END_ID_SET : 'endset';
STATEMENT_ID_IMPORT_AS : 'as';
STATEMENT_INCLUDE_IGNORE_MISSING : 'ignore missing';
STATEMENT_INCLUDE_WITH_CONTEXT : 'with context';
STATEMENT_INCLUDE_WITHOUT_CONTEXT : 'without context';
END_STATEMENT_ID_PREFIX : 'end';
IDENTIFIER : IDENTIFIER_START IDENTIFIER_CONTINUE*;
fragment IDENTIFIER_START : [a-zA-Z_];
fragment IDENTIFIER_CONTINUE : [a-zA-Z0-0_];