php_parser_rs/parser/internal/
constants.rs

1use crate::lexer::token::TokenKind;
2use crate::parser::ast::constant::ClassishConstant;
3use crate::parser::ast::constant::ConstantEntry;
4use crate::parser::ast::constant::ConstantStatement;
5use crate::parser::ast::modifiers::ConstantModifierGroup;
6use crate::parser::error::ParseResult;
7use crate::parser::expressions;
8use crate::parser::internal::identifiers;
9use crate::parser::internal::utils;
10use crate::parser::state::State;
11
12pub fn parse(state: &mut State) -> ParseResult<ConstantStatement> {
13    let comments = state.stream.comments();
14    let start = utils::skip(state, TokenKind::Const)?;
15
16    let mut entries = vec![];
17
18    loop {
19        let name = identifiers::constant_identifier(state)?;
20        let span = utils::skip(state, TokenKind::Equals)?;
21        let value = expressions::create(state)?;
22
23        entries.push(ConstantEntry {
24            name,
25            equals: span,
26            value,
27        });
28
29        if state.stream.current().kind == TokenKind::Comma {
30            state.stream.next();
31        } else {
32            break;
33        }
34    }
35
36    let end = utils::skip_semicolon(state)?;
37
38    Ok(ConstantStatement {
39        comments,
40        r#const: start,
41        entries,
42        semicolon: end,
43    })
44}
45
46pub fn classish(
47    state: &mut State,
48    modifiers: ConstantModifierGroup,
49) -> ParseResult<ClassishConstant> {
50    let attributes = state.get_attributes();
51
52    let comments = state.stream.comments();
53    let start = utils::skip(state, TokenKind::Const)?;
54
55    let mut entries = vec![];
56
57    loop {
58        let name = identifiers::identifier_maybe_reserved(state)?;
59        let span = utils::skip(state, TokenKind::Equals)?;
60        let value = expressions::create(state)?;
61
62        entries.push(ConstantEntry {
63            name,
64            equals: span,
65            value,
66        });
67
68        if state.stream.current().kind == TokenKind::Comma {
69            state.stream.next();
70        } else {
71            break;
72        }
73    }
74
75    let end = utils::skip_semicolon(state)?;
76
77    Ok(ClassishConstant {
78        comments,
79        attributes,
80        modifiers,
81        r#const: start,
82        entries,
83        semicolon: end,
84    })
85}