update parser

This commit is contained in:
Michael Zhang 2020-01-13 22:59:35 -06:00
parent 01b40ae057
commit a147fb06f5
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
2 changed files with 56 additions and 3 deletions

View file

@ -1,3 +1,5 @@
use std::collections::HashMap;
#[derive(Debug)] #[derive(Debug)]
pub enum Toplevel { pub enum Toplevel {
Use(Use), Use(Use),
@ -10,11 +12,23 @@ pub struct Use(pub Vec<String>);
#[derive(Debug)] #[derive(Debug)]
pub struct Component { pub struct Component {
pub name: String, pub name: String,
pub body: Vec<ComponentBody>,
} }
#[derive(Debug)] #[derive(Debug)]
pub enum ComponentBody { pub enum ComponentBody {
Constructor(), Constructor(),
View(), View(Rsx),
Fn(), Fn(),
} }
#[derive(Debug)]
pub enum Rsx {
Tag {
tag: String,
attrs: HashMap<String, String>,
inner: Vec<Rsx>,
},
CodeSegment(String),
Text(String),
}

View file

@ -1,4 +1,5 @@
use std::iter::FromIterator; use std::iter::FromIterator;
use std::collections::HashMap;
use proc_macro2::{Ident, Punct, TokenTree, Delimiter, TokenStream, Group, Spacing, Literal}; use proc_macro2::{Ident, Punct, TokenTree, Delimiter, TokenStream, Group, Spacing, Literal};
@ -22,6 +23,7 @@ Component: Component = {
"component" <name:Ident> <body:Body<ComponentBody*>> => { "component" <name:Ident> <body:Body<ComponentBody*>> => {
Component { Component {
name: name.to_string(), name: name.to_string(),
body,
} }
} }
}; };
@ -30,8 +32,8 @@ ComponentBody: ComponentBody = {
"constructor" "(" ")" BraceGrouper => { "constructor" "(" ")" BraceGrouper => {
ComponentBody::Constructor() ComponentBody::Constructor()
}, },
"view" BraceGrouper => { "view" <rsx:Body<Rsx>> => {
ComponentBody::View() ComponentBody::View(rsx)
}, },
"fn" Ident "(" Delim<Arg, ","> ")" BraceGrouper => { "fn" Ident "(" Delim<Arg, ","> ")" BraceGrouper => {
ComponentBody::Fn() ComponentBody::Fn()
@ -44,6 +46,29 @@ Arg: () = {
Ident ":" Ident => {}, Ident ":" Ident => {},
}; };
Rsx: Rsx = {
"<" <tag:Ident> <attrs:Attrs> "/" ">" => { Rsx::Tag { tag: tag.to_string(), attrs, inner: Vec::new(), } },
"<" <tag:Ident> <attrs:Attrs> ">" <inner:Rsx*> "<" "/" <closeTag:Ident> ">" => {
assert_eq!(tag, closeTag, "Tags {} and {} do not match.", tag, closeTag);
Rsx::Tag { tag: tag.to_string(), attrs, inner }
},
BraceGrouper => { Rsx::CodeSegment(<>.to_string()) },
AnyText => { Rsx::Text(<>) },
};
Attrs: HashMap<String, String> = {
(AttrLhs "=" BraceGrouper)* => {
<>.into_iter()
.map(|(lhs, _, rhs)| (lhs.to_string(), rhs.to_string()))
.collect()
}
};
AttrLhs: String = {
<a:Ident> ":" <b:Ident> => format!("{}:{}", a, b),
Ident => <>.to_string(),
};
// //
pub ArbitraryBlocks: Vec<TokenTree> = AnyToken*; pub ArbitraryBlocks: Vec<TokenTree> = AnyToken*;
@ -58,6 +83,12 @@ BraceGrouper: TokenTree = {
"{" <b:AnyToken*> "}" => TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::from_iter(b.into_iter()))), "{" <b:AnyToken*> "}" => TokenTree::Group(Group::new(Delimiter::Brace, TokenStream::from_iter(b.into_iter()))),
}; };
AnyText: String = {
Ident => <>.to_string(),
Punct => <>.to_string(),
Literal => <>.to_string(),
};
AnyToken: TokenTree = { AnyToken: TokenTree = {
Grouper => <>, Grouper => <>,
@ -70,6 +101,10 @@ AnyToken: TokenTree = {
":" => TokenTree::Punct(Punct::new(':', Spacing::Alone)), ":" => TokenTree::Punct(Punct::new(':', Spacing::Alone)),
";" => TokenTree::Punct(Punct::new(';', Spacing::Alone)), ";" => TokenTree::Punct(Punct::new(';', Spacing::Alone)),
"," => TokenTree::Punct(Punct::new(',', Spacing::Alone)), "," => TokenTree::Punct(Punct::new(',', Spacing::Alone)),
"<" => TokenTree::Punct(Punct::new('<', Spacing::Alone)),
">" => TokenTree::Punct(Punct::new('>', Spacing::Alone)),
"/" => TokenTree::Punct(Punct::new('/', Spacing::Alone)),
"=" => TokenTree::Punct(Punct::new('=', Spacing::Alone)),
Ident => TokenTree::Ident(<>), Ident => TokenTree::Ident(<>),
Punct => TokenTree::Punct(<>), Punct => TokenTree::Punct(<>),
@ -115,6 +150,10 @@ extern {
")" => TokenType::Punct(')', _), ")" => TokenType::Punct(')', _),
"[" => TokenType::Punct('[', _), "[" => TokenType::Punct('[', _),
"]" => TokenType::Punct(']', _), "]" => TokenType::Punct(']', _),
"<" => TokenType::Punct('<', _),
">" => TokenType::Punct('>', _),
"/" => TokenType::Punct('/', _),
"=" => TokenType::Punct('=', _),
Punct => TokenType::Punct(_, <Punct>), Punct => TokenType::Punct(_, <Punct>),
Ident => TokenType::Ident(<Ident>), Ident => TokenType::Ident(<Ident>),