diff --git a/crates/squawk/src/debug.rs b/crates/squawk/src/debug.rs index a2104232..c4c3d5e5 100644 --- a/crates/squawk/src/debug.rs +++ b/crates/squawk/src/debug.rs @@ -2,7 +2,8 @@ use std::{io, path::PathBuf}; use annotate_snippets::{Level, Message, Renderer, Snippet}; use anyhow::Result; -use squawk_syntax::syntax_error::SyntaxError; +use serde_json::json; +use squawk_syntax::{ast::AstNode, syntax_error::SyntaxError}; use crate::{ file::{sql_from_path, sql_from_stdin}, @@ -13,11 +14,11 @@ pub(crate) fn debug( f: &mut W, paths: &[PathBuf], read_stdin: bool, - dump_ast: &DebugOption, + debug_option: &DebugOption, verbose: bool, ) -> Result<()> { let process_dump_ast = |sql: &str, filename: &str, f: &mut W| -> Result<()> { - match dump_ast { + match debug_option { DebugOption::Lex => { let tokens = squawk_lexer::tokenize(sql); let mut start = 0; @@ -61,6 +62,9 @@ pub(crate) fn debug( })?; } } + DebugOption::Ast => { + dump_ast(f, sql)?; + } } Ok(()) }; @@ -77,6 +81,30 @@ pub(crate) fn debug( Ok(()) } +fn dump_ast(f: &mut W, sql: &str) -> Result<()> { + let parse = squawk_syntax::SourceFile::parse(sql); + let file = parse.tree(); + + let stmts = file + .stmts() + .map(|stmt| { + // No api guarantees for now + json!({ + "type": format!("{:?}", stmt.syntax().kind()) + }) + }) + .collect::>(); + + let output = json!({ + "version": "0.1", + "stmts": stmts, + }); + + writeln!(f, "{}", serde_json::to_string_pretty(&output)?)?; + + Ok(()) +} + fn render_syntax_errors( errors: &[SyntaxError], filename: &str, @@ -96,3 +124,28 @@ fn render_syntax_errors( } Ok(()) } + +#[cfg(test)] +mod test { + use insta::assert_snapshot; + + use super::dump_ast; + + #[test] + fn dump_ast_basic_output() { + let mut buffer = vec![]; + dump_ast( + &mut buffer, + " +select; +insert into t values (1, 'a', true); +update t set c = 10 where b = 5; +delete from t; +truncate t; +", + ) + .unwrap(); + let output = String::from_utf8(buffer).expect("Invalid UTF-8"); + assert_snapshot!(output); + } +} diff --git a/crates/squawk/src/main.rs b/crates/squawk/src/main.rs index dda48752..4b40e0e3 100644 --- a/crates/squawk/src/main.rs +++ b/crates/squawk/src/main.rs @@ -61,7 +61,8 @@ arg_enum! { #[derive(Debug, StructOpt)] pub enum DebugOption { Lex, - Parse + Parse, + Ast } } diff --git a/crates/squawk/src/snapshots/squawk__debug__test__dump_ast_basic_output.snap b/crates/squawk/src/snapshots/squawk__debug__test__dump_ast_basic_output.snap new file mode 100644 index 00000000..b0495b20 --- /dev/null +++ b/crates/squawk/src/snapshots/squawk__debug__test__dump_ast_basic_output.snap @@ -0,0 +1,24 @@ +--- +source: crates/squawk/src/debug.rs +expression: output +--- +{ + "stmts": [ + { + "type": "SELECT" + }, + { + "type": "INSERT" + }, + { + "type": "UPDATE" + }, + { + "type": "DELETE" + }, + { + "type": "TRUNCATE" + } + ], + "version": "0.1" +} diff --git a/crates/squawk_parser/src/lib.rs b/crates/squawk_parser/src/lib.rs index 497be206..8de02ca3 100644 --- a/crates/squawk_parser/src/lib.rs +++ b/crates/squawk_parser/src/lib.rs @@ -24,26 +24,6 @@ // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -// https://www.scattered-thoughts.net/writing/babys-second-wasm-compiler/ -// -// https://craftinginterpreters.com/parsing-expressions.html -// -// see: https://github.com/rust-lang/rust-analyzer/blob/master/crates/parser/src/parser.rs -// https://rust-analyzer.github.io/blog/2020/09/16/challeging-LR-parsing.html -// https://github.com/rust-lang/rust-analyzer/blob/master/docs/dev/syntax.md -// https://ericlippert.com/2012/06/08/red-green-trees/ -// https://github.com/swiftlang/swift/tree/5e2c815edfd758f9b1309ce07bfc01c4bc20ec23/lib/Syntax -// https://swift-ast-explorer.com -// https://github.com/rust-lang/rust-analyzer/blob/cf156a7a43f822e71309e50470ac34363da26727/docs/dev/syntax.md -// https://github.com/kaleidawave/ezno/blob/8ce921e39c3d4e947063f206347b2932cee456ec/parser/src/lib.rs#L177 -// https://kaleidawave.github.io/posts/sets-types-and-type-checking/ -// https://github.com/m-novikov/tree-sitter-sql/tree/main -// https://github.com/withered-magic/starpls/tree/79f47e12dab8be650804ce7fa931ee5e1e116eae/crates/starpls_parser/src -// https://github.com/apache/datafusion-sqlparser-rs -- removes comments and whitespace :/ - -// rust analyzer has a builtin doc test like thing where you generate snapshot -// style tests from comments on top of grammar functions - use drop_bomb::DropBomb; use event::Event; use grammar::OPERATOR_FIRST; diff --git a/crates/squawk_syntax/README.md b/crates/squawk_syntax/README.md new file mode 100644 index 00000000..8995144d --- /dev/null +++ b/crates/squawk_syntax/README.md @@ -0,0 +1,5 @@ +# squawk_syntax + +## related + +- https://github.com/rust-lang/rust-analyzer/blob/d2f17873ff19786a121fb3302f91779c1a1b957f/docs/book/src/contributing/syntax.md