mirror of
https://github.com/danog/parser.git
synced 2024-11-27 04:14:55 +01:00
parent
1a7aae97d9
commit
b254e59bde
7
phpast/samples/match.php
Normal file
7
phpast/samples/match.php
Normal file
@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
match ($expr) {
|
||||
'foo' => 'bar',
|
||||
'baz', 'car', 'bob' => 'foop',
|
||||
default => null,
|
||||
};
|
@ -709,6 +709,7 @@ impl Lexer {
|
||||
#[allow(dead_code)]
|
||||
fn identifier_to_keyword(ident: &str) -> Option<TokenKind> {
|
||||
Some(match ident {
|
||||
"match" => TokenKind::Match,
|
||||
"abstract" => TokenKind::Abstract,
|
||||
"array" => TokenKind::Array,
|
||||
"as" => TokenKind::As,
|
||||
@ -718,6 +719,7 @@ fn identifier_to_keyword(ident: &str) -> Option<TokenKind> {
|
||||
"continue" => TokenKind::Continue,
|
||||
"const" => TokenKind::Const,
|
||||
"declare" => TokenKind::Declare,
|
||||
"default" => TokenKind::Default,
|
||||
"echo" => TokenKind::Echo,
|
||||
"else" => TokenKind::Else,
|
||||
"elseif" => TokenKind::ElseIf,
|
||||
|
@ -96,6 +96,7 @@ pub enum TokenKind {
|
||||
LeftShift,
|
||||
LessThan,
|
||||
LessThanEquals,
|
||||
Match,
|
||||
Minus,
|
||||
Namespace,
|
||||
NamespaceSeparator,
|
||||
@ -226,6 +227,7 @@ impl Display for TokenKind {
|
||||
Self::LeftShift => "<<",
|
||||
Self::LessThan => "<",
|
||||
Self::LessThanEquals => "<=",
|
||||
Self::Match => "match",
|
||||
Self::Minus => "-",
|
||||
Self::Namespace => "namespace",
|
||||
Self::NamespaceSeparator => "\\",
|
||||
|
@ -354,7 +354,17 @@ pub enum Expression {
|
||||
},
|
||||
Clone {
|
||||
target: Box<Self>
|
||||
}
|
||||
},
|
||||
Match {
|
||||
condition: Box<Self>,
|
||||
arms: Vec<MatchArm>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Serialize)]
|
||||
pub struct MatchArm {
|
||||
pub conditions: Option<Vec<Expression>>,
|
||||
pub body: Expression,
|
||||
}
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Clone, Serialize)]
|
||||
|
@ -1,5 +1,5 @@
|
||||
mod ast;
|
||||
mod parser;
|
||||
|
||||
pub use ast::{Statement, Expression, Program, Block, Param, Identifier, Type, InfixOp};
|
||||
pub use ast::{Statement, Expression, Program, Block, Param, Identifier, Type, InfixOp, MatchArm};
|
||||
pub use parser::{Parser, ParseError};
|
@ -1,6 +1,6 @@
|
||||
use std::{vec::IntoIter, fmt::{Display}};
|
||||
use trunk_lexer::{Token, TokenKind, Span};
|
||||
use crate::{Program, Statement, Block, Expression, ast::{ArrayItem, Use, MethodFlag, ClassFlag, ElseIf, UseKind, MagicConst}, Identifier, Type};
|
||||
use crate::{Program, Statement, Block, Expression, ast::{ArrayItem, Use, MethodFlag, ClassFlag, ElseIf, UseKind, MagicConst}, Identifier, Type, MatchArm};
|
||||
|
||||
type ParseResult<T> = Result<T, ParseError>;
|
||||
|
||||
@ -789,6 +789,46 @@ impl Parser {
|
||||
|
||||
e
|
||||
},
|
||||
TokenKind::Match => {
|
||||
self.next();
|
||||
self.lparen()?;
|
||||
|
||||
let condition = Box::new(self.expression(0)?);
|
||||
|
||||
self.rparen()?;
|
||||
self.lbrace()?;
|
||||
|
||||
let mut arms = Vec::new();
|
||||
while self.current.kind != TokenKind::RightBrace {
|
||||
let mut conditions = Vec::new();
|
||||
|
||||
while self.current.kind != TokenKind::DoubleArrow {
|
||||
if self.current.kind == TokenKind::Default {
|
||||
self.next();
|
||||
break;
|
||||
}
|
||||
|
||||
conditions.push(self.expression(0)?);
|
||||
|
||||
self.optional_comma()?;
|
||||
}
|
||||
|
||||
expect!(self, TokenKind::DoubleArrow, "expected =>");
|
||||
|
||||
let body = self.expression(0)?;
|
||||
|
||||
self.optional_comma()?;
|
||||
|
||||
arms.push(MatchArm {
|
||||
conditions: if conditions.is_empty() { None } else { Some(conditions) },
|
||||
body,
|
||||
})
|
||||
}
|
||||
|
||||
self.rbrace()?;
|
||||
|
||||
Expression::Match { condition, arms }
|
||||
},
|
||||
TokenKind::Array => {
|
||||
let mut items = vec![];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user