summaryrefslogtreecommitdiff
path: root/build.rs
diff options
context:
space:
mode:
authorNadrieril2019-03-01 17:28:19 +0100
committerNadrieril2019-03-01 17:28:19 +0100
commite5d9aee00b0c775df1d8e2d8819aeb80dffa73c2 (patch)
treee763a24a0d635048232e72e167ca37eafec69369 /build.rs
parent8a2b7536902831079eddd7b00291b718f5dd7186 (diff)
Split abnf_to_pest and dhall into their own crates
Diffstat (limited to 'build.rs')
-rw-r--r--build.rs148
1 files changed, 0 insertions, 148 deletions
diff --git a/build.rs b/build.rs
deleted file mode 100644
index a418c67..0000000
--- a/build.rs
+++ /dev/null
@@ -1,148 +0,0 @@
-use std::fs::File;
-use std::io::{Read,Write,BufReader,BufRead};
-use std::collections::HashMap;
-use itertools::Itertools;
-
-use lalrpop;
-
-struct PestRuleSettings {
- visible: bool,
- replace: Option<String>,
-}
-
-impl Default for PestRuleSettings {
- fn default() -> Self { PestRuleSettings { visible: true, replace: None } }
-}
-
-fn abnf_to_pest(data: &Vec<u8>, rule_settings: &HashMap<String, PestRuleSettings>) -> std::io::Result<String> {
- use abnf::abnf::*;
- use pretty::{Doc, BoxDoc};
- fn format_rule(x: Rule, rule_settings: &HashMap<String, PestRuleSettings>) -> Doc<BoxDoc<()>> {
- let rulename = format_rulename(x.name);
- let default = Default::default();
- let setting = rule_settings.get(&rulename).unwrap_or(&default);
- let visible = if setting.visible { "" } else { "_" };
- let contents = match setting.replace {
- None => format_alternation(x.elements),
- Some(ref x) => Doc::text(x.clone()),
- };
- Doc::nil()
- .append(Doc::text(rulename))
- .append(Doc::text(" = "))
- .append(Doc::text(visible))
- .append(Doc::text("{"))
- .append(Doc::space().append(contents).nest(2))
- .append(Doc::space())
- .append(Doc::text("}"))
- .group()
- }
- fn format_rulename(x: String) -> String {
- let x = x.replace("-", "_");
- if x == "if" || x == "else" || x == "as" || x == "let" || x == "in" || x == "fn" {
- x + "_"
- } else {
- x
- }
- }
- fn format_alternation(x: Alternation) -> Doc<'static, BoxDoc<'static, ()>> {
- Doc::intersperse(
- x.concatenations.into_iter().map(format_concatenation),
- Doc::space().append(Doc::text("| "))
- )
- }
- fn format_concatenation(x: Concatenation) -> Doc<'static, BoxDoc<'static, ()>> {
- Doc::intersperse(
- x.repetitions.into_iter().map(format_repetition),
- Doc::text(" ~ ")
- )
- }
- fn format_repetition(x: Repetition) -> Doc<'static, BoxDoc<'static, ()>> {
- format_element(x.element)
- .append(x.repeat.map(format_repeat).map(Doc::text).unwrap_or(Doc::nil()))
- }
- fn format_repeat(x: Repeat) -> String {
- match (x.min.unwrap_or(0), x.max) {
- (0, None) => "*".into(),
- (1, None) => "+".into(),
- (0, Some(1)) => "?".into(),
- (min, None) => format!("{{{},}}", min),
- (min, Some(max)) if min == max => format!("{{{}}}", min),
- (min, Some(max)) => format!("{{{},{}}}", min, max),
- }
- }
- fn format_element(x: Element) -> Doc<'static, BoxDoc<'static, ()>> {
- use abnf::abnf::Element::*;
- match x {
- Rulename(s) => Doc::text(format_rulename(s)),
- Group(g) =>
- Doc::text("(")
- .append(format_alternation(g.alternation).nest(4).group())
- .append(Doc::text(")")),
- Option(o) =>
- Doc::text("(")
- .append(format_alternation(o.alternation).nest(4).group())
- .append(Doc::text(")?")),
- CharVal(s) => Doc::text(format!("^\"{}\"", s.replace("\"", "\\\"").replace("\\", "\\\\"))),
- NumVal(r) => Doc::text(format_range(r)),
- ProseVal(_) => unimplemented!(),
- }
- }
- fn format_range(x: Range) -> String {
- use abnf::abnf::Range::*;
- match x {
- Range(x, y) => format!("'{}'..'{}'", format_char(x), format_char(y)),
- OneOf(v) => format!("\"{}\"", v.into_iter().map(format_char).join("")),
- }
- }
- fn format_char(x: u64) -> String {
- if x <= (u8::max_value() as u64) {
- let x: u8 = x as u8;
- if x.is_ascii_graphic() {
- let x: char = x as char;
- if x != '"' && x != '\'' && x != '\\' {
- return x.to_string();
- }
- }
- }
- format!("\\u{{{:02X}}}", x)
- }
- let make_err = |e| std::io::Error::new(std::io::ErrorKind::Other, format!("{}", e));
-
- let rules = rulelist_comp(&data).map_err(make_err)?.1;
- let formatted_rules = rules.into_iter().map(|x| format_rule(x, rule_settings));
- let doc: Doc<_> = Doc::intersperse(formatted_rules, Doc::newline());
- Ok(format!("{}", doc.pretty(80)))
-}
-
-fn main() -> std::io::Result<()> {
- lalrpop::process_root().unwrap();
- println!("cargo:rerun-if-changed=src/grammar.lalrpop");
-
-
- let abnf_path = "dhall-lang/standard/dhall.abnf";
- let visibility_path = "src/dhall.pest.visibility";
- let pest_path = "src/dhall.pest";
- println!("cargo:rerun-if-changed={}", abnf_path);
- println!("cargo:rerun-if-changed={}", visibility_path);
-
- let mut file = File::open(abnf_path)?;
- let mut data = Vec::new();
- file.read_to_end(&mut data)?;
- data.push('\n' as u8);
-
- let mut rule_settings: HashMap<String, PestRuleSettings> = HashMap::new();
- for line in BufReader::new(File::open(visibility_path)?).lines() {
- let line = line?;
- if line.len() >= 2 && &line[0..2] == "# " {
- rule_settings.insert(line[2..].into(), PestRuleSettings { visible: false, ..Default::default() });
- } else {
- rule_settings.insert(line, PestRuleSettings { visible: true, ..Default::default() });
- }
- }
-
- let mut file = File::create(pest_path)?;
- writeln!(&mut file, "{}", abnf_to_pest(&data, &rule_settings)?)?;
- writeln!(&mut file, "final_expression = _{{ SOI ~ complete_expression ~ EOI }}")?;
-
- Ok(())
-}