Parse simple number literal

This commit is contained in:
Joscha 2022-11-17 10:56:59 +01:00
parent 4aecce8107
commit c593e4c872
4 changed files with 133 additions and 3 deletions

85
Cargo.lock generated
View file

@ -2,6 +2,15 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 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]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.66" version = "1.0.66"
@ -25,6 +34,21 @@ version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 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]] [[package]]
name = "clap" name = "clap"
version = "4.0.26" version = "4.0.26"
@ -62,6 +86,45 @@ dependencies = [
"os_str_bytes", "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]] [[package]]
name = "heck" name = "heck"
version = "0.4.0" version = "0.4.0"
@ -119,6 +182,12 @@ dependencies = [
"version_check", "version_check",
] ]
[[package]]
name = "proc-macro-hack"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.47" version = "1.0.47"
@ -159,6 +228,7 @@ name = "tada"
version = "0.0.0" version = "0.0.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"chumsky",
"clap", "clap",
] ]
@ -171,6 +241,15 @@ dependencies = [
"winapi-util", "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]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.5" version = "1.0.5"
@ -183,6 +262,12 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 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]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.9" version = "0.3.9"

View file

@ -5,4 +5,5 @@ edition = "2021"
[dependencies] [dependencies]
anyhow = "1.0.66" anyhow = "1.0.66"
chumsky = "0.8.0"
clap = { version = "4.0.26", features = ["derive", "deprecated"] } clap = { version = "4.0.26", features = ["derive", "deprecated"] }

View file

@ -1,9 +1,11 @@
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use chumsky::Parser as _;
use clap::Parser; use clap::Parser;
mod builtin; mod builtin;
mod parser;
mod table; mod table;
mod value; mod value;
@ -25,9 +27,14 @@ fn main() -> anyhow::Result<()> {
match args.command { match args.command {
Command::Parse { file } => { Command::Parse { file } => {
let content = fs::read_to_string(&file)?; let content = fs::read_to_string(&file)?;
print!("{content}"); match parser::parser().parse(&content as &str) {
if !content.ends_with('\n') { Ok(lit) => println!("Successful parse: {lit:#?}"),
println!(); Err(errs) => {
println!("Parsing failed");
for err in errs {
println!("{err:?}");
}
}
} }
} }
} }

37
src/parser.rs Normal file
View 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())
}