Expand description

QASM

This library is a parser for the IBM OpenQASM 2.0 language.

It is seperated into 3 parts:

  1. Processing - Removing comments and resolving include statements.
  2. Lexing - Splitting up the processed source file into a list of tokens (Vec<Token>)
  3. Parsing - Turning the list of tokens into a list of AST nodes.

There is methods provided for each.

Processing

Processing is done with the processing function. It requires 2 arguments, the input string, and the Path of the directory it is in. This path is used to locate the include files. It is used like so:

extern crate qasm;
use std::env;

let source = r#"
OPENQASM 2.0;
// Here is a comment
include "sample.inc";

qreg a[3];
// And so on
"#;

let cwd = env::current_dir().unwrap();
qasm::process(source, &cwd);
/* Will Return:
 *
 * ```
 * OPENQASM 2.0;
 *
 * (CONTENTS OF SAMPLE.INC)
 *
 * qreg a[3];
 * ```
 */

Lexing

Lexing is done with the lex function. It takes a source string (which must not have any comments or include statements) and returns a Vector of Tokens.

It is used like so:

extern crate qasm;

let source = r#"
OPENQASM 2.0;
qreg a[3];
CX a[0], a[1];
"#;

let tokens = qasm::lex(source);
println!("{:?}", tokens);
// [OpenQASM, Real(2.0), Semicolon,
//  QReg, Id("a"), LSParen, NNInteger(3), RSParen, Semicolon,
//  Id("CX"), Id("a"), LSParen, NNInteger(0), RSParen, Comma, Id("a"), LSParen, NNInteger(1), RSParen, Semicolon]

for a full list of tokens that can be returned, please see the Token enum.

Parsing

Parsing is done with the parse function. It accepts a vector of Tokens and returns a vector of AstNodes or an Error as a result

It is used like so:

extern crate qasm;
use qasm::Token;

let mut tokens = vec![
    Token::OpenQASM,
    Token::Real(2.0),
    Token::Semicolon,
    Token::QReg,
    Token::Id("a".to_string()),
    Token::LSParen,
    Token::NNInteger(3),
    Token::RSParen,
    Token::Semicolon,
    Token::Id("CX".to_string()),
    Token::Id("a".to_string()),
    Token::LSParen,
    Token::NNInteger(0),
    Token::RSParen,
    Token::Comma,
    Token::Id("a".to_string()),
    Token::LSParen,
    Token::NNInteger(1),
    Token::RSParen,
    Token::Semicolon,
];
let ast = qasm::parse(&mut tokens);

// Ok([QReg("a", 3), ApplyGate("CX", [Qubit("a", 0), Qubit("a", 1)], [])])

Combining Functions

The functions can be combined to process, lex and parse a source string. Here is an example that reads a file ‘test.qasm’, processes it and then prints the AST.

test.qasm

OPENQASM 2.0;

// Clifford gate: Hadamard
gate h a { u2(0,pi) a; }

qreg q[2];
creg c[1];

h q[0];
CX q[0], q[1];

measure q[1] -> c[1];

main.rs

extern crate qvnt_qasm as qasm;

use std::env;
use std::fs::File;
use std::io::prelude::*;
use qasm::{process, lex, parse};

fn main() {
    let cwd = vec![env::current_dir().unwrap()];
    let mut source = String::new();

    let mut f = File::open("test.qasm").expect("cannot find source file 'test.qasm'");
    f.read_to_string(&mut source).expect("couldn't read file 'test.qasm'");

    let processed_source = process(&source, cwd).unwrap();
    let mut tokens = lex(&processed_source);
    let ast = parse(&mut tokens);

    println!("{:?}", ast);
}

Output

Ok([
    Gate("h", ["a"], [], [ApplyGate("u2", [Register("a")], [" 0 ", " pi "])]),
    QReg("q", 2),
    CReg("c", 1),
    ApplyGate("h", [Qubit("q", 0)], []),
    ApplyGate("CX", [Qubit("q", 0), Qubit("q", 1)], []),
    Measure(Qubit("q", 1), Qubit("c", 1))
])

Structs

Enums

Representation of arguments to the ASTNodes. These are never top level, thus they have been left to a seperate enum.

AST Nodes. These can pattern matched to evaluate the ast.

Represents Errors that can occur during parsing.

Functions

Take a source string with no includes or comments and returns the tokens

Changes a vector of tokens into an AST.

Remove comments from an input string and resolves include statements.