quantrs2_circuit/qasm/
parser.rs

1//! Parser for `OpenQASM` 3.0
2
3use super::ast::{
4    BinaryOp, ClassicalRef, ComparisonOp, Condition, Declaration, Expression, ForLoop,
5    GateDefinition, Literal, Measurement, QasmGate, QasmProgram, QasmRegister, QasmStatement,
6    QubitRef, UnaryOp,
7};
8use std::collections::HashMap;
9use std::str::FromStr;
10use thiserror::Error;
11
12/// Parser error types
13#[derive(Debug, Error)]
14pub enum ParseError {
15    #[error("Unexpected token: {0}")]
16    UnexpectedToken(String),
17
18    #[error("Expected {expected}, found {found}")]
19    ExpectedToken { expected: String, found: String },
20
21    #[error("Invalid syntax: {0}")]
22    InvalidSyntax(String),
23
24    #[error("Undefined identifier: {0}")]
25    UndefinedIdentifier(String),
26
27    #[error("Type mismatch: {0}")]
28    TypeMismatch(String),
29
30    #[error("Invalid number: {0}")]
31    InvalidNumber(String),
32
33    #[error("Unexpected end of input")]
34    UnexpectedEof,
35
36    #[error("Version mismatch: expected 3.0, found {0}")]
37    VersionMismatch(String),
38}
39
40/// Token types for lexing
41#[derive(Debug, Clone, PartialEq)]
42enum Token {
43    // Keywords
44    OpenQasm,
45    Include,
46    Qubit,
47    Bit,
48    Gate,
49    Measure,
50    Reset,
51    Barrier,
52    If,
53    Else,
54    For,
55    While,
56    In,
57    Const,
58    Def,
59    Return,
60    Delay,
61    Ctrl,
62    Inv,
63    Pow,
64
65    // Identifiers and literals
66    Identifier(String),
67    Integer(i64),
68    Float(f64),
69    String(String),
70
71    // Operators
72    Plus,
73    Minus,
74    Star,
75    Slash,
76    Percent,
77    Power,
78    Assign,
79    Eq,
80    Ne,
81    Lt,
82    Le,
83    Gt,
84    Ge,
85    And,
86    Or,
87    Not,
88    BitAnd,
89    BitOr,
90    BitXor,
91    BitNot,
92    Shl,
93    Shr,
94    Arrow,
95
96    // Delimiters
97    LeftParen,
98    RightParen,
99    LeftBracket,
100    RightBracket,
101    LeftBrace,
102    RightBrace,
103    Semicolon,
104    Comma,
105    Colon,
106    Dot,
107
108    // Special
109    Eof,
110}
111
112/// Lexer for tokenizing QASM input
113struct Lexer<'a> {
114    input: &'a str,
115    position: usize,
116    current: Option<char>,
117}
118
119impl<'a> Lexer<'a> {
120    fn new(input: &'a str) -> Self {
121        let mut lexer = Lexer {
122            input,
123            position: 0,
124            current: None,
125        };
126        lexer.advance();
127        lexer
128    }
129
130    fn advance(&mut self) {
131        self.current = self.input.chars().nth(self.position);
132        if self.current.is_some() {
133            self.position += 1;
134        }
135    }
136
137    fn peek(&self) -> Option<char> {
138        self.input.chars().nth(self.position)
139    }
140
141    fn skip_whitespace(&mut self) {
142        while let Some(ch) = self.current {
143            if ch.is_whitespace() {
144                self.advance();
145            } else if ch == '/' && self.peek() == Some('/') {
146                // Skip line comment
147                while self.current.is_some() && self.current != Some('\n') {
148                    self.advance();
149                }
150            } else if ch == '/' && self.peek() == Some('*') {
151                // Skip block comment
152                self.advance(); // skip '/'
153                self.advance(); // skip '*'
154                while self.current.is_some() {
155                    if self.current == Some('*') && self.peek() == Some('/') {
156                        self.advance(); // skip '*'
157                        self.advance(); // skip '/'
158                        break;
159                    }
160                    self.advance();
161                }
162            } else {
163                break;
164            }
165        }
166    }
167
168    fn read_identifier(&mut self) -> String {
169        let mut result = String::new();
170        while let Some(ch) = self.current {
171            if ch.is_alphanumeric() || ch == '_' {
172                result.push(ch);
173                self.advance();
174            } else {
175                break;
176            }
177        }
178        result
179    }
180
181    fn read_number(&mut self) -> Result<Token, ParseError> {
182        let mut result = String::new();
183        let mut has_dot = false;
184
185        while let Some(ch) = self.current {
186            if ch.is_numeric() {
187                result.push(ch);
188                self.advance();
189            } else if ch == '.' && !has_dot && self.peek().is_some_and(char::is_numeric) {
190                has_dot = true;
191                result.push(ch);
192                self.advance();
193            } else if ch == 'e' || ch == 'E' {
194                result.push(ch);
195                self.advance();
196                if let Some(sign_ch) = self.current {
197                    if sign_ch == '+' || sign_ch == '-' {
198                        result.push(sign_ch);
199                        self.advance();
200                    }
201                }
202            } else {
203                break;
204            }
205        }
206
207        if has_dot || result.contains('e') || result.contains('E') {
208            result
209                .parse::<f64>()
210                .map(Token::Float)
211                .map_err(|_| ParseError::InvalidNumber(result))
212        } else {
213            result
214                .parse::<i64>()
215                .map(Token::Integer)
216                .map_err(|_| ParseError::InvalidNumber(result))
217        }
218    }
219
220    fn read_string(&mut self) -> Result<String, ParseError> {
221        let mut result = String::new();
222        self.advance(); // skip opening quote
223
224        while let Some(ch) = self.current {
225            if ch == '"' {
226                self.advance(); // skip closing quote
227                return Ok(result);
228            } else if ch == '\\' {
229                self.advance();
230                match self.current {
231                    Some('n') => result.push('\n'),
232                    Some('t') => result.push('\t'),
233                    Some('r') => result.push('\r'),
234                    Some('\\') => result.push('\\'),
235                    Some('"') => result.push('"'),
236                    _ => return Err(ParseError::InvalidSyntax("Invalid escape sequence".into())),
237                }
238                self.advance();
239            } else {
240                result.push(ch);
241                self.advance();
242            }
243        }
244
245        Err(ParseError::UnexpectedEof)
246    }
247
248    fn next_token(&mut self) -> Result<Token, ParseError> {
249        self.skip_whitespace();
250
251        match self.current {
252            None => Ok(Token::Eof),
253            Some(ch) => match ch {
254                '+' => {
255                    self.advance();
256                    Ok(Token::Plus)
257                }
258                '*' => {
259                    self.advance();
260                    if self.current == Some('*') {
261                        self.advance();
262                        Ok(Token::Power)
263                    } else {
264                        Ok(Token::Star)
265                    }
266                }
267                '/' => {
268                    self.advance();
269                    Ok(Token::Slash)
270                }
271                '%' => {
272                    self.advance();
273                    Ok(Token::Percent)
274                }
275                '(' => {
276                    self.advance();
277                    Ok(Token::LeftParen)
278                }
279                ')' => {
280                    self.advance();
281                    Ok(Token::RightParen)
282                }
283                '[' => {
284                    self.advance();
285                    Ok(Token::LeftBracket)
286                }
287                ']' => {
288                    self.advance();
289                    Ok(Token::RightBracket)
290                }
291                '{' => {
292                    self.advance();
293                    Ok(Token::LeftBrace)
294                }
295                '}' => {
296                    self.advance();
297                    Ok(Token::RightBrace)
298                }
299                ';' => {
300                    self.advance();
301                    Ok(Token::Semicolon)
302                }
303                ',' => {
304                    self.advance();
305                    Ok(Token::Comma)
306                }
307                ':' => {
308                    self.advance();
309                    Ok(Token::Colon)
310                }
311                '.' => {
312                    self.advance();
313                    Ok(Token::Dot)
314                }
315                '~' => {
316                    self.advance();
317                    Ok(Token::BitNot)
318                }
319                '"' => self.read_string().map(Token::String),
320                '-' => {
321                    self.advance();
322                    if self.current == Some('>') {
323                        self.advance();
324                        Ok(Token::Arrow)
325                    } else {
326                        Ok(Token::Minus)
327                    }
328                }
329                '=' => {
330                    self.advance();
331                    if self.current == Some('=') {
332                        self.advance();
333                        Ok(Token::Eq)
334                    } else {
335                        Ok(Token::Assign)
336                    }
337                }
338                '!' => {
339                    self.advance();
340                    if self.current == Some('=') {
341                        self.advance();
342                        Ok(Token::Ne)
343                    } else {
344                        Ok(Token::Not)
345                    }
346                }
347                '<' => {
348                    self.advance();
349                    match self.current {
350                        Some('=') => {
351                            self.advance();
352                            Ok(Token::Le)
353                        }
354                        Some('<') => {
355                            self.advance();
356                            Ok(Token::Shl)
357                        }
358                        _ => Ok(Token::Lt),
359                    }
360                }
361                '>' => {
362                    self.advance();
363                    match self.current {
364                        Some('=') => {
365                            self.advance();
366                            Ok(Token::Ge)
367                        }
368                        Some('>') => {
369                            self.advance();
370                            Ok(Token::Shr)
371                        }
372                        _ => Ok(Token::Gt),
373                    }
374                }
375                '&' => {
376                    self.advance();
377                    if self.current == Some('&') {
378                        self.advance();
379                        Ok(Token::And)
380                    } else {
381                        Ok(Token::BitAnd)
382                    }
383                }
384                '|' => {
385                    self.advance();
386                    if self.current == Some('|') {
387                        self.advance();
388                        Ok(Token::Or)
389                    } else {
390                        Ok(Token::BitOr)
391                    }
392                }
393                '^' => {
394                    self.advance();
395                    Ok(Token::BitXor)
396                }
397                _ if ch.is_alphabetic() || ch == '_' => {
398                    let ident = self.read_identifier();
399                    Ok(match ident.as_str() {
400                        "OPENQASM" => Token::OpenQasm,
401                        "include" => Token::Include,
402                        "qubit" => Token::Qubit,
403                        "bit" => Token::Bit,
404                        "gate" => Token::Gate,
405                        "measure" => Token::Measure,
406                        "reset" => Token::Reset,
407                        "barrier" => Token::Barrier,
408                        "if" => Token::If,
409                        "else" => Token::Else,
410                        "for" => Token::For,
411                        "while" => Token::While,
412                        "in" => Token::In,
413                        "const" => Token::Const,
414                        "def" => Token::Def,
415                        "return" => Token::Return,
416                        "delay" => Token::Delay,
417                        "ctrl" => Token::Ctrl,
418                        "inv" => Token::Inv,
419                        "pow" => Token::Pow,
420                        "pi" => Token::Identifier("pi".into()),
421                        "e" => Token::Identifier("e".into()),
422                        "tau" => Token::Identifier("tau".into()),
423                        _ => Token::Identifier(ident),
424                    })
425                }
426                _ if ch.is_numeric() => self.read_number(),
427                _ => Err(ParseError::UnexpectedToken(ch.to_string())),
428            },
429        }
430    }
431}
432
433/// QASM parser
434pub struct QasmParser<'a> {
435    lexer: Lexer<'a>,
436    current_token: Token,
437    /// Symbol table for tracking declarations
438    symbols: HashMap<String, SymbolType>,
439}
440
441#[derive(Debug, Clone)]
442enum SymbolType {
443    QuantumRegister(usize),
444    ClassicalRegister(usize),
445    Gate(Vec<String>, Vec<String>), // params, qubits
446    Constant,
447    Variable,
448}
449
450impl<'a> QasmParser<'a> {
451    /// Create a new parser for the given input
452    pub fn new(input: &'a str) -> Result<Self, ParseError> {
453        let mut lexer = Lexer::new(input);
454        let current_token = lexer.next_token()?;
455
456        Ok(QasmParser {
457            lexer,
458            current_token,
459            symbols: HashMap::new(),
460        })
461    }
462
463    /// Parse a complete QASM program
464    pub fn parse_program(&mut self) -> Result<QasmProgram, ParseError> {
465        // Parse version declaration
466        self.expect_token(&Token::OpenQasm)?;
467        let version = self.parse_version()?;
468        self.expect_token(&Token::Semicolon)?;
469
470        // Parse includes
471        let mut includes = Vec::new();
472        while self.current_token == Token::Include {
473            includes.push(self.parse_include()?);
474        }
475
476        // Parse declarations and statements
477        let mut declarations = Vec::new();
478        let mut statements = Vec::new();
479
480        while self.current_token != Token::Eof {
481            match &self.current_token {
482                Token::Qubit => declarations.push(self.parse_quantum_register()?),
483                Token::Bit => declarations.push(self.parse_classical_register()?),
484                Token::Gate => declarations.push(self.parse_gate_definition()?),
485                Token::Const => declarations.push(self.parse_constant()?),
486                _ => statements.push(self.parse_statement()?),
487            }
488        }
489
490        Ok(QasmProgram {
491            version,
492            includes,
493            declarations,
494            statements,
495        })
496    }
497
498    fn advance(&mut self) -> Result<(), ParseError> {
499        self.current_token = self.lexer.next_token()?;
500        Ok(())
501    }
502
503    fn expect_token(&mut self, expected: &Token) -> Result<(), ParseError> {
504        if std::mem::discriminant(&self.current_token) == std::mem::discriminant(expected) {
505            self.advance()
506        } else {
507            Err(ParseError::ExpectedToken {
508                expected: format!("{expected:?}"),
509                found: format!("{:?}", self.current_token),
510            })
511        }
512    }
513
514    fn parse_version(&mut self) -> Result<String, ParseError> {
515        match &self.current_token {
516            Token::Float(v) => {
517                let version = if *v == 3.0 {
518                    "3.0".to_string()
519                } else {
520                    format!("{v}")
521                };
522                if !version.starts_with("3.") {
523                    return Err(ParseError::VersionMismatch(version));
524                }
525                self.advance()?;
526                Ok(version)
527            }
528            Token::Integer(v) if *v == 3 => {
529                // Check if next token is a dot followed by a number
530                self.advance()?;
531                if self.current_token == Token::Dot {
532                    self.advance()?;
533                    if let Token::Integer(minor) = self.current_token.clone() {
534                        let minor_val = minor;
535                        self.advance()?;
536                        Ok(format!("3.{minor_val}"))
537                    } else {
538                        Ok("3.0".to_string())
539                    }
540                } else {
541                    Ok("3.0".to_string())
542                }
543            }
544            _ => Err(ParseError::ExpectedToken {
545                expected: "version number".into(),
546                found: format!("{:?}", self.current_token),
547            }),
548        }
549    }
550
551    fn parse_include(&mut self) -> Result<String, ParseError> {
552        self.expect_token(&Token::Include)?;
553
554        match &self.current_token {
555            Token::String(s) => {
556                let include = s.clone();
557                self.advance()?;
558                self.expect_token(&Token::Semicolon)?;
559                Ok(include)
560            }
561            _ => Err(ParseError::ExpectedToken {
562                expected: "string".into(),
563                found: format!("{:?}", self.current_token),
564            }),
565        }
566    }
567
568    fn parse_quantum_register(&mut self) -> Result<Declaration, ParseError> {
569        self.expect_token(&Token::Qubit)?;
570
571        let (size, name) = if self.current_token == Token::LeftBracket {
572            // qubit[size] name format
573            self.advance()?; // consume [
574
575            let size = match &self.current_token {
576                Token::Integer(n) => {
577                    let size = *n as usize;
578                    self.advance()?;
579                    size
580                }
581                Token::Identifier(_) => {
582                    // For constants like 'n', we'll use a default size of 4
583                    // In a full implementation, we'd evaluate the constant
584                    self.advance()?;
585                    4 // placeholder
586                }
587                _ => {
588                    return Err(ParseError::ExpectedToken {
589                        expected: "integer or identifier".into(),
590                        found: format!("{:?}", self.current_token),
591                    })
592                }
593            };
594
595            self.expect_token(&Token::RightBracket)?;
596
597            let name = match &self.current_token {
598                Token::Identifier(s) => s.clone(),
599                _ => {
600                    return Err(ParseError::ExpectedToken {
601                        expected: "identifier".into(),
602                        found: format!("{:?}", self.current_token),
603                    })
604                }
605            };
606            self.advance()?;
607
608            (size, name)
609        } else {
610            // qubit name format (single qubit)
611            let name = match &self.current_token {
612                Token::Identifier(s) => s.clone(),
613                _ => {
614                    return Err(ParseError::ExpectedToken {
615                        expected: "identifier".into(),
616                        found: format!("{:?}", self.current_token),
617                    })
618                }
619            };
620            self.advance()?;
621
622            (1, name)
623        };
624
625        self.expect_token(&Token::Semicolon)?;
626
627        // Add to symbol table
628        self.symbols
629            .insert(name.clone(), SymbolType::QuantumRegister(size));
630
631        Ok(Declaration::QuantumRegister(QasmRegister { name, size }))
632    }
633
634    fn parse_classical_register(&mut self) -> Result<Declaration, ParseError> {
635        self.expect_token(&Token::Bit)?;
636
637        let (size, name) = if self.current_token == Token::LeftBracket {
638            // bit[size] name format
639            self.advance()?; // consume [
640
641            let size = match &self.current_token {
642                Token::Integer(n) => {
643                    let size = *n as usize;
644                    self.advance()?;
645                    size
646                }
647                Token::Identifier(_) => {
648                    // For constants like 'n', we'll use a default size of 4
649                    // In a full implementation, we'd evaluate the constant
650                    self.advance()?;
651                    4 // placeholder
652                }
653                _ => {
654                    return Err(ParseError::ExpectedToken {
655                        expected: "integer or identifier".into(),
656                        found: format!("{:?}", self.current_token),
657                    })
658                }
659            };
660
661            self.expect_token(&Token::RightBracket)?;
662
663            let name = match &self.current_token {
664                Token::Identifier(s) => s.clone(),
665                _ => {
666                    return Err(ParseError::ExpectedToken {
667                        expected: "identifier".into(),
668                        found: format!("{:?}", self.current_token),
669                    })
670                }
671            };
672            self.advance()?;
673
674            (size, name)
675        } else {
676            // bit name format (single bit)
677            let name = match &self.current_token {
678                Token::Identifier(s) => s.clone(),
679                _ => {
680                    return Err(ParseError::ExpectedToken {
681                        expected: "identifier".into(),
682                        found: format!("{:?}", self.current_token),
683                    })
684                }
685            };
686            self.advance()?;
687
688            (1, name)
689        };
690
691        self.expect_token(&Token::Semicolon)?;
692
693        // Add to symbol table
694        self.symbols
695            .insert(name.clone(), SymbolType::ClassicalRegister(size));
696
697        Ok(Declaration::ClassicalRegister(QasmRegister { name, size }))
698    }
699
700    fn parse_gate_definition(&mut self) -> Result<Declaration, ParseError> {
701        self.expect_token(&Token::Gate)?;
702
703        let name = match &self.current_token {
704            Token::Identifier(s) => s.clone(),
705            _ => {
706                return Err(ParseError::ExpectedToken {
707                    expected: "identifier".into(),
708                    found: format!("{:?}", self.current_token),
709                })
710            }
711        };
712        self.advance()?;
713
714        // Parse parameters
715        let mut params = Vec::new();
716        if self.current_token == Token::LeftParen {
717            self.advance()?;
718
719            while self.current_token != Token::RightParen {
720                match &self.current_token {
721                    Token::Identifier(s) => {
722                        params.push(s.clone());
723                        self.advance()?;
724                    }
725                    _ => {
726                        return Err(ParseError::ExpectedToken {
727                            expected: "identifier".into(),
728                            found: format!("{:?}", self.current_token),
729                        })
730                    }
731                }
732
733                if self.current_token == Token::Comma {
734                    self.advance()?;
735                }
736            }
737
738            self.expect_token(&Token::RightParen)?;
739        }
740
741        // Parse qubit arguments
742        let mut qubits = Vec::new();
743        while self.current_token != Token::LeftBrace {
744            match &self.current_token {
745                Token::Identifier(s) => {
746                    qubits.push(s.clone());
747                    self.advance()?;
748                }
749                _ => {
750                    return Err(ParseError::ExpectedToken {
751                        expected: "identifier".into(),
752                        found: format!("{:?}", self.current_token),
753                    })
754                }
755            }
756
757            if self.current_token == Token::Comma {
758                self.advance()?;
759            }
760        }
761
762        // Parse body
763        self.expect_token(&Token::LeftBrace)?;
764        let mut body = Vec::new();
765
766        while self.current_token != Token::RightBrace {
767            body.push(self.parse_statement()?);
768        }
769
770        self.expect_token(&Token::RightBrace)?;
771
772        // Add to symbol table
773        self.symbols.insert(
774            name.clone(),
775            SymbolType::Gate(params.clone(), qubits.clone()),
776        );
777
778        Ok(Declaration::GateDefinition(GateDefinition {
779            name,
780            params,
781            qubits,
782            body,
783        }))
784    }
785
786    fn parse_constant(&mut self) -> Result<Declaration, ParseError> {
787        self.expect_token(&Token::Const)?;
788
789        let name = match &self.current_token {
790            Token::Identifier(s) => s.clone(),
791            _ => {
792                return Err(ParseError::ExpectedToken {
793                    expected: "identifier".into(),
794                    found: format!("{:?}", self.current_token),
795                })
796            }
797        };
798        self.advance()?;
799
800        self.expect_token(&Token::Assign)?;
801
802        let expr = self.parse_expression()?;
803
804        self.expect_token(&Token::Semicolon)?;
805
806        // Add to symbol table
807        self.symbols.insert(name.clone(), SymbolType::Constant);
808
809        Ok(Declaration::Constant(name, expr))
810    }
811
812    fn parse_statement(&mut self) -> Result<QasmStatement, ParseError> {
813        match &self.current_token {
814            Token::Measure => self.parse_measure(),
815            Token::Reset => self.parse_reset(),
816            Token::Barrier => self.parse_barrier(),
817            Token::If => self.parse_if(),
818            Token::For => self.parse_for(),
819            Token::While => self.parse_while(),
820            Token::Delay => self.parse_delay(),
821            Token::Identifier(_) => {
822                // Could be gate application, assignment, or function call
823                self.parse_identifier_statement()
824            }
825            Token::Ctrl | Token::Inv | Token::Pow => self.parse_modified_gate(),
826            _ => Err(ParseError::UnexpectedToken(format!(
827                "{:?}",
828                self.current_token
829            ))),
830        }
831    }
832
833    // Simplified implementations for brevity - full parser would implement all methods
834
835    fn parse_measure(&mut self) -> Result<QasmStatement, ParseError> {
836        self.expect_token(&Token::Measure)?;
837
838        let mut qubits = Vec::new();
839        let mut targets = Vec::new();
840
841        // Parse first qubit -> classical pair
842        qubits.push(self.parse_qubit_ref()?);
843        self.expect_token(&Token::Arrow)?;
844        targets.push(self.parse_classical_ref()?);
845
846        // Parse additional pairs
847        while self.current_token == Token::Comma {
848            self.advance()?;
849            qubits.push(self.parse_qubit_ref()?);
850            self.expect_token(&Token::Arrow)?;
851            targets.push(self.parse_classical_ref()?);
852        }
853
854        self.expect_token(&Token::Semicolon)?;
855
856        Ok(QasmStatement::Measure(Measurement { qubits, targets }))
857    }
858
859    fn parse_reset(&mut self) -> Result<QasmStatement, ParseError> {
860        self.expect_token(&Token::Reset)?;
861
862        let mut qubits = Vec::new();
863        qubits.push(self.parse_qubit_ref()?);
864
865        while self.current_token == Token::Comma {
866            self.advance()?;
867            qubits.push(self.parse_qubit_ref()?);
868        }
869
870        self.expect_token(&Token::Semicolon)?;
871
872        Ok(QasmStatement::Reset(qubits))
873    }
874
875    fn parse_barrier(&mut self) -> Result<QasmStatement, ParseError> {
876        self.expect_token(&Token::Barrier)?;
877
878        let mut qubits = Vec::new();
879
880        if self.current_token != Token::Semicolon {
881            qubits.push(self.parse_qubit_ref()?);
882
883            while self.current_token == Token::Comma {
884                self.advance()?;
885                qubits.push(self.parse_qubit_ref()?);
886            }
887        }
888
889        self.expect_token(&Token::Semicolon)?;
890
891        Ok(QasmStatement::Barrier(qubits))
892    }
893
894    fn parse_if(&mut self) -> Result<QasmStatement, ParseError> {
895        self.expect_token(&Token::If)?;
896        self.expect_token(&Token::LeftParen)?;
897
898        let condition = self.parse_condition()?;
899
900        self.expect_token(&Token::RightParen)?;
901
902        let statement = Box::new(self.parse_statement()?);
903
904        Ok(QasmStatement::If(condition, statement))
905    }
906
907    fn parse_for(&mut self) -> Result<QasmStatement, ParseError> {
908        self.expect_token(&Token::For)?;
909
910        let variable = match &self.current_token {
911            Token::Identifier(s) => s.clone(),
912            _ => {
913                return Err(ParseError::ExpectedToken {
914                    expected: "identifier".into(),
915                    found: format!("{:?}", self.current_token),
916                })
917            }
918        };
919        self.advance()?;
920
921        self.expect_token(&Token::In)?;
922        self.expect_token(&Token::LeftBracket)?;
923
924        let start = self.parse_expression()?;
925        self.expect_token(&Token::Colon)?;
926        let end = self.parse_expression()?;
927
928        let step = if self.current_token == Token::Colon {
929            self.advance()?;
930            Some(self.parse_expression()?)
931        } else {
932            None
933        };
934
935        self.expect_token(&Token::RightBracket)?;
936        self.expect_token(&Token::LeftBrace)?;
937
938        let mut body = Vec::new();
939        while self.current_token != Token::RightBrace {
940            body.push(self.parse_statement()?);
941        }
942
943        self.expect_token(&Token::RightBrace)?;
944
945        Ok(QasmStatement::For(ForLoop {
946            variable,
947            start,
948            end,
949            step,
950            body,
951        }))
952    }
953
954    fn parse_while(&mut self) -> Result<QasmStatement, ParseError> {
955        self.expect_token(&Token::While)?;
956        self.expect_token(&Token::LeftParen)?;
957
958        let condition = self.parse_condition()?;
959
960        self.expect_token(&Token::RightParen)?;
961        self.expect_token(&Token::LeftBrace)?;
962
963        let mut body = Vec::new();
964        while self.current_token != Token::RightBrace {
965            body.push(self.parse_statement()?);
966        }
967
968        self.expect_token(&Token::RightBrace)?;
969
970        Ok(QasmStatement::While(condition, body))
971    }
972
973    fn parse_delay(&mut self) -> Result<QasmStatement, ParseError> {
974        self.expect_token(&Token::Delay)?;
975        self.expect_token(&Token::LeftBracket)?;
976
977        let duration = self.parse_expression()?;
978
979        self.expect_token(&Token::RightBracket)?;
980
981        let mut qubits = Vec::new();
982
983        if self.current_token != Token::Semicolon {
984            qubits.push(self.parse_qubit_ref()?);
985
986            while self.current_token == Token::Comma {
987                self.advance()?;
988                qubits.push(self.parse_qubit_ref()?);
989            }
990        }
991
992        self.expect_token(&Token::Semicolon)?;
993
994        Ok(QasmStatement::Delay(duration, qubits))
995    }
996
997    fn parse_identifier_statement(&mut self) -> Result<QasmStatement, ParseError> {
998        let name = match &self.current_token {
999            Token::Identifier(s) => s.clone(),
1000            _ => return Err(ParseError::InvalidSyntax("Expected identifier".into())),
1001        };
1002        self.advance()?;
1003
1004        match &self.current_token {
1005            Token::LeftParen => {
1006                // Function call or gate with parameters
1007                self.parse_gate_or_call(name)
1008            }
1009            Token::LeftBracket | Token::Identifier(_) => {
1010                // Gate application
1011                let mut gate = QasmGate {
1012                    name,
1013                    params: Vec::new(),
1014                    qubits: Vec::new(),
1015                    control: None,
1016                    inverse: false,
1017                    power: None,
1018                };
1019
1020                // Parse qubits
1021                gate.qubits.push(self.parse_qubit_ref()?);
1022
1023                while self.current_token == Token::Comma {
1024                    self.advance()?;
1025                    gate.qubits.push(self.parse_qubit_ref()?);
1026                }
1027
1028                self.expect_token(&Token::Semicolon)?;
1029
1030                Ok(QasmStatement::Gate(gate))
1031            }
1032            _ => Err(ParseError::InvalidSyntax("Invalid statement".into())),
1033        }
1034    }
1035
1036    fn parse_modified_gate(&mut self) -> Result<QasmStatement, ParseError> {
1037        let mut control = None;
1038        let mut inverse = false;
1039        let mut power = None;
1040
1041        // Parse modifiers
1042        loop {
1043            match &self.current_token {
1044                Token::Ctrl => {
1045                    self.advance()?;
1046                    if self.current_token == Token::LeftParen {
1047                        self.advance()?;
1048                        control = Some(match &self.current_token {
1049                            Token::Integer(n) => *n as usize,
1050                            _ => {
1051                                return Err(ParseError::ExpectedToken {
1052                                    expected: "integer".into(),
1053                                    found: format!("{:?}", self.current_token),
1054                                })
1055                            }
1056                        });
1057                        self.advance()?;
1058                        self.expect_token(&Token::RightParen)?;
1059                    } else {
1060                        control = Some(1);
1061                    }
1062                }
1063                Token::Inv => {
1064                    inverse = true;
1065                    self.advance()?;
1066                }
1067                Token::Pow => {
1068                    self.advance()?;
1069                    self.expect_token(&Token::LeftParen)?;
1070                    power = Some(self.parse_expression()?);
1071                    self.expect_token(&Token::RightParen)?;
1072                }
1073                _ => break,
1074            }
1075        }
1076
1077        // Parse gate name
1078        let name = match &self.current_token {
1079            Token::Identifier(s) => s.clone(),
1080            _ => {
1081                return Err(ParseError::ExpectedToken {
1082                    expected: "gate name".into(),
1083                    found: format!("{:?}", self.current_token),
1084                })
1085            }
1086        };
1087        self.advance()?;
1088
1089        // Parse parameters if present
1090        let mut params = Vec::new();
1091        if self.current_token == Token::LeftParen {
1092            self.advance()?;
1093
1094            while self.current_token != Token::RightParen {
1095                params.push(self.parse_expression()?);
1096
1097                if self.current_token == Token::Comma {
1098                    self.advance()?;
1099                }
1100            }
1101
1102            self.expect_token(&Token::RightParen)?;
1103        }
1104
1105        // Parse qubits
1106        let mut qubits = Vec::new();
1107        qubits.push(self.parse_qubit_ref()?);
1108
1109        while self.current_token == Token::Comma {
1110            self.advance()?;
1111            qubits.push(self.parse_qubit_ref()?);
1112        }
1113
1114        self.expect_token(&Token::Semicolon)?;
1115
1116        Ok(QasmStatement::Gate(QasmGate {
1117            name,
1118            params,
1119            qubits,
1120            control,
1121            inverse,
1122            power,
1123        }))
1124    }
1125
1126    fn parse_gate_or_call(&mut self, name: String) -> Result<QasmStatement, ParseError> {
1127        self.expect_token(&Token::LeftParen)?;
1128
1129        let mut args = Vec::new();
1130
1131        while self.current_token != Token::RightParen {
1132            args.push(self.parse_expression()?);
1133
1134            if self.current_token == Token::Comma {
1135                self.advance()?;
1136            }
1137        }
1138
1139        self.expect_token(&Token::RightParen)?;
1140
1141        // Check if this is followed by qubits (gate) or semicolon (function call)
1142        match &self.current_token {
1143            Token::Identifier(_) | Token::LeftBracket => {
1144                // Gate with parameters
1145                let mut qubits = Vec::new();
1146                qubits.push(self.parse_qubit_ref()?);
1147
1148                while self.current_token == Token::Comma {
1149                    self.advance()?;
1150                    qubits.push(self.parse_qubit_ref()?);
1151                }
1152
1153                self.expect_token(&Token::Semicolon)?;
1154
1155                Ok(QasmStatement::Gate(QasmGate {
1156                    name,
1157                    params: args,
1158                    qubits,
1159                    control: None,
1160                    inverse: false,
1161                    power: None,
1162                }))
1163            }
1164            Token::Semicolon => {
1165                // Function call
1166                self.advance()?;
1167                Ok(QasmStatement::Call(name, args))
1168            }
1169            _ => Err(ParseError::InvalidSyntax(
1170                "Expected qubits or semicolon".into(),
1171            )),
1172        }
1173    }
1174
1175    fn parse_qubit_ref(&mut self) -> Result<QubitRef, ParseError> {
1176        let register = match &self.current_token {
1177            Token::Identifier(s) => s.clone(),
1178            _ => {
1179                return Err(ParseError::ExpectedToken {
1180                    expected: "register name".into(),
1181                    found: format!("{:?}", self.current_token),
1182                })
1183            }
1184        };
1185        self.advance()?;
1186
1187        if self.current_token == Token::LeftBracket {
1188            self.advance()?;
1189
1190            let start = match &self.current_token {
1191                Token::Integer(n) => *n as usize,
1192                _ => {
1193                    return Err(ParseError::ExpectedToken {
1194                        expected: "integer".into(),
1195                        found: format!("{:?}", self.current_token),
1196                    })
1197                }
1198            };
1199            self.advance()?;
1200
1201            if self.current_token == Token::Colon {
1202                // Slice
1203                self.advance()?;
1204                let end = match &self.current_token {
1205                    Token::Integer(n) => *n as usize,
1206                    _ => {
1207                        return Err(ParseError::ExpectedToken {
1208                            expected: "integer".into(),
1209                            found: format!("{:?}", self.current_token),
1210                        })
1211                    }
1212                };
1213                self.advance()?;
1214                self.expect_token(&Token::RightBracket)?;
1215
1216                Ok(QubitRef::Slice {
1217                    register,
1218                    start,
1219                    end,
1220                })
1221            } else {
1222                // Single index
1223                self.expect_token(&Token::RightBracket)?;
1224                Ok(QubitRef::Single {
1225                    register,
1226                    index: start,
1227                })
1228            }
1229        } else {
1230            // Entire register
1231            Ok(QubitRef::Register(register))
1232        }
1233    }
1234
1235    fn parse_classical_ref(&mut self) -> Result<ClassicalRef, ParseError> {
1236        let register = match &self.current_token {
1237            Token::Identifier(s) => s.clone(),
1238            _ => {
1239                return Err(ParseError::ExpectedToken {
1240                    expected: "register name".into(),
1241                    found: format!("{:?}", self.current_token),
1242                })
1243            }
1244        };
1245        self.advance()?;
1246
1247        if self.current_token == Token::LeftBracket {
1248            self.advance()?;
1249
1250            let start = match &self.current_token {
1251                Token::Integer(n) => *n as usize,
1252                _ => {
1253                    return Err(ParseError::ExpectedToken {
1254                        expected: "integer".into(),
1255                        found: format!("{:?}", self.current_token),
1256                    })
1257                }
1258            };
1259            self.advance()?;
1260
1261            if self.current_token == Token::Colon {
1262                // Slice
1263                self.advance()?;
1264                let end = match &self.current_token {
1265                    Token::Integer(n) => *n as usize,
1266                    _ => {
1267                        return Err(ParseError::ExpectedToken {
1268                            expected: "integer".into(),
1269                            found: format!("{:?}", self.current_token),
1270                        })
1271                    }
1272                };
1273                self.advance()?;
1274                self.expect_token(&Token::RightBracket)?;
1275
1276                Ok(ClassicalRef::Slice {
1277                    register,
1278                    start,
1279                    end,
1280                })
1281            } else {
1282                // Single index
1283                self.expect_token(&Token::RightBracket)?;
1284                Ok(ClassicalRef::Single {
1285                    register,
1286                    index: start,
1287                })
1288            }
1289        } else {
1290            // Entire register
1291            Ok(ClassicalRef::Register(register))
1292        }
1293    }
1294
1295    fn parse_expression(&mut self) -> Result<Expression, ParseError> {
1296        self.parse_or_expression()
1297    }
1298
1299    fn parse_or_expression(&mut self) -> Result<Expression, ParseError> {
1300        let mut left = self.parse_and_expression()?;
1301
1302        while self.current_token == Token::Or {
1303            self.advance()?;
1304            let right = self.parse_and_expression()?;
1305            left = Expression::Binary(BinaryOp::Or, Box::new(left), Box::new(right));
1306        }
1307
1308        Ok(left)
1309    }
1310
1311    fn parse_and_expression(&mut self) -> Result<Expression, ParseError> {
1312        let mut left = self.parse_equality_expression()?;
1313
1314        while self.current_token == Token::And {
1315            self.advance()?;
1316            let right = self.parse_equality_expression()?;
1317            left = Expression::Binary(BinaryOp::And, Box::new(left), Box::new(right));
1318        }
1319
1320        Ok(left)
1321    }
1322
1323    fn parse_equality_expression(&mut self) -> Result<Expression, ParseError> {
1324        let mut left = self.parse_relational_expression()?;
1325
1326        loop {
1327            let op = match &self.current_token {
1328                Token::Eq => BinaryOp::Eq,
1329                Token::Ne => BinaryOp::Ne,
1330                _ => break,
1331            };
1332            self.advance()?;
1333
1334            let right = self.parse_relational_expression()?;
1335            left = Expression::Binary(op, Box::new(left), Box::new(right));
1336        }
1337
1338        Ok(left)
1339    }
1340
1341    fn parse_relational_expression(&mut self) -> Result<Expression, ParseError> {
1342        let mut left = self.parse_additive_expression()?;
1343
1344        loop {
1345            let op = match &self.current_token {
1346                Token::Lt => BinaryOp::Lt,
1347                Token::Le => BinaryOp::Le,
1348                Token::Gt => BinaryOp::Gt,
1349                Token::Ge => BinaryOp::Ge,
1350                _ => break,
1351            };
1352            self.advance()?;
1353
1354            let right = self.parse_additive_expression()?;
1355            left = Expression::Binary(op, Box::new(left), Box::new(right));
1356        }
1357
1358        Ok(left)
1359    }
1360
1361    fn parse_additive_expression(&mut self) -> Result<Expression, ParseError> {
1362        let mut left = self.parse_multiplicative_expression()?;
1363
1364        loop {
1365            let op = match &self.current_token {
1366                Token::Plus => BinaryOp::Add,
1367                Token::Minus => BinaryOp::Sub,
1368                _ => break,
1369            };
1370            self.advance()?;
1371
1372            let right = self.parse_multiplicative_expression()?;
1373            left = Expression::Binary(op, Box::new(left), Box::new(right));
1374        }
1375
1376        Ok(left)
1377    }
1378
1379    fn parse_multiplicative_expression(&mut self) -> Result<Expression, ParseError> {
1380        let mut left = self.parse_unary_expression()?;
1381
1382        loop {
1383            let op = match &self.current_token {
1384                Token::Star => BinaryOp::Mul,
1385                Token::Slash => BinaryOp::Div,
1386                Token::Percent => BinaryOp::Mod,
1387                _ => break,
1388            };
1389            self.advance()?;
1390
1391            let right = self.parse_unary_expression()?;
1392            left = Expression::Binary(op, Box::new(left), Box::new(right));
1393        }
1394
1395        Ok(left)
1396    }
1397
1398    fn parse_unary_expression(&mut self) -> Result<Expression, ParseError> {
1399        match &self.current_token {
1400            Token::Minus => {
1401                self.advance()?;
1402                Ok(Expression::Unary(
1403                    UnaryOp::Neg,
1404                    Box::new(self.parse_unary_expression()?),
1405                ))
1406            }
1407            Token::Not => {
1408                self.advance()?;
1409                Ok(Expression::Unary(
1410                    UnaryOp::Not,
1411                    Box::new(self.parse_unary_expression()?),
1412                ))
1413            }
1414            Token::BitNot => {
1415                self.advance()?;
1416                Ok(Expression::Unary(
1417                    UnaryOp::BitNot,
1418                    Box::new(self.parse_unary_expression()?),
1419                ))
1420            }
1421            _ => self.parse_postfix_expression(),
1422        }
1423    }
1424
1425    fn parse_postfix_expression(&mut self) -> Result<Expression, ParseError> {
1426        let mut expr = self.parse_primary_expression()?;
1427
1428        loop {
1429            match &self.current_token {
1430                Token::LeftBracket => {
1431                    self.advance()?;
1432                    let index = self.parse_expression()?;
1433                    self.expect_token(&Token::RightBracket)?;
1434
1435                    match expr {
1436                        Expression::Variable(name) => {
1437                            expr = Expression::Index(name, Box::new(index));
1438                        }
1439                        _ => {
1440                            return Err(ParseError::InvalidSyntax(
1441                                "Cannot index non-variable".into(),
1442                            ))
1443                        }
1444                    }
1445                }
1446                Token::LeftParen => {
1447                    // Function call
1448                    self.advance()?;
1449                    let mut args = Vec::new();
1450
1451                    while self.current_token != Token::RightParen {
1452                        args.push(self.parse_expression()?);
1453                        if self.current_token == Token::Comma {
1454                            self.advance()?;
1455                        }
1456                    }
1457
1458                    self.expect_token(&Token::RightParen)?;
1459
1460                    match expr {
1461                        Expression::Variable(name) => {
1462                            expr = Expression::Function(name, args);
1463                        }
1464                        _ => {
1465                            return Err(ParseError::InvalidSyntax(
1466                                "Cannot call non-function".into(),
1467                            ))
1468                        }
1469                    }
1470                }
1471                _ => break,
1472            }
1473        }
1474
1475        Ok(expr)
1476    }
1477
1478    fn parse_primary_expression(&mut self) -> Result<Expression, ParseError> {
1479        match &self.current_token {
1480            Token::Integer(n) => {
1481                let value = *n;
1482                self.advance()?;
1483                Ok(Expression::Literal(Literal::Integer(value)))
1484            }
1485            Token::Float(f) => {
1486                let value = *f;
1487                self.advance()?;
1488                Ok(Expression::Literal(Literal::Float(value)))
1489            }
1490            Token::String(s) => {
1491                let value = s.clone();
1492                self.advance()?;
1493                Ok(Expression::Literal(Literal::String(value)))
1494            }
1495            Token::Identifier(s) => {
1496                let name = s.clone();
1497                self.advance()?;
1498
1499                // Check for special constants
1500                match name.as_str() {
1501                    "pi" => Ok(Expression::Literal(Literal::Pi)),
1502                    "e" => Ok(Expression::Literal(Literal::Euler)),
1503                    "tau" => Ok(Expression::Literal(Literal::Tau)),
1504                    _ => Ok(Expression::Variable(name)),
1505                }
1506            }
1507            Token::LeftParen => {
1508                self.advance()?;
1509                let expr = self.parse_expression()?;
1510                self.expect_token(&Token::RightParen)?;
1511                Ok(expr)
1512            }
1513            _ => Err(ParseError::UnexpectedToken(format!(
1514                "{:?}",
1515                self.current_token
1516            ))),
1517        }
1518    }
1519
1520    fn parse_condition(&mut self) -> Result<Condition, ParseError> {
1521        let left = self.parse_expression()?;
1522
1523        let op = match &self.current_token {
1524            Token::Eq => ComparisonOp::Eq,
1525            Token::Ne => ComparisonOp::Ne,
1526            Token::Lt => ComparisonOp::Lt,
1527            Token::Le => ComparisonOp::Le,
1528            Token::Gt => ComparisonOp::Gt,
1529            Token::Ge => ComparisonOp::Ge,
1530            _ => {
1531                return Err(ParseError::ExpectedToken {
1532                    expected: "comparison operator".into(),
1533                    found: format!("{:?}", self.current_token),
1534                })
1535            }
1536        };
1537        self.advance()?;
1538
1539        let right = self.parse_expression()?;
1540
1541        Ok(Condition { left, op, right })
1542    }
1543}
1544
1545/// Parse a QASM 3.0 string into an AST
1546pub fn parse_qasm3(input: &str) -> Result<QasmProgram, ParseError> {
1547    let mut parser = QasmParser::new(input)?;
1548    parser.parse_program()
1549}
1550
1551#[cfg(test)]
1552mod tests {
1553    use super::*;
1554
1555    #[test]
1556    fn test_parse_simple_circuit() {
1557        let input = r#"
1558OPENQASM 3.0;
1559include "stdgates.inc";
1560
1561qubit[2] q;
1562bit[2] c;
1563
1564h q[0];
1565cx q[0], q[1];
1566measure q -> c;
1567"#;
1568
1569        let result = parse_qasm3(input);
1570        assert!(result.is_ok());
1571
1572        let program = result.expect("parse_qasm3 should succeed for valid input");
1573        assert_eq!(program.version, "3.0");
1574        assert_eq!(program.includes, vec!["stdgates.inc"]);
1575        assert_eq!(program.declarations.len(), 2);
1576        assert_eq!(program.statements.len(), 3);
1577    }
1578
1579    #[test]
1580    fn test_parse_gate_definition() {
1581        let input = r"
1582OPENQASM 3.0;
1583
1584gate mygate(theta) q {
1585    rx(theta) q;
1586    ry(theta/2) q;
1587}
1588
1589qubit q;
1590mygate(pi/4) q;
1591";
1592
1593        let result = parse_qasm3(input);
1594        assert!(result.is_ok());
1595    }
1596}