Make lexeme and token logging more concise
This commit is contained in:
parent
cb24837ff0
commit
735b58866c
15 changed files with 229 additions and 20 deletions
|
|
@ -4,7 +4,7 @@ use crate::types::Config;
|
|||
|
||||
pub mod parser;
|
||||
|
||||
pub trait Parseable {
|
||||
pub trait Parseable: std::fmt::Display {
|
||||
fn probe(lexeme: &Lexeme) -> bool;
|
||||
fn lex(lexeme: &Lexeme) -> Self;
|
||||
fn render(&self) -> String;
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ fn lex(text: &str, map: LexMap, config: &Config) -> Vec<Token> {
|
|||
let segments = segment::segment(text);
|
||||
let lexemes = Lexeme::collect(&segments);
|
||||
|
||||
log!("Lexing segments: {segments:?}");
|
||||
log!("Segments: {segments:?}");
|
||||
|
||||
let mut iterator = lexemes.iter().peekable();
|
||||
while let Some(lexeme) = iterator.next() {
|
||||
|
|
@ -51,7 +51,7 @@ fn lex(text: &str, map: LexMap, config: &Config) -> Vec<Token> {
|
|||
tokens.push(Token::Header(header));
|
||||
continue;
|
||||
} else if Paragraph::probe(lexeme) {
|
||||
log!("Probed block context None -> Paragraph: {lexeme:?}");
|
||||
log!("Block Context: None -> Paragraph on {lexeme}");
|
||||
state.context.block = Block::Paragraph;
|
||||
tokens.push(Token::Paragraph(Paragraph::new(true)));
|
||||
}
|
||||
|
|
@ -67,7 +67,7 @@ fn lex(text: &str, map: LexMap, config: &Config) -> Vec<Token> {
|
|||
},
|
||||
Block::Paragraph => {
|
||||
if Paragraph::probe_end(lexeme) {
|
||||
log!("Probed block context Paragraph -> None: {lexeme:?}");
|
||||
log!("Block Context: Paragraph -> None on {lexeme}");
|
||||
tokens.push(Token::Paragraph(Paragraph::new(false)));
|
||||
state.context.block = Block::None;
|
||||
}
|
||||
|
|
@ -86,29 +86,24 @@ fn lex(text: &str, map: LexMap, config: &Config) -> Vec<Token> {
|
|||
state.context.inline = Inline::Code;
|
||||
tokens.push(Token::Code(Code::new(true)));
|
||||
continue;
|
||||
} else if Oblique::probe(lexeme) {
|
||||
log!("Inline Context: None -> Oblique on {lexeme}");
|
||||
state.context.inline = Inline::Oblique;
|
||||
tokens.push(Token::Oblique(Oblique::new(true)));
|
||||
continue;
|
||||
} else if Anchor::probe(lexeme) {
|
||||
log!("Positively probed anchor: {lexeme:?}");
|
||||
state.context.inline = Inline::Anchor;
|
||||
state.buffers.anchor.clear();
|
||||
|
||||
if lexeme.match_as_char('|') {
|
||||
log!("{:#?} matches as a pipe char", lexeme.text());
|
||||
state.buffers.anchor.candidate.leading = true;
|
||||
} else {
|
||||
log!(
|
||||
"{:#?} not a pipe: assuming it's the anchor text",
|
||||
lexeme.text(),
|
||||
);
|
||||
state.buffers.anchor.candidate.text = lexeme.text();
|
||||
// because we probed positively and this is not a pipe,
|
||||
// the next lexeme must be and so it was now parsed
|
||||
iterator.next();
|
||||
}
|
||||
continue;
|
||||
} else if Oblique::probe(lexeme) {
|
||||
state.context.inline = Inline::Oblique;
|
||||
tokens.push(Token::Oblique(Oblique::new(true)));
|
||||
continue;
|
||||
}
|
||||
},
|
||||
Inline::Code => {
|
||||
|
|
@ -120,6 +115,7 @@ fn lex(text: &str, map: LexMap, config: &Config) -> Vec<Token> {
|
|||
},
|
||||
Inline::Oblique => {
|
||||
if Oblique::probe(lexeme) {
|
||||
log!("Inline Context: Oblique -> None on {lexeme}");
|
||||
state.context.inline = Inline::None;
|
||||
tokens.push(Token::Oblique(Oblique::new(false)));
|
||||
continue;
|
||||
|
|
@ -135,7 +131,7 @@ fn lex(text: &str, map: LexMap, config: &Config) -> Vec<Token> {
|
|||
for &(ref probe, lex) in map {
|
||||
if probe(lexeme) {
|
||||
let token = lex(lexeme);
|
||||
log!("Lexmap lexed {lexeme:?} into {token:?}");
|
||||
log!("Lexmap lexed {lexeme} into {token}");
|
||||
tokens.push(token);
|
||||
break;
|
||||
}
|
||||
|
|
@ -173,6 +169,30 @@ impl AnchorBuffer {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for AnchorBuffer {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_text = if self.text.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
format!("text: {:?}", self.text)
|
||||
};
|
||||
let display_destination = if self.destination.is_empty() {
|
||||
String::new()
|
||||
} else {
|
||||
format!(", dest: {:?}", self.destination)
|
||||
};
|
||||
|
||||
let display_text_and_destination =
|
||||
format!("{display_text}{display_destination}");
|
||||
|
||||
write!(
|
||||
f,
|
||||
"AnchorBuffer [{display_text_and_destination}] >> {}",
|
||||
self.candidate,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl State {
|
||||
fn new() -> State {
|
||||
State {
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ pub fn parse(
|
|||
state: &mut State,
|
||||
tokens: &mut Vec<Token>,
|
||||
) -> bool {
|
||||
log!(
|
||||
"Resolving open context: {:#?}",
|
||||
state.clone().buffers.anchor
|
||||
);
|
||||
log!("Solving: {}", state.clone().buffers.anchor);
|
||||
let buffer = &mut state.buffers.anchor;
|
||||
let candidate = &mut buffer.candidate;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt;
|
||||
|
||||
use crate::{prelude::*, syntax::content::parser::segment::delimiter::Delimiters};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
@ -154,6 +156,19 @@ impl Lexeme {
|
|||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Lexeme {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
use crate::dev::wrap;
|
||||
|
||||
let next_display = if self.last() {
|
||||
" <EOI>"
|
||||
} else {
|
||||
&format!("-> {}", wrap(&self.next))
|
||||
};
|
||||
write!(f, "{} {}", wrap(&self.text), next_display)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -39,6 +39,24 @@ impl Token {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Token {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let data = match *self {
|
||||
Token::Anchor(ref d) => format!("{d}"),
|
||||
Token::Code(ref d) => format!("{d}"),
|
||||
Token::Header(ref d) => format!("{d}"),
|
||||
Token::LineBreak(ref d) => format!("{d}"),
|
||||
Token::Literal(ref d) => format!("{d}"),
|
||||
Token::Oblique(ref d) => format!("{d}"),
|
||||
Token::Paragraph(ref d) => format!("{d}"),
|
||||
Token::PreFormat(ref d) => format!("{d}"),
|
||||
Token::Span(ref d) => format!("{d}"),
|
||||
};
|
||||
|
||||
write!(f, "T*{data}")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ impl Parseable for Anchor {
|
|||
fn render(&self) -> String {
|
||||
let Some(ref destination) = self.destination else {
|
||||
panic!(
|
||||
"Attempt to render anchor {self:?} without knowing its destination."
|
||||
"Attempt to render anchor {self:#?} without knowing its destination."
|
||||
)
|
||||
};
|
||||
|
||||
|
|
@ -40,6 +40,41 @@ impl Parseable for Anchor {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Anchor {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
use crate::dev::wrap;
|
||||
|
||||
let display_destination = match self.destination {
|
||||
Some(ref destination) => { if destination.is_empty() {
|
||||
"<empty>"
|
||||
} else {
|
||||
destination
|
||||
}},
|
||||
None => "<unknown>"
|
||||
};
|
||||
|
||||
let mut tail = String::new();
|
||||
|
||||
if self.leading {
|
||||
tail.push_str(" [Leading]");
|
||||
}
|
||||
if self.balanced {
|
||||
tail.push_str(" [Balanced]");
|
||||
}
|
||||
if self.external {
|
||||
tail.push_str(" [External]");
|
||||
}
|
||||
|
||||
write!(
|
||||
f,
|
||||
"Anchor {:?} -> {:?}{}",
|
||||
wrap(&self.text),
|
||||
display_destination,
|
||||
tail
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Anchor {
|
||||
pub fn new(
|
||||
text: &str,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ impl Parseable for Code {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Code {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_open_state = if self.open { "open" } else { "closed" };
|
||||
write!(f, "Code [{display_open_state}]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -112,6 +112,27 @@ impl Parseable for Header {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Header {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_open_state = if let Some(open_state) = self.open {
|
||||
if open_state { "open" } else { "closed" }
|
||||
} else {
|
||||
"unknown"
|
||||
};
|
||||
|
||||
let display_dom_id = match self.dom_id {
|
||||
Some(ref dom_id) => format!(" DOM ID {dom_id}"),
|
||||
None => String::new()
|
||||
};
|
||||
|
||||
write!(
|
||||
f,
|
||||
"Header [{} L{}{}]",
|
||||
display_open_state, self.level, display_dom_id
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Eq, PartialEq)]
|
||||
pub enum Level {
|
||||
One,
|
||||
|
|
|
|||
|
|
@ -18,3 +18,9 @@ impl Parseable for LineBreak {
|
|||
"\n".to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for LineBreak {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "LineBreak")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,3 +20,9 @@ impl Parseable for Literal {
|
|||
self.text.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Literal {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "Literal {}", crate::dev::wrap(&self.text))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,13 @@ impl Parseable for Oblique {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Oblique {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_open_state = if self.open { "open" } else { "closed" };
|
||||
write!(f, "Oblique [{display_open_state}]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -40,6 +40,16 @@ impl Parseable for Paragraph {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Paragraph {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_open_state = match self.open {
|
||||
Some(open_state) => { if open_state { "open" } else { "closed" } },
|
||||
None => "unknown"
|
||||
};
|
||||
write!(f, "Paragraph [{display_open_state}]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,17 @@ impl PreFormat {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PreFormat {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_open_state = if let Some(open_state) = self.open {
|
||||
if open_state { "open" } else { "closed" }
|
||||
} else {
|
||||
"unknown"
|
||||
};
|
||||
write!(f, "PreFormat [{display_open_state}]")
|
||||
}
|
||||
}
|
||||
|
||||
impl Parseable for PreFormat {
|
||||
fn probe(lexeme: &Lexeme) -> bool {
|
||||
lexeme.match_first_char('`') && (lexeme.next() == "\n" || lexeme.last())
|
||||
|
|
|
|||
|
|
@ -34,6 +34,17 @@ impl Parseable for Span {
|
|||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Span {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
let display_open_state = match self.open {
|
||||
Some(ref open_state) => {
|
||||
if *open_state { "open" } else { "closed" }},
|
||||
None => "unknown"
|
||||
};
|
||||
write!(f, "Span [{display_open_state}]")
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue