cqlib-core 0.1.0-beta.1

The high-performance core foundation for the CQLib quantum computing ecosystem.
Documentation
// This code is part of Cqlib.
//
// (C) Copyright China Telecom Quantum Group 2026
//
// This code is licensed under the Apache License, Version 2.0. You may
// obtain a copy of this license in the LICENSE.txt file in the root directory
// of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.
//
// Any modifications or derivative works of this code must retain this
// copyright notice, and modified files need to carry a notice indicating
// that they have been altered from the originals.

use std::str::FromStr;
use crate::ir::qasm2::ast::*;

grammar;

pub Main: OpenQASMProgram = {
    "OPENQASM" <v:Real> ";" <s:Statement*> => OpenQASMProgram { version: v, statements: s }
};

pub ProgramBody: OpenQASMProgram = {
    <s:Statement*> => OpenQASMProgram { version: 2.0, statements: s }
};

Statement: Statement = {
    Decl,
    "include" <s:QuotedStr> ";" => Statement::Include(s),
    Qop,
    "if" "(" <creg:Id> "==" <value:Int> ")" <s:Qop> =>
        Statement::If(creg, value, Box::new(s)),
    "barrier" <a:ArgList> ";" => Statement::Barrier(a),
    // 门声明
    "gate" <name:Id> <p:ParamIdList?> <q:IdList> "{" <body:GateBody> "}" => {
        Statement::GateDecl(Box::new(GateDeclData {
            name,
            params: p.unwrap_or(vec![]),
            qubits: q,
            body
        }))
    },
    "opaque" <name:Id> <p:ParamIdList?> <q:IdList> ";" => Statement::Opaque(name, p.unwrap_or(vec![]), q),
};

Decl: Statement = {
    "qreg" <id:Id> "[" <n:Int> "]" ";" => Statement::QReg(id, n),
    "creg" <id:Id> "[" <n:Int> "]" ";" => Statement::CReg(id, n),
};

Qop: Statement = {
    Uop,
    "measure" <q:Arg> "->" <c:Arg> ";" => Statement::Measure(q, c),
    "reset" <a:Arg> ";" => Statement::Reset(a),
};

Uop: Statement = {
    <name:GateId> <p:ParamExpList?> <args:ArgList> ";" =>
        Statement::CustomGate(name, p.unwrap_or(vec![]), args),
};

GateBody: Vec<Statement> = {
    <s:GateBodyStatement*> => s,
};

GateBodyStatement: Statement = {
    Uop,
    "barrier" <ids:IdList> ";" => {
        Statement::Barrier(ids.into_iter().map(Argument::Id).collect())
    },
};

ParamIdList: Vec<String> = {
    "(" ")" => vec![],
    "(" <ids:IdList> ")" => ids,
};

ParamExpList: Vec<Expression> = {
    "(" ")" => vec![],
    "(" <exprs:ExpList> ")" => exprs,
};

GateId: String = {
    <id:Id> => id,
    "U" => "U".to_string(),
    "CX" => "CX".to_string(),
};

// 表达式优先级处理 - 使用 LALRPOP 的优先级宏
// 注意:Exp 返回 Expression(而非 Box),因为 AST 的 CustomGate 期望 Vec<Expression>
pub Exp: Expression = {
    <l:Exp> "+" <r:Term> => Expression::BinaryOp(Box::new(l), OpCode::Add, Box::new(r)),
    <l:Exp> "-" <r:Term> => Expression::BinaryOp(Box::new(l), OpCode::Sub, Box::new(r)),
    Term,
};

Term: Expression = {
    <l:Term> "*" <r:Factor> => Expression::BinaryOp(Box::new(l), OpCode::Mul, Box::new(r)),
    <l:Term> "/" <r:Factor> => Expression::BinaryOp(Box::new(l), OpCode::Div, Box::new(r)),
    Factor,
};

Factor: Expression = {
    <l:Unary> "^" <r:Factor> => Expression::BinaryOp(Box::new(l), OpCode::Pow, Box::new(r)),
    Unary,
};

Unary: Expression = {
    <op:UnaryOp> "(" <e:Exp> ")" => Expression::UnaryOp(op, Box::new(e)),
    "-" <e:Unary> => Expression::UnaryOp(UnaryOpCode::Neg, Box::new(e)),
    Primary,
};

Primary: Expression = {
    <r:Real> => Expression::Real(r),
    <n:Int> => Expression::Integer(n),
    "pi" => Expression::Pi,
    <id:Id> => Expression::Id(id),
    "(" <e:Exp> ")" => e,
};

UnaryOp: UnaryOpCode = {
    "sin" => UnaryOpCode::Sin,
    "cos" => UnaryOpCode::Cos,
    "tan" => UnaryOpCode::Tan,
    "exp" => UnaryOpCode::Exp,
    "ln" => UnaryOpCode::Ln,
    "sqrt" => UnaryOpCode::Sqrt,
    "asin" => UnaryOpCode::Asin,
    "acos" => UnaryOpCode::Acos,
    "atan" => UnaryOpCode::Atan,
};

Arg: Argument = {
    <id:Id> => Argument::Id(id),
    <id:Id> "[" <n:Int> "]" => Argument::IndexedId(id, n),
};

// 基础词法规则
Id: String = <s:r"[a-z][a-zA-Z0-9_]*"> => s.to_string();
Int: i64 = <s:r"0|[1-9][0-9]*"> => i64::from_str(s).unwrap_or(-1);
Real: f64 = <s:r"([0-9]+\.[0-9]*|\.[0-9]+)([eE][-+]?[0-9]+)?|[0-9]+[eE][-+]?[0-9]+"> => f64::from_str(s).unwrap();
QuotedStr: String = <s:r#""[^"]*""#> => s[1..s.len()-1].to_string();

// 列表宏
Comma<T>: Vec<T> = {
    <first:T> <rest:("," <T>)*> => {
        let mut values = vec![first];
        values.extend(rest);
        values
    }
};
IdList = Comma<Id>;
ExpList = Comma<Exp>;
ArgList = Comma<Arg>;

// 忽略空白字符 [cite: 42]
match {
    r"\s*" => { },
    r"//[^\n\r]*" => { },
    _
}