Rewrites to prepare for parser swap

This commit is contained in:
Greg Shuflin 2021-11-14 02:15:08 -08:00
parent abab667c43
commit 205ab7179d
6 changed files with 15 additions and 26 deletions

View File

@ -34,7 +34,6 @@ impl Fold for RecursiveDescentFn {
}
result.map_err(|mut parse_error: ParseError| {
parse_error.production_name = Some(stringify!(#ident).to_string());
parse_error
})
}

View File

@ -82,27 +82,18 @@ struct Error {
}
fn format_parse_error(error: ParseError, source_reference: &SourceReference) -> String {
/*
let line_num = error.token.location.line_num;
let ch = error.token.location.char_num;
*/
let line_num = 1;
let ch = 4;
let offset = error.location.offset;
let (line_start, line_num, line_from_program) = source_reference.get_line(offset);
let ch = offset - line_start;
let line_from_program = source_reference.get_line(line_num as usize);
let location_pointer = format!("{}^", " ".repeat(ch));
let line_num_digits = format!("{}", line_num).chars().count();
let space_padding = " ".repeat(line_num_digits);
let production = match error.production_name {
Some(n) => format!("\n(from production \"{}\")", n),
None => "".to_string(),
};
format!(
r#"
{error_msg}{production}
{error_msg}
{space_padding} |
{line_num} | {}
{space_padding} | {}
@ -112,6 +103,5 @@ fn format_parse_error(error: ParseError, source_reference: &SourceReference) ->
error_msg = error.msg,
space_padding = space_padding,
line_num = line_num,
production = production
)
}

View File

@ -182,15 +182,15 @@ use crate::{
/// Represents a parsing error
#[derive(Debug)]
pub struct ParseError {
pub production_name: Option<String>,
pub msg: String,
pub location: Location,
pub token: Token,
}
impl ParseError {
fn new_with_token<T, M>(msg: M, token: Token) -> ParseResult<T>
where M: Into<String> {
Err(ParseError { msg: msg.into(), token, production_name: None })
Err(ParseError { msg: msg.into(), location: Default::default(), token, })
}
}
@ -298,7 +298,7 @@ impl Parser {
next_token = Some(&r.next_token);
format!(", next token: {}", r.next_token)
};
buf.push_str(&format!("{}`{}`{}\n", indent, r.production_name, effective_token));
buf.push_str(&format!("{}`{}`{}\n", indent, "XXX", effective_token));
}
buf
}

View File

@ -25,13 +25,14 @@ impl Parser {
pub(crate) fn parse(
&mut self,
input: &str,
_source_reference: &SourceReference,
) -> Result<AST, ParseError> {
schala_parser::program(input, self).map_err(|err: peg::error::ParseError<_>| {
use peg::str::LineCol;
schala_parser::program(input, self).map_err(|err: peg::error::ParseError<LineCol>| {
let msg = err.to_string();
ParseError {
production_name: Some("some-production".to_string()),
msg,
location: err.location.offset.into(),
token: crate::tokenizing::Token {
kind: crate::tokenizing::TokenKind::Semicolon,
location: Default::default(),

View File

@ -141,7 +141,8 @@ impl SourceReference {
self.last_source = Some(source.to_string());
}
pub fn get_line(&self, line: usize) -> String {
// (line_start, line_num, the string itself)
pub fn get_line(&self, line: usize) -> (usize, usize, String) {
//TODO make sure this is utf8-safe
let start_idx = match self.newline_offsets.binary_search(&line) {
Ok(index) | Err(index) => index,
@ -153,7 +154,7 @@ impl SourceReference {
let end = self.newline_offsets.get(start_idx + 1).cloned().unwrap_or_else(|| last_source.len());
let slice = &last_source.as_bytes()[start..end];
std::str::from_utf8(slice).unwrap().to_string()
(start, start_idx, std::str::from_utf8(slice).unwrap().to_string())
}
}

View File

@ -52,10 +52,8 @@ where T: Hash + Eq
/// Quickly create an AST from a string, with no error checking. For test use only
#[cfg(test)]
pub fn quick_ast(input: &str) -> crate::ast::AST {
let mut source_reference = crate::schala::SourceReference::new();
let mut parser = crate::parsing::new::Parser::new();
source_reference.load_new_source(input);
let output = parser.parse(input, &source_reference);
let output = parser.parse(input);
output.unwrap()
}