rqml/src/parser.rs

97 lines
3.3 KiB
Rust
Raw Normal View History

2020-07-05 01:54:02 +00:00
extern crate pest;
use crate::Value::{QmlIdent, QmlNumber, QmlString};
2020-07-05 21:29:44 +00:00
use pest::iterators::Pairs;
2020-07-05 01:54:02 +00:00
use pest::Parser;
use std::collections::HashMap;
use std::fs::read_to_string;
#[derive(Parser)]
#[grammar = "../pest/qml.pest"]
struct QmlParser;
#[derive(Debug, Clone)]
pub enum Value {
QmlString(String),
QmlNumber(f64),
QmlIdent(String),
}
#[derive(Debug, Clone)]
pub struct QML {
pub properties: HashMap<String, Value>,
pub children: Vec<(String, QML)>,
}
pub fn parse_qml(path: &str) -> QML {
let qml_file = read_to_string(path).unwrap();
let qml_tokens =
QmlParser::parse(Rule::qml, qml_file.as_str()).unwrap_or_else(|e| panic!("{}", e));
parse(qml_tokens)
}
fn parse(qml: Pairs<Rule>) -> QML {
let mut qmldoc = QML {
properties: Default::default(),
children: vec![],
};
for pair in qml {
// println!("Rule {:?} Str {}", pair.as_rule(), pair.as_str());
match pair.as_rule() {
Rule::import => {
let mut tokens = pair.into_inner();
println!("Found new Import {} ", tokens.next().unwrap().as_str());
}
Rule::body => {
let mut tokens = pair.into_inner();
let ident = tokens.next().unwrap().as_str();
println!("Found new Body: {} ", ident);
qmldoc
.children
.push((String::from(ident), parse(tokens.into_iter())));
}
Rule::property => {
let mut tokens = pair.into_inner();
let ident = tokens.next().unwrap().as_str();
let value = tokens.next().unwrap();
// let value = tokens.next().unwrap().as_str();
match value.as_rule() {
Rule::number => {
let num: f64 = value.as_str().parse().unwrap();
println!("Found new Property: {} {:?}", ident, num);
qmldoc
.properties
.insert(String::from(ident), QmlNumber(num));
}
Rule::string => {
println!("Found new Property: {} {}", ident, value.as_str());
qmldoc.properties.insert(
String::from(ident),
QmlString(String::from(value.into_inner().next().unwrap().as_str())),
);
}
Rule::ident => {
println!("Found new Property: {} {}", ident, value.as_str());
qmldoc
.properties
.insert(String::from(ident), QmlIdent(String::from(value.as_str())));
}
_ => {}
}
}
Rule::function => {
let mut tokens = pair.into_inner();
let ident = tokens.next().unwrap().as_str();
let value = tokens.concat();
qmldoc.properties.insert(
String::from(ident),
QmlString(String::from(value.clone().trim())),
);
}
_ => return parse(pair.into_inner()),
}
}
qmldoc
}