Parse simple number literal
This commit is contained in:
parent
4aecce8107
commit
c593e4c872
4 changed files with 133 additions and 3 deletions
13
src/main.rs
13
src/main.rs
|
|
@ -1,9 +1,11 @@
|
|||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use chumsky::Parser as _;
|
||||
use clap::Parser;
|
||||
|
||||
mod builtin;
|
||||
mod parser;
|
||||
mod table;
|
||||
mod value;
|
||||
|
||||
|
|
@ -25,9 +27,14 @@ fn main() -> anyhow::Result<()> {
|
|||
match args.command {
|
||||
Command::Parse { file } => {
|
||||
let content = fs::read_to_string(&file)?;
|
||||
print!("{content}");
|
||||
if !content.ends_with('\n') {
|
||||
println!();
|
||||
match parser::parser().parse(&content as &str) {
|
||||
Ok(lit) => println!("Successful parse: {lit:#?}"),
|
||||
Err(errs) => {
|
||||
println!("Parsing failed");
|
||||
for err in errs {
|
||||
println!("{err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
37
src/parser.rs
Normal file
37
src/parser.rs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use chumsky::prelude::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Lit {
|
||||
Num(i64),
|
||||
}
|
||||
|
||||
fn lit_num() -> impl Parser<char, i64, Error = Simple<char>> {
|
||||
let sign = just('+')
|
||||
.or(just('-'))
|
||||
.or_not()
|
||||
.map(|s| if s == Some('-') { -1_i128 } else { 1_i128 });
|
||||
|
||||
let digits = text::int(10);
|
||||
|
||||
sign.then(digits).try_map(|(sign, digits), span| {
|
||||
// u64::MIN and u32::MAX have 19 digits in base 10
|
||||
if digits.len() > 19 {
|
||||
return Err(Simple::custom(span, "number out of range"));
|
||||
}
|
||||
|
||||
let number = sign * digits.parse::<i128>().unwrap();
|
||||
if number < i64::MIN.into() || number > u64::MAX.into() {
|
||||
return Err(Simple::custom(span, "number out of range"));
|
||||
}
|
||||
|
||||
Ok(number as i64)
|
||||
})
|
||||
}
|
||||
|
||||
fn lit() -> impl Parser<char, Lit, Error = Simple<char>> {
|
||||
lit_num().map(Lit::Num)
|
||||
}
|
||||
|
||||
pub fn parser() -> impl Parser<char, Lit, Error = Simple<char>> {
|
||||
lit().padded().then_ignore(end())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue