Parse simple number literal
This commit is contained in:
parent
4aecce8107
commit
c593e4c872
4 changed files with 133 additions and 3 deletions
85
Cargo.lock
generated
85
Cargo.lock
generated
|
|
@ -2,6 +2,15 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
|
||||
dependencies = [
|
||||
"const-random",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.66"
|
||||
|
|
@ -25,6 +34,21 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chumsky"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8d02796e4586c6c41aeb68eae9bfb4558a522c35f1430c14b40136c3706e09e4"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.26"
|
||||
|
|
@ -62,6 +86,45 @@ dependencies = [
|
|||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "368a7a772ead6ce7e1de82bfb04c485f3db8ec744f72925af5735e29a22cc18e"
|
||||
dependencies = [
|
||||
"const-random-macro",
|
||||
"proc-macro-hack",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random-macro"
|
||||
version = "0.1.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d7d6ab3c3a2282db210df5f02c4dab6e0a7057af0fb7ebd4070f30fe05c0ddb"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"proc-macro-hack",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
|
|
@ -119,6 +182,12 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-hack"
|
||||
version = "0.5.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.47"
|
||||
|
|
@ -159,6 +228,7 @@ name = "tada"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chumsky",
|
||||
"clap",
|
||||
]
|
||||
|
||||
|
|
@ -171,6 +241,15 @@ dependencies = [
|
|||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.5"
|
||||
|
|
@ -183,6 +262,12 @@ version = "0.9.4"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
anyhow = "1.0.66"
|
||||
chumsky = "0.8.0"
|
||||
clap = { version = "4.0.26", features = ["derive", "deprecated"] }
|
||||
|
|
|
|||
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