quantrs2_tytan/problem_dsl/
parser.rs

1//! Parser for the problem DSL.
2
3use super::ast::*;
4use super::error::ParseError;
5use super::lexer::Token;
6
7/// Parser for DSL syntax
8#[derive(Debug, Clone)]
9pub struct Parser {
10    /// Current tokens
11    tokens: Vec<Token>,
12    /// Current position
13    position: usize,
14    /// Error messages
15    errors: Vec<ParseError>,
16}
17
18impl Parser {
19    /// Create a new parser
20    pub const fn new() -> Self {
21        Self {
22            tokens: Vec::new(),
23            position: 0,
24            errors: Vec::new(),
25        }
26    }
27
28    /// Set tokens for parsing
29    pub fn set_tokens(&mut self, tokens: Vec<Token>) {
30        self.tokens = tokens;
31        self.position = 0;
32        self.errors.clear();
33    }
34
35    /// Parse tokens into AST
36    pub fn parse(&mut self) -> Result<AST, ParseError> {
37        self.parse_program()
38    }
39
40    /// Parse program
41    fn parse_program(&mut self) -> Result<AST, ParseError> {
42        let mut declarations = Vec::new();
43        let mut objective = None;
44        let mut constraints = Vec::new();
45
46        while !self.is_at_end() {
47            match self.current_token() {
48                Token::Var | Token::Param => {
49                    declarations.push(self.parse_declaration()?);
50                }
51                Token::Minimize | Token::Maximize => {
52                    if objective.is_some() {
53                        return Err(ParseError {
54                            message: "Multiple objectives not supported yet".to_string(),
55                            line: 0,
56                            column: 0,
57                        });
58                    }
59                    objective = Some(self.parse_objective()?);
60                }
61                Token::Subject => {
62                    self.advance(); // consume 'subject'
63                    self.expect(Token::To)?;
64
65                    while !self.is_at_end() && !matches!(self.current_token(), Token::Eof) {
66                        constraints.push(self.parse_constraint()?);
67                    }
68                }
69                Token::NewLine | Token::Comment(_) => {
70                    self.advance();
71                }
72                _ => {
73                    return Err(ParseError {
74                        message: format!("Unexpected token: {:?}", self.current_token()),
75                        line: 0,
76                        column: 0,
77                    });
78                }
79            }
80        }
81
82        let obj = objective.ok_or_else(|| ParseError {
83            message: "No objective function found".to_string(),
84            line: 0,
85            column: 0,
86        })?;
87
88        Ok(AST::Program {
89            declarations,
90            objective: obj,
91            constraints,
92        })
93    }
94
95    /// Parse declaration
96    fn parse_declaration(&mut self) -> Result<Declaration, ParseError> {
97        match self.current_token() {
98            Token::Var => self.parse_variable_declaration(),
99            Token::Param => self.parse_parameter_declaration(),
100            _ => Err(ParseError {
101                message: "Expected variable or parameter declaration".to_string(),
102                line: 0,
103                column: 0,
104            }),
105        }
106    }
107
108    /// Parse variable declaration
109    fn parse_variable_declaration(&mut self) -> Result<Declaration, ParseError> {
110        self.advance(); // consume 'var'
111
112        let name = self.expect_identifier()?;
113        let var_type = self.parse_variable_type()?;
114
115        self.expect(Token::Semicolon)?;
116
117        Ok(Declaration::Variable {
118            name,
119            var_type,
120            domain: None,
121            attributes: std::collections::HashMap::new(),
122        })
123    }
124
125    /// Parse parameter declaration
126    fn parse_parameter_declaration(&mut self) -> Result<Declaration, ParseError> {
127        self.advance(); // consume 'param'
128
129        let name = self.expect_identifier()?;
130        self.expect(Token::Equal)?;
131        let value = self.parse_value()?;
132
133        self.expect(Token::Semicolon)?;
134
135        Ok(Declaration::Parameter {
136            name,
137            value,
138            description: None,
139        })
140    }
141
142    /// Parse variable type
143    fn parse_variable_type(&mut self) -> Result<super::types::VarType, ParseError> {
144        use super::types::VarType;
145
146        match self.current_token() {
147            Token::Binary => {
148                self.advance();
149                Ok(VarType::Binary)
150            }
151            Token::Integer => {
152                self.advance();
153                Ok(VarType::Integer)
154            }
155            Token::Continuous => {
156                self.advance();
157                Ok(VarType::Continuous)
158            }
159            _ => Err(ParseError {
160                message: "Expected variable type (binary, integer, continuous)".to_string(),
161                line: 0,
162                column: 0,
163            }),
164        }
165    }
166
167    /// Parse value
168    fn parse_value(&mut self) -> Result<Value, ParseError> {
169        match self.current_token() {
170            Token::Number(n) => {
171                let value = *n;
172                self.advance();
173                Ok(Value::Number(value))
174            }
175            Token::Boolean(b) => {
176                let value = *b;
177                self.advance();
178                Ok(Value::Boolean(value))
179            }
180            Token::String(s) => {
181                let value = s.clone();
182                self.advance();
183                Ok(Value::String(value))
184            }
185            Token::LeftBracket => {
186                self.advance(); // consume '['
187                let mut elements = Vec::new();
188
189                while !matches!(self.current_token(), Token::RightBracket) {
190                    elements.push(self.parse_value()?);
191
192                    if matches!(self.current_token(), Token::Comma) {
193                        self.advance();
194                    } else {
195                        break;
196                    }
197                }
198
199                self.expect(Token::RightBracket)?;
200                Ok(Value::Array(elements))
201            }
202            _ => Err(ParseError {
203                message: "Expected value".to_string(),
204                line: 0,
205                column: 0,
206            }),
207        }
208    }
209
210    /// Parse objective
211    fn parse_objective(&mut self) -> Result<Objective, ParseError> {
212        match self.current_token() {
213            Token::Minimize => {
214                self.advance();
215                let expr = self.parse_expression()?;
216                self.expect(Token::Semicolon)?;
217                Ok(Objective::Minimize(expr))
218            }
219            Token::Maximize => {
220                self.advance();
221                let expr = self.parse_expression()?;
222                self.expect(Token::Semicolon)?;
223                Ok(Objective::Maximize(expr))
224            }
225            _ => Err(ParseError {
226                message: "Expected minimize or maximize".to_string(),
227                line: 0,
228                column: 0,
229            }),
230        }
231    }
232
233    /// Parse constraint
234    fn parse_constraint(&mut self) -> Result<Constraint, ParseError> {
235        let expression = self.parse_constraint_expression()?;
236        self.expect(Token::Semicolon)?;
237
238        Ok(Constraint {
239            name: None,
240            expression,
241            tags: Vec::new(),
242        })
243    }
244
245    /// Parse constraint expression
246    fn parse_constraint_expression(&mut self) -> Result<ConstraintExpression, ParseError> {
247        let left = self.parse_expression()?;
248
249        let op = match self.current_token() {
250            Token::Equal => ComparisonOp::Equal,
251            Token::NotEqual => ComparisonOp::NotEqual,
252            Token::Less => ComparisonOp::Less,
253            Token::Greater => ComparisonOp::Greater,
254            Token::LessEqual => ComparisonOp::LessEqual,
255            Token::GreaterEqual => ComparisonOp::GreaterEqual,
256            _ => {
257                return Err(ParseError {
258                    message: "Expected comparison operator".to_string(),
259                    line: 0,
260                    column: 0,
261                })
262            }
263        };
264
265        self.advance(); // consume operator
266        let right = self.parse_expression()?;
267
268        Ok(ConstraintExpression::Comparison { left, op, right })
269    }
270
271    /// Parse expression
272    fn parse_expression(&mut self) -> Result<Expression, ParseError> {
273        self.parse_additive()
274    }
275
276    /// Parse additive expression
277    fn parse_additive(&mut self) -> Result<Expression, ParseError> {
278        let mut expr = self.parse_multiplicative()?;
279
280        while matches!(self.current_token(), Token::Plus | Token::Minus) {
281            let op = match self.current_token() {
282                Token::Plus => BinaryOperator::Add,
283                Token::Minus => BinaryOperator::Subtract,
284                _ => unreachable!(),
285            };
286            self.advance();
287            let right = self.parse_multiplicative()?;
288            expr = Expression::BinaryOp {
289                op,
290                left: Box::new(expr),
291                right: Box::new(right),
292            };
293        }
294
295        Ok(expr)
296    }
297
298    /// Parse multiplicative expression
299    fn parse_multiplicative(&mut self) -> Result<Expression, ParseError> {
300        let mut expr = self.parse_primary()?;
301
302        while matches!(self.current_token(), Token::Times | Token::Divide) {
303            let op = match self.current_token() {
304                Token::Times => BinaryOperator::Multiply,
305                Token::Divide => BinaryOperator::Divide,
306                _ => unreachable!(),
307            };
308            self.advance();
309            let right = self.parse_primary()?;
310            expr = Expression::BinaryOp {
311                op,
312                left: Box::new(expr),
313                right: Box::new(right),
314            };
315        }
316
317        Ok(expr)
318    }
319
320    /// Parse primary expression
321    fn parse_primary(&mut self) -> Result<Expression, ParseError> {
322        match self.current_token() {
323            Token::Number(n) => {
324                let value = *n;
325                self.advance();
326                Ok(Expression::Literal(Value::Number(value)))
327            }
328            Token::Boolean(b) => {
329                let value = *b;
330                self.advance();
331                Ok(Expression::Literal(Value::Boolean(value)))
332            }
333            Token::String(s) => {
334                let value = s.clone();
335                self.advance();
336                Ok(Expression::Literal(Value::String(value)))
337            }
338            Token::Identifier(name) => {
339                let var_name = name.clone();
340                self.advance();
341
342                // Check for indexing
343                if matches!(self.current_token(), Token::LeftBracket) {
344                    self.advance(); // consume '['
345                    let mut indices = Vec::new();
346
347                    loop {
348                        indices.push(self.parse_expression()?);
349
350                        if matches!(self.current_token(), Token::Comma) {
351                            self.advance();
352                        } else {
353                            break;
354                        }
355                    }
356
357                    self.expect(Token::RightBracket)?;
358                    Ok(Expression::IndexedVar {
359                        name: var_name,
360                        indices,
361                    })
362                } else {
363                    Ok(Expression::Variable(var_name))
364                }
365            }
366            Token::LeftParen => {
367                self.advance(); // consume '('
368                let expr = self.parse_expression()?;
369                self.expect(Token::RightParen)?;
370                Ok(expr)
371            }
372            _ => Err(ParseError {
373                message: "Expected expression".to_string(),
374                line: 0,
375                column: 0,
376            }),
377        }
378    }
379
380    /// Current token
381    fn current_token(&self) -> &Token {
382        self.tokens.get(self.position).unwrap_or(&Token::Eof)
383    }
384
385    /// Advance to next token
386    fn advance(&mut self) {
387        if !self.is_at_end() {
388            self.position += 1;
389        }
390    }
391
392    /// Check if at end of tokens
393    fn is_at_end(&self) -> bool {
394        self.position >= self.tokens.len() || matches!(self.current_token(), Token::Eof)
395    }
396
397    /// Expect specific token
398    fn expect(&mut self, expected: Token) -> Result<(), ParseError> {
399        if std::mem::discriminant(self.current_token()) == std::mem::discriminant(&expected) {
400            self.advance();
401            Ok(())
402        } else {
403            Err(ParseError {
404                message: format!("Expected {:?}, found {:?}", expected, self.current_token()),
405                line: 0,
406                column: 0,
407            })
408        }
409    }
410
411    /// Expect identifier and return its name
412    fn expect_identifier(&mut self) -> Result<String, ParseError> {
413        match self.current_token() {
414            Token::Identifier(name) => {
415                let result = name.clone();
416                self.advance();
417                Ok(result)
418            }
419            _ => Err(ParseError {
420                message: "Expected identifier".to_string(),
421                line: 0,
422                column: 0,
423            }),
424        }
425    }
426}
427
428impl Default for Parser {
429    fn default() -> Self {
430        Self::new()
431    }
432}