Add lexing of '?'

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-15 12:11:30 +01:00
parent 5354d4ac7b
commit beac224f5b
2 changed files with 30 additions and 3 deletions

View file

@ -238,6 +238,7 @@ pub enum TokenOperator {
GreaterOrEqual, GreaterOrEqual,
Lesser, Lesser,
LesserOrEqual, LesserOrEqual,
QuestionMark,
} }
#[derive(Debug, Copy, Clone, PartialEq, Eq)] #[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -567,6 +568,7 @@ fn parse_operator<'input>(input: &mut Input<'input>) -> PResult<'input, Template
"=".value(TokenOperator::Equal), "=".value(TokenOperator::Equal),
cut_err(fail), cut_err(fail),
)), )),
'?' => empty.value(TokenOperator::QuestionMark),
_ => fail, _ => fail,
}, },
) )
@ -604,6 +606,7 @@ fn ident_terminator_check<'input>(input: &mut Input<'input>) -> PResult<'input,
fn ident_terminator<'input>(input: &mut Input<'input>) -> PResult<'input, ()> { fn ident_terminator<'input>(input: &mut Input<'input>) -> PResult<'input, ()> {
alt(( alt((
eof.void(), eof.void(),
parse_operator.void(),
one_of(('{', '}')).void(), one_of(('{', '}')).void(),
one_of(('(', ',', ')')).void(), one_of(('(', ',', ')')).void(),
one_of((' ', '\t', '\r', '\n')).void(), one_of((' ', '\t', '\r', '\n')).void(),
@ -905,4 +908,26 @@ mod tests {
) )
"#); "#);
} }
#[test]
fn parse_question_mark() {
let input = "{{= foo? }}";
let output = parse(input.into());
insta::assert_debug_snapshot!(output, @r#"
Ok(
ParsedTemplate {
tokens: [
[LeftDelim]"{{" (0..2),
[WantsOutput]"=" (2..3),
[Whitespace]" " (3..4),
[Ident]"foo" (4..7),
[Operator(QuestionMark)]"?" (7..8),
[Whitespace]" " (8..9),
[RightDelim]"}}" (9..11),
],
},
)
"#);
}
} }

View file

@ -7,6 +7,7 @@ use winnow::combinator::cut_err;
use winnow::combinator::delimited; use winnow::combinator::delimited;
use winnow::combinator::dispatch; use winnow::combinator::dispatch;
use winnow::combinator::expression; use winnow::combinator::expression;
use winnow::combinator::fail;
use winnow::combinator::not; use winnow::combinator::not;
use winnow::combinator::opt; use winnow::combinator::opt;
use winnow::combinator::peek; use winnow::combinator::peek;
@ -685,8 +686,9 @@ fn parse_expression<'input>(
op: TokenOperator::$val, op: TokenOperator::$val,
lhs: Box::new(lhs), lhs: Box::new(lhs),
rhs: Box::new(rhs) rhs: Box::new(rhs)
})) })),
),* )*
_ => fail
} }
}; };
} }
@ -737,6 +739,7 @@ mod tests {
use winnow::combinator::fail; use winnow::combinator::fail;
use winnow::stream::TokenSlice; use winnow::stream::TokenSlice;
use crate::lexer::TokenKind;
use crate::parser::AstError; use crate::parser::AstError;
use crate::parser::AstFailure; use crate::parser::AstFailure;
use crate::parser::TemplateAst; use crate::parser::TemplateAst;
@ -744,7 +747,6 @@ mod tests {
use crate::parser::parse; use crate::parser::parse;
use crate::parser::parse_block; use crate::parser::parse_block;
use crate::parser::parse_end; use crate::parser::parse_end;
use crate::lexer::TokenKind;
fn panic_pretty<'a>( fn panic_pretty<'a>(
input: &'_ str, input: &'_ str,