Rust铁路图生成库railroad的使用,可高效创建语法图和流程图的可视化工具
Rust铁路图生成库railroad的使用,可高效创建语法图和流程图的可视化工具
railroad是一个用于创建语法铁路图(railroad diagram)的Rust库,可以生成可缩放矢量图形(SVG)。铁路图是一种表示上下文无关语法的方式,每个图表都有唯一的起点和终点,描述的语言中的所有内容都表示为这些点之间的可能路径之一。
基本使用
使用这个库时,通过实现Node
的基元来创建图表。通过将简单元素包装成更复杂的结构来组合成更复杂的结构。
use railroad::*;
let mut seq = Sequence::default();
seq.push(Box::new(Start) as Box<dyn Node>)
.push(Box::new(Terminal::new("BEGIN".to_owned())))
.push(Box::new(NonTerminal::new("syntax".to_owned())))
.push(Box::new(End));
let mut dia = Diagram::new(seq);
dia.add_element(svg::Element::new("style")
.set("type", "text/css")
.text(DEFAULT_CSS));
println!("{}", dia);
完整示例
下面是一个更完整的示例,展示如何创建更复杂的语法图:
use railroad::*;
fn main() {
// 创建一个选择结构(或分支)
let mut choice = Choice::new(0);
choice.push(Box::new(Terminal::new("if".to_owned())));
choice.push(Box::new(Terminal::new("unless".to_owned())));
// 创建一个可选结构
let optional = Optional::new(
Box::new(NonTerminal::new("condition".to_owned()))
);
// 创建一个序列
let mut seq = Sequence::default();
seq.push(Box::new(Start));
seq.push(Box::new(choice));
seq.push(Box::new(optional));
seq.push(Box::new(Terminal::new("then".to_owned())));
seq.push(Box::new(NonTerminal::new("expression".to_owned())));
seq.push(Box::new(End));
// 创建图表并添加样式
let mut dia = Diagram::new(seq);
dia.add_element(
svg::Element::new("style")
.set("type", "text/css")
.text(DEFAULT_CSS)
);
// 输出SVG
println!("{}", dia);
}
调试功能
当向这个库添加新的Node
基元时,可以使用examples/visual.rs
快速生成特殊情况并检查它们是否正确渲染。使用visual-debug
功能可以在渲染的图表中添加参考线和SVG代码中的额外信息。
安装
在项目中添加以下依赖到Cargo.toml:
railroad = "0.3.3"
或者运行:
cargo add railroad
railroad库采用MIT许可证,是一个轻量级(24.6 KiB)的Rust库,非常适合用于生成语法图、流程图等可视化工具。
完整示例demo
下面是一个更详细的示例,展示如何创建一个SQL SELECT语句的铁路图:
use railroad::*;
fn main() {
// 创建SELECT子句
let select_clause = {
let mut seq = Sequence::default();
seq.push(Box::new(Terminal::new("SELECT".to_owned())));
seq.push(Box::new(NonTerminal::new("columns".to_owned())));
seq
};
// 创建FROM子句
let from_clause = {
let mut seq = Sequence::default();
seq.push(Box::new(Terminal::new("FROM".to_owned())));
seq.push(Box::new(NonTerminal::new("tables".to_owned())));
seq
};
// 创建WHERE子句(可选)
let where_clause = Optional::new(
Box::new({
let mut seq = Sequence::default();
seq.push(Box::new(Terminal::new("WHERE".to_owned())));
seq.push(Box::new(NonTerminal::new("condition".to_owned())));
seq
})
);
// 创建GROUP BY子句(可选)
let group_by_clause = Optional::new(
Box::new({
let mut seq = Sequence::default();
seq.push(Box::new(Terminal::new("GROUP BY".to_owned())));
seq.push(Box::new(NonTerminal::new("columns".to_owned())));
seq
})
);
// 创建完整的SQL语句
let mut sql_stmt = Sequence::default();
sql_stmt.push(Box::new(Start));
sql_stmt.push(Box::new(select_clause));
sql_stmt.push(Box::new(from_clause));
sql_stmt.push(Box::new(where_clause));
sql_stmt.push(Box::new(group_by_clause));
sql_stmt.push(Box::new(End));
// 创建图表并添加样式
let mut diagram = Diagram::new(sql_stmt);
diagram.add_element(
svg::Element::new("style")
.set("type", "text/css")
.text(DEFAULT_CSS)
);
// 输出SVG
println!("{}", diagram);
}
这个示例展示了如何创建一个包含多个可选子句的SQL SELECT语句的铁路图。代码中使用了Sequence来组合多个元素,并使用Optional来表示可选的子句。
1 回复