diff options
Diffstat (limited to 'src/bin/gen.rs')
-rw-r--r-- | src/bin/gen.rs | 112 |
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 @@ | |||
1 | extern crate serde; | ||
2 | #[macro_use] | ||
3 | extern crate serde_derive; | ||
4 | |||
5 | extern crate file; | ||
6 | extern crate ron; | ||
7 | |||
8 | use std::path::PathBuf; | ||
9 | use std::fmt::Write; | ||
10 | |||
11 | fn 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)] | ||
18 | struct Grammar { | ||
19 | keywords: Vec<String>, | ||
20 | tokens: Vec<String>, | ||
21 | nodes: Vec<String>, | ||
22 | } | ||
23 | |||
24 | impl 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 | |||
96 | fn grammar_file() -> PathBuf { | ||
97 | let dir = env!("CARGO_MANIFEST_DIR"); | ||
98 | PathBuf::from(dir).join("grammar.ron") | ||
99 | } | ||
100 | |||
101 | fn generated_file() -> PathBuf { | ||
102 | let dir = env!("CARGO_MANIFEST_DIR"); | ||
103 | PathBuf::from(dir).join("src/syntax_kinds.rs") | ||
104 | } | ||
105 | |||
106 | fn scream(word: &str) -> String { | ||
107 | word.chars().map(|c| c.to_ascii_uppercase()).collect() | ||
108 | } | ||
109 | |||
110 | fn kw_token(keyword: &str) -> String { | ||
111 | format!("{}_KW", scream(keyword)) | ||
112 | } | ||