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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
use crate::lexer;
use std::mem;

/*構文木の定義*/
pub enum Expr {
    Number(f64),
    PrefixExpr {
        operator: String,
        right: Box<Expr>,
    },
    InfixExpr {
        left: Box<Expr>,
        operator: String,
        right: Box<Expr>,
    },
    Fraction {
        numerator: Box<Expr>,
        denominator: Box<Expr>,
    },
}
/*演算優先度の定義*/
#[derive(PartialOrd, PartialEq)]
enum Precedence {
    Lowest,
    Sum,
    Product,
    Prefix,
}

/*構文解析器の構造定義*/
pub struct Parser {
    token: Vec<Option<lexer::Token>>,
    position: usize,
}

/*構文解析器*/
impl Parser {
    pub fn init(mut lexer: lexer::Lexer) -> Result<Parser, String> {
        //トークンを可変配列にまとめてぶち込む->文法エラー検出が容易
        let mut token: Vec<Option<lexer::Token>> = Vec::new();
        loop {
            match lexer.token() {
                Ok(x) => {
                    //終端検出
                    if x.is_none() {
                        break;
                    } else {
                        token.push(x);
                    }
                }
                Err(e) => {
                    return Err(e);
                }
            }
        }
        Ok(Parser { token, position: 0 })
    }
    //全字句の解析(優先度がLowest以上の式の解析)
    pub fn parse(&mut self) -> Option<Box<Expr>> {
        self.parse_expression(Precedence::Lowest)
    }
    //式の解析
    fn parse_expression(&mut self, precedence: Precedence) -> Option<Box<Expr>> {
        //左辺の解析
        let mut now = self.parse_prefix()?;
        //右辺の優先度が基準優先度より高い場合に中置演算子式として解析
        while self.peek().is_some() && precedence < self.peek_precedence() {
            self.next();
            now = self.parse_infix(now)?;
        }
        Some(now)
    }
    //前置演算子式(マイナス,数値,括弧,引数,分数)の解析
    fn parse_prefix(&mut self) -> Option<Box<Expr>> {
        match self.curr()?.as_ref()? {
            lexer::Token::Minus => self.parse_minus(),
            lexer::Token::Number(_) => self.parse_number(),
            lexer::Token::LParen => self.parse_grouped_expression(),
            lexer::Token::Frac => self.parse_fraction(),
            _ => None,
        }
    }
    //マイナスの解析(演算子を-として右辺をparse_expression()で解析)
    fn parse_minus(&mut self) -> Option<Box<Expr>> {
        self.next();
        Some(Box::new(Expr::PrefixExpr {
            operator: "Minus".to_string(),
            right: self.parse_expression(Precedence::Prefix)?,
        }))
    }
    //数値の解析(Token::NumberをExpr::Numberに変換)
    fn parse_number(&mut self) -> Option<Box<Expr>> {
        match self.curr()? {
            Some(lexer::Token::Number(n)) => Some(Box::new(Expr::Number(*n))),
            _ => None,
        }
    }
    //括弧の解析
    fn parse_grouped_expression(&mut self) -> Option<Box<Expr>> {
        self.next();
        let expression = self.parse_expression(Precedence::Lowest);
        if self.discriminant(&lexer::Token::RParen) {
            self.next();
            expression
        } else {
            None
        }
    }
    //引数の解析
    fn parse_arguments(&mut self) -> Option<Box<Expr>> {
        self.next();
        let expression = self.parse_expression(Precedence::Lowest);
        if self.discriminant(&lexer::Token::RBrace) {
            self.next();
            expression
        } else {
            None
        }
    }
    //分数の解析
    fn parse_fraction(&mut self) -> Option<Box<Expr>> {
        self.next();
        let numerator = self.parse_arguments()?;
        self.next();
        let denominator = self.parse_arguments()?;
        Some(Box::new(Expr::Fraction {
            numerator,
            denominator,
        }))
    }
    //中置演算子の解析
    fn parse_infix(&mut self, left: Box<Expr>) -> Option<Box<Expr>> {
        match self.curr()?.as_ref()? {
            lexer::Token::Plus | lexer::Token::Minus | lexer::Token::Times | lexer::Token::Div => {
                self.parse_infix_expression(left)
            }
            _ => Some(left),
        }
    }
    //中置演算子式の解析
    fn parse_infix_expression(&mut self, left: Box<Expr>) -> Option<Box<Expr>> {
        let token = self.curr()?.as_ref()?;
        let operator = format!("{:?}", token);
        //現在解析中の演算子の優先度を取得
        let precedence = Self::token_precedence(token);
        self.next();
        //右辺の解析
        //優先度大→式が入る
        //優先度同等以下→最初の項が入る
        let right = self.parse_expression(precedence)?;
        Some(Box::new(Expr::InfixExpr {
            left,
            operator,
            right,
        }))
    }
    fn token_precedence(token: &lexer::Token) -> Precedence {
        match token {
            lexer::Token::Plus | lexer::Token::Minus => Precedence::Sum,
            lexer::Token::Div | lexer::Token::Times => Precedence::Product,
            _ => Precedence::Lowest,
        }
    }
    fn peek_precedence(&mut self) -> Precedence {
        return match self.peek() {
            Some(x) => Self::token_precedence(x.as_ref().unwrap()),
            None => Precedence::Lowest,
        };
    }
    //次のトークンが引数として与えられたトークンかどうか判別する
    fn discriminant(&mut self, token: &lexer::Token) -> bool {
        match self.peek() {
            Some(x) => mem::discriminant(x.as_ref().unwrap()) == mem::discriminant(token),
            None => false,
        }
    }
    fn next(&mut self) {
        self.position += 1
    }
    fn curr(&mut self) -> Option<&Option<lexer::Token>> {
        self.token.get(self.position)
    }
    fn peek(&mut self) -> Option<&Option<lexer::Token>> {
        self.token.get(self.position + 1)
    }
}