From 9a4793ae1c52e01748b64990527fc125d58408c1 Mon Sep 17 00:00:00 2001 From: Felix Date: Tue, 13 Apr 2021 21:03:02 +0200 Subject: [PATCH] parser: implement base structures --- src/{main.rs => bin/ckconf.rs} | 2 +- src/lib.rs | 126 +++++++++++++++++++++++++++++++++ src/parser.rs | 35 +++++++++ 3 files changed, 162 insertions(+), 1 deletion(-) rename src/{main.rs => bin/ckconf.rs} (98%) create mode 100644 src/lib.rs create mode 100644 src/parser.rs diff --git a/src/main.rs b/src/bin/ckconf.rs similarity index 98% rename from src/main.rs rename to src/bin/ckconf.rs index 673f6e3..6253daf 100644 --- a/src/main.rs +++ b/src/bin/ckconf.rs @@ -3,7 +3,7 @@ use std::env; use std::fs; -mod lex; +use gayconf::lex; fn main() { let argv: Vec = env::args().collect(); diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d087bba --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,126 @@ +// See the end of this file for copyright and license terms. + +use std::str::Chars; +use std::collections::HashMap; + +pub mod lex; +use crate::lex::{Lexer, SyntaxError}; + +pub mod parser; +use parser::Parser; + +pub struct Config<'a> { + nodes: HashMap>, +} + +impl <'a> Config<'a> { + pub fn parse(stream: Chars<'a>) -> Result, SyntaxError> { + let lexer: Lexer<'a> = Lexer::new(stream); + let parser: Parser<'a> = Parser::new(lexer); + let mut nodes = HashMap::new(); + + for nr in parser { + match nr { + Ok(node) => { + let name = node.name.clone(); + nodes.insert(name, node); + }, + Err(err) => return Err(err), + } + } + + Ok(Config { + nodes + }) + } + + fn get_node(&self, name: &str) -> Option<&Node<'a>> { + self.nodes.get(name) + } +} + +pub struct Node<'a> { + pub(crate) name: String, + pub(crate) val: NodeVal<'a>, +} + +enum NodeVal<'a> { + Bool(bool), + Int(i64), + String(&'a str), +} + +impl <'a> Node<'a> { + pub fn name(&self) -> &str { + &self.name + } + + fn val_bool(&self) -> Option { + match self.val { + NodeVal::Bool(b) => Some(b), + _ => None, + } + } + + fn val_int(&self) -> Option { + match self.val { + NodeVal::Int(i) => Some(i), + _ => None, + } + } + + pub fn val_str(&self) -> Option<&'a str> { + match self.val { + NodeVal::String(s) => Some(s), + _ => None, + } + } +} + +trait GetNodeVal { + fn get(&self, name: &str) -> Option; + fn get_or(&self, name: &str, default: T) -> T { + match self.get(name) { + Some(x) => x, + None => default, + } + } +} + +impl GetNodeVal for Config<'_> { + fn get(&self, name: &str) -> Option { + match self.get_node(name)?.val { + NodeVal::Bool(b) => Some(b), + _ => None, + } + } +} + +impl GetNodeVal for Config<'_> { + fn get(&self, name: &str) -> Option { + match self.get_node(name)?.val { + NodeVal::Int(i) => Some(i), + _ => None, + } + } +} + +impl <'a> GetNodeVal<&'a str> for Config<'a> { + fn get(&self, name: &str) -> Option<&'a str> { + match self.get_node(name)?.val { + NodeVal::String(s) => Some(s), + _ => None, + } + } +} + +// Copyright (C) 2021 Fefie +// This file is part of gayconf. +// +// gayconf is ethical software: you can use, redistribute, +// and/or modify it under the terms of the CNPLv5+ as found +// in the LICENSE file in the source code root directory or +// at . +// +// gayconf comes with ABSOLUTELY NO WARRANTY, to the extent +// permitted by applicable law. See the CNPL for details. diff --git a/src/parser.rs b/src/parser.rs new file mode 100644 index 0000000..6fba088 --- /dev/null +++ b/src/parser.rs @@ -0,0 +1,35 @@ +// See the end of this file for copyright and license terms. + +use crate::lex::{Token, TokenKind, Lexer, SyntaxError}; +use crate::Node; + +pub struct Parser<'a> { + lexer: Lexer<'a>, +} + +impl <'a> Parser<'a> { + pub const fn new(lexer: Lexer<'a>) -> Parser<'a> { + Parser { + lexer + } + } +} + +impl <'a> Iterator for Parser<'a> { + type Item = Result, SyntaxError>; + + fn next(&mut self) -> Option, SyntaxError>> { + panic!("unimplemented") + } +} + +// Copyright (C) 2021 Fefie +// This file is part of gayconf. +// +// gayconf is ethical software: you can use, redistribute, +// and/or modify it under the terms of the CNPLv5+ as found +// in the LICENSE file in the source code root directory or +// at . +// +// gayconf comes with ABSOLUTELY NO WARRANTY, to the extent +// permitted by applicable law. See the CNPL for details.