parser: implement base structures

This commit is contained in:
anna 2021-04-13 21:03:02 +02:00
parent e0da8d92d0
commit 9a4793ae1c
Signed by: fef
GPG key ID: EC22E476DC2D3D84
3 changed files with 162 additions and 1 deletions

View file

@ -3,7 +3,7 @@
use std::env;
use std::fs;
mod lex;
use gayconf::lex;
fn main() {
let argv: Vec<String> = env::args().collect();

126
src/lib.rs Normal file
View file

@ -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<String, Node<'a>>,
}
impl <'a> Config<'a> {
pub fn parse(stream: Chars<'a>) -> Result<Config<'a>, 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<bool> {
match self.val {
NodeVal::Bool(b) => Some(b),
_ => None,
}
}
fn val_int(&self) -> Option<i64> {
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<T> {
fn get(&self, name: &str) -> Option<T>;
fn get_or(&self, name: &str, default: T) -> T {
match self.get(name) {
Some(x) => x,
None => default,
}
}
}
impl GetNodeVal<bool> for Config<'_> {
fn get(&self, name: &str) -> Option<bool> {
match self.get_node(name)?.val {
NodeVal::Bool(b) => Some(b),
_ => None,
}
}
}
impl GetNodeVal<i64> for Config<'_> {
fn get(&self, name: &str) -> Option<i64> {
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 <owo@fef.moe>
// 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 <https://git.pixie.town/thufie/CNPL>.
//
// gayconf comes with ABSOLUTELY NO WARRANTY, to the extent
// permitted by applicable law. See the CNPL for details.

35
src/parser.rs Normal file
View file

@ -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<Node<'a>, SyntaxError>;
fn next(&mut self) -> Option<Result<Node<'a>, SyntaxError>> {
panic!("unimplemented")
}
}
// Copyright (C) 2021 Fefie <owo@fef.moe>
// 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 <https://git.pixie.town/thufie/CNPL>.
//
// gayconf comes with ABSOLUTELY NO WARRANTY, to the extent
// permitted by applicable law. See the CNPL for details.