diff options
author | Aleksey Kladov <[email protected]> | 2017-12-28 22:21:54 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2017-12-28 22:21:54 +0000 |
commit | 5276a7d3be01687e3ea7054ec103711587c9d36e (patch) | |
tree | c8b4d79a49cc74c3dd1a588b636196e1bcfa311c | |
parent | 5e1e8ed34a46738dda507a4a0f4e73065be74e57 (diff) |
Grammar in ron
-rw-r--r-- | Cargo.toml | 7 | ||||
-rw-r--r-- | grammar.ron | 6 | ||||
-rw-r--r-- | src/bin/gen.rs | 82 | ||||
-rw-r--r-- | src/syntax_kinds.rs | 16 |
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" | |||
3 | version = "0.1.0" | 3 | version = "0.1.0" |
4 | authors = ["Aleksey Kladov <[email protected]>"] | 4 | authors = ["Aleksey Kladov <[email protected]>"] |
5 | 5 | ||
6 | [dev-dependencies] | 6 | [dependencies] |
7 | serde = "1.0.26" | ||
8 | serde_derive = "1.0.26" | ||
7 | file = "1.1.1" | 9 | file = "1.1.1" |
10 | ron = "0.1.5" | ||
11 | |||
12 | [dev-dependencies] | ||
8 | difference = "1.0.0" | 13 | difference = "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 @@ | |||
1 | Grammar( | ||
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 @@ | |||
1 | extern crate serde; | ||
2 | #[macro_use] | ||
3 | extern crate serde_derive; | ||
4 | |||
5 | extern crate ron; | ||
6 | extern crate file; | ||
7 | |||
8 | use std::path::PathBuf; | ||
9 | use std::ascii::AsciiExt; | ||
10 | use std::fmt::Write; | ||
11 | |||
12 | fn 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)] | ||
19 | struct Grammar { | ||
20 | syntax_kinds: Vec<String>, | ||
21 | } | ||
22 | |||
23 | impl 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 | |||
70 | fn grammar_file() -> PathBuf { | ||
71 | let dir = env!("CARGO_MANIFEST_DIR"); | ||
72 | PathBuf::from(dir).join("grammar.ron") | ||
73 | } | ||
74 | |||
75 | fn generated_file() -> PathBuf { | ||
76 | let dir = env!("CARGO_MANIFEST_DIR"); | ||
77 | PathBuf::from(dir).join("src/syntax_kinds.rs") | ||
78 | } | ||
79 | |||
80 | fn 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 | ||
1 | use tree::{SyntaxKind, SyntaxInfo}; | 2 | use tree::{SyntaxKind, SyntaxInfo}; |
2 | 3 | ||
3 | pub const IDENT: SyntaxKind = SyntaxKind(1); | 4 | pub const IDENT: SyntaxKind = SyntaxKind(0); |
4 | pub const WHITESPACE: SyntaxKind = SyntaxKind(2); | 5 | pub const WHITESPACE: SyntaxKind = SyntaxKind(1); |
5 | |||
6 | 6 | ||
7 | static IDENT_INFO: SyntaxInfo = SyntaxInfo { | 7 | static IDENT_INFO: SyntaxInfo = SyntaxInfo { |
8 | name: "IDENT", | 8 | name: "IDENT", |
9 | }; | ||
10 | static WHITESPACE_INFO: SyntaxInfo = SyntaxInfo { | ||
11 | name: "WHITESPACE", | ||
9 | }; | 12 | }; |
10 | 13 | ||
11 | pub(crate) fn syntax_info(kind: SyntaxKind) -> &'static SyntaxInfo { | 14 | pub(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 | } |