From d545a5c75cb181758dd745b031eacfd7fc8a6929 Mon Sep 17 00:00:00 2001
From: Aleksey Kladov <aleksey.kladov@gmail.com>
Date: Sun, 18 Aug 2019 21:54:51 +0300
Subject: [PATCH] deserialize grammar

---
 Cargo.lock                       |   1 +
 crates/ra_syntax/src/grammar.ron | 106 +++++++++++++++----------------
 crates/ra_tools/Cargo.toml       |   1 +
 crates/ra_tools/src/codegen.rs   |  36 ++++++++++-
 4 files changed, 88 insertions(+), 56 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index 4f8be32124f..e7354e937cd 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1365,6 +1365,7 @@ dependencies = [
  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
  "teraron 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron
index f2c20573e81..a1881025351 100644
--- a/crates/ra_syntax/src/grammar.ron
+++ b/crates/ra_syntax/src/grammar.ron
@@ -2,61 +2,61 @@
 // See `cargo gen-syntax` (defined in crates/tools/src/main.rs)
 Grammar(
     single_byte_tokens: [
-        [";", "SEMI"],
-        [",", "COMMA"],
-        ["(", "L_PAREN"],
-        [")", "R_PAREN"],
-        ["{", "L_CURLY"],
-        ["}", "R_CURLY"],
-        ["[", "L_BRACK"],
-        ["]", "R_BRACK"],
-        ["<", "L_ANGLE"],
-        [">", "R_ANGLE"],
-        ["@", "AT"],
-        ["#", "POUND"],
-        ["~", "TILDE"],
-        ["?", "QUESTION"],
-        ["$", "DOLLAR"],
-        ["&", "AMP"],
-        ["|", "PIPE"],
-        ["+", "PLUS"],
-        ["*", "STAR"],
-        ["/", "SLASH"],
-        ["^", "CARET"],
-        ["%", "PERCENT"],
-        ["_", "UNDERSCORE"],
+        (";", "SEMI"),
+        (",", "COMMA"),
+        ("(", "L_PAREN"),
+        (")", "R_PAREN"),
+        ("{", "L_CURLY"),
+        ("}", "R_CURLY"),
+        ("[", "L_BRACK"),
+        ("]", "R_BRACK"),
+        ("<", "L_ANGLE"),
+        (">", "R_ANGLE"),
+        ("@", "AT"),
+        ("#", "POUND"),
+        ("~", "TILDE"),
+        ("?", "QUESTION"),
+        ("$", "DOLLAR"),
+        ("&", "AMP"),
+        ("|", "PIPE"),
+        ("+", "PLUS"),
+        ("*", "STAR"),
+        ("/", "SLASH"),
+        ("^", "CARET"),
+        ("%", "PERCENT"),
+        ("_", "UNDERSCORE"),
     ],
     // Tokens for which the longest match must be chosen (e.g. `..` is a DOTDOT, but `.` is a DOT)
     multi_byte_tokens: [
-        [".", "DOT"],
-        ["..", "DOTDOT"],
-        ["...", "DOTDOTDOT"],
-        ["..=", "DOTDOTEQ"],
-        [":", "COLON"],
-        ["::", "COLONCOLON"],
-        ["=", "EQ"],
-        ["==", "EQEQ"],
-        ["=>", "FAT_ARROW"],
-        ["!", "EXCL"],
-        ["!=", "NEQ"],
-        ["-", "MINUS"],
-        ["->", "THIN_ARROW"],
-        ["<=", "LTEQ"],
-        [">=", "GTEQ"],
-        ["+=", "PLUSEQ"],
-        ["-=", "MINUSEQ"],
-        ["|=", "PIPEEQ"],
-        ["&=", "AMPEQ"],
-        ["^=", "CARETEQ"],
-        ["/=", "SLASHEQ"],
-        ["*=", "STAREQ"],
-        ["%=", "PERCENTEQ"],
-        ["&&", "AMPAMP"],
-        ["||", "PIPEPIPE"],
-        ["<<", "SHL"],
-        [">>", "SHR"],
-        ["<<=", "SHLEQ"],
-        [">>=", "SHREQ"],
+        (".", "DOT"),
+        ("..", "DOTDOT"),
+        ("...", "DOTDOTDOT"),
+        ("..=", "DOTDOTEQ"),
+        (":", "COLON"),
+        ("::", "COLONCOLON"),
+        ("=", "EQ"),
+        ("==", "EQEQ"),
+        ("=>", "FAT_ARROW"),
+        ("!", "EXCL"),
+        ("!=", "NEQ"),
+        ("-", "MINUS"),
+        ("->", "THIN_ARROW"),
+        ("<=", "LTEQ"),
+        (">=", "GTEQ"),
+        ("+=", "PLUSEQ"),
+        ("-=", "MINUSEQ"),
+        ("|=", "PIPEEQ"),
+        ("&=", "AMPEQ"),
+        ("^=", "CARETEQ"),
+        ("/=", "SLASHEQ"),
+        ("*=", "STAREQ"),
+        ("%=", "PERCENTEQ"),
+        ("&&", "AMPAMP"),
+        ("||", "PIPEPIPE"),
+        ("<<", "SHL"),
+        (">>", "SHR"),
+        ("<<=", "SHLEQ"),
+        (">>=", "SHREQ"),
     ],
     keywords: [
         "async",
@@ -692,7 +692,7 @@ Grammar(
         "LifetimeArg": (),
 
         "MacroItems": (
-            traits: [ "ModuleItemOwner", "FnDefOwner" ],            
+            traits: [ "ModuleItemOwner", "FnDefOwner" ],
         ),
 
         "MacroStmts" : (
diff --git a/crates/ra_tools/Cargo.toml b/crates/ra_tools/Cargo.toml
index 02bab8f52dd..ab9fa5d861c 100644
--- a/crates/ra_tools/Cargo.toml
+++ b/crates/ra_tools/Cargo.toml
@@ -12,3 +12,4 @@ itertools = "0.8.0"
 clap = "2.32.0"
 quote = "1.0.2"
 ron = "0.5.1"
+serde = { version = "1.0.0", features = ["derive"] }
diff --git a/crates/ra_tools/src/codegen.rs b/crates/ra_tools/src/codegen.rs
index 405fb623cc6..f0a54808a2c 100644
--- a/crates/ra_tools/src/codegen.rs
+++ b/crates/ra_tools/src/codegen.rs
@@ -1,6 +1,8 @@
-use std::{fs, path::Path};
+use std::{collections::BTreeMap, fs, path::Path};
 
+use quote::quote;
 use ron;
+use serde::Deserialize;
 
 use crate::{project_root, Mode, Result, AST, GRAMMAR};
 
@@ -12,10 +14,38 @@ pub fn generate(mode: Mode) -> Result<()> {
 }
 
 fn generate_ast(grammar_src: &Path, dst: &Path, mode: Mode) -> Result<()> {
-    let src: ron::Value = {
+    let src: Grammar = {
         let text = fs::read_to_string(grammar_src)?;
         ron::de::from_str(&text)?
     };
-    eprintln!("{:?}", src);
+    eprintln!("{:#?}", src);
     Ok(())
 }
+
+#[derive(Deserialize, Debug)]
+struct Grammar {
+    single_byte_tokens: Vec<(String, String)>,
+    multi_byte_tokens: Vec<(String, String)>,
+    keywords: Vec<String>,
+    contextual_keywords: Vec<String>,
+    literals: Vec<String>,
+    tokens: Vec<String>,
+    ast: BTreeMap<String, AstNode>,
+}
+
+#[derive(Deserialize, Debug)]
+struct AstNode {
+    #[serde(default)]
+    traits: Vec<String>,
+    #[serde(default)]
+    collections: Vec<Attr>,
+    #[serde(default)]
+    options: Vec<Attr>,
+}
+
+#[derive(Deserialize, Debug)]
+#[serde(untagged)]
+enum Attr {
+    Type(String),
+    NameType(String, String),
+}