mirror of
https://github.com/ParkerTenBroeck/automata.git
synced 2026-06-07 05:28:45 -04:00
NPDA's working
This commit is contained in:
parent
f375757fd6
commit
0e285ec100
6 changed files with 356 additions and 167 deletions
|
|
@ -26,10 +26,18 @@ impl<'a> Logs<'a> {
|
|||
self.logs.push(entry);
|
||||
}
|
||||
|
||||
pub fn emit_error_locless(&mut self, msg: impl Into<String>) {
|
||||
self.emit(LogEntry {
|
||||
message: msg.into(),
|
||||
span: None,
|
||||
level: LogLevel::Error,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn emit_error(&mut self, msg: impl Into<String>, span: Span) {
|
||||
self.emit(LogEntry {
|
||||
message: msg.into(),
|
||||
span,
|
||||
span: Some(span),
|
||||
level: LogLevel::Error,
|
||||
});
|
||||
}
|
||||
|
|
@ -37,7 +45,15 @@ impl<'a> Logs<'a> {
|
|||
pub fn emit_warning(&mut self, msg: impl Into<String>, span: Span) {
|
||||
self.emit(LogEntry {
|
||||
message: msg.into(),
|
||||
span,
|
||||
span: Some(span),
|
||||
level: LogLevel::Warning,
|
||||
});
|
||||
}
|
||||
|
||||
pub fn emit_warning_locless(&mut self, msg: impl Into<String>) {
|
||||
self.emit(LogEntry {
|
||||
message: msg.into(),
|
||||
span: None,
|
||||
level: LogLevel::Warning,
|
||||
});
|
||||
}
|
||||
|
|
@ -45,7 +61,7 @@ impl<'a> Logs<'a> {
|
|||
pub fn emit_info(&mut self, msg: impl Into<String>, span: Span) {
|
||||
self.emit(LogEntry {
|
||||
message: msg.into(),
|
||||
span,
|
||||
span: Some(span),
|
||||
level: LogLevel::Info,
|
||||
});
|
||||
}
|
||||
|
|
@ -66,7 +82,7 @@ pub enum LogLevel {
|
|||
|
||||
pub struct LogEntry {
|
||||
pub message: String,
|
||||
pub span: Span,
|
||||
pub span: Option<Span>,
|
||||
pub level: LogLevel,
|
||||
}
|
||||
|
||||
|
|
@ -93,61 +109,53 @@ impl<'a> Display for LogEntryDisplay<'a> {
|
|||
}
|
||||
writeln!(f, "{}{RESET}", self.entry.message)?;
|
||||
|
||||
let line_start = self
|
||||
.src
|
||||
.get(..=self.entry.span.0)
|
||||
.unwrap_or("")
|
||||
.lines()
|
||||
.count();
|
||||
let line_end = self
|
||||
.src
|
||||
.get(..self.entry.span.1)
|
||||
.unwrap_or("")
|
||||
.lines()
|
||||
.count();
|
||||
if let Some(span) = self.entry.span {
|
||||
let line_start = self.src.get(..=span.0).unwrap_or("").lines().count();
|
||||
let line_end = self.src.get(..span.1).unwrap_or("").lines().count();
|
||||
|
||||
let padding = line_end.ilog10() as usize;
|
||||
let padding = line_end.ilog10() as usize;
|
||||
|
||||
let start = self
|
||||
.src
|
||||
.get(..self.entry.span.0)
|
||||
.and_then(|s| s.rfind('\n'))
|
||||
.map(|v| v + 1)
|
||||
.unwrap_or(0);
|
||||
let start = self
|
||||
.src
|
||||
.get(..span.0)
|
||||
.and_then(|s| s.rfind('\n'))
|
||||
.map(|v| v + 1)
|
||||
.unwrap_or(0);
|
||||
|
||||
let end = self
|
||||
.src
|
||||
.get(self.entry.span.1..)
|
||||
.and_then(|s| s.find('\n'))
|
||||
.map(|v| v + self.entry.span.1)
|
||||
.unwrap_or(self.src.len());
|
||||
let end = self
|
||||
.src
|
||||
.get(span.1..)
|
||||
.and_then(|s| s.find('\n'))
|
||||
.map(|v| v + span.1)
|
||||
.unwrap_or(self.src.len());
|
||||
|
||||
let mut index = start;
|
||||
for (i, line) in self.src.get(start..end).unwrap_or("").lines().enumerate() {
|
||||
write!(f, "{BOLD}{CYAN}{:>padding$}: {RESET}", i + line_start)?;
|
||||
for char in line.chars() {
|
||||
if char == '\t' {
|
||||
write!(f, " ")?
|
||||
} else {
|
||||
write!(f, "{char}")?
|
||||
let mut index = start;
|
||||
for (i, line) in self.src.get(start..end).unwrap_or("").lines().enumerate() {
|
||||
write!(f, "{BOLD}{CYAN}{:>padding$}: {RESET}", i + line_start)?;
|
||||
for char in line.chars() {
|
||||
if char == '\t' {
|
||||
write!(f, " ")?
|
||||
} else {
|
||||
write!(f, "{char}")?
|
||||
}
|
||||
}
|
||||
}
|
||||
writeln!(f)?;
|
||||
write!(f, "{BOLD}{CYAN}")?;
|
||||
for _ in 0..padding + 3 {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
for char in line.chars() {
|
||||
if (self.entry.span.0..self.entry.span.1).contains(&index) {
|
||||
write!(f, "~")?;
|
||||
} else {
|
||||
writeln!(f)?;
|
||||
write!(f, "{BOLD}{CYAN}")?;
|
||||
for _ in 0..padding + 3 {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
index += char.len_utf8();
|
||||
for char in line.chars() {
|
||||
if (span.0..span.1).contains(&index) {
|
||||
write!(f, "~")?;
|
||||
} else {
|
||||
write!(f, " ")?;
|
||||
}
|
||||
index += char.len_utf8();
|
||||
}
|
||||
write!(f, "{RESET}")?;
|
||||
index += '\n'.len_utf8();
|
||||
writeln!(f)?;
|
||||
}
|
||||
write!(f, "{RESET}")?;
|
||||
index += '\n'.len_utf8();
|
||||
writeln!(f)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@ use super::lexer::{Lexer, Token};
|
|||
use std::iter::Peekable;
|
||||
|
||||
pub struct Parser<'a> {
|
||||
lexer: Peekable<Lexer<'a>>,
|
||||
lexer: Lexer<'a>,
|
||||
peek: Option<Spanned<Token<'a>>>,
|
||||
logs: Logs<'a>,
|
||||
src: &'a str,
|
||||
eof: Span,
|
||||
|
|
@ -18,11 +19,15 @@ impl<'a> Parser<'a> {
|
|||
eof: lexer.eof_span(),
|
||||
src: lexer.input(),
|
||||
logs: Logs::new(lexer.input()),
|
||||
lexer: lexer.peekable(),
|
||||
peek: None,
|
||||
lexer,
|
||||
}
|
||||
}
|
||||
|
||||
fn next_token(&mut self) -> Option<Spanned<Token<'a>>> {
|
||||
if self.peek.is_some(){
|
||||
return self.peek.take()
|
||||
}
|
||||
loop {
|
||||
match self.lexer.next()? {
|
||||
Spanned(Ok(Token::Comment(_)), _) => {}
|
||||
|
|
@ -33,12 +38,10 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
|
||||
fn peek_token(&mut self) -> Option<Spanned<Token<'a>>> {
|
||||
loop {
|
||||
match *self.lexer.peek()? {
|
||||
Spanned(Ok(ok), r) => return Some(Spanned(ok, r)),
|
||||
Spanned(Err(err), span) => self.logs.emit_error(format!("lexer: {err:?}"), span),
|
||||
}
|
||||
if self.peek.is_none(){
|
||||
self.peek = self.next_token();
|
||||
}
|
||||
self.peek
|
||||
}
|
||||
|
||||
fn expect_token(&mut self, expected: Token<'a>) -> (bool, Span) {
|
||||
|
|
@ -125,6 +128,7 @@ impl<'a> Parser<'a> {
|
|||
Some(Spanned(Token::LPar, _)) => self.parse_tupple().map(Item::Tuple),
|
||||
Some(Spanned(Token::LBrace | Token::LBracket, _)) => self.parse_list().map(Item::List),
|
||||
Some(Spanned(got, span)) => {
|
||||
self.next_token();
|
||||
self.logs.emit_error(
|
||||
format!(
|
||||
"unexpected token {:#}, expected {:}|{:}|{:}|{:}|{:}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue