From 8b0f7f0dddce6885ebacd215b1f44dbcd50001bc Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:07:57 +0800 Subject: [PATCH 01/18] Add preliminary SPPF visitor code --- sdk-rust/src/output/parser_rust.rs | 130 +++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 6 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index 5d92f5a0..673f66ff 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -110,7 +110,8 @@ pub fn write( compress_automata, )?; } - write_code_visitor(&mut writer, grammar, expected)?; + write_code_ast_visitor(&mut writer, grammar, expected)?; + write_code_sppf_visitor(&mut writer, grammar, expected)?; Ok(()) } @@ -462,14 +463,14 @@ fn write_code_constructors( } /// Generates the visitor for the parse result -fn write_code_visitor( +fn write_code_ast_visitor( writer: &mut dyn Write, grammar: &Grammar, expected: &TerminalSet, ) -> Result<(), Error> { writeln!(writer)?; - writeln!(writer, "/// Visitor interface")?; - writeln!(writer, "pub trait Visitor {{")?; + writeln!(writer, "/// AST Visitor interface")?; + writeln!(writer, "pub trait AstVisitor {{")?; for terminal_ref in &expected.content { let Some(terminal) = grammar.get_terminal(terminal_ref.sid()) else { continue; @@ -505,7 +506,7 @@ fn write_code_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit(result: &ParseResult, visitor: &dyn Visitor) {{" + "pub fn visit(result: &ParseResult, visitor: &dyn AstVisitor) {{" )?; writeln!(writer, " let ast = result.get_ast();")?; writeln!(writer, " let root = ast.get_root();")?; @@ -518,7 +519,7 @@ fn write_code_visitor( )?; writeln!( writer, - "pub fn visit_ast_node(node: AstNode, visitor: &dyn Visitor) {{" + "pub fn visit_ast_node(node: AstNode, visitor: &dyn AstVisitor) {{" )?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children.iter() {{")?; @@ -563,3 +564,120 @@ fn write_code_visitor( writeln!(writer, "}}")?; Ok(()) } + +fn write_code_sppf_visitor( + writer: &mut dyn Write, + grammar: &Grammar, + expected: &TerminalSet, +) -> Result<(), Error> { + writeln!(writer)?; + writeln!(writer, "/// SPPF Visitor interface")?; + writeln!(writer, "pub trait SppfVisitor {{")?; + for terminal_ref in &expected.content { + let Some(terminal) = grammar.get_terminal(terminal_ref.sid()) else { + continue; + }; + if terminal.name.starts_with(PREFIX_GENERATED_TERMINAL) { + continue; + } + writeln!( + writer, + " fn on_terminal_{}(&self, _node: &SppfNodeVersions) {{}}", + to_snake_case(&terminal.name) + )?; + } + for variable in &grammar.variables { + if variable.name.starts_with(PREFIX_GENERATED_VARIABLE) { + continue; + } + writeln!( + writer, + " fn on_variable_{}(&self, _node: &SppfNodeVersions) {{}}", + to_snake_case(&variable.name) + )?; + } + for symbol in &grammar.virtuals { + writeln!( + writer, + " fn on_virtual_{}(&self, _node: &SppfNodeVersions) {{}}", + to_snake_case(&symbol.name) + )?; + } + writeln!(writer, "}}")?; + writeln!(writer)?; + writeln!(writer, "/// Walk the AST of a result using a visitor")?; + writeln!( + writer, + "pub fn visit(result: &ParseResult, visitor: &dyn SppfVisitor) {{" + )?; + writeln!(writer, " let sppf = result.get_ast();")?; + writeln!(writer, " let root = sppf.get_root();")?; + writeln!(writer, " visit_sppf_node(root, visitor);")?; + writeln!(writer, "}}")?; + writeln!(writer)?; + + writeln!( + writer, + "/// Walk the sub-AST from the specified node using a visitor" + )?; + writeln!( + writer, + "pub fn visit_sppf_node(node: SppfNode, visitor: &dyn SppfVisitor) {{" + )?; + writeln!(writer, " let versions = node.versions();")?; + writeln!(writer, " for version in versions.iter() {{")?; + writeln!(writer, " visit_sppf_version_node(version, visitor);")?; + writeln!(writer, " }}")?; + writeln!(writer, "}}")?; + + writeln!( + writer, + "/// Walk the sub-AST from the specified node using a visitor" + )?; + writeln!( + writer, + "pub fn visit_sppf_version_node(node: SppfNode, visitor: &dyn SppfVisitor) {{" + )?; + writeln!(writer, " let children = node.children();")?; + writeln!(writer, " for child in children.iter() {{")?; + writeln!(writer, " visit_sppf_node(child, visitor);")?; + writeln!(writer, " }}")?; + writeln!(writer, " match node.get_symbol().id {{")?; + for terminal_ref in &expected.content { + let Some(terminal) = grammar.get_terminal(terminal_ref.sid()) else { + continue; + }; + if terminal.name.starts_with(PREFIX_GENERATED_TERMINAL) { + continue; + } + writeln!( + writer, + " 0x{:04X} => visitor.on_terminal_{}(&node),", + terminal.id, + to_snake_case(&terminal.name) + )?; + } + for variable in &grammar.variables { + if variable.name.starts_with(PREFIX_GENERATED_VARIABLE) { + continue; + } + writeln!( + writer, + " 0x{:04X} => visitor.on_variable_{}(&node),", + variable.id, + to_snake_case(&variable.name) + )?; + } + for symbol in &grammar.virtuals { + writeln!( + writer, + " 0x{:04X} => visitor.on_virtual_{}(&node),", + symbol.id, + to_snake_case(&symbol.name) + )?; + } + writeln!(writer, " _ => ()")?; + writeln!(writer, " }};")?; + writeln!(writer, "}}")?; + Ok(()) +} From 1cba0d55460761bb33553a1ea9ea75bf9f96ea9d Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:10:17 +0800 Subject: [PATCH 02/18] disambiguate the visit function name --- sdk-rust/src/output/parser_rust.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index 673f66ff..fd67f3b3 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -506,7 +506,7 @@ fn write_code_ast_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit(result: &ParseResult, visitor: &dyn AstVisitor) {{" + "pub fn visit_ast(result: &ParseResult, visitor: &dyn AstVisitor) {{" )?; writeln!(writer, " let ast = result.get_ast();")?; writeln!(writer, " let root = ast.get_root();")?; @@ -608,7 +608,7 @@ fn write_code_sppf_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit(result: &ParseResult, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf(result: &ParseResult, visitor: &dyn SppfVisitor) {{" )?; writeln!(writer, " let sppf = result.get_ast();")?; writeln!(writer, " let root = sppf.get_root();")?; From 7c5c6a0c43af309fe3b06a961589764d6afce147 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:13:58 +0800 Subject: [PATCH 03/18] fix include item for sppf --- sdk-rust/src/output/lexer_rust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-rust/src/output/lexer_rust.rs b/sdk-rust/src/output/lexer_rust.rs index dee36439..1a7b836d 100644 --- a/sdk-rust/src/output/lexer_rust.rs +++ b/sdk-rust/src/output/lexer_rust.rs @@ -98,7 +98,7 @@ pub fn write( if is_rnglr { ", ParseResultSppf" } else { "" } )?; if is_rnglr { - writeln!(writer, "use hime_redist::sppf::SppfImpl;")?; + writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersions}};")?; } writeln!(writer, "use hime_redist::symbols::SemanticBody;")?; writeln!(writer, "use hime_redist::symbols::SemanticElementTrait;")?; From 5c95aafe8acf591e8cceb0bf39818466b7c20b18 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:30:47 +0800 Subject: [PATCH 04/18] use dyn-clone to clone visitor on different versions --- runtime-rust/Cargo.toml | 3 ++- runtime-rust/src/lib.rs | 2 ++ sdk-rust/src/output/lexer_rust.rs | 3 ++- sdk-rust/src/output/parser_rust.rs | 19 ++++++++++--------- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/runtime-rust/Cargo.toml b/runtime-rust/Cargo.toml index dcdfcfa4..013980f5 100644 --- a/runtime-rust/Cargo.toml +++ b/runtime-rust/Cargo.toml @@ -19,7 +19,8 @@ debug = [] std = ["serde/std"] [dependencies] +dyn-clone = "1.0.14" serde = { version = "1", default-features = false, features = ["derive", "alloc"] } [badges] -maintenance = { status = "actively-developed" } \ No newline at end of file +maintenance = { status = "actively-developed" } diff --git a/runtime-rust/src/lib.rs b/runtime-rust/src/lib.rs index e7b2aa7a..75ce5832 100644 --- a/runtime-rust/src/lib.rs +++ b/runtime-rust/src/lib.rs @@ -58,3 +58,5 @@ pub mod utils; /// The version of this program pub const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub use dyn_clone; \ No newline at end of file diff --git a/sdk-rust/src/output/lexer_rust.rs b/sdk-rust/src/output/lexer_rust.rs index 1a7b836d..e6a8f416 100644 --- a/sdk-rust/src/output/lexer_rust.rs +++ b/sdk-rust/src/output/lexer_rust.rs @@ -98,7 +98,8 @@ pub fn write( if is_rnglr { ", ParseResultSppf" } else { "" } )?; if is_rnglr { - writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersions}};")?; + writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersion, SppfNodeVersions}};")?; + writeln!(writer, "use hime_redist::dyn_clone::{{DynClone, clone_box}};")?; } writeln!(writer, "use hime_redist::symbols::SemanticBody;")?; writeln!(writer, "use hime_redist::symbols::SemanticElementTrait;")?; diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index fd67f3b3..2f8cbbcc 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -572,7 +572,7 @@ fn write_code_sppf_visitor( ) -> Result<(), Error> { writeln!(writer)?; writeln!(writer, "/// SPPF Visitor interface")?; - writeln!(writer, "pub trait SppfVisitor {{")?; + writeln!(writer, "pub trait SppfVisitor: DynClone {{")?; for terminal_ref in &expected.content { let Some(terminal) = grammar.get_terminal(terminal_ref.sid()) else { continue; @@ -582,7 +582,7 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_terminal_{}(&self, _node: &SppfNodeVersions) {{}}", + " fn on_terminal_{}(&self, _node: &SppfNodeVersion) {{}}", to_snake_case(&terminal.name) )?; } @@ -592,14 +592,14 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_variable_{}(&self, _node: &SppfNodeVersions) {{}}", + " fn on_variable_{}(&self, _node: &SppfNodeVersion) {{}}", to_snake_case(&variable.name) )?; } for symbol in &grammar.virtuals { writeln!( writer, - " fn on_virtual_{}(&self, _node: &SppfNodeVersions) {{}}", + " fn on_virtual_{}(&self, _node: &SppfNodeVersion) {{}}", to_snake_case(&symbol.name) )?; } @@ -608,7 +608,7 @@ fn write_code_sppf_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit_sppf(result: &ParseResult, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf(result: &ParseResult, visitor: Box) {{" )?; writeln!(writer, " let sppf = result.get_ast();")?; writeln!(writer, " let root = sppf.get_root();")?; @@ -622,10 +622,11 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_node(node: SppfNode, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf_node(node: SppfNode, visitor: Box) {{" )?; writeln!(writer, " let versions = node.versions();")?; - writeln!(writer, " for version in versions.iter() {{")?; + writeln!(writer, " for version in versions {{")?; + writeln!(writer, " let visitor = clone_box(&*visitor);")?; writeln!(writer, " visit_sppf_version_node(version, visitor);")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; @@ -636,10 +637,10 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNode, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf_version_node(node: SppfNode, visitor: Box) {{" )?; writeln!(writer, " let children = node.children();")?; - writeln!(writer, " for child in children.iter() {{")?; + writeln!(writer, " for child in children {{")?; writeln!(writer, " visit_sppf_node(child, visitor);")?; writeln!(writer, " }}")?; writeln!(writer, " match node.get_symbol().id {{")?; From d85ce8614d450f7c53df05346c96e6d11e559b2c Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:32:50 +0800 Subject: [PATCH 05/18] fixup! use dyn-clone to clone visitor on different versions --- sdk-rust/src/output/parser_rust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index 2f8cbbcc..a5cc9259 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -637,7 +637,7 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNode, visitor: Box) {{" + "pub fn visit_sppf_version_node(node: SppfNodeVersion<, visitor: Box) {{" )?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children {{")?; From 5d0c48271d0e0ff3628933ab7b726d326225ff90 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:33:41 +0800 Subject: [PATCH 06/18] fixup! fixup! use dyn-clone to clone visitor on different versions --- sdk-rust/src/output/lexer_rust.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sdk-rust/src/output/lexer_rust.rs b/sdk-rust/src/output/lexer_rust.rs index e6a8f416..ed65374b 100644 --- a/sdk-rust/src/output/lexer_rust.rs +++ b/sdk-rust/src/output/lexer_rust.rs @@ -98,8 +98,9 @@ pub fn write( if is_rnglr { ", ParseResultSppf" } else { "" } )?; if is_rnglr { - writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersion, SppfNodeVersions}};")?; + writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersion}};")?; writeln!(writer, "use hime_redist::dyn_clone::{{DynClone, clone_box}};")?; + writeln!(writer, "use alloc::boxed::Box;")?; } writeln!(writer, "use hime_redist::symbols::SemanticBody;")?; writeln!(writer, "use hime_redist::symbols::SemanticElementTrait;")?; From b313a0911f066c0c66536bc7a9bea859a4267cc6 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:35:12 +0800 Subject: [PATCH 07/18] fixup! fixup! fixup! use dyn-clone to clone visitor on different versions --- sdk-rust/src/output/parser_rust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index a5cc9259..f2cedcb2 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -637,7 +637,7 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNodeVersion<, visitor: Box) {{" + "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: Box) {{" )?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children {{")?; From 0b92596ea9af7de59f924deb2078395febb9b315 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:30:47 +0800 Subject: [PATCH 08/18] use dyn-clone to clone visitor on different versions --- runtime-rust/Cargo.toml | 3 ++- runtime-rust/src/lib.rs | 2 ++ sdk-rust/src/output/lexer_rust.rs | 4 +++- sdk-rust/src/output/parser_rust.rs | 19 ++++++++++--------- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/runtime-rust/Cargo.toml b/runtime-rust/Cargo.toml index dcdfcfa4..013980f5 100644 --- a/runtime-rust/Cargo.toml +++ b/runtime-rust/Cargo.toml @@ -19,7 +19,8 @@ debug = [] std = ["serde/std"] [dependencies] +dyn-clone = "1.0.14" serde = { version = "1", default-features = false, features = ["derive", "alloc"] } [badges] -maintenance = { status = "actively-developed" } \ No newline at end of file +maintenance = { status = "actively-developed" } diff --git a/runtime-rust/src/lib.rs b/runtime-rust/src/lib.rs index e7b2aa7a..75ce5832 100644 --- a/runtime-rust/src/lib.rs +++ b/runtime-rust/src/lib.rs @@ -58,3 +58,5 @@ pub mod utils; /// The version of this program pub const CRATE_VERSION: &str = env!("CARGO_PKG_VERSION"); + +pub use dyn_clone; \ No newline at end of file diff --git a/sdk-rust/src/output/lexer_rust.rs b/sdk-rust/src/output/lexer_rust.rs index 1a7b836d..ed65374b 100644 --- a/sdk-rust/src/output/lexer_rust.rs +++ b/sdk-rust/src/output/lexer_rust.rs @@ -98,7 +98,9 @@ pub fn write( if is_rnglr { ", ParseResultSppf" } else { "" } )?; if is_rnglr { - writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersions}};")?; + writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersion}};")?; + writeln!(writer, "use hime_redist::dyn_clone::{{DynClone, clone_box}};")?; + writeln!(writer, "use alloc::boxed::Box;")?; } writeln!(writer, "use hime_redist::symbols::SemanticBody;")?; writeln!(writer, "use hime_redist::symbols::SemanticElementTrait;")?; diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index fd67f3b3..f2cedcb2 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -572,7 +572,7 @@ fn write_code_sppf_visitor( ) -> Result<(), Error> { writeln!(writer)?; writeln!(writer, "/// SPPF Visitor interface")?; - writeln!(writer, "pub trait SppfVisitor {{")?; + writeln!(writer, "pub trait SppfVisitor: DynClone {{")?; for terminal_ref in &expected.content { let Some(terminal) = grammar.get_terminal(terminal_ref.sid()) else { continue; @@ -582,7 +582,7 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_terminal_{}(&self, _node: &SppfNodeVersions) {{}}", + " fn on_terminal_{}(&self, _node: &SppfNodeVersion) {{}}", to_snake_case(&terminal.name) )?; } @@ -592,14 +592,14 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_variable_{}(&self, _node: &SppfNodeVersions) {{}}", + " fn on_variable_{}(&self, _node: &SppfNodeVersion) {{}}", to_snake_case(&variable.name) )?; } for symbol in &grammar.virtuals { writeln!( writer, - " fn on_virtual_{}(&self, _node: &SppfNodeVersions) {{}}", + " fn on_virtual_{}(&self, _node: &SppfNodeVersion) {{}}", to_snake_case(&symbol.name) )?; } @@ -608,7 +608,7 @@ fn write_code_sppf_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit_sppf(result: &ParseResult, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf(result: &ParseResult, visitor: Box) {{" )?; writeln!(writer, " let sppf = result.get_ast();")?; writeln!(writer, " let root = sppf.get_root();")?; @@ -622,10 +622,11 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_node(node: SppfNode, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf_node(node: SppfNode, visitor: Box) {{" )?; writeln!(writer, " let versions = node.versions();")?; - writeln!(writer, " for version in versions.iter() {{")?; + writeln!(writer, " for version in versions {{")?; + writeln!(writer, " let visitor = clone_box(&*visitor);")?; writeln!(writer, " visit_sppf_version_node(version, visitor);")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; @@ -636,10 +637,10 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNode, visitor: &dyn SppfVisitor) {{" + "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: Box) {{" )?; writeln!(writer, " let children = node.children();")?; - writeln!(writer, " for child in children.iter() {{")?; + writeln!(writer, " for child in children {{")?; writeln!(writer, " visit_sppf_node(child, visitor);")?; writeln!(writer, " }}")?; writeln!(writer, " match node.get_symbol().id {{")?; From cd17d53754d270e9e992f3856b97ecbfd507539e Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 16:58:00 +0800 Subject: [PATCH 09/18] fix ownership problem for sppf visitor --- sdk-rust/src/output/parser_rust.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index f2cedcb2..6256dd24 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -622,14 +622,22 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_node(node: SppfNode, visitor: Box) {{" + "pub fn visit_sppf_node(node: SppfNode, visitor: &Box) {{" )?; - writeln!(writer, " let versions = node.versions();")?; - writeln!(writer, " for version in versions {{")?; - writeln!(writer, " let visitor = clone_box(&*visitor);")?; - writeln!(writer, " visit_sppf_version_node(version, visitor);")?; + + writeln!(writer, " if node.versions_count() == 1 {{")?; + writeln!(writer, " let version = node.first_version();")?; + writeln!(writer, " visit_sppf_version_node(version, visitor);")?; + writeln!(writer, " }} else {{")?; + writeln!(writer, " let versions = node.versions();")?; + writeln!(writer, " for version in versions {{")?; + writeln!(writer, " let visitor = clone_box(&**visitor);")?; + writeln!(writer, " visit_sppf_version_node(version, &visitor);")?; + writeln!(writer, " }}")?; + writeln!(writer, " }}")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; + writeln!(writer)?; writeln!( writer, @@ -637,7 +645,7 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: Box) {{" + "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: &Box) {{" )?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children {{")?; From da1e260dff04d7411ff8b78269ad039342bb71f9 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 17:02:18 +0800 Subject: [PATCH 10/18] fix indent --- sdk-rust/src/output/parser_rust.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index 6256dd24..af85c8cf 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -625,15 +625,14 @@ fn write_code_sppf_visitor( "pub fn visit_sppf_node(node: SppfNode, visitor: &Box) {{" )?; - writeln!(writer, " if node.versions_count() == 1 {{")?; - writeln!(writer, " let version = node.first_version();")?; - writeln!(writer, " visit_sppf_version_node(version, visitor);")?; - writeln!(writer, " }} else {{")?; - writeln!(writer, " let versions = node.versions();")?; - writeln!(writer, " for version in versions {{")?; - writeln!(writer, " let visitor = clone_box(&**visitor);")?; - writeln!(writer, " visit_sppf_version_node(version, &visitor);")?; - writeln!(writer, " }}")?; + writeln!(writer, " if node.versions_count() == 1 {{")?; + writeln!(writer, " let version = node.first_version();")?; + writeln!(writer, " visit_sppf_version_node(version, visitor);")?; + writeln!(writer, " }} else {{")?; + writeln!(writer, " let versions = node.versions();")?; + writeln!(writer, " for version in versions {{")?; + writeln!(writer, " let visitor = clone_box(&**visitor);")?; + writeln!(writer, " visit_sppf_version_node(version, &visitor);")?; writeln!(writer, " }}")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; From 73535fd1412e0aafb2e243d8d33636c3a455ccd8 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 17:03:23 +0800 Subject: [PATCH 11/18] add missing reference --- sdk-rust/src/output/parser_rust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index af85c8cf..b3ae2fbd 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -608,7 +608,7 @@ fn write_code_sppf_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit_sppf(result: &ParseResult, visitor: Box) {{" + "pub fn visit_sppf(result: &ParseResult, visitor: &Box) {{" )?; writeln!(writer, " let sppf = result.get_ast();")?; writeln!(writer, " let root = sppf.get_root();")?; From 25a23f03ff9e5c5fa2cce52d7a678c4d35e274ff Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 17:52:40 +0800 Subject: [PATCH 12/18] let visitor to be mutable --- sdk-rust/src/output/parser_rust.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index b3ae2fbd..d9af3dea 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -582,7 +582,7 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_terminal_{}(&self, _node: &SppfNodeVersion) {{}}", + " fn on_terminal_{}(&mut self, _node: &SppfNodeVersion) {{}}", to_snake_case(&terminal.name) )?; } @@ -592,14 +592,14 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_variable_{}(&self, _node: &SppfNodeVersion) {{}}", + " fn on_variable_{}(&mut self, _node: &SppfNodeVersion) {{}}", to_snake_case(&variable.name) )?; } for symbol in &grammar.virtuals { writeln!( writer, - " fn on_virtual_{}(&self, _node: &SppfNodeVersion) {{}}", + " fn on_virtual_{}(&mut self, _node: &SppfNodeVersion) {{}}", to_snake_case(&symbol.name) )?; } @@ -608,7 +608,7 @@ fn write_code_sppf_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit_sppf(result: &ParseResult, visitor: &Box) {{" + "pub fn visit_sppf(result: &ParseResult, visitor: &mut Box) {{" )?; writeln!(writer, " let sppf = result.get_ast();")?; writeln!(writer, " let root = sppf.get_root();")?; @@ -622,7 +622,7 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_node(node: SppfNode, visitor: &Box) {{" + "pub fn visit_sppf_node(node: SppfNode, visitor: &mut Box) {{" )?; writeln!(writer, " if node.versions_count() == 1 {{")?; @@ -631,8 +631,8 @@ fn write_code_sppf_visitor( writeln!(writer, " }} else {{")?; writeln!(writer, " let versions = node.versions();")?; writeln!(writer, " for version in versions {{")?; - writeln!(writer, " let visitor = clone_box(&**visitor);")?; - writeln!(writer, " visit_sppf_version_node(version, &visitor);")?; + writeln!(writer, " let mut visitor = clone_box(&**visitor);")?; + writeln!(writer, " visit_sppf_version_node(version, &mut visitor);")?; writeln!(writer, " }}")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; @@ -644,7 +644,7 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: &Box) {{" + "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: &mut Box) {{" )?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children {{")?; From 1205f4b29faf70fb48ad20c99fc4b14742285199 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 20:44:36 +0800 Subject: [PATCH 13/18] do pre-order traversal instead for sppf --- sdk-rust/src/output/parser_rust.rs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index d9af3dea..d14e9aad 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -625,15 +625,15 @@ fn write_code_sppf_visitor( "pub fn visit_sppf_node(node: SppfNode, visitor: &mut Box) {{" )?; - writeln!(writer, " if node.versions_count() == 1 {{")?; - writeln!(writer, " let version = node.first_version();")?; - writeln!(writer, " visit_sppf_version_node(version, visitor);")?; - writeln!(writer, " }} else {{")?; + writeln!(writer, " if node.versions_count() > 1 {{")?; writeln!(writer, " let versions = node.versions();")?; writeln!(writer, " for version in versions {{")?; writeln!(writer, " let mut visitor = clone_box(&**visitor);")?; writeln!(writer, " visit_sppf_version_node(version, &mut visitor);")?; writeln!(writer, " }}")?; + writeln!(writer, " }} else {{")?; + writeln!(writer, " let version = node.first_version();")?; + writeln!(writer, " visit_sppf_version_node(version, visitor);")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; writeln!(writer)?; @@ -646,10 +646,6 @@ fn write_code_sppf_visitor( writer, "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: &mut Box) {{" )?; - writeln!(writer, " let children = node.children();")?; - writeln!(writer, " for child in children {{")?; - writeln!(writer, " visit_sppf_node(child, visitor);")?; - writeln!(writer, " }}")?; writeln!(writer, " match node.get_symbol().id {{")?; for terminal_ref in &expected.content { let Some(terminal) = grammar.get_terminal(terminal_ref.sid()) else { @@ -686,6 +682,10 @@ fn write_code_sppf_visitor( } writeln!(writer, " _ => ()")?; writeln!(writer, " }};")?; + writeln!(writer, " let children = node.children();")?; + writeln!(writer, " for child in children {{")?; + writeln!(writer, " visit_sppf_node(child, visitor);")?; + writeln!(writer, " }}")?; writeln!(writer, "}}")?; Ok(()) } From 03dfa8ba0f8ae824579726322a93e475cf7b917d Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 20:45:41 +0800 Subject: [PATCH 14/18] support mut for ast visitor --- sdk-rust/src/output/parser_rust.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index d14e9aad..f428edaf 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -480,7 +480,7 @@ fn write_code_ast_visitor( } writeln!( writer, - " fn on_terminal_{}(&self, _node: &AstNode) {{}}", + " fn on_terminal_{}(&mut self, _node: &AstNode) {{}}", to_snake_case(&terminal.name) )?; } @@ -490,14 +490,14 @@ fn write_code_ast_visitor( } writeln!( writer, - " fn on_variable_{}(&self, _node: &AstNode) {{}}", + " fn on_variable_{}(&mut self, _node: &AstNode) {{}}", to_snake_case(&variable.name) )?; } for symbol in &grammar.virtuals { writeln!( writer, - " fn on_virtual_{}(&self, _node: &AstNode) {{}}", + " fn on_virtual_{}(&mut self, _node: &AstNode) {{}}", to_snake_case(&symbol.name) )?; } @@ -506,7 +506,7 @@ fn write_code_ast_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit_ast(result: &ParseResult, visitor: &dyn AstVisitor) {{" + "pub fn visit_ast(result: &ParseResult, visitor: &mut dyn AstVisitor) {{" )?; writeln!(writer, " let ast = result.get_ast();")?; writeln!(writer, " let root = ast.get_root();")?; @@ -519,7 +519,7 @@ fn write_code_ast_visitor( )?; writeln!( writer, - "pub fn visit_ast_node(node: AstNode, visitor: &dyn AstVisitor) {{" + "pub fn visit_ast_node(node: AstNode, visitor: &mut dyn AstVisitor) {{" )?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children.iter() {{")?; From 4e88caf0a6d6b8b82d0798b116bcf33e91139d85 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 21:32:27 +0800 Subject: [PATCH 15/18] use clone_trait_object instead --- sdk-rust/src/output/lexer_rust.rs | 2 +- sdk-rust/src/output/parser_rust.rs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/sdk-rust/src/output/lexer_rust.rs b/sdk-rust/src/output/lexer_rust.rs index ed65374b..fdd4e8ee 100644 --- a/sdk-rust/src/output/lexer_rust.rs +++ b/sdk-rust/src/output/lexer_rust.rs @@ -99,7 +99,7 @@ pub fn write( )?; if is_rnglr { writeln!(writer, "use hime_redist::sppf::{{SppfImpl, SppfNode, SppfNodeVersion}};")?; - writeln!(writer, "use hime_redist::dyn_clone::{{DynClone, clone_box}};")?; + writeln!(writer, "use hime_redist::dyn_clone::{{DynClone, clone_trait_object}};")?; writeln!(writer, "use alloc::boxed::Box;")?; } writeln!(writer, "use hime_redist::symbols::SemanticBody;")?; diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index f428edaf..744ff32a 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -605,6 +605,8 @@ fn write_code_sppf_visitor( } writeln!(writer, "}}")?; writeln!(writer)?; + writeln!(writer, "clone_trait_object!(SppfVisitor)")?; + writeln!(writer)?; writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, @@ -628,7 +630,7 @@ fn write_code_sppf_visitor( writeln!(writer, " if node.versions_count() > 1 {{")?; writeln!(writer, " let versions = node.versions();")?; writeln!(writer, " for version in versions {{")?; - writeln!(writer, " let mut visitor = clone_box(&**visitor);")?; + writeln!(writer, " let mut visitor = visitor.clone();")?; writeln!(writer, " visit_sppf_version_node(version, &mut visitor);")?; writeln!(writer, " }}")?; writeln!(writer, " }} else {{")?; From 39dd2cdd17b0444ad842fb67f16e1dad1cc892cd Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Sun, 15 Oct 2023 21:33:50 +0800 Subject: [PATCH 16/18] fixup! use clone_trait_object instead --- sdk-rust/src/output/parser_rust.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index 744ff32a..a690210e 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -605,7 +605,7 @@ fn write_code_sppf_visitor( } writeln!(writer, "}}")?; writeln!(writer)?; - writeln!(writer, "clone_trait_object!(SppfVisitor)")?; + writeln!(writer, "clone_trait_object!(SppfVisitor);")?; writeln!(writer)?; writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( From 13e227e6e656552c77399bb338e4f457d81e9485 Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Mon, 16 Oct 2023 00:21:19 +0800 Subject: [PATCH 17/18] push tree to a buffer on divergent branch --- sdk-rust/src/output/parser_rust.rs | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index a690210e..f6828318 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -582,7 +582,7 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_terminal_{}(&mut self, _node: &SppfNodeVersion) {{}}", + " fn on_terminal_{}(&mut self, node: &SppfNodeVersion) {{}}", to_snake_case(&terminal.name) )?; } @@ -592,14 +592,14 @@ fn write_code_sppf_visitor( } writeln!( writer, - " fn on_variable_{}(&mut self, _node: &SppfNodeVersion) {{}}", + " fn on_variable_{}(&mut self, node: &SppfNodeVersion) {{}}", to_snake_case(&variable.name) )?; } for symbol in &grammar.virtuals { writeln!( writer, - " fn on_virtual_{}(&mut self, _node: &SppfNodeVersion) {{}}", + " fn on_virtual_{}(&mut self, node: &SppfNodeVersion) {{}}", to_snake_case(&symbol.name) )?; } @@ -610,11 +610,11 @@ fn write_code_sppf_visitor( writeln!(writer, "/// Walk the AST of a result using a visitor")?; writeln!( writer, - "pub fn visit_sppf(result: &ParseResult, visitor: &mut Box) {{" + "pub fn visit_sppf(result: &ParseResult, visitor: &mut Box, trees: &mut Vec>) {{" )?; writeln!(writer, " let sppf = result.get_ast();")?; writeln!(writer, " let root = sppf.get_root();")?; - writeln!(writer, " visit_sppf_node(root, visitor);")?; + writeln!(writer, " visit_sppf_node(root, visitor, trees);")?; writeln!(writer, "}}")?; writeln!(writer)?; @@ -624,18 +624,19 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_node(node: SppfNode, visitor: &mut Box) {{" + "pub fn visit_sppf_node(node: SppfNode, visitor: &mut Box, trees: &mut Vec>) {{" )?; writeln!(writer, " if node.versions_count() > 1 {{")?; writeln!(writer, " let versions = node.versions();")?; writeln!(writer, " for version in versions {{")?; writeln!(writer, " let mut visitor = visitor.clone();")?; - writeln!(writer, " visit_sppf_version_node(version, &mut visitor);")?; + writeln!(writer, " visit_sppf_version_node(version, &mut visitor, trees);")?; + writeln!(writer, " trees.push(visitor);")?; writeln!(writer, " }}")?; writeln!(writer, " }} else {{")?; writeln!(writer, " let version = node.first_version();")?; - writeln!(writer, " visit_sppf_version_node(version, visitor);")?; + writeln!(writer, " visit_sppf_version_node(version, visitor, trees);")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; writeln!(writer)?; @@ -646,7 +647,7 @@ fn write_code_sppf_visitor( )?; writeln!( writer, - "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: &mut Box) {{" + "pub fn visit_sppf_version_node(node: SppfNodeVersion, visitor: &mut Box, trees: &mut Vec>) {{" )?; writeln!(writer, " match node.get_symbol().id {{")?; for terminal_ref in &expected.content { @@ -686,7 +687,7 @@ fn write_code_sppf_visitor( writeln!(writer, " }};")?; writeln!(writer, " let children = node.children();")?; writeln!(writer, " for child in children {{")?; - writeln!(writer, " visit_sppf_node(child, visitor);")?; + writeln!(writer, " visit_sppf_node(child, visitor, trees);")?; writeln!(writer, " }}")?; writeln!(writer, "}}")?; Ok(()) From 1685de8bddc454fe29c7b8be832a5cbc5eba58fc Mon Sep 17 00:00:00 2001 From: Steve Fan <29133953+stevefan1999-personal@users.noreply.github.com> Date: Tue, 17 Oct 2023 15:00:52 +0800 Subject: [PATCH 18/18] use generated constants for id matching --- sdk-rust/src/output/parser_rust.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk-rust/src/output/parser_rust.rs b/sdk-rust/src/output/parser_rust.rs index d24d0f4c..7419ec4b 100644 --- a/sdk-rust/src/output/parser_rust.rs +++ b/sdk-rust/src/output/parser_rust.rs @@ -661,8 +661,8 @@ fn write_code_sppf_visitor( } writeln!( writer, - " 0x{:04X} => visitor.on_terminal_{}(&node),", - terminal.id, + " ID_TERMINAL_{} => visitor.on_terminal_{}(&node),", + to_upper_case(&terminal.name), to_snake_case(&terminal.name) )?; } @@ -672,16 +672,16 @@ fn write_code_sppf_visitor( } writeln!( writer, - " 0x{:04X} => visitor.on_variable_{}(&node),", - variable.id, + " ID_VARIABLE_{} => visitor.on_variable_{}(&node),", + to_upper_case(&variable.name), to_snake_case(&variable.name) )?; } for symbol in &grammar.virtuals { writeln!( writer, - " 0x{:04X} => visitor.on_virtual_{}(&node),", - symbol.id, + " ID_VIRTUAL_{} => visitor.on_virtual_{}(&node),", + to_upper_case(&symbol.name), to_snake_case(&symbol.name) )?; }