chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

245
vendor/pest/tests/calculator.rs vendored Normal file
View File

@@ -0,0 +1,245 @@
// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
#[macro_use]
extern crate pest;
use pest::error::Error;
use pest::iterators::{Pair, Pairs};
use pest::pratt_parser::{Assoc, Op, PrattParser};
use pest::{state, ParseResult, Parser, ParserState};
#[allow(dead_code, non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
expression,
primary,
number,
plus,
minus,
times,
divide,
modulus,
power,
}
struct CalculatorParser;
impl Parser<Rule> for CalculatorParser {
// false positive: pest uses `..` as a complete range (historically)
#[allow(clippy::almost_complete_range)]
fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
fn expression(
state: Box<ParserState<'_, Rule>>,
) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::expression, |s| {
s.sequence(|s| {
primary(s).and_then(|s| {
s.repeat(|s| {
s.sequence(|s| {
plus(s)
.or_else(minus)
.or_else(times)
.or_else(divide)
.or_else(modulus)
.or_else(power)
.and_then(primary)
})
})
})
})
})
}
fn primary(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state
.sequence(|s| {
s.match_string("(")
.and_then(expression)
.and_then(|s| s.match_string(")"))
})
.or_else(number)
}
fn number(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::number, |s| {
s.sequence(|s| {
s.optional(|s| s.match_string("-")).and_then(|s| {
s.match_string("0").or_else(|s| {
s.sequence(|s| {
s.match_range('1'..'9')
.and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
})
})
})
})
})
}
fn plus(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::plus, |s| s.match_string("+"))
}
fn minus(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::minus, |s| s.match_string("-"))
}
fn times(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::times, |s| s.match_string("*"))
}
fn divide(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::divide, |s| s.match_string("/"))
}
fn modulus(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::modulus, |s| s.match_string("%"))
}
fn power(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::power, |s| s.match_string("^"))
}
state(input, |state| match rule {
Rule::expression => expression(state),
_ => unreachable!(),
})
}
}
#[allow(deprecated)]
enum PrattOrPrecClimber<'a> {
Pratt(&'a PrattParser<Rule>),
PrecClimber(&'a pest::prec_climber::PrecClimber<Rule>),
}
fn consume(pair: Pair<Rule>, pratt_or_climber: &PrattOrPrecClimber) -> i32 {
let primary = |pair| consume(pair, pratt_or_climber);
let infix = |lhs: i32, op: Pair<Rule>, rhs: i32| match op.as_rule() {
Rule::plus => lhs + rhs,
Rule::minus => lhs - rhs,
Rule::times => lhs * rhs,
Rule::divide => lhs / rhs,
Rule::modulus => lhs % rhs,
Rule::power => lhs.pow(rhs as u32),
_ => unreachable!(),
};
#[allow(deprecated)]
match (pair.as_rule(), pratt_or_climber) {
(Rule::expression, PrattOrPrecClimber::Pratt(pratt)) => pratt
.map_primary(primary)
.map_infix(infix)
.parse(pair.into_inner()),
(Rule::expression, PrattOrPrecClimber::PrecClimber(climber)) => {
climber.climb(pair.into_inner(), primary, infix)
}
(Rule::number, _) => pair.as_str().parse().unwrap(),
_ => unreachable!(),
}
}
#[test]
fn number() {
parses_to! {
parser: CalculatorParser,
input: "-12",
rule: Rule::expression,
tokens: [
expression(0, 3, [
number(0, 3)
])
]
};
}
#[test]
fn parens() {
parses_to! {
parser: CalculatorParser,
input: "((-12))",
rule: Rule::expression,
tokens: [
expression(0, 7, [
expression(1, 6, [
expression(2, 5, [
number(2, 5)
])
])
])
]
};
}
#[test]
fn expression() {
parses_to! {
parser: CalculatorParser,
input: "-12+3*(4-9)^7^2",
rule: Rule::expression,
tokens: [
expression(0, 15, [
number(0, 3),
plus(3, 4),
number(4, 5),
times(5, 6),
expression(7, 10, [
number(7, 8),
minus(8, 9),
number(9, 10)
]),
power(11, 12),
number(12, 13),
power(13, 14),
number(14, 15)
])
]
};
}
#[test]
#[allow(deprecated)]
fn prec_climb() {
use pest::prec_climber::{Assoc, Operator, PrecClimber};
let climber = PrecClimber::new(vec![
Operator::new(Rule::plus, Assoc::Left) | Operator::new(Rule::minus, Assoc::Left),
Operator::new(Rule::times, Assoc::Left)
| Operator::new(Rule::divide, Assoc::Left)
| Operator::new(Rule::modulus, Assoc::Left),
Operator::new(Rule::power, Assoc::Right),
]);
let pairs = CalculatorParser::parse(Rule::expression, "-12+3*(4-9)^3^2/9%7381");
assert_eq!(
-1_525,
consume(
pairs.unwrap().next().unwrap(),
&PrattOrPrecClimber::PrecClimber(&climber)
)
);
}
#[test]
fn pratt_parse() {
let pratt = PrattParser::new()
.op(Op::infix(Rule::plus, Assoc::Left) | Op::infix(Rule::minus, Assoc::Left))
.op(Op::infix(Rule::times, Assoc::Left)
| Op::infix(Rule::divide, Assoc::Left)
| Op::infix(Rule::modulus, Assoc::Left))
.op(Op::infix(Rule::power, Assoc::Right));
let pairs = CalculatorParser::parse(Rule::expression, "-12+3*(4-9)^3^2/9%7381");
assert_eq!(
-1_525,
consume(
pairs.unwrap().next().unwrap(),
&PrattOrPrecClimber::Pratt(&pratt)
)
);
}

464
vendor/pest/tests/json.rs vendored Normal file
View File

@@ -0,0 +1,464 @@
// pest. The Elegant Parser
// Copyright (c) 2018 Dragoș Tiselice
//
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. All files in the project carrying such notice may not be copied,
// modified, or distributed except according to those terms.
#[macro_use]
extern crate pest;
use std::collections::HashMap;
use pest::error::Error;
use pest::iterators::{Pair, Pairs};
use pest::{state, ParseResult, Parser, ParserState, Span};
#[allow(dead_code, non_camel_case_types)]
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
enum Rule {
json,
object,
pair,
array,
value,
string,
escape,
unicode,
hex,
number,
int,
exp,
bool,
null,
}
struct JsonParser;
impl Parser<Rule> for JsonParser {
// false positive: pest uses `..` as a complete range (historically)
#[allow(clippy::almost_complete_range)]
fn parse(rule: Rule, input: &str) -> Result<Pairs<Rule>, Error<Rule>> {
fn json(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
value(state)
}
fn object(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::object, |s| {
s.sequence(|s| {
s.match_string("{")
.and_then(skip)
.and_then(pair)
.and_then(skip)
.and_then(|s| {
s.repeat(|s| {
s.sequence(|s| {
s.match_string(",")
.and_then(skip)
.and_then(pair)
.and_then(skip)
})
})
})
.and_then(|s| s.match_string("}"))
})
.or_else(|s| {
s.sequence(|s| {
s.match_string("{")
.and_then(skip)
.and_then(|s| s.match_string("}"))
})
})
})
}
fn pair(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::pair, |s| {
s.sequence(|s| {
string(s)
.and_then(skip)
.and_then(|s| s.match_string(":"))
.and_then(skip)
.and_then(value)
})
})
}
fn array(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::array, |s| {
s.sequence(|s| {
s.match_string("[")
.and_then(skip)
.and_then(value)
.and_then(skip)
.and_then(|s| {
s.repeat(|s| {
s.sequence(|s| {
s.match_string(",")
.and_then(skip)
.and_then(value)
.and_then(skip)
})
})
})
.and_then(|s| s.match_string("]"))
})
.or_else(|s| {
s.sequence(|s| {
s.match_string("[")
.and_then(skip)
.and_then(|s| s.match_string("]"))
})
})
})
}
fn value(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::value, |s| {
string(s)
.or_else(number)
.or_else(object)
.or_else(array)
.or_else(bool)
.or_else(null)
})
}
fn string(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::string, |s| {
s.match_string("\"")
.and_then(|s| {
s.repeat(|s| {
escape(s).or_else(|s| {
s.sequence(|s| {
s.lookahead(false, |s| {
s.match_string("\"").or_else(|s| s.match_string("\\"))
})
.and_then(|s| s.skip(1))
})
})
})
})
.and_then(|pos| pos.match_string("\""))
})
}
fn escape(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.sequence(|s| {
s.match_string("\\").and_then(|s| {
s.match_string("\"")
.or_else(|s| s.match_string("\\"))
.or_else(|s| s.match_string("/"))
.or_else(|s| s.match_string("b"))
.or_else(|s| s.match_string("f"))
.or_else(|s| s.match_string("n"))
.or_else(|s| s.match_string("r"))
.or_else(|s| s.match_string("t"))
.or_else(unicode)
})
})
}
fn unicode(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.sequence(|s| {
s.match_string("u")
.and_then(hex)
.and_then(hex)
.and_then(hex)
})
}
fn hex(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state
.match_range('0'..'9')
.or_else(|s| s.match_range('a'..'f'))
.or_else(|s| s.match_range('A'..'F'))
}
fn number(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::number, |s| {
s.sequence(|s| {
s.optional(|s| s.match_string("-"))
.and_then(int)
.and_then(|s| {
s.optional(|s| {
s.sequence(|s| {
s.match_string(".")
.and_then(|s| s.match_range('0'..'9'))
.and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
.and_then(|s| s.optional(exp))
.or_else(exp)
})
})
})
})
})
}
fn int(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.match_string("0").or_else(|s| {
s.sequence(|s| {
s.match_range('1'..'9')
.and_then(|s| s.repeat(|s| s.match_range('0'..'9')))
})
})
}
fn exp(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.sequence(|s| {
s.match_string("E")
.or_else(|s| s.match_string("e"))
.and_then(|s| {
s.optional(|s| s.match_string("+").or_else(|s| s.match_string("-")))
})
.and_then(int)
})
}
fn bool(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::bool, |s| {
s.match_string("true").or_else(|s| s.match_string("false"))
})
}
fn null(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.rule(Rule::null, |s| s.match_string("null"))
}
fn skip(state: Box<ParserState<'_, Rule>>) -> ParseResult<Box<ParserState<'_, Rule>>> {
state.repeat(|s| {
s.match_string(" ")
.or_else(|s| s.match_string("\t"))
.or_else(|s| s.match_string("\r"))
.or_else(|s| s.match_string("\n"))
})
}
state(input, |state| match rule {
Rule::json => json(state),
Rule::object => object(state),
Rule::pair => pair(state),
Rule::array => array(state),
Rule::value => value(state),
Rule::string => string(state),
Rule::escape => escape(state),
Rule::unicode => unicode(state),
Rule::hex => hex(state),
Rule::number => number(state),
Rule::int => int(state),
Rule::exp => exp(state),
Rule::bool => bool(state),
Rule::null => null(state),
})
}
}
#[derive(Debug, PartialEq)]
enum Json<'i> {
Null,
Bool(bool),
Number(f64),
String(Span<'i>),
Array(Vec<Json<'i>>),
Object(HashMap<Span<'i>, Json<'i>>),
}
fn consume(pair: Pair<Rule>) -> Json {
fn value(pair: Pair<Rule>) -> Json {
let pair = pair.into_inner().next().unwrap();
match pair.as_rule() {
Rule::null => Json::Null,
Rule::bool => match pair.as_str() {
"false" => Json::Bool(false),
"true" => Json::Bool(true),
_ => unreachable!(),
},
Rule::number => Json::Number(pair.as_str().parse().unwrap()),
Rule::string => Json::String(pair.as_span()),
Rule::array => Json::Array(pair.into_inner().map(value).collect()),
Rule::object => {
let pairs = pair.into_inner().map(|pos| {
let mut pair = pos.into_inner();
let key = pair.next().unwrap().as_span();
let value = value(pair.next().unwrap());
(key, value)
});
Json::Object(pairs.collect())
}
_ => unreachable!(),
}
}
value(pair)
}
#[test]
fn null() {
parses_to! {
parser: JsonParser,
input: "null",
rule: Rule::null,
tokens: [
null(0, 4)
]
};
}
#[test]
fn bool() {
parses_to! {
parser: JsonParser,
input: "false",
rule: Rule::bool,
tokens: [
bool(0, 5)
]
};
}
#[test]
fn number_zero() {
parses_to! {
parser: JsonParser,
input: "0",
rule: Rule::number,
tokens: [
number(0, 1)
]
};
}
#[test]
fn float() {
parses_to! {
parser: JsonParser,
input: "100.001",
rule: Rule::number,
tokens: [
number(0, 7)
]
};
}
#[test]
fn float_with_exp() {
parses_to! {
parser: JsonParser,
input: "100.001E+100",
rule: Rule::number,
tokens: [
number(0, 12)
]
};
}
#[test]
fn number_minus_zero() {
parses_to! {
parser: JsonParser,
input: "-0",
rule: Rule::number,
tokens: [
number(0, 2)
]
};
}
#[test]
fn string_with_escapes() {
parses_to! {
parser: JsonParser,
input: "\"asd\\u0000\\\"\"",
rule: Rule::string,
tokens: [
string(0, 13)
]
};
}
#[test]
fn array_empty() {
parses_to! {
parser: JsonParser,
input: "[ ]",
rule: Rule::array,
tokens: [
array(0, 3)
]
};
}
#[test]
fn array() {
parses_to! {
parser: JsonParser,
input: "[0.0e1, false, null, \"a\", [0]]",
rule: Rule::array,
tokens: [
array(0, 30, [
value(1, 6, [number(1, 6)]),
value(8, 13, [bool(8, 13)]),
value(15, 19, [null(15, 19)]),
value(21, 24, [string(21, 24)]),
value(26, 29, [
array(26, 29, [
value(27, 28, [number(27, 28)])
])
])
])
]
};
}
#[test]
fn object() {
parses_to! {
parser: JsonParser,
input: "{\"a\" : 3, \"b\" : [{}, 3]}",
rule: Rule::object,
tokens: [
object(0, 24, [
pair(1, 8, [
string(1, 4),
value(7, 8, [number(7, 8)])
]),
pair(10, 23, [
string(10, 13),
value(16, 23, [
array(16, 23, [
value(17, 19, [object(17, 19)]),
value(21, 22, [number(21, 22)])
])
])
])
])
]
};
}
#[test]
fn ast() {
let input = "{\"a\": [null, true, 3.4]}";
let ast = consume(
JsonParser::parse(Rule::json, input)
.unwrap()
.next()
.unwrap(),
);
if let Json::Object(pairs) = ast {
let vals: Vec<&Json> = pairs.values().collect();
assert_eq!(
**vals.first().unwrap(),
Json::Array(vec![Json::Null, Json::Bool(true), Json::Number(3.4)])
);
}
}