General Programming Language Parsing
Recipe | Crates | Categories |
---|---|---|
Parse JavaScript | ||
Parse JavaScript
swc_ecma_parser⮳ is a feature-complete ECMAScript / TypeScript parser written in Rust.
use swc_common::FileName; use swc_common::input::StringInput; use swc_common::sync::Lrc; use swc_ecma_ast::EsVersion; use swc_ecma_ast::Program; use swc_ecma_parser::EsSyntax; use swc_ecma_parser::Parser; use swc_ecma_parser::Syntax; use swc_ecma_parser::lexer::Lexer; // `swc_ecma_parser` is a library for parsing ECMAScript (JavaScript) code. // In `Cargo.toml`: // swc_ecma_parser = "6.0.1" # or latest // swc_ecma_ast = "5.0.1" // swc_common = "5.0.0" fn main() { let cm: Lrc<swc_common::SourceMap> = Default::default(); let fm = cm.new_source_file( FileName::Custom("example.js".into()).into(), "const a = 1;".into(), ); let lexer = Lexer::new( Syntax::Es(EsSyntax { jsx: true, ..Default::default() }), EsVersion::latest(), StringInput::from(&*fm), None, ); let mut parser = Parser::new_from(lexer); let program: Program = parser.parse_program().expect("Failed to parse"); // Print the parsed program println!("{:#?}", program); }
Parse SQL
sqlparser
⮳ is a general SQL lexer and parser with support for ANSI SQL:2011.
use std::ops::ControlFlow; use sqlparser::ast::SetExpr; use sqlparser::ast::Statement; use sqlparser::dialect::GenericDialect; use sqlparser::parser::Parser; // `sqlparser` can be used as a foundation for SQL query engines and SQL // analysis. // // Add to your `Cargo.toml`: // sqlparser = { version = "0.54.0", features = ["visitor"] } fn main() -> anyhow::Result<()> { let sql = "SELECT * FROM users WHERE age > 18"; let dialect = GenericDialect {}; // Or AnsiDialect, PostgreSqlDialect, etc. // Create a parser for a `Dialect`: let mut parser = Parser::new(&dialect).try_with_sql(sql)?; // You may configure the parser with e.g. // .with_recursion_limit(n).with_options(options) // Parse potentially multiple statements; tokenize the sql string and sets // this parser's state to parse the resulting tokens. let statements = parser.parse_statements()?; // You may also use `parse_sql`: // let statements = Parser::parse_sql( // &dialect, "SELECT * FROM foo" // )?; for statement in statements.clone() { // `statement` is a top-level construct: SELECT, INSERT, CREATE, etc. match statement { // SELECT statment. Statement::Query(query) => match *query.body { // SELECT .. FROM .. HAVING (no ORDER BY or set operations). SetExpr::Select(select) => { println!("SELECT statement:"); println!(" Projection: {:?}", select.projection); println!(" From: {:?}", select.from); println!(" Where: {:?}", select.selection); } _ => println!("Not a SELECT statement"), }, _ => println!("Not a Query statement"), } } // The original SQL text can be generated from the AST // (Abstract Syntax Tree). assert_eq!(statements[0].to_string(), sql); // You may also visit all statements, expressions, or tables. // You can also implement a custom `Visitor`. let mut visited = vec![]; sqlparser::ast::visit_statements(&statements, |stmt| { visited.push(format!("Statement: {}", stmt)); ControlFlow::<()>::Continue(()) }); println!("{:?}", visited); Ok(()) }
See also
diesel
⮳ is an ORM that includes SQL parsing.