Skip to main content

oak_apl/parser/
mod.rs

1#![doc = include_str!("readme.md")]
2pub mod element_type;
3
4pub use element_type::AplElementType;
5
6use crate::{language::AplLanguage, lexer::token_type::AplTokenType};
7use oak_core::{
8    OakError, TextEdit,
9    parser::{Parser, ParserState},
10    source::Source,
11};
12
13pub(crate) type State<'a, S> = ParserState<'a, AplLanguage, S>;
14
15pub struct AplParser<'config> {
16    pub(crate) config: &'config AplLanguage,
17}
18
19impl<'config> AplParser<'config> {
20    pub fn new(config: &'config AplLanguage) -> Self {
21        Self { config }
22    }
23
24    /// 解析 APL 语句
25    pub(crate) fn parse_statement<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
26        let cp = state.checkpoint();
27
28        // 尝试解析赋值语句: ID ← Expression
29        if state.at(AplTokenType::Identifier) && state.peek_kind_at(1) == Some(AplTokenType::LeftArrow) {
30            state.advance(); // ID
31            state.advance(); // ←
32            self.parse_expression(state)?;
33            state.finish_at(cp, AplElementType::Assignment);
34        }
35        else {
36            self.parse_expression(state)?;
37            state.finish_at(cp, AplElementType::Statement);
38        }
39
40        Ok(())
41    }
42
43    /// 解析 APL 表达式(简化版)
44    pub(crate) fn parse_expression<'a, S: Source + ?Sized>(&self, state: &mut State<'a, S>) -> Result<(), OakError> {
45        let cp = state.checkpoint();
46
47        while state.not_at_end() && !state.at(AplTokenType::Newline) && !state.at(AplTokenType::Diamond) {
48            if state.at(AplTokenType::Identifier) {
49                state.advance();
50            }
51            else if state.at(AplTokenType::NumberLiteral) {
52                state.advance();
53            }
54            else if state.at(AplTokenType::StringLiteral) {
55                state.advance();
56            }
57            else if state.at(AplTokenType::LeftParen) {
58                state.advance();
59                self.parse_expression(state)?;
60                state.expect(AplTokenType::RightParen).ok();
61            }
62            else if state.at(AplTokenType::LeftBrace) {
63                // Dfn { ... }
64                state.advance();
65                while state.not_at_end() && !state.at(AplTokenType::RightBrace) {
66                    state.advance();
67                }
68                state.expect(AplTokenType::RightBrace).ok();
69            }
70            else {
71                // 可能是原始函数或运算符
72                state.advance();
73            }
74        }
75
76        state.finish_at(cp, AplElementType::Expression);
77        Ok(())
78    }
79}
80
81impl<'config> Parser<AplLanguage> for AplParser<'config> {
82    fn parse<'a, S: Source + ?Sized>(&self, text: &'a S, edits: &[TextEdit], cache: &'a mut impl oak_core::ParseCache<AplLanguage>) -> oak_core::ParseOutput<'a, AplLanguage> {
83        let lexer = crate::lexer::AplLexer::new(self.config);
84        oak_core::parser::parse_with_lexer(&lexer, text, edits, cache, |state| {
85            let checkpoint = state.checkpoint();
86
87            while state.not_at_end() && !state.at(AplTokenType::Eof) {
88                if state.at(AplTokenType::Newline) || state.at(AplTokenType::Whitespace) {
89                    state.advance();
90                    continue;
91                }
92
93                if state.at(AplTokenType::Comment) {
94                    state.advance();
95                    continue;
96                }
97
98                self.parse_statement(state)?;
99
100                if state.at(AplTokenType::Diamond) {
101                    state.advance();
102                }
103            }
104
105            Ok(state.finish_at(checkpoint, AplElementType::Root))
106        })
107    }
108}