summaryrefslogtreecommitdiff
path: root/src/parser.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser.rs')
-rw-r--r--src/parser.rs122
1 files changed, 73 insertions, 49 deletions
diff --git a/src/parser.rs b/src/parser.rs
index c7a8abe..297230c 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -40,16 +40,18 @@ struct Context<'a> {
40 cur: [Option<Symbol<'a>>;2], 40 cur: [Option<Symbol<'a>>;2],
41 icur: usize, 41 icur: usize,
42 ll: Lexer<'a>, 42 ll: Lexer<'a>,
43 source: usize,
43} 44}
44 45
45impl<'a> Context<'a> { 46impl<'a> Context<'a> {
46 pub fn new( mut ll: Lexer<'a> ) -> Self { 47 pub fn new( mut ll: Lexer<'a>, source: usize ) -> Self {
47 let cur = [ll.next(), ll.next()]; 48 let cur = [ll.next(), ll.next()];
48 //println!(" - cur: {:?}, peek: {:?}", cur[0], cur[1] ); 49 //println!(" - cur: {:?}, peek: {:?}", cur[0], cur[1] );
49 Self { 50 Self {
50 cur, 51 cur,
51 icur: 0, 52 icur: 0,
52 ll 53 ll,
54 source,
53 } 55 }
54 } 56 }
55 57
@@ -75,6 +77,10 @@ impl<'a> Context<'a> {
75 Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol())) 77 Ok(f( self.cur().unwrap().symbol(), self.peek().unwrap().symbol()))
76 } 78 }
77 } 79 }
80
81 pub fn source(&self) -> usize {
82 self.source
83 }
78} 84}
79 85
80trait SymbolHelper { 86trait SymbolHelper {
@@ -195,7 +201,7 @@ impl Parser {
195 } 201 }
196 } 202 }
197 203
198 fn lex_error(&self, error: &Symbol) -> ParseResult<Token> { 204 fn lex_error<T>(&self, error: &Symbol) -> ParseResult<T> {
199 if let SymbolType::Error{what} = error.symbol() { 205 if let SymbolType::Error{what} = error.symbol() {
200 Err(ParseError { 206 Err(ParseError {
201 position: error.start().clone(), 207 position: error.start().clone(),
@@ -209,15 +215,15 @@ impl Parser {
209 } 215 }
210 } 216 }
211 217
212 pub fn parse(&self, src: &str ) -> ParseResult<Token> { 218 pub fn parse(&self, src: &str, source: usize ) -> ParseResult<Vec<View>> {
213 let ll = Lexer::new( src ); 219 let ll = Lexer::new( src );
214 let mut ctx = Context::new( ll ); 220 let mut ctx = Context::new( ll, source );
215 221
216 // Parse the root of the file, the input context 222 // Parse the root of the file, the input context
217 self.p_input( &mut ctx ) 223 self.p_input( &mut ctx )
218 } 224 }
219 225
220 fn p_input(&self, ctx: &mut Context ) -> ParseResult<Token> { 226 fn p_input(&self, ctx: &mut Context ) -> ParseResult<Vec<View>> {
221 let mut children = Vec::new(); 227 let mut children = Vec::new();
222 loop { 228 loop {
223 if ctx.cur().is_none() { 229 if ctx.cur().is_none() {
@@ -229,7 +235,7 @@ impl Parser {
229 children.push( self.parse_tag_view( ctx )? ); 235 children.push( self.parse_tag_view( ctx )? );
230 } 236 }
231 SymbolType::Error{..} => { 237 SymbolType::Error{..} => {
232 return self.lex_error( &ctx.cur().unwrap() ); 238 self.lex_error( &ctx.cur().unwrap() )?;
233 } 239 }
234 _ => { 240 _ => {
235 241
@@ -237,11 +243,11 @@ impl Parser {
237 } 243 }
238 ctx.next(); 244 ctx.next();
239 } 245 }
240 Ok(Token::Root(children)) 246 Ok(children)
241 } 247 }
242 248
243 fn parse_tag_view(&self, ctx: &mut Context) -> ParseResult<Token> { 249 fn parse_tag_view(&self, ctx: &mut Context) -> ParseResult<View> {
244 let mut tb = self.parse_open_tag( ctx )?; 250 let tb = self.parse_open_tag( ctx )?;
245 if !tb.is_name( &SymbolType::View ) { 251 if !tb.is_name( &SymbolType::View ) {
246 return Err(ParseError{ 252 return Err(ParseError{
247 position: tb.start_pos(), 253 position: tb.start_pos(),
@@ -250,9 +256,10 @@ impl Parser {
250 } 256 }
251 257
252 if tb.is_unary() { 258 if tb.is_unary() {
253 return tb.build(); 259 return tb.build_view(ctx, Vec::new());
254 } 260 }
255 let mut children = Vec::new(); 261 let mut children = Vec::new();
262 let mut outputs = Vec::new();
256 263
257 //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() ); 264 //println!("--parse-tag-view-- tag parsed, next token: {:?}", ctx.cur() );
258 loop { 265 loop {
@@ -265,47 +272,37 @@ impl Parser {
265 ctx.next(); 272 ctx.next();
266 } 273 }
267 SymbolType::StartFlat => { 274 SymbolType::StartFlat => {
268 //child.is_name(SymbolType::Output) 275 let subtb = self.parse_tag_body( ctx )?;
269 children.push( self.parse_tag_body( ctx )? ); 276 if subtb.is_name(&SymbolType::Output) {
277 outputs.push(subtb.build_output(ctx)?);
278 } else {
279 children.push(subtb.build()?);
280 }
270 } 281 }
271 SymbolType::StartPoint => { 282 SymbolType::StartPoint => {
272 let end = self.parse_end_tag( ctx )?; 283 let end = self.parse_end_tag( ctx )?;
273 //println!("End tag: {:?}, open tag: {:?}", end, tb.name() ); 284 //println!("End tag: {:?}, open tag: {:?}", end, tb.name() );
274 if tb.is_name(end.symbol()) { 285 if tb.is_name(end.symbol()) {
275 // They match, time to decide what we're doing. 286 // They match, time to decide what we're doing.
276 let any_outputs = children.iter().any( 287 let any_outputs = outputs.len() > 0;
277 |t| matches!(t, Token::Output(..)) 288 let all_text = children.iter().all(
289 |t| matches!(t, Token::Text(..))
278 ); 290 );
279 if children.iter().all(|t| matches!(t, Token::Text(..)) || matches!(t, Token::Output(..))) { 291 if !any_outputs {
280 // Everything is either text or output 292 // Create an implicit output called "content"
281 if !any_outputs { 293 outputs.push(Output{
282 // Special case, if it's only text then we create an implicit output. 294 name: "content".to_string(),
283 tb.add_child(Token::Output("content".to_string(), /*Properties::new(),*/ children )); 295 code: children,
284 } 296 });
285 else {
286 // Standard case, outputs are included, text is
287 // skipped.
288 for token in children {
289 if matches!(token, Token::Output(..)) {
290 tb.add_child( token );
291 }
292 }
293 }
294 } else { 297 } else {
295 // We have another mix, now check to see if there 298 if !all_text {
296 // are any outptus, if so this is an error.
297 if any_outputs {
298 return Err(ParseError{ 299 return Err(ParseError{
299 position: *end.start(), 300 position: *end.start(),
300 what: "You cannot mix non-output and output tags in a view.".to_string() 301 what: "You cannot mix non-output and output tags in a view.".to_string()
301 }); 302 });
302 } else {
303 // No outputs at all, we create an implict output
304 tb.add_child(Token::Output("content".to_string(), /*Properties::new(), */children ));
305 } 303 }
306 } 304 }
307 305 return tb.build_view(ctx,outputs);
308 return tb.build();
309 } else { 306 } else {
310 // They don't match, complain. 307 // They don't match, complain.
311 return Err(ParseError{ 308 return Err(ParseError{
@@ -392,10 +389,10 @@ impl Parser {
392 Ok(name) 389 Ok(name)
393 } 390 }
394 391
395 fn parse_tag_body(&self, ctx: &mut Context ) -> ParseResult<Token> { 392 fn parse_tag_body<'a>(&self, ctx: &mut Context<'a> ) -> ParseResult<TagBuilder<'a>> {
396 let mut tb = self.parse_open_tag( ctx )?; 393 let mut tb = self.parse_open_tag( ctx )?;
397 if tb.is_unary() { 394 if tb.is_unary() {
398 return tb.build(); 395 return Ok(tb);
399 } 396 }
400 397
401 loop { 398 loop {
@@ -408,13 +405,13 @@ impl Parser {
408 ctx.next(); 405 ctx.next();
409 } 406 }
410 SymbolType::StartFlat => { 407 SymbolType::StartFlat => {
411 tb.add_child( self.parse_tag_body( ctx )? ); 408 tb.add_child( self.parse_tag_body( ctx )?.build()? );
412 } 409 }
413 SymbolType::StartPoint => { 410 SymbolType::StartPoint => {
414 let end = self.parse_end_tag( ctx )?; 411 let end = self.parse_end_tag( ctx )?;
415 if tb.is_name(end.symbol()) { 412 if tb.is_name(end.symbol()) {
416 // They match, end. 413 // They match, end.
417 return tb.build(); 414 return Ok(tb);
418 } else { 415 } else {
419 // They don't match, complain. 416 // They don't match, complain.
420 return Err(ParseError{ 417 return Err(ParseError{
@@ -424,7 +421,7 @@ impl Parser {
424 } 421 }
425 } 422 }
426 SymbolType::Error{..} => { 423 SymbolType::Error{..} => {
427 self.lex_error( &ctx.cur().unwrap() )?; 424 return self.lex_error( &ctx.cur().unwrap() );
428 } 425 }
429 _ => { 426 _ => {
430 427
@@ -565,15 +562,42 @@ impl<'a> TagBuilder<'a> {
565 self.tag_type 562 self.tag_type
566 } 563 }
567 564
565 pub fn build_view(mut self, ctx: &Context, outputs: Vec<Output>) -> ParseResult<View> {
566 if let Some(sym) = self.name {
567 if *sym.symbol() == SymbolType::View {
568 Ok(View {
569 name: self.params.swap_remove(0),
570 source: ctx.source(),
571 outputs: outputs,
572 //theme: Option<String>
573 layout: self.props.get("layout").cloned(),
574 })
575 } else {
576 Err(ParseError::new(self.start_pos, &format!("Expected tag type view, found {:?}", sym.symbol())))
577 }
578 } else {
579 Err(ParseError::new(self.start_pos, "Broken Parser? No tag type found when building view."))
580 }
581 }
582
583 pub fn build_output(mut self, ctx: &Context) -> ParseResult<Output> {
584 if let Some(sym) = self.name {
585 if *sym.symbol() == SymbolType::Output {
586 Ok(Output {
587 name: self.params.swap_remove(0),
588 code: self.children,
589 })
590 } else {
591 Err(ParseError::new(self.start_pos, &format!("Expected tag type view, found {:?}", sym.symbol())))
592 }
593 } else {
594 Err(ParseError::new(self.start_pos, "Broken Parser? No tag type found when building view."))
595 }
596 }
597
568 pub fn build(mut self) -> ParseResult<Token> { 598 pub fn build(mut self) -> ParseResult<Token> {
569 if let Some(sym) = self.name { 599 if let Some(sym) = self.name {
570 match sym.symbol() { 600 match sym.symbol() {
571 SymbolType::View => {
572 Ok(Token::View(self.params.swap_remove(0), self.props, self.children))
573 }
574 SymbolType::Output => {
575 Ok(Token::Output(self.params.swap_remove(0), /*self.props,*/ self.children))
576 }
577 SymbolType::Show => { 601 SymbolType::Show => {
578 Ok(Token::Show(self.params.swap_remove(0), self.props)) 602 Ok(Token::Show(self.params.swap_remove(0), self.props))
579 } 603 }