From 5276a7d3be01687e3ea7054ec103711587c9d36e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 29 Dec 2017 01:21:54 +0300 Subject: Grammar in ron --- src/bin/gen.rs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/syntax_kinds.rs | 16 +++++++---- 2 files changed, 92 insertions(+), 6 deletions(-) create mode 100644 src/bin/gen.rs (limited to 'src') diff --git a/src/bin/gen.rs b/src/bin/gen.rs new file mode 100644 index 000000000..d3539321e --- /dev/null +++ b/src/bin/gen.rs @@ -0,0 +1,82 @@ +extern crate serde; +#[macro_use] +extern crate serde_derive; + +extern crate ron; +extern crate file; + +use std::path::PathBuf; +use std::ascii::AsciiExt; +use std::fmt::Write; + +fn main() { + let grammar = Grammar::read(); + let text = grammar.to_syntax_kinds(); + file::put_text(&generated_file(), &text).unwrap(); +} + +#[derive(Deserialize)] +struct Grammar { + syntax_kinds: Vec, +} + +impl Grammar { + fn read() -> Grammar { + let text = file::get_text(&grammar_file()).unwrap(); + ron::de::from_str(&text).unwrap() + } + + fn to_syntax_kinds(&self) -> String { + let mut acc = String::new(); + acc.push_str("// Generated from grammar.ron\n"); + acc.push_str("use tree::{SyntaxKind, SyntaxInfo};\n"); + acc.push_str("\n"); + for (idx, kind) in self.syntax_kinds.iter().enumerate() { + let sname = scream(kind); + write!( + acc, + "pub const {}: SyntaxKind = SyntaxKind({});\n", + sname, idx + ).unwrap(); + } + acc.push_str("\n"); + for kind in self.syntax_kinds.iter() { + let sname = scream(kind); + write!( + acc, + "static {sname}_INFO: SyntaxInfo = SyntaxInfo {{\n name: \"{sname}\",\n}};\n", + sname = sname + ).unwrap(); + } + acc.push_str("\n"); + + acc.push_str("pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {\n"); + acc.push_str(" match kind {\n"); + for kind in self.syntax_kinds.iter() { + let sname = scream(kind); + write!( + acc, + " {sname} => &{sname}_INFO,\n", + sname = sname + ).unwrap(); + } + acc.push_str(" _ => unreachable!()\n"); + acc.push_str(" }\n"); + acc.push_str("}\n"); + acc + } +} + +fn grammar_file() -> PathBuf { + let dir = env!("CARGO_MANIFEST_DIR"); + PathBuf::from(dir).join("grammar.ron") +} + +fn generated_file() -> PathBuf { + let dir = env!("CARGO_MANIFEST_DIR"); + PathBuf::from(dir).join("src/syntax_kinds.rs") +} + +fn scream(word: &str) -> String { + word.chars().map(|c| c.to_ascii_uppercase()).collect() +} \ No newline at end of file diff --git a/src/syntax_kinds.rs b/src/syntax_kinds.rs index 18574b7f5..a5485c4c1 100644 --- a/src/syntax_kinds.rs +++ b/src/syntax_kinds.rs @@ -1,16 +1,20 @@ +// Generated from grammar.ron use tree::{SyntaxKind, SyntaxInfo}; -pub const IDENT: SyntaxKind = SyntaxKind(1); -pub const WHITESPACE: SyntaxKind = SyntaxKind(2); - +pub const IDENT: SyntaxKind = SyntaxKind(0); +pub const WHITESPACE: SyntaxKind = SyntaxKind(1); static IDENT_INFO: SyntaxInfo = SyntaxInfo { - name: "IDENT", + name: "IDENT", +}; +static WHITESPACE_INFO: SyntaxInfo = SyntaxInfo { + name: "WHITESPACE", }; pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { match kind { IDENT => &IDENT_INFO, - _ => unreachable!(), + WHITESPACE => &WHITESPACE_INFO, + _ => unreachable!() } -} \ No newline at end of file +} -- cgit v1.2.3