This commit is contained in:
elkowar 2021-05-14 17:08:35 +02:00
commit 3b129957cd
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
8 changed files with 1476 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

421
Cargo.lock generated Normal file
View file

@ -0,0 +1,421 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544"
[[package]]
name = "arrayvec"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "ascii-canvas"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff8eb72df928aafb99fe5d37b383f2fe25bd2a765e3e5f7c365916b6f2463a29"
dependencies = [
"term",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bit-set"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "blake2b_simd"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587"
dependencies = [
"arrayref",
"arrayvec",
"constant_time_eq",
]
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "crossbeam-utils"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4feb231f0d4d6af81aed15928e58ecf5816aa62a2393e2c82f46973e92a9a278"
dependencies = [
"autocfg",
"cfg-if",
"lazy_static",
]
[[package]]
name = "crunchy"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
[[package]]
name = "diff"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "dirs"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "ena"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3"
dependencies = [
"log",
]
[[package]]
name = "fixedbitset"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d"
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
[[package]]
name = "hermit-abi"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "322f4de77956e22ed0e5032c359a0f1273f1f7f0d79bfa3b8ffbc730d7fbcc5c"
dependencies = [
"libc",
]
[[package]]
name = "indexmap"
version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "824845a0bf897a9042383849b02c1bc219c2383772efcd5c6f9766fa4b81aef3"
dependencies = [
"autocfg",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37d572918e350e82412fe766d24b15e6682fb2ed2bbe018280caa810397cb319"
dependencies = [
"either",
]
[[package]]
name = "lalrpop"
version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46962a8c71b91c3524b117dfdd70844d4265a173c4c9109f98171aebdcf1195f"
dependencies = [
"ascii-canvas",
"atty",
"bit-set",
"diff",
"ena",
"itertools",
"lalrpop-util",
"petgraph",
"pico-args",
"regex",
"regex-syntax",
"string_cache",
"term",
"tiny-keccak",
"unicode-xid",
]
[[package]]
name = "lalrpop-util"
version = "0.19.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a708007b751af124d09e9c5d97515257902bc6b486a56b40bcafd939e8ff467"
dependencies = [
"regex",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.94"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18794a8ad5b29321f790b55d93dfba91e125cb1a9edbd4f8e3150acc771c1a5e"
[[package]]
name = "log"
version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b16bd47d9e329435e309c58469fe0791c2d0d1ba96ec0954152a5ae2b04387dc"
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "nomwut"
version = "0.1.0"
dependencies = [
"lalrpop",
"lalrpop-util",
"regex",
]
[[package]]
name = "petgraph"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "467d164a6de56270bd7c4d070df81d07beace25012d5103ced4e9ff08d6afdb7"
dependencies = [
"fixedbitset",
"indexmap",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "pico-args"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7d7afeb98c5a10e0bffcc7fc16e105b04d06729fac5fd6384aebf7ff5cb5a67d"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "redox_users"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d"
dependencies = [
"getrandom",
"redox_syscall",
"rust-argon2",
]
[[package]]
name = "regex"
version = "1.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "rust-argon2"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b18820d944b33caa75a71378964ac46f58517c92b6ae5f762636247c09e78fb"
dependencies = [
"base64",
"blake2b_simd",
"constant_time_eq",
"crossbeam-utils",
]
[[package]]
name = "siphasher"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cbce6d4507c7e4a3962091436e56e95290cb71fa302d0d270e32130b75fbff27"
[[package]]
name = "string_cache"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ddb1139b5353f96e429e1a5e19fbaf663bddedaa06d1dbd49f82e352601209a"
dependencies = [
"lazy_static",
"new_debug_unreachable",
"phf_shared",
"precomputed-hash",
]
[[package]]
name = "term"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42"
dependencies = [
"byteorder",
"dirs",
"winapi",
]
[[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-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

16
Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "nomwut"
version = "0.1.0"
authors = ["elkowar <5300871+elkowar@users.noreply.github.com>"]
edition = "2018"
build = "build.rs"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
lalrpop-util = "0.19.5"
regex = "1"
[build-dependencies]
lalrpop = "0.19.5"

4
build.rs Normal file
View file

@ -0,0 +1,4 @@
extern crate lalrpop;
fn main() {
lalrpop::process_root().unwrap();
}

38
src/calc.lalrpop Normal file
View file

@ -0,0 +1,38 @@
use std::str::FromStr;
use crate::lexer;
use crate::Expr;
grammar;
extern {
type Location = usize;
type Error = lexer::LexicalError;
enum lexer::Tok {
"(" => lexer::Tok::LPren,
")" => lexer::Tok::RPren,
Space => lexer::Tok::Space,
Int => lexer::Tok::Int(<i32>),
}
}
Sep<T, S>: Vec<T> = {
<mut v:(<T> S)*> <e:T?> => match e {
None => v,
Some(e) => {
v.push(e);
v
}
}
}
pub Expr: Expr = {
"(" <elems:Sep<Expr, Space>> ")" => Expr::List(elems),
<n:Int> => Expr::Number(n),
};
// vim:shiftwidth=4

869
src/calc.rs Normal file
View file

@ -0,0 +1,869 @@
// auto-generated: "lalrpop 0.19.5"
// sha3: f4883744b015673a40928edc8f19edfbcd87416d27a5af7681a47c80f6af451
use std::str::FromStr;
use crate::lexer;
use crate::Expr;
#[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)]
use self::__lalrpop_util::state_machine as __state_machine;
extern crate core;
extern crate alloc;
#[cfg_attr(rustfmt, rustfmt_skip)]
mod __parse__Expr {
#![allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens)]
use std::str::FromStr;
use crate::lexer;
use crate::Expr;
#[allow(unused_extern_crates)]
extern crate lalrpop_util as __lalrpop_util;
#[allow(unused_imports)]
use self::__lalrpop_util::state_machine as __state_machine;
extern crate core;
extern crate alloc;
use super::__ToTriple;
#[allow(dead_code)]
pub(crate) enum __Symbol<>
{
Variant0(lexer::Tok),
Variant1(i32),
Variant2(Expr),
Variant3(alloc::vec::Vec<Expr>),
Variant4(core::option::Option<Expr>),
Variant5(Vec<Expr>),
}
const __ACTION: &[i8] = &[
// State 0
2, 0, 5, 0,
// State 1
2, -11, 5, 0,
// State 2
2, -13, 5, 0,
// State 3
0, 0, 0, 0,
// State 4
0, -7, 0, -7,
// State 5
0, -10, 0, 9,
// State 6
0, 10, 0, 0,
// State 7
0, -12, 0, 11,
// State 8
-4, -4, -4, 0,
// State 9
0, -6, 0, -6,
// State 10
-5, -5, -5, 0,
];
fn __action(state: i8, integer: usize) -> i8 {
__ACTION[(state as usize) * 4 + integer]
}
const __EOF_ACTION: &[i8] = &[
// State 0
0,
// State 1
0,
// State 2
0,
// State 3
-14,
// State 4
-7,
// State 5
0,
// State 6
0,
// State 7
0,
// State 8
0,
// State 9
-6,
// State 10
0,
];
fn __goto(state: i8, nt: usize) -> i8 {
match nt {
2 => 2,
3 => match state {
1 => 5,
2 => 7,
_ => 3,
},
5 => 6,
_ => 0,
}
}
fn __expected_tokens(__state: i8) -> alloc::vec::Vec<alloc::string::String> {
const __TERMINAL: &[&str] = &[
r###""(""###,
r###"")""###,
r###"Int"###,
r###"Space"###,
];
__TERMINAL.iter().enumerate().filter_map(|(index, terminal)| {
let next_state = __action(__state, index);
if next_state == 0 {
None
} else {
Some(alloc::string::ToString::to_string(terminal))
}
}).collect()
}
pub(crate) struct __StateMachine<>
where
{
__phantom: core::marker::PhantomData<()>,
}
impl<> __state_machine::ParserDefinition for __StateMachine<>
where
{
type Location = usize;
type Error = lexer::LexicalError;
type Token = lexer::Tok;
type TokenIndex = usize;
type Symbol = __Symbol<>;
type Success = Expr;
type StateIndex = i8;
type Action = i8;
type ReduceIndex = i8;
type NonterminalIndex = usize;
#[inline]
fn start_location(&self) -> Self::Location {
Default::default()
}
#[inline]
fn start_state(&self) -> Self::StateIndex {
0
}
#[inline]
fn token_to_index(&self, token: &Self::Token) -> Option<usize> {
__token_to_integer(token, core::marker::PhantomData::<()>)
}
#[inline]
fn action(&self, state: i8, integer: usize) -> i8 {
__action(state, integer)
}
#[inline]
fn error_action(&self, state: i8) -> i8 {
__action(state, 4 - 1)
}
#[inline]
fn eof_action(&self, state: i8) -> i8 {
__EOF_ACTION[state as usize]
}
#[inline]
fn goto(&self, state: i8, nt: usize) -> i8 {
__goto(state, nt)
}
fn token_to_symbol(&self, token_index: usize, token: Self::Token) -> Self::Symbol {
__token_to_symbol(token_index, token, core::marker::PhantomData::<()>)
}
fn expected_tokens(&self, state: i8) -> alloc::vec::Vec<alloc::string::String> {
__expected_tokens(state)
}
#[inline]
fn uses_error_recovery(&self) -> bool {
false
}
#[inline]
fn error_recovery_symbol(
&self,
recovery: __state_machine::ErrorRecovery<Self>,
) -> Self::Symbol {
panic!("error recovery not enabled for this grammar")
}
fn reduce(
&mut self,
action: i8,
start_location: Option<&Self::Location>,
states: &mut alloc::vec::Vec<i8>,
symbols: &mut alloc::vec::Vec<__state_machine::SymbolTriple<Self>>,
) -> Option<__state_machine::ParseResult<Self>> {
__reduce(
action,
start_location,
states,
symbols,
core::marker::PhantomData::<()>,
)
}
fn simulate_reduce(&self, action: i8) -> __state_machine::SimulatedReduce<Self> {
panic!("error recovery not enabled for this grammar")
}
}
fn __token_to_integer<
>(
__token: &lexer::Tok,
_: core::marker::PhantomData<()>,
) -> Option<usize>
{
match *__token {
lexer::Tok::LPren if true => Some(0),
lexer::Tok::RPren if true => Some(1),
lexer::Tok::Int(_) if true => Some(2),
lexer::Tok::Space if true => Some(3),
_ => None,
}
}
fn __token_to_symbol<
>(
__token_index: usize,
__token: lexer::Tok,
_: core::marker::PhantomData<()>,
) -> __Symbol<>
{
match __token_index {
0 | 1 | 3 => __Symbol::Variant0(__token),
2 => match __token {
lexer::Tok::Int(__tok0) if true => __Symbol::Variant1(__tok0),
_ => unreachable!(),
},
_ => unreachable!(),
}
}
pub struct ExprParser {
_priv: (),
}
impl ExprParser {
pub fn new() -> ExprParser {
ExprParser {
_priv: (),
}
}
#[allow(dead_code)]
pub fn parse<
__TOKEN: __ToTriple<>,
__TOKENS: IntoIterator<Item=__TOKEN>,
>(
&self,
__tokens0: __TOKENS,
) -> Result<Expr, __lalrpop_util::ParseError<usize, lexer::Tok, lexer::LexicalError>>
{
let __tokens = __tokens0.into_iter();
let mut __tokens = __tokens.map(|t| __ToTriple::to_triple(t));
__state_machine::Parser::drive(
__StateMachine {
__phantom: core::marker::PhantomData::<()>,
},
__tokens,
)
}
}
pub(crate) fn __reduce<
>(
__action: i8,
__lookahead_start: Option<&usize>,
__states: &mut alloc::vec::Vec<i8>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> Option<Result<Expr,__lalrpop_util::ParseError<usize, lexer::Tok, lexer::LexicalError>>>
{
let (__pop_states, __nonterminal) = match __action {
0 => {
__reduce0(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
1 => {
__reduce1(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
2 => {
__reduce2(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
3 => {
__reduce3(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
4 => {
__reduce4(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
5 => {
__reduce5(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
6 => {
__reduce6(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
7 => {
__reduce7(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
8 => {
__reduce8(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
9 => {
__reduce9(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
10 => {
__reduce10(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
11 => {
__reduce11(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
12 => {
__reduce12(__lookahead_start, __symbols, core::marker::PhantomData::<()>)
}
13 => {
// __Expr = Expr => ActionFn(0);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action0::<>(__sym0);
return Some(Ok(__nt));
}
_ => panic!("invalid action code {}", __action)
};
let __states_len = __states.len();
__states.truncate(__states_len - __pop_states);
let __state = *__states.last().unwrap();
let __next_state = __goto(__state, __nonterminal);
__states.push(__next_state);
None
}
#[inline(never)]
fn __symbol_type_mismatch() -> ! {
panic!("symbol type mismatch")
}
fn __pop_Variant2<
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>
) -> (usize, Expr, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant2(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant5<
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>
) -> (usize, Vec<Expr>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant5(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant3<
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>
) -> (usize, alloc::vec::Vec<Expr>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant4<
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>
) -> (usize, core::option::Option<Expr>, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant4(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant1<
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>
) -> (usize, i32, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant1(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
fn __pop_Variant0<
>(
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>
) -> (usize, lexer::Tok, usize)
{
match __symbols.pop() {
Some((__l, __Symbol::Variant0(__v), __r)) => (__l, __v, __r),
_ => __symbol_type_mismatch()
}
}
pub(crate) fn __reduce0<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// (<Expr> Space) = Expr, Space => ActionFn(8);
assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym1.2.clone();
let __nt = super::__action8::<>(__sym0, __sym1);
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
(2, 0)
}
pub(crate) fn __reduce1<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// (<Expr> Space)* = => ActionFn(6);
let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
let __end = __start.clone();
let __nt = super::__action6::<>(&__start, &__end);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(0, 1)
}
pub(crate) fn __reduce2<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// (<Expr> Space)* = (<Expr> Space)+ => ActionFn(7);
let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action7::<>(__sym0);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(1, 1)
}
pub(crate) fn __reduce3<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// (<Expr> Space)+ = Expr, Space => ActionFn(11);
assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant0(__symbols);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym1.2.clone();
let __nt = super::__action11::<>(__sym0, __sym1);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(2, 2)
}
pub(crate) fn __reduce4<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// (<Expr> Space)+ = (<Expr> Space)+, Expr, Space => ActionFn(12);
assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant2(__symbols);
let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone();
let __end = __sym2.2.clone();
let __nt = super::__action12::<>(__sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant3(__nt), __end));
(3, 2)
}
pub(crate) fn __reduce5<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Expr = "(", Sep<Expr, Space>, ")" => ActionFn(1);
assert!(__symbols.len() >= 3);
let __sym2 = __pop_Variant0(__symbols);
let __sym1 = __pop_Variant5(__symbols);
let __sym0 = __pop_Variant0(__symbols);
let __start = __sym0.0.clone();
let __end = __sym2.2.clone();
let __nt = super::__action1::<>(__sym0, __sym1, __sym2);
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
(3, 3)
}
pub(crate) fn __reduce6<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Expr = Int => ActionFn(2);
let __sym0 = __pop_Variant1(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action2::<>(__sym0);
__symbols.push((__start, __Symbol::Variant2(__nt), __end));
(1, 3)
}
pub(crate) fn __reduce7<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Expr? = Expr => ActionFn(4);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action4::<>(__sym0);
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
(1, 4)
}
pub(crate) fn __reduce8<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Expr? = => ActionFn(5);
let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
let __end = __start.clone();
let __nt = super::__action5::<>(&__start, &__end);
__symbols.push((__start, __Symbol::Variant4(__nt), __end));
(0, 4)
}
pub(crate) fn __reduce9<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Sep<Expr, Space> = Expr => ActionFn(15);
let __sym0 = __pop_Variant2(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action15::<>(__sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(1, 5)
}
pub(crate) fn __reduce10<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Sep<Expr, Space> = => ActionFn(16);
let __start = __lookahead_start.cloned().or_else(|| __symbols.last().map(|s| s.2.clone())).unwrap_or_default();
let __end = __start.clone();
let __nt = super::__action16::<>(&__start, &__end);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(0, 5)
}
pub(crate) fn __reduce11<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Sep<Expr, Space> = (<Expr> Space)+, Expr => ActionFn(17);
assert!(__symbols.len() >= 2);
let __sym1 = __pop_Variant2(__symbols);
let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone();
let __end = __sym1.2.clone();
let __nt = super::__action17::<>(__sym0, __sym1);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(2, 5)
}
pub(crate) fn __reduce12<
>(
__lookahead_start: Option<&usize>,
__symbols: &mut alloc::vec::Vec<(usize,__Symbol<>,usize)>,
_: core::marker::PhantomData<()>,
) -> (usize, usize)
{
// Sep<Expr, Space> = (<Expr> Space)+ => ActionFn(18);
let __sym0 = __pop_Variant3(__symbols);
let __start = __sym0.0.clone();
let __end = __sym0.2.clone();
let __nt = super::__action18::<>(__sym0);
__symbols.push((__start, __Symbol::Variant5(__nt), __end));
(1, 5)
}
}
pub use self::__parse__Expr::ExprParser;
fn __action0<
>(
(_, __0, _): (usize, Expr, usize),
) -> Expr
{
__0
}
fn __action1<
>(
(_, _, _): (usize, lexer::Tok, usize),
(_, elems, _): (usize, Vec<Expr>, usize),
(_, _, _): (usize, lexer::Tok, usize),
) -> Expr
{
Expr::List(elems)
}
fn __action2<
>(
(_, n, _): (usize, i32, usize),
) -> Expr
{
Expr::Number(n)
}
fn __action3<
>(
(_, mut v, _): (usize, alloc::vec::Vec<Expr>, usize),
(_, e, _): (usize, core::option::Option<Expr>, usize),
) -> Vec<Expr>
{
match e {
None => v,
Some(e) => {
v.push(e);
v
}
}
}
fn __action4<
>(
(_, __0, _): (usize, Expr, usize),
) -> core::option::Option<Expr>
{
Some(__0)
}
fn __action5<
>(
__lookbehind: &usize,
__lookahead: &usize,
) -> core::option::Option<Expr>
{
None
}
fn __action6<
>(
__lookbehind: &usize,
__lookahead: &usize,
) -> alloc::vec::Vec<Expr>
{
alloc::vec![]
}
fn __action7<
>(
(_, v, _): (usize, alloc::vec::Vec<Expr>, usize),
) -> alloc::vec::Vec<Expr>
{
v
}
fn __action8<
>(
(_, __0, _): (usize, Expr, usize),
(_, _, _): (usize, lexer::Tok, usize),
) -> Expr
{
__0
}
fn __action9<
>(
(_, __0, _): (usize, Expr, usize),
) -> alloc::vec::Vec<Expr>
{
alloc::vec![__0]
}
fn __action10<
>(
(_, v, _): (usize, alloc::vec::Vec<Expr>, usize),
(_, e, _): (usize, Expr, usize),
) -> alloc::vec::Vec<Expr>
{
{ let mut v = v; v.push(e); v }
}
fn __action11<
>(
__0: (usize, Expr, usize),
__1: (usize, lexer::Tok, usize),
) -> alloc::vec::Vec<Expr>
{
let __start0 = __0.0.clone();
let __end0 = __1.2.clone();
let __temp0 = __action8(
__0,
__1,
);
let __temp0 = (__start0, __temp0, __end0);
__action9(
__temp0,
)
}
fn __action12<
>(
__0: (usize, alloc::vec::Vec<Expr>, usize),
__1: (usize, Expr, usize),
__2: (usize, lexer::Tok, usize),
) -> alloc::vec::Vec<Expr>
{
let __start0 = __1.0.clone();
let __end0 = __2.2.clone();
let __temp0 = __action8(
__1,
__2,
);
let __temp0 = (__start0, __temp0, __end0);
__action10(
__0,
__temp0,
)
}
fn __action13<
>(
__0: (usize, core::option::Option<Expr>, usize),
) -> Vec<Expr>
{
let __start0 = __0.0.clone();
let __end0 = __0.0.clone();
let __temp0 = __action6(
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action3(
__temp0,
__0,
)
}
fn __action14<
>(
__0: (usize, alloc::vec::Vec<Expr>, usize),
__1: (usize, core::option::Option<Expr>, usize),
) -> Vec<Expr>
{
let __start0 = __0.0.clone();
let __end0 = __0.2.clone();
let __temp0 = __action7(
__0,
);
let __temp0 = (__start0, __temp0, __end0);
__action3(
__temp0,
__1,
)
}
fn __action15<
>(
__0: (usize, Expr, usize),
) -> Vec<Expr>
{
let __start0 = __0.0.clone();
let __end0 = __0.2.clone();
let __temp0 = __action4(
__0,
);
let __temp0 = (__start0, __temp0, __end0);
__action13(
__temp0,
)
}
fn __action16<
>(
__lookbehind: &usize,
__lookahead: &usize,
) -> Vec<Expr>
{
let __start0 = __lookbehind.clone();
let __end0 = __lookahead.clone();
let __temp0 = __action5(
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action13(
__temp0,
)
}
fn __action17<
>(
__0: (usize, alloc::vec::Vec<Expr>, usize),
__1: (usize, Expr, usize),
) -> Vec<Expr>
{
let __start0 = __1.0.clone();
let __end0 = __1.2.clone();
let __temp0 = __action4(
__1,
);
let __temp0 = (__start0, __temp0, __end0);
__action14(
__0,
__temp0,
)
}
fn __action18<
>(
__0: (usize, alloc::vec::Vec<Expr>, usize),
) -> Vec<Expr>
{
let __start0 = __0.2.clone();
let __end0 = __0.2.clone();
let __temp0 = __action5(
&__start0,
&__end0,
);
let __temp0 = (__start0, __temp0, __end0);
__action14(
__0,
__temp0,
)
}
pub trait __ToTriple<> {
fn to_triple(value: Self) -> Result<(usize,lexer::Tok,usize), __lalrpop_util::ParseError<usize, lexer::Tok, lexer::LexicalError>>;
}
impl<> __ToTriple<> for (usize, lexer::Tok, usize) {
fn to_triple(value: Self) -> Result<(usize,lexer::Tok,usize), __lalrpop_util::ParseError<usize, lexer::Tok, lexer::LexicalError>> {
Ok(value)
}
}
impl<> __ToTriple<> for Result<(usize, lexer::Tok, usize), lexer::LexicalError> {
fn to_triple(value: Self) -> Result<(usize,lexer::Tok,usize), __lalrpop_util::ParseError<usize, lexer::Tok, lexer::LexicalError>> {
match value {
Ok(v) => Ok(v),
Err(error) => Err(__lalrpop_util::ParseError::User { error }),
}
}
}

85
src/lexer.rs Normal file
View file

@ -0,0 +1,85 @@
use std::str::CharIndices;
pub type Spanned<Tok, Loc, Error> = Result<(Loc, Tok, Loc), Error>;
#[derive(Copy, Clone, Debug)]
pub enum Tok {
LPren,
RPren,
Space,
Int(i32),
}
#[derive(Debug, Copy, Clone)]
pub enum LexicalError {
InvalidDigit,
UnknownToken,
}
impl std::fmt::Display for LexicalError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
pub struct Lexer<'input> {
chars: CharIndices<'input>,
}
impl<'input> Lexer<'input> {
pub fn new(input: &'input str) -> Self {
Lexer {
chars: input.char_indices(),
}
}
}
impl<'input> Iterator for Lexer<'input> {
type Item = Spanned<Tok, usize, LexicalError>;
fn next(&mut self) -> Option<Self::Item> {
let c = self.chars.next();
match c {
Some((i, '(')) => Some(Ok((i, Tok::LPren, i + 1))),
Some((i, ')')) => Some(Ok((i, Tok::RPren, i + 1))),
Some((i, s)) if s.is_whitespace() => {
let mut last_space = i;
loop {
match self.chars.next() {
Some((i, next)) if next.is_whitespace() => {
last_space = i;
}
_ => {
break;
}
}
}
Some(Ok((i, Tok::Space, last_space + 1)))
}
Some((i, s)) if s.is_digit(10) || s == '-' => {
let mut end = i;
let mut digits = String::new();
loop {
match self.chars.next() {
Some((i, next)) if next.is_digit(10) => {
end = i;
digits.push(next);
}
_ => {
break;
}
}
}
let num = match digits.parse::<i32>() {
Ok(num) => num,
Err(_err) => return Some(Err(LexicalError::InvalidDigit)),
};
Some(Ok((i, Tok::Int(num), end + 1)))
}
Some((_, _)) => Some(Err(LexicalError::UnknownToken)),
None => None,
}
}
}

42
src/main.rs Normal file
View file

@ -0,0 +1,42 @@
#![allow(unused_imports)]
use lalrpop_util::lalrpop_mod;
mod lexer;
lalrpop_mod!(pub calc);
#[derive(Debug)]
pub enum Expr {
List(Vec<Expr>),
Symbol(String),
Number(i32),
}
fn main() {}
#[allow(unused_macros)]
macro_rules! test_p {
($e:expr) => {
let e = $e;
let lex = crate::lexer::Lexer::new(e);
let p = calc::ExprParser::new();
match p.parse(lex) {
Ok(res) => println!("{:?}", res),
Err(e) => eprintln!("{:?}", e),
}
};
}
#[test]
fn calc() {
//assert!(calc::ExprParser::new().parse("(1 2 3)").is_ok());
test_p!("1");
test_p!("(12)");
test_p!("(1 2)");
println!("\n\n\n\n\n\n");
panic!()
}