2929use PackageFactory \ComponentEngine \Language \AST \Node \BinaryOperation \BinaryOperationNode ;
3030use PackageFactory \ComponentEngine \Language \AST \Node \BinaryOperation \BinaryOperator ;
3131use PackageFactory \ComponentEngine \Language \AST \Node \Expression \ExpressionNode ;
32- use PackageFactory \ComponentEngine \Language \AST \Node \Tag \TagNode ;
3332use PackageFactory \ComponentEngine \Language \AST \Node \TernaryOperation \TernaryOperationNode ;
3433use PackageFactory \ComponentEngine \Language \AST \Node \UnaryOperation \UnaryOperationNode ;
3534use PackageFactory \ComponentEngine \Language \AST \Node \UnaryOperation \UnaryOperator ;
3837use PackageFactory \ComponentEngine \Language \Parser \NullLiteral \NullLiteralParser ;
3938use PackageFactory \ComponentEngine \Language \Parser \StringLiteral \StringLiteralParser ;
4039use PackageFactory \ComponentEngine \Language \Parser \Tag \TagParser ;
40+ use PackageFactory \ComponentEngine \Language \Parser \TemplateLiteral \TemplateLiteralParser ;
4141use PackageFactory \ComponentEngine \Language \Parser \ValueReference \ValueReferenceParser ;
4242use PackageFactory \ComponentEngine \Parser \Source \Range ;
4343use PackageFactory \ComponentEngine \Parser \Tokenizer \Scanner ;
@@ -52,16 +52,19 @@ final class ExpressionParser
5252 private readonly StringLiteralParser $ stringLiteralParser ;
5353 private readonly IntegerLiteralParser $ integerLiteralParser ;
5454 private readonly ValueReferenceParser $ valueReferenceParser ;
55+ private readonly TemplateLiteralParser $ templateLiteralParser ;
5556 private readonly TagParser $ tagParser ;
5657
5758 public function __construct (
58- private ?TokenType $ stopAt = null
59+ private ?TokenType $ stopAt = null ,
60+ private Precedence $ precedence = Precedence::SEQUENCE
5961 ) {
6062 $ this ->booleanLiteralParser = new BooleanLiteralParser ();
6163 $ this ->nullLiteralParser = new NullLiteralParser ();
6264 $ this ->stringLiteralParser = new StringLiteralParser ();
6365 $ this ->integerLiteralParser = new IntegerLiteralParser ();
6466 $ this ->valueReferenceParser = new ValueReferenceParser ();
67+ $ this ->templateLiteralParser = new TemplateLiteralParser ();
6568 $ this ->tagParser = new TagParser ();
6669 }
6770
@@ -131,6 +134,8 @@ public function parseUnaryStatement(\Iterator &$tokens): ExpressionNode
131134 $ this ->parseValueReference ($ tokens ),
132135 TokenType::TAG_START_OPENING =>
133136 $ this ->parseTag ($ tokens ),
137+ TokenType::TEMPLATE_LITERAL_START =>
138+ $ this ->parseTemplateLiteral ($ tokens ),
134139 TokenType::BRACKET_ROUND_OPEN =>
135140 $ this ->parseBracketedExpression ($ tokens ),
136141 default =>
@@ -146,6 +151,7 @@ public function parseUnaryStatement(\Iterator &$tokens): ExpressionNode
146151 TokenType::NUMBER_HEXADECIMAL ,
147152 TokenType::STRING ,
148153 TokenType::TAG_START_OPENING ,
154+ TokenType::TEMPLATE_LITERAL_START ,
149155 TokenType::BRACKET_ROUND_OPEN
150156 ),
151157 actualToken: $ tokens ->current ()
@@ -216,6 +222,14 @@ private function withStopAt(TokenType $stopAt): self
216222 return $ newExpressionParser ;
217223 }
218224
225+ private function withPrecedence (Precedence $ precedence ): self
226+ {
227+ $ newExpressionParser = clone $ this ;
228+ $ newExpressionParser ->precedence = $ precedence ;
229+
230+ return $ newExpressionParser ;
231+ }
232+
219233 /**
220234 * @param \Iterator<mixed,Token> $tokens
221235 * @return boolean
@@ -224,11 +238,21 @@ private function shouldStop(\Iterator &$tokens): bool
224238 {
225239 Scanner::skipSpaceAndComments ($ tokens );
226240
227- if (is_null ($ this ->stopAt )) {
228- return Scanner::isEnd ($ tokens );
241+ if (Scanner::isEnd ($ tokens )) {
242+ return true ;
243+ }
244+
245+ $ type = Scanner::type ($ tokens );
246+
247+ if ($ this ->precedence ->mustStopAt ($ type )) {
248+ return true ;
249+ }
250+
251+ if ($ this ->stopAt && $ type === $ this ->stopAt ) {
252+ return true ;
229253 }
230254
231- return Scanner:: type ( $ tokens ) === $ this -> stopAt ;
255+ return false ;
232256 }
233257
234258 /**
@@ -315,6 +339,20 @@ private function parseTag(\Iterator &$tokens): ExpressionNode
315339 );
316340 }
317341
342+ /**
343+ * @param \Iterator<mixed,Token> $tokens
344+ * @return ExpressionNode
345+ */
346+ private function parseTemplateLiteral (\Iterator &$ tokens ): ExpressionNode
347+ {
348+ $ templateLiteralNode = $ this ->templateLiteralParser ->parse ($ tokens );
349+
350+ return new ExpressionNode (
351+ rangeInSource: $ templateLiteralNode ->rangeInSource ,
352+ root: $ templateLiteralNode
353+ );
354+ }
355+
318356 /**
319357 * @param \Iterator<mixed,Token> $tokens
320358 * @return ExpressionNode
@@ -412,7 +450,9 @@ private function parseAccessType(\Iterator &$tokens): AccessType
412450 private function parseBinaryOperation (\Iterator &$ tokens , ExpressionNode $ leftOperand ): ExpressionNode
413451 {
414452 $ operator = $ this ->parseBinaryOperator ($ tokens );
415- $ rightOperand = $ this ->parse ($ tokens );
453+ $ rightOperand = $ this
454+ ->withPrecedence (Precedence::forBinaryOperator ($ operator ))
455+ ->parse ($ tokens );
416456 $ rangeInSource = Range::from (
417457 $ leftOperand ->rangeInSource ->start ,
418458 $ rightOperand ->rangeInSource ->end
0 commit comments