aboutsummaryrefslogtreecommitdiff
path: root/src/bin/gen.rs
diff options
context:
space:
mode:
authorbors[bot] <bors[bot]@users.noreply.github.com>2018-02-03 09:54:52 +0000
committerbors[bot] <bors[bot]@users.noreply.github.com>2018-02-03 09:54:52 +0000
commit3c70ae2e26f654ce536f00fde8c159e4ebe6901a (patch)
tree89fe4c9e08b76f69d39f4a565848c4ba054b6da7 /src/bin/gen.rs
parent6d9753bf548b22ab1a54462f72c9c0bf4ff69382 (diff)
parent9435ea4b8e990521ee7a6206b6106bb3ce392746 (diff)
Merge #38
38: Move tools to a separate package r=matklad a=matklad
Diffstat (limited to 'src/bin/gen.rs')
-rw-r--r--src/bin/gen.rs112
1 files changed, 0 insertions, 112 deletions
diff --git a/src/bin/gen.rs b/src/bin/gen.rs
deleted file mode 100644
index e32f5044e..000000000
--- a/src/bin/gen.rs
+++ /dev/null
@@ -1,112 +0,0 @@
1extern crate serde;
2#[macro_use]
3extern crate serde_derive;
4
5extern crate file;
6extern crate ron;
7
8use std::path::PathBuf;
9use std::fmt::Write;
10
11fn main() {
12 let grammar = Grammar::read();
13 let text = grammar.to_syntax_kinds();
14 file::put_text(&generated_file(), &text).unwrap();
15}
16
17#[derive(Deserialize)]
18struct Grammar {
19 keywords: Vec<String>,
20 tokens: Vec<String>,
21 nodes: Vec<String>,
22}
23
24impl Grammar {
25 fn read() -> Grammar {
26 let text = file::get_text(&grammar_file()).unwrap();
27 ron::de::from_str(&text).unwrap()
28 }
29
30 fn to_syntax_kinds(&self) -> String {
31 let mut acc = String::new();
32 acc.push_str("#![allow(bad_style, missing_docs, unreachable_pub)]\n");
33 acc.push_str("#![cfg_attr(rustfmt, rustfmt_skip)]\n");
34 acc.push_str("//! Generated from grammar.ron\n");
35 acc.push_str("use tree::SyntaxInfo;\n");
36 acc.push_str("\n");
37
38 let syntax_kinds: Vec<String> = self.keywords
39 .iter()
40 .map(|kw| kw_token(kw))
41 .chain(self.tokens.iter().cloned())
42 .chain(self.nodes.iter().cloned())
43 .collect();
44
45 // enum SyntaxKind
46 acc.push_str("/// The kind of syntax node, e.g. `IDENT`, `USE_KW`, or `STRUCT_DEF`.\n");
47 acc.push_str("#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]\n");
48 acc.push_str("pub enum SyntaxKind {\n");
49 for kind in syntax_kinds.iter() {
50 write!(acc, " {},\n", scream(kind)).unwrap();
51 }
52 acc.push_str("\n");
53 acc.push_str(" // Technical SyntaxKinds: they appear temporally during parsing,\n");
54 acc.push_str(" // but never end up in the final tree\n");
55 acc.push_str(" #[doc(hidden)]\n");
56 acc.push_str(" TOMBSTONE,\n");
57 acc.push_str(" #[doc(hidden)]\n");
58 acc.push_str(" EOF,\n");
59 acc.push_str("}\n");
60 acc.push_str("pub(crate) use self::SyntaxKind::*;\n");
61 acc.push_str("\n");
62
63 // fn info
64 acc.push_str("impl SyntaxKind {\n");
65 acc.push_str(" pub(crate) fn info(self) -> &'static SyntaxInfo {\n");
66 acc.push_str(" match self {\n");
67 for kind in syntax_kinds.iter() {
68 let sname = scream(kind);
69 write!(
70 acc,
71 " {sname} => &SyntaxInfo {{ name: \"{sname}\" }},\n",
72 sname = sname
73 ).unwrap();
74 }
75 acc.push_str("\n");
76 acc.push_str(" TOMBSTONE => &SyntaxInfo { name: \"TOMBSTONE\" },\n");
77 acc.push_str(" EOF => &SyntaxInfo { name: \"EOF\" },\n");
78 acc.push_str(" }\n");
79 acc.push_str(" }\n");
80 acc.push_str("}\n");
81 acc.push_str("\n");
82
83 // fn ident_to_keyword
84 acc.push_str("pub(crate) fn ident_to_keyword(ident: &str) -> Option<SyntaxKind> {\n");
85 acc.push_str(" match ident {\n");
86 for kw in self.keywords.iter() {
87 write!(acc, " {:?} => Some({}),\n", kw, kw_token(kw)).unwrap();
88 }
89 acc.push_str(" _ => None,\n");
90 acc.push_str(" }\n");
91 acc.push_str("}\n");
92 acc
93 }
94}
95
96fn grammar_file() -> PathBuf {
97 let dir = env!("CARGO_MANIFEST_DIR");
98 PathBuf::from(dir).join("grammar.ron")
99}
100
101fn generated_file() -> PathBuf {
102 let dir = env!("CARGO_MANIFEST_DIR");
103 PathBuf::from(dir).join("src/syntax_kinds.rs")
104}
105
106fn scream(word: &str) -> String {
107 word.chars().map(|c| c.to_ascii_uppercase()).collect()
108}
109
110fn kw_token(keyword: &str) -> String {
111 format!("{}_KW", scream(keyword))
112}