sdl and parser

This commit is contained in:
SimonFJ20 2023-01-20 15:47:43 +01:00
parent 2762361968
commit 15baba8cbb
4 changed files with 187 additions and 46 deletions

56
Cargo.lock generated
View File

@ -2,6 +2,62 @@
# It is not intended for manual editing.
version = 3
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "sdl2"
version = "0.35.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7959277b623f1fb9e04aea73686c3ca52f01b2145f8ea16f4ff30d8b7623b1a"
dependencies = [
"bitflags",
"lazy_static",
"libc",
"sdl2-sys",
]
[[package]]
name = "sdl2-sys"
version = "0.35.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3586be2cf6c0a8099a79a12b4084357aa9b3e0b0d7980e3b67aaf7a9d55f9f0"
dependencies = [
"cfg-if",
"libc",
"version-compare",
]
[[package]]
name = "version-compare"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "579a42fc0b8e0c63b76519a339be31bed574929511fa53c1a3acae26eb258f29"
[[package]]
name = "web-stack-project"
version = "0.1.0"
dependencies = [
"sdl2",
]

View File

@ -5,4 +5,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.sdl2]
version = "0.35.2"
features = ["image", "mixer", "ttf"]

View File

@ -30,6 +30,10 @@ pub enum Token {
RBrace(String),
LBracket(String),
RBracket(String),
Equal(String),
Colon(String),
SemiColon(String),
Comma(String),
}
#[derive(PartialEq)]

View File

@ -1,70 +1,149 @@
#![allow(dead_code)]
use std::iter::Map;
use super::lexer::Token;
use std::collections::HashMap;
pub enum Node {
Element {
name: String,
ids: Vec<String>,
classes: Vec<String>,
properties: Map<String, Box<Node>>,
properties: HashMap<String, Box<Node>>,
values: Vec<Node>,
},
Object(Map<String, Box<Node>>),
Object(HashMap<String, Box<Node>>),
Array(Vec<Node>),
Int(i64),
Float(f64),
String(String),
Bool(bool),
Null,
}
// pub struct Parser {
// tokens: Vec<Token>,
// }
pub struct Parser {
tokens: Vec<Token>,
index: usize,
}
// impl Parser {
// pub fn new(lexer: Lexer) -> Self {
// Self { lexer }
// }
// }
type ParserError = String;
// type ParserError = String;
impl Parser {
pub fn new(tokens: Vec<Token>) -> Self {
Self { tokens, index: 0 }
}
// impl Parser {
// pub fn new(tokens: Vec<Token>) -> Self {
// Self { tokens, index: 0 }
// }
pub fn parse_top_level(&mut self) -> Result<Node, ParserError> {
match self.current() {
Some(Token::Name(_)) => self.parse_element(),
Some(_) => self.parse_value(),
None => Err("expected value or element".to_owned()),
}
}
// pub fn parse_top_level(&mut self) -> Result<Node, ParserError> {
// match self.peek() {
// Some(Token::Name(_)) => self.parse_element(),
// Some(_) => self.parse_value(),
// None => Err("expected value or element".to_owned()),
// }
// }
fn parse_element(&mut self) -> Result<Node, ParserError> {}
// fn parse_element(&mut self) -> Result<Node, ParserError> {}
fn parse_value(&mut self) -> Result<Node, ParserError> {
match self.current() {
Some(Token::LBrace(_)) => self.parse_object(),
Some(Token::LBracket(_)) => self.parse_object(),
Some(Token::Int(value)) => Ok(Node::Int(
value.parse().map_err(|_| "malformed int".to_string())?,
)),
Some(Token::Float(value)) => Ok(Node::Int(
value.parse().map_err(|_| "malformed float".to_string())?,
)),
Some(Token::String(value)) => Ok(Node::String(value[1..value.len() - 1].to_string())),
Some(Token::False(_)) => Ok(Node::Bool(false)),
Some(Token::True(_)) => Ok(Node::Bool(false)),
Some(Token::Null(_)) => Ok(Node::Null),
Some(_) => Err("unexpected token, expected value".to_owned()),
None => Err("expected value".to_owned()),
}
}
// fn parse_value(&mut self) -> Result<Node, ParserError> {
// match self.peek() {
// Some(Token::LBrace(_)) => self.parse_object(),
// Some(Token::LBracket(_)) => self.parse_object(),
// Some(_) => Err("unexpected token, expected value".to_owned()),
// None => Err("expected value".to_owned()),
// }
// }
fn parse_object(&mut self) -> Result<Node, ParserError> {
self.step();
let mut values = HashMap::<String, Box<Node>>::new();
match self.current() {
Some(Token::RBrace(_)) => {
self.step();
Ok(Node::Object(values))
}
Some(t @ (Token::Name(_) | Token::String(_))) => {
let key = match t {
Token::Name(v) => v,
Token::String(v) => &v[1..v.len() - 1].to_string(),
_ => panic!("checked by previous predicate"),
};
self.step();
match self.current() {
Some(Token::Equal(_) | Token::Colon(_)) => {}
_ => return Err("expected ':' or '='".to_string()),
}
self.step();
values[key] = Box::new(self.parse_value()?);
self.parse_object_tail(values)
}
_ => Err("expected Name, String or '}'".to_string()),
}
}
// fn parse_object(&mut self) -> Result<Node, ParserError> {}
// fn parse_array(&mut self) -> Result<Node, ParserError> {}
// fn parse_number(&mut self) -> Result<Node, ParserError> {}
// fn parse_string(&mut self) -> Result<Node, ParserError> {}
// fn parse_bool(&mut self) -> Result<Node, ParserError> {}
// fn parse_null(&mut self) -> Result<Node, ParserError> {}
fn parse_object_tail(&mut self, values: HashMap<String, Box<Node>>) -> Result<Node, String> {
loop {
match self.current() {
Some(Token::RBrace(_)) => {
self.step();
break Ok(Node::Object(values));
}
Some(Token::Comma(_)) => {
self.step();
match self.current() {
Some(Token::RBrace(_)) => {
self.step();
break Ok(Node::Object(values));
}
Some(t @ (Token::Name(_) | Token::String(_))) => {
let key = match t {
Token::Name(v) => v,
Token::String(v) => &v[1..v.len() - 1].to_string(),
_ => panic!("unterminated object, checked by previous predicate"),
};
self.step();
match self.current() {
Some(Token::Equal(_) | Token::Colon(_)) => {}
_ => return Err("expected ':' or '='".to_string()),
}
self.step();
values[key] = Box::new(self.parse_value()?);
}
_ => {
break Err(
"unterminated object, expected Name, String or '}'".to_string()
)
}
}
}
_ => break Err("unterminated object, expected ',' or '}'".to_string()),
}
}
}
// fn step(&mut self) {
// self.index += 1
// }
// fn peek(&self) -> Option<&Token> {
// self.tokens.get(self.index)
// }
// }
fn parse_array(&mut self) -> Result<Node, ParserError> {
self.step();
let mut values = Vec::<Node>::new();
match self.current() {
Some(Token::RBracket(_)) => {
self.step();
Ok(Node::Array(values))
}
_ => Err("unterminated array, expected Value or ']'".to_string()),
}
}
fn step(&mut self) {
self.index += 1
}
fn current(&self) -> Option<&Token> {
self.tokens.get(self.index)
}
}