erl_parse/
parser.rs

1use erl_tokenize::LexicalToken;
2
3use crate::traits::{Expect, Parse, ParseTail, TokenRead};
4use crate::{Error, ErrorKind, Result};
5
6#[derive(Debug)]
7pub struct Parser<T> {
8    reader: T,
9    // TODO: optimize
10    // (単一のバッファとトランザクション開始位置配列、に分離)
11    transactions: Vec<Vec<LexicalToken>>,
12    last_read_error: Option<Error>,
13}
14impl<T> Parser<T>
15where
16    T: TokenRead,
17{
18    pub fn new(reader: T) -> Self {
19        Parser {
20            reader,
21            transactions: Vec::new(),
22            last_read_error: None,
23        }
24    }
25    pub fn parse<P: Parse>(&mut self) -> Result<P> {
26        track!(P::parse(self))
27    }
28    pub fn parse_tail<P: ParseTail>(&mut self, head: P::Head) -> Result<P> {
29        track!(P::parse_tail(self, head))
30    }
31    pub fn expect<P: Parse + Expect>(&mut self, expected: &P::Value) -> Result<P> {
32        self.transaction(|parser| {
33            let actual = track!(parser.parse::<P>(), "expected={:?}", expected)?;
34            track!(actual.expect(expected))?;
35            Ok(actual)
36        })
37    }
38    pub fn expect_any<P: Parse + Expect>(&mut self, expected: &[&P::Value]) -> Result<P> {
39        let actual = track!(self.parse::<P>())?;
40        let mut last_error = None;
41        for e in expected.iter() {
42            if let Err(e) = track!(actual.expect(e)) {
43                last_error = Some(e);
44            } else {
45                last_error = None;
46                break;
47            }
48        }
49        if let Some(e) = last_error {
50            Err(e)
51        } else {
52            Ok(actual)
53        }
54    }
55    pub fn peek<F, P>(&mut self, f: F) -> Result<P>
56    where
57        F: FnOnce(&mut Self) -> Result<P>,
58    {
59        self.start_transaction();
60        let result = track!(f(self));
61        self.abort_transaction();
62        result
63    }
64    pub fn transaction<F, P>(&mut self, f: F) -> Result<P>
65    where
66        F: FnOnce(&mut Self) -> Result<P>,
67    {
68        self.start_transaction();
69        let result = track!(f(self));
70        if result.is_ok() {
71            self.commit_transaction();
72        } else {
73            self.abort_transaction();
74        }
75        result
76    }
77    pub fn eos(&mut self) -> Result<bool> {
78        if let Some(t) = track!(self.reader.try_read_token())? {
79            self.reader.unread_token(t);
80            Ok(false)
81        } else {
82            Ok(true)
83        }
84    }
85
86    fn next_token(&mut self) -> Result<LexicalToken> {
87        if let Some(ref e) = self.last_read_error {
88            return Err(e.clone());
89        }
90        match self.reader.read_token() {
91            Err(e) => {
92                if let ErrorKind::UnexpectedEos = *e.kind() {
93                } else {
94                    self.last_read_error = Some(e.clone());
95                }
96                Err(e)
97            }
98            Ok(t) => {
99                if let Some(tail) = self.transactions.last_mut() {
100                    tail.push(t.clone());
101                }
102                Ok(t)
103            }
104        }
105    }
106    fn start_transaction(&mut self) {
107        self.transactions.push(Vec::new());
108    }
109    fn commit_transaction(&mut self) {
110        let last = self.transactions.pop().unwrap();
111        if let Some(tail) = self.transactions.last_mut() {
112            tail.extend(last);
113        }
114    }
115    fn abort_transaction(&mut self) {
116        let last = self.transactions.pop().unwrap();
117        for t in last.into_iter().rev() {
118            self.reader.unread_token(t);
119        }
120    }
121}
122impl<T> Parser<T> {
123    pub fn reader(&self) -> &T {
124        &self.reader
125    }
126    pub fn reader_mut(&mut self) -> &mut T {
127        &mut self.reader
128    }
129    pub fn into_reader(self) -> T {
130        self.reader
131    }
132}
133impl Parse for LexicalToken {
134    fn parse<T>(parser: &mut Parser<T>) -> Result<Self>
135    where
136        T: TokenRead,
137    {
138        track!(parser.next_token())
139    }
140}