summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <mike@xagasoft.com>2026-06-08 09:56:20 -0700
committerMike Buland <mike@xagasoft.com>2026-06-08 09:56:20 -0700
commit55750a223008b256fddd8636ff4d474f959c8a23 (patch)
tree632440d989f974da6c98bcc1fd29699e1496851a
parent83ab8c67beecfc05684c9400e29f7d77225d3af9 (diff)
downloadcrimtag-55750a223008b256fddd8636ff4d474f959c8a23.tar.gz
crimtag-55750a223008b256fddd8636ff4d474f959c8a23.tar.bz2
crimtag-55750a223008b256fddd8636ff4d474f959c8a23.tar.xz
crimtag-55750a223008b256fddd8636ff4d474f959c8a23.zip
Many little changes to parsing, getting better.
-rw-r--r--src/lexer.rs2
-rw-r--r--src/lib.rs7
-rw-r--r--src/parser.rs113
3 files changed, 87 insertions, 35 deletions
diff --git a/src/lexer.rs b/src/lexer.rs
index 902bb64..4225b32 100644
--- a/src/lexer.rs
+++ b/src/lexer.rs
@@ -229,7 +229,7 @@ impl<'a> Lexer<'a> {
229 } else { 229 } else {
230 Some(Symbol::new( match s { 230 Some(Symbol::new( match s {
231 "fragment" => SymbolType::Fragment, 231 "fragment" => SymbolType::Fragment,
232 "section" => SymbolType::Section, 232 "show" => SymbolType::Show,
233 "output" => SymbolType::Output, 233 "output" => SymbolType::Output,
234 _ => SymbolType::Token(s) 234 _ => SymbolType::Token(s)
235 }, start_pos, end_pos )) 235 }, start_pos, end_pos ))
diff --git a/src/lib.rs b/src/lib.rs
index 5e912cf..25d9be1 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,10 +40,10 @@ enum FragmentSource {
40struct Fragment { 40struct Fragment {
41 name: String, 41 name: String,
42 source: usize, 42 source: usize,
43 sections: HashMap<String, Section>, 43 sections: HashMap<String, Output>,
44} 44}
45 45
46struct Section { 46struct Output {
47 name: String, 47 name: String,
48 ast_root: Token, 48 ast_root: Token,
49} 49}
@@ -53,7 +53,8 @@ type Properties = HashMap<String, String>;
53enum Token { 53enum Token {
54 Root(Vec<Token>), 54 Root(Vec<Token>),
55 Fragment(String,Properties,Vec<Token>), 55 Fragment(String,Properties,Vec<Token>),
56 Section(String,Properties,Vec<Token>), 56 Output(String,Properties,Vec<Token>),
57 Show(String,Properties),
57 Text(String), 58 Text(String),
58 Literal(String), 59 Literal(String),
59 /* 60 /*
diff --git a/src/parser.rs b/src/parser.rs
index 2d845cd..368a246 100644
--- a/src/parser.rs
+++ b/src/parser.rs
@@ -5,7 +5,7 @@ use core::error::Error;
5use std::fmt; 5use std::fmt;
6 6
7#[derive(Debug)] 7#[derive(Debug)]
8struct ParseError { 8pub struct ParseError {
9 position: Position, 9 position: Position,
10 what: String, 10 what: String,
11} 11}
@@ -18,6 +18,8 @@ impl fmt::Display for ParseError {
18 18
19impl Error for ParseError { } 19impl Error for ParseError { }
20 20
21pub type ParseResult<T> = Result<T, ParseError>;
22
21struct Context<'a> { 23struct Context<'a> {
22 cur: [Option<Symbol<'a>>;2], 24 cur: [Option<Symbol<'a>>;2],
23 icur: usize, 25 icur: usize,
@@ -51,6 +53,19 @@ impl<'a> Context<'a> {
51 } 53 }
52} 54}
53 55
56impl Option<Symbol> {
57 pub fn is<T: Fn( &SymbolType ) -> bool>(&self, f: T ) -> ParseError<bool> {
58 if let Some(st) = self {
59 Ok(f( &self.symbol ))
60 } else {
61 Err(ParseError{
62 position: Position::new(0,0),
63 what: "Unexpeceted end of stream.".to_string()
64 })
65 }
66 }
67}
68
54pub struct Parser { 69pub struct Parser {
55} 70}
56 71
@@ -137,21 +152,21 @@ impl Parser {
137 } 152 }
138 } 153 }
139 154
140 fn lex_error(&self, error: &Symbol) -> Result<Token,Box<dyn Error>> { 155 fn lex_error(&self, error: &Symbol) -> ParseResult<Token> {
141 if let SymbolType::Error{what} = error.symbol() { 156 if let SymbolType::Error{what} = error.symbol() {
142 Err(Box::new(ParseError { 157 Err(ParseError {
143 position: error.start().clone(), 158 position: error.start().clone(),
144 what: format!("What: {:?}", *what) 159 what: format!("What: {:?}", *what)
145 })) 160 })
146 } else { 161 } else {
147 Err(Box::new(ParseError { 162 Err(ParseError {
148 position: Position::new(0,0), 163 position: Position::new(0,0),
149 what: "Not an error?".to_string(), 164 what: "Not an error?".to_string(),
150 })) 165 })
151 } 166 }
152 } 167 }
153 168
154 pub fn parse(&mut self, src: &str ) -> Result<Token,Box<dyn Error>> { 169 pub fn parse(&mut self, src: &str ) -> ParseResult<Token> {
155 let mut ll = Lexer::new( src ); 170 let mut ll = Lexer::new( src );
156 let mut ctx = Context::new( ll ); 171 let mut ctx = Context::new( ll );
157 172
@@ -159,7 +174,7 @@ impl Parser {
159 self.p_input( &mut ctx ) 174 self.p_input( &mut ctx )
160 } 175 }
161 176
162 fn p_input(&mut self, ctx: &mut Context ) -> Result<Token, Box<dyn Error>> { 177 fn p_input(&mut self, ctx: &mut Context ) -> ParseResult<Token> {
163 let mut children = Vec::new(); 178 let mut children = Vec::new();
164 loop { 179 loop {
165 if ctx.cur().is_none() { 180 if ctx.cur().is_none() {
@@ -182,7 +197,7 @@ impl Parser {
182 Ok(Token::Root(children)) 197 Ok(Token::Root(children))
183 } 198 }
184 199
185 fn parse_tag(&mut self, ctx: &mut Context) -> Result<Token, Box<dyn Error>> { 200 fn parse_tag(&mut self, ctx: &mut Context) -> ParseResult<TagBuilder> {
186 let mut tb = TagBuilder::new(); 201 let mut tb = TagBuilder::new();
187 202
188 println!("--> Begin parse_tag <--"); 203 println!("--> Begin parse_tag <--");
@@ -193,28 +208,23 @@ impl Parser {
193 208
194 if ctx.next().is_some() { 209 if ctx.next().is_some() {
195 match ctx.cur().unwrap().symbol() { 210 match ctx.cur().unwrap().symbol() {
196 SymbolType::Fragment | SymbolType::Section | 211 SymbolType::Fragment | SymbolType::Show |
197 SymbolType::Output => { 212 SymbolType::Output => {
198 let name_sym = ctx.cur().unwrap(); 213 let name_sym = ctx.cur().unwrap();
199 ctx.next(); 214 ctx.next();
200 tb.set_name( name_sym ); 215 tb.set_name( name_sym );
201 } 216 }
202 _ => { 217 _ => {
203 return Err(Box::new(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()})); 218 return Err(ParseError{position: ctx.cur().unwrap().start().clone(), what: "Unexpecetd symbol".to_string()});
204 } 219 }
205 } 220 }
206 } else { 221 } else {
207 return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); 222 return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()});
208 } 223 }
209 224
210 println!("--> Begin parse_tag_params <--");
211 self.parse_tag_params( ctx, &mut tb )?; 225 self.parse_tag_params( ctx, &mut tb )?;
212 println!("--> End parse_tag_params <--");
213 println!("--> Begin parse_tag_props <--");
214 self.parse_tag_props( ctx, &mut tb )?; 226 self.parse_tag_props( ctx, &mut tb )?;
215 println!("--> End parse_tag_props <--");
216 227
217 println!("---> {:?}", ctx.cur() );
218 if let Some(end_sym) = ctx.cur() { 228 if let Some(end_sym) = ctx.cur() {
219 match end_sym.symbol() { 229 match end_sym.symbol() {
220 SymbolType::EndPoint => { 230 SymbolType::EndPoint => {
@@ -224,19 +234,57 @@ impl Parser {
224 tb.set_type( TagType::Unary ); 234 tb.set_type( TagType::Unary );
225 } 235 }
226 _ => { 236 _ => {
227 return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); 237 return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()});
228 } 238 }
229 } 239 }
230 } 240 }
231 241
232 tb.build() 242 Ok(tb)
233 } 243 }
234 244
235 fn parse_tag_params(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<(), Box<dyn Error>> { 245 fn parse_end_tag(&mut self, ctx: &mut Context ) -> &'a str {
246 if !ctx.cur().is(|s| matches!(s, Symbol::StartPoint))? {
247 return Err(ParseError{
248 position: ctx.cur().
249 });
250 }
251 ctx.next()
252 }
253
254 fn parse_tag_body(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> {
236 loop { 255 loop {
237 if ctx.cur().is_none() { 256 if ctx.cur().is_none() {
257 return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()});
258 }
259 match ctx.cur().unwrap().symbol() {
260 SymbolType::Text(s) => {
261 tb.add_child(Token:: Text(s.to_string()));
262 }
263 SymbolType::StartFlat => {
264 tb.add_child( self.parse_tag( ctx )? );
265 }
266 SymbolType::StartPoint => {
267 let end_tag = self.parse_end_tag( ctx )?;
238 268
239 return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); 269 }
270 SymbolType::Error{..} => {
271 return self.lex_error( &ctx.cur().unwrap() );
272 }
273 _ => {
274
275 }
276 }
277 ctx.next();
278 }
279 Ok(Token::Root(children))
280 Ok(())
281 }
282
283 fn parse_tag_params(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> {
284 loop {
285 if ctx.cur().is_none() {
286
287 return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()});
240 } 288 }
241 match ctx.cur().unwrap().symbol() { 289 match ctx.cur().unwrap().symbol() {
242 SymbolType::Literal(s) => { 290 SymbolType::Literal(s) => {
@@ -251,10 +299,10 @@ impl Parser {
251 Ok(()) 299 Ok(())
252 } 300 }
253 301
254 fn parse_tag_props(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> Result<(), Box<dyn Error>> { 302 fn parse_tag_props(&mut self, ctx: &mut Context, tb: &mut TagBuilder ) -> ParseResult<()> {
255 loop { 303 loop {
256 if ctx.cur().is_none() { 304 if ctx.cur().is_none() {
257 return Err(Box::new(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()})); 305 return Err(ParseError{position: Position::new(0,0), what: "Unexpecetd end of stream".to_string()});
258 } 306 }
259 if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() { 307 if let SymbolType::Token(s) = ctx.cur().unwrap().symbol() {
260 if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) { 308 if ctx.peek().is_some_and(|s|s.check_type(|t| matches!(t,SymbolType::Equals))) {
@@ -263,10 +311,10 @@ impl Parser {
263 let SymbolType::Literal(lv) = sym.symbol() { 311 let SymbolType::Literal(lv) = sym.symbol() {
264 tb.add_prop( s.to_string(), lv.to_string() ); 312 tb.add_prop( s.to_string(), lv.to_string() );
265 } else { 313 } else {
266 return Err(Box::new(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()})); 314 return Err(ParseError{position: Position::new(0,0), what: "Expected quoted literal string".to_string()});
267 } 315 }
268 } else { 316 } else {
269 return Err(Box::new(ParseError{position:Position::new(0,0), what: "Expected = ".to_string()})); 317 return Err(ParseError{position:Position::new(0,0), what: "Expected = ".to_string()});
270 } 318 }
271 } else { 319 } else {
272 break; 320 break;
@@ -343,28 +391,31 @@ impl<'a> TagBuilder<'a> {
343 self.tag_type = tag_type; 391 self.tag_type = tag_type;
344 } 392 }
345 393
346 pub fn build(mut self) -> Result<Token,Box<dyn Error>> { 394 pub fn build(mut self) -> ParseResult<Token> {
347 if let Some(sym) = self.name { 395 if let Some(sym) = self.name {
348 match sym.symbol() { 396 match sym.symbol() {
349 SymbolType::Fragment => { 397 SymbolType::Fragment => {
350 Ok(Token::Fragment(self.params.swap_remove(0), self.props, self.children)) 398 Ok(Token::Fragment(self.params.swap_remove(0), self.props, self.children))
351 } 399 }
352 SymbolType::Output => { 400 SymbolType::Output => {
353 Ok(Token::Section(self.params.swap_remove(0), self.props, self.children)) 401 Ok(Token::Output(self.params.swap_remove(0), self.props, self.children))
402 }
403 SymbolType::Show => {
404 Ok(Token::Show(self.params.swap_remove(0), self.props))
354 } 405 }
355 _ => { 406 _ => {
356 println!("Unkown tag type"); 407 println!("Unkown tag type");
357 Err(Box::new(ParseError { 408 Err(ParseError {
358 position: Position::new(0,0), 409 position: Position::new(0,0),
359 what: "Bad tag type".to_string(), 410 what: "Bad tag type".to_string(),
360 })) 411 })
361 } 412 }
362 } 413 }
363 } else { 414 } else {
364 Err(Box::new(ParseError { 415 Err(ParseError {
365 position: Position::new(0,0), 416 position: Position::new(0,0),
366 what: "Bad tag type".to_string(), 417 what: "Bad tag type".to_string(),
367 })) 418 })
368 } 419 }
369 } 420 }
370} 421}