summaryrefslogtreecommitdiffstats
path: root/third_party/rust/jsparagus-parser/src/lib.rs
blob: e78744afa50780604b21bd9c7acb075e1fa4167e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#![cfg_attr(feature = "unstable", feature(test))]

mod lexer;
pub mod numeric_value;
mod parser;
mod queue_stack;
mod simulator;
mod unicode;
mod unicode_data;

#[cfg(test)]
mod tests;

extern crate arrayvec;
extern crate jsparagus_ast as ast;
extern crate jsparagus_generated_parser as generated_parser;
extern crate jsparagus_json_log as json_log;

use crate::parser::Parser;
use ast::{
    arena,
    source_atom_set::SourceAtomSet,
    source_slice_list::SourceSliceList,
    types::{Module, Script},
};
use bumpalo;
use generated_parser::{
    AstBuilder, StackValue, TerminalId, START_STATE_MODULE, START_STATE_SCRIPT, TABLES,
};
pub use generated_parser::{ParseError, Result};
use json_log::json_debug;
use lexer::Lexer;
use std::cell::RefCell;
use std::rc::Rc;

pub struct ParseOptions {}
impl ParseOptions {
    pub fn new() -> Self {
        Self {}
    }
}

pub fn parse_script<'alloc>(
    allocator: &'alloc bumpalo::Bump,
    source: &'alloc str,
    _options: &ParseOptions,
    atoms: Rc<RefCell<SourceAtomSet<'alloc>>>,
    slices: Rc<RefCell<SourceSliceList<'alloc>>>,
) -> Result<'alloc, arena::Box<'alloc, Script<'alloc>>> {
    json_debug!({
        "parse": "script",
    });
    Ok(parse(allocator, source, START_STATE_SCRIPT, atoms, slices)?.to_ast()?)
}

pub fn parse_module<'alloc>(
    allocator: &'alloc bumpalo::Bump,
    source: &'alloc str,
    _options: &ParseOptions,
    atoms: Rc<RefCell<SourceAtomSet<'alloc>>>,
    slices: Rc<RefCell<SourceSliceList<'alloc>>>,
) -> Result<'alloc, arena::Box<'alloc, Module<'alloc>>> {
    json_debug!({
        "parse": "module",
    });
    Ok(parse(allocator, source, START_STATE_MODULE, atoms, slices)?.to_ast()?)
}

fn parse<'alloc>(
    allocator: &'alloc bumpalo::Bump,
    source: &'alloc str,
    start_state: usize,
    atoms: Rc<RefCell<SourceAtomSet<'alloc>>>,
    slices: Rc<RefCell<SourceSliceList<'alloc>>>,
) -> Result<'alloc, StackValue<'alloc>> {
    let mut tokens = Lexer::new(allocator, source.chars(), atoms.clone(), slices.clone());

    TABLES.check();

    let mut parser = Parser::new(AstBuilder::new(allocator, atoms, slices), start_state);

    loop {
        let t = tokens.next(&parser)?;
        if t.terminal_id == TerminalId::End {
            break;
        }
        parser.write_token(t)?;
    }
    parser.close(tokens.offset())
}

pub fn is_partial_script<'alloc>(
    allocator: &'alloc bumpalo::Bump,
    source: &'alloc str,
    atoms: Rc<RefCell<SourceAtomSet<'alloc>>>,
    slices: Rc<RefCell<SourceSliceList<'alloc>>>,
) -> Result<'alloc, bool> {
    let mut parser = Parser::new(
        AstBuilder::new(allocator, atoms.clone(), slices.clone()),
        START_STATE_SCRIPT,
    );
    let mut tokens = Lexer::new(allocator, source.chars(), atoms, slices);
    loop {
        let t = tokens.next(&parser)?;
        if t.terminal_id == TerminalId::End {
            break;
        }
        parser.write_token(t)?;
    }
    Ok(!parser.can_close())
}