Change Error::Parse
This commit is contained in:
parent
780f13eecc
commit
da55a54420
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.1.4...Unreleased) - ReleaseDate
|
## [Unreleased](https://github.com/dalance/sv-parser/compare/v0.1.4...Unreleased) - ReleaseDate
|
||||||
|
|
||||||
|
* [Added] parse error position
|
||||||
* [Fixed] spacing rule aroung text_macro_identifier
|
* [Fixed] spacing rule aroung text_macro_identifier
|
||||||
* [Fixed] cond_predicate in cond_predicate
|
* [Fixed] cond_predicate in cond_predicate
|
||||||
* [Fixed] fixed_number priority in delay_value
|
* [Fixed] fixed_number priority in delay_value
|
||||||
|
@ -15,7 +15,7 @@ pub enum ErrorKind {
|
|||||||
#[fail(display = "Include error")]
|
#[fail(display = "Include error")]
|
||||||
Include,
|
Include,
|
||||||
#[fail(display = "Parse error: {:?}", _0)]
|
#[fail(display = "Parse error: {:?}", _0)]
|
||||||
Parse(Option<usize>),
|
Parse(Option<(PathBuf, usize)>),
|
||||||
#[fail(display = "Preprocess error")]
|
#[fail(display = "Preprocess error")]
|
||||||
Preprocess,
|
Preprocess,
|
||||||
#[fail(display = "Define argument not found: {}", _0)]
|
#[fail(display = "Define argument not found: {}", _0)]
|
||||||
|
@ -110,8 +110,20 @@ fn preprocess_str<T: AsRef<Path>, U: AsRef<Path>>(
|
|||||||
let span = Span::new_extra(&s, SpanInfo::default());
|
let span = Span::new_extra(&s, SpanInfo::default());
|
||||||
let (_, pp_text) = pp_parser(span).map_err(|x| match x {
|
let (_, pp_text) = pp_parser(span).map_err(|x| match x {
|
||||||
nom::Err::Incomplete(_) => ErrorKind::Parse(None),
|
nom::Err::Incomplete(_) => ErrorKind::Parse(None),
|
||||||
nom::Err::Error(e) => ErrorKind::Parse(error_position(&e)),
|
nom::Err::Error(e) => {
|
||||||
nom::Err::Failure(e) => ErrorKind::Parse(error_position(&e)),
|
if let Some(pos) = error_position(&e) {
|
||||||
|
ErrorKind::Parse(Some((PathBuf::from(path.as_ref()), pos)))
|
||||||
|
} else {
|
||||||
|
ErrorKind::Parse(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nom::Err::Failure(e) => {
|
||||||
|
if let Some(pos) = error_position(&e) {
|
||||||
|
ErrorKind::Parse(Some((PathBuf::from(path.as_ref()), pos)))
|
||||||
|
} else {
|
||||||
|
ErrorKind::Parse(None)
|
||||||
|
}
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut ret = PreprocessedText::new();
|
let mut ret = PreprocessedText::new();
|
||||||
|
@ -14,6 +14,14 @@ edition = "2018"
|
|||||||
default = []
|
default = []
|
||||||
trace = ["sv-parser-parser/trace"]
|
trace = ["sv-parser-parser/trace"]
|
||||||
|
|
||||||
|
[package.metadata.release]
|
||||||
|
pre-release-replacements = [
|
||||||
|
{file = "../README.md", search = "sv-parser = \"[a-z0-9\\.-]+\"", replace = "sv-parser = \"{{version}}\""},
|
||||||
|
{file = "../CHANGELOG.md", search = "Unreleased", replace = "v{{version}}"},
|
||||||
|
{file = "../CHANGELOG.md", search = "ReleaseDate", replace = "{{date}}"},
|
||||||
|
{file = "../CHANGELOG.md", search = "Change Log", replace = "Change Log\n\n## [Unreleased](https://github.com/dalance/sv-parser/compare/v{{version}}...Unreleased) - ReleaseDate"},
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nom = "5.0.0"
|
nom = "5.0.0"
|
||||||
nom-greedyerror = "0.1.0"
|
nom-greedyerror = "0.1.0"
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Read;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::process;
|
use std::{cmp, process};
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use sv_parser::parse_sv;
|
use sv_parser::parse_sv;
|
||||||
|
use sv_parser_error::ErrorKind;
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
struct Opt {
|
struct Opt {
|
||||||
@ -37,10 +40,79 @@ fn main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(x) => {
|
Err(x) => {
|
||||||
println!("parse failed: {:?} ({})", path, x);
|
match x.kind() {
|
||||||
|
ErrorKind::Parse(Some((origin_path, origin_pos))) => {
|
||||||
|
println!("parse failed: {:?}", path);
|
||||||
|
print_parse_error(origin_path, origin_pos);
|
||||||
|
}
|
||||||
|
x => {
|
||||||
|
println!("parse failed: {:?} ({})", path, x);
|
||||||
|
}
|
||||||
|
}
|
||||||
exit = 1;
|
exit = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
process::exit(exit);
|
process::exit(exit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static CHAR_CR: u8 = 0x0d;
|
||||||
|
static CHAR_LF: u8 = 0x0a;
|
||||||
|
|
||||||
|
fn print_parse_error(origin_path: &PathBuf, origin_pos: &usize) {
|
||||||
|
let mut f = File::open(&origin_path).unwrap();
|
||||||
|
let mut s = String::new();
|
||||||
|
let _ = f.read_to_string(&mut s);
|
||||||
|
|
||||||
|
let mut pos = 0;
|
||||||
|
let mut column = 1;
|
||||||
|
let mut last_lf = None;
|
||||||
|
while pos < s.len() {
|
||||||
|
if s.as_bytes()[pos] == CHAR_LF {
|
||||||
|
column += 1;
|
||||||
|
last_lf = Some(pos);
|
||||||
|
}
|
||||||
|
pos += 1;
|
||||||
|
|
||||||
|
if *origin_pos == pos {
|
||||||
|
let row = if let Some(last_lf) = last_lf {
|
||||||
|
pos - last_lf
|
||||||
|
} else {
|
||||||
|
pos + 1
|
||||||
|
};
|
||||||
|
let mut next_crlf = pos;
|
||||||
|
while next_crlf < s.len() {
|
||||||
|
if s.as_bytes()[next_crlf] == CHAR_CR || s.as_bytes()[next_crlf] == CHAR_LF {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next_crlf += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let column_len = format!("{}", column).len();
|
||||||
|
|
||||||
|
print!(" {}:{}:{}\n", origin_path.to_string_lossy(), column, row);
|
||||||
|
|
||||||
|
print!("{}|\n", " ".repeat(column_len + 1));
|
||||||
|
|
||||||
|
print!("{} |", column);
|
||||||
|
|
||||||
|
let beg = if let Some(last_lf) = last_lf {
|
||||||
|
last_lf + 1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
print!(
|
||||||
|
" {}\n",
|
||||||
|
String::from_utf8_lossy(&s.as_bytes()[beg..next_crlf])
|
||||||
|
);
|
||||||
|
|
||||||
|
print!("{}|", " ".repeat(column_len + 1));
|
||||||
|
|
||||||
|
print!(
|
||||||
|
" {}{}\n",
|
||||||
|
" ".repeat(pos - beg),
|
||||||
|
"^".repeat(cmp::min(origin_pos + 1, next_crlf) - origin_pos)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -86,7 +86,16 @@ pub fn parse_sv<T: AsRef<Path>, U: AsRef<Path>>(
|
|||||||
nom::Err::Error(e) => error_position(&e),
|
nom::Err::Error(e) => error_position(&e),
|
||||||
nom::Err::Failure(e) => error_position(&e),
|
nom::Err::Failure(e) => error_position(&e),
|
||||||
};
|
};
|
||||||
Err(ErrorKind::Parse(pos).into())
|
let origin = if let Some(pos) = pos {
|
||||||
|
if let Some(origin) = text.origin(pos) {
|
||||||
|
Some((origin.0.clone(), origin.1))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Err(ErrorKind::Parse(origin).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -113,7 +122,16 @@ pub fn parse_lib<T: AsRef<Path>, U: AsRef<Path>>(
|
|||||||
nom::Err::Error(e) => error_position(&e),
|
nom::Err::Error(e) => error_position(&e),
|
||||||
nom::Err::Failure(e) => error_position(&e),
|
nom::Err::Failure(e) => error_position(&e),
|
||||||
};
|
};
|
||||||
Err(ErrorKind::Parse(pos).into())
|
let origin = if let Some(pos) = pos {
|
||||||
|
if let Some(origin) = text.origin(pos) {
|
||||||
|
Some((origin.0.clone(), origin.1))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Err(ErrorKind::Parse(origin).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user