aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2017-12-28 22:21:54 +0000
committerAleksey Kladov <[email protected]>2017-12-28 22:21:54 +0000
commit5276a7d3be01687e3ea7054ec103711587c9d36e (patch)
treec8b4d79a49cc74c3dd1a588b636196e1bcfa311c
parent5e1e8ed34a46738dda507a4a0f4e73065be74e57 (diff)
Grammar in ron
-rw-r--r--Cargo.toml7
-rw-r--r--grammar.ron6
-rw-r--r--src/bin/gen.rs82
-rw-r--r--src/syntax_kinds.rs16
4 files changed, 104 insertions, 7 deletions
diff --git a/Cargo.toml b/Cargo.toml
index b16ca4c7e..0afd4d327 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -3,6 +3,11 @@ name = "libsyntax2"
3version = "0.1.0" 3version = "0.1.0"
4authors = ["Aleksey Kladov <[email protected]>"] 4authors = ["Aleksey Kladov <[email protected]>"]
5 5
6[dev-dependencies] 6[dependencies]
7serde = "1.0.26"
8serde_derive = "1.0.26"
7file = "1.1.1" 9file = "1.1.1"
10ron = "0.1.5"
11
12[dev-dependencies]
8difference = "1.0.0" 13difference = "1.0.0"
diff --git a/grammar.ron b/grammar.ron
new file mode 100644
index 000000000..18c382536
--- /dev/null
+++ b/grammar.ron
@@ -0,0 +1,6 @@
1Grammar(
2 syntax_kinds: [
3 "IDENT",
4 "WHITESPACE",
5 ]
6) \ No newline at end of file
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 @@
1extern crate serde;
2#[macro_use]
3extern crate serde_derive;
4
5extern crate ron;
6extern crate file;
7
8use std::path::PathBuf;
9use std::ascii::AsciiExt;
10use std::fmt::Write;
11
12fn main() {
13 let grammar = Grammar::read();
14 let text = grammar.to_syntax_kinds();
15 file::put_text(&generated_file(), &text).unwrap();
16}
17
18#[derive(Deserialize)]
19struct Grammar {
20 syntax_kinds: Vec<String>,
21}
22
23impl Grammar {
24 fn read() -> Grammar {
25 let text = file::get_text(&grammar_file()).unwrap();
26 ron::de::from_str(&text).unwrap()
27 }
28
29 fn to_syntax_kinds(&self) -> String {
30 let mut acc = String::new();
31 acc.push_str("// Generated from grammar.ron\n");
32 acc.push_str("use tree::{SyntaxKind, SyntaxInfo};\n");
33 acc.push_str("\n");
34 for (idx, kind) in self.syntax_kinds.iter().enumerate() {
35 let sname = scream(kind);
36 write!(
37 acc,
38 "pub const {}: SyntaxKind = SyntaxKind({});\n",
39 sname, idx
40 ).unwrap();
41 }
42 acc.push_str("\n");
43 for kind in self.syntax_kinds.iter() {
44 let sname = scream(kind);
45 write!(
46 acc,
47 "static {sname}_INFO: SyntaxInfo = SyntaxInfo {{\n name: \"{sname}\",\n}};\n",
48 sname = sname
49 ).unwrap();
50 }
51 acc.push_str("\n");
52
53 acc.push_str("pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {\n");
54 acc.push_str(" match kind {\n");
55 for kind in self.syntax_kinds.iter() {
56 let sname = scream(kind);
57 write!(
58 acc,
59 " {sname} => &{sname}_INFO,\n",
60 sname = sname
61 ).unwrap();
62 }
63 acc.push_str(" _ => unreachable!()\n");
64 acc.push_str(" }\n");
65 acc.push_str("}\n");
66 acc
67 }
68}
69
70fn grammar_file() -> PathBuf {
71 let dir = env!("CARGO_MANIFEST_DIR");
72 PathBuf::from(dir).join("grammar.ron")
73}
74
75fn generated_file() -> PathBuf {
76 let dir = env!("CARGO_MANIFEST_DIR");
77 PathBuf::from(dir).join("src/syntax_kinds.rs")
78}
79
80fn scream(word: &str) -> String {
81 word.chars().map(|c| c.to_ascii_uppercase()).collect()
82} \ 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 @@
1// Generated from grammar.ron
1use tree::{SyntaxKind, SyntaxInfo}; 2use tree::{SyntaxKind, SyntaxInfo};
2 3
3pub const IDENT: SyntaxKind = SyntaxKind(1); 4pub const IDENT: SyntaxKind = SyntaxKind(0);
4pub const WHITESPACE: SyntaxKind = SyntaxKind(2); 5pub const WHITESPACE: SyntaxKind = SyntaxKind(1);
5
6 6
7static IDENT_INFO: SyntaxInfo = SyntaxInfo { 7static IDENT_INFO: SyntaxInfo = SyntaxInfo {
8 name: "IDENT", 8 name: "IDENT",
9};
10static WHITESPACE_INFO: SyntaxInfo = SyntaxInfo {
11 name: "WHITESPACE",
9}; 12};
10 13
11pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { 14pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo {
12 match kind { 15 match kind {
13 IDENT => &IDENT_INFO, 16 IDENT => &IDENT_INFO,
14 _ => unreachable!(), 17 WHITESPACE => &WHITESPACE_INFO,
18 _ => unreachable!()
15 } 19 }
16} \ No newline at end of file 20}