Source code

Revision control

Copy as Markdown

Other Tools

ast_types! {
/// Represents an integer value
#[derive(Copy)]
enum IntegerLit<'a> {
/// Parses `-?[1-9][0-9]*`
#[derive(Copy)]
Dec(struct DecLit<'a>(
&'a str = crate::whitespace::ws(nom::combinator::recognize(nom::sequence::tuple((
nom::combinator::opt(nom::character::complete::char('-')),
nom::character::complete::one_of("123456789"),
nom::bytes::complete::take_while(nom::AsChar::is_dec_digit)
)))),
)),
/// Parses `-?0[Xx][0-9A-Fa-f]+)`
#[derive(Copy)]
Hex(struct HexLit<'a>(
&'a str = crate::whitespace::ws(nom::combinator::recognize(nom::sequence::tuple((
nom::combinator::opt(nom::character::complete::char('-')),
nom::character::complete::char('0'),
nom::character::complete::one_of("xX"),
nom::bytes::complete::take_while(nom::AsChar::is_hex_digit)
)))),
)),
/// Parses `-?0[0-7]*`
#[derive(Copy)]
Oct(struct OctLit<'a>(
&'a str = crate::whitespace::ws(nom::combinator::recognize(nom::sequence::tuple((
nom::combinator::opt(nom::character::complete::char('-')),
nom::character::complete::char('0'),
nom::bytes::complete::take_while(nom::AsChar::is_oct_digit)
)))),
)),
}
/// Represents a string value
///
/// Follow `/"[^"]*"/`
#[derive(Copy)]
struct StringLit<'a>(
&'a str = crate::whitespace::ws(nom::sequence::delimited(
nom::character::complete::char('"'),
nom::bytes::complete::take_while(|c| c != '"'),
nom::character::complete::char('"'),
)),
)
/// Represents a default literal value. Ex: `34|34.23|"value"|[ ]|true|false|null`
#[derive(Copy)]
enum DefaultValue<'a> {
Boolean(BooleanLit),
/// Represents `[ ]`
#[derive(Copy, Default)]
EmptyArray(struct EmptyArrayLit {
open_bracket: term!(OpenBracket),
close_bracket: term!(CloseBracket),
}),
/// Represents `{ }`
#[derive(Copy, Default)]
EmptyDictionary(struct EmptyDictionaryLit {
open_brace: term!(OpenBrace),
close_brace: term!(CloseBrace),
}),
Float(FloatLit<'a>),
Integer(IntegerLit<'a>),
Null(term!(null)),
String(StringLit<'a>),
}
/// Represents `true`, `false`, `34.23`, `null`, `56`, ...
#[derive(Copy)]
enum ConstValue<'a> {
Boolean(BooleanLit),
Float(FloatLit<'a>),
Integer(IntegerLit<'a>),
Null(term!(null)),
}
/// Represents either `true` or `false`
#[derive(Copy)]
struct BooleanLit(
bool = nom::branch::alt((
nom::combinator::value(true, weedle!(term!(true))),
nom::combinator::value(false, weedle!(term!(false))),
)),
)
/// Represents a floating point value, `NaN`, `Infinity`, '+Infinity`
#[derive(Copy)]
enum FloatLit<'a> {
/// Parses `/-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/`
#[derive(Copy)]
Value(struct FloatValueLit<'a>(
&'a str = crate::whitespace::ws(nom::combinator::recognize(nom::sequence::tuple((
nom::combinator::opt(nom::character::complete::char('-')),
nom::branch::alt((
nom::combinator::value((), nom::sequence::tuple((
// (?:[0-9]+\.[0-9]*|[0-9]*\.[0-9]+)
nom::branch::alt((
nom::sequence::tuple((
nom::bytes::complete::take_while1(nom::AsChar::is_dec_digit),
nom::character::complete::char('.'),
nom::bytes::complete::take_while(nom::AsChar::is_dec_digit),
)),
nom::sequence::tuple((
nom::bytes::complete::take_while(nom::AsChar::is_dec_digit),
nom::character::complete::char('.'),
nom::bytes::complete::take_while1(nom::AsChar::is_dec_digit),
)),
)),
// (?:[Ee][+-]?[0-9]+)?
nom::combinator::opt(nom::sequence::tuple((
nom::character::complete::one_of("eE"),
nom::combinator::opt(nom::character::complete::one_of("+-")),
nom::bytes::complete::take_while1(nom::AsChar::is_dec_digit),
))),
))),
// [0-9]+[Ee][+-]?[0-9]+
nom::combinator::value((), nom::sequence::tuple((
nom::bytes::complete::take_while1(nom::AsChar::is_dec_digit),
nom::character::complete::one_of("eE"),
nom::combinator::opt(nom::character::complete::one_of("+-")),
nom::bytes::complete::take_while1(nom::AsChar::is_dec_digit),
))),
)),
)))),
)),
NegInfinity(term!(-Infinity)),
Infinity(term!(Infinity)),
NaN(term!(NaN)),
}
}
#[cfg(test)]
mod test {
use super::*;
use crate::term::*;
use crate::Parse;
test!(should_parse_integer { "45" =>
"";
IntegerLit => IntegerLit::Dec(DecLit("45"))
});
test!(should_parse_integer_surrounding_with_spaces { " 123123 " =>
"";
IntegerLit => IntegerLit::Dec(DecLit("123123"))
});
test!(should_parse_integer_preceding_others { "3453 string" =>
"string";
IntegerLit => IntegerLit::Dec(DecLit("3453"))
});
test!(should_parse_neg_integer { "-435" =>
"";
IntegerLit => IntegerLit::Dec(DecLit("-435"))
});
test!(should_parse_hex_number { "0X08" =>
"";
IntegerLit => IntegerLit::Hex(HexLit("0X08"))
});
test!(should_parse_hex_large_number { "0xA" =>
"";
IntegerLit => IntegerLit::Hex(HexLit("0xA"))
});
test!(should_parse_zero { "0" =>
"";
IntegerLit => IntegerLit::Oct(OctLit("0"))
});
test!(should_parse_oct_number { "-07561" =>
"";
IntegerLit => IntegerLit::Oct(OctLit("-07561"))
});
test!(should_parse_float { "45.434" =>
"";
FloatLit => FloatLit::Value(FloatValueLit("45.434"))
});
test!(should_parse_float_surrounding_with_spaces { " 2345.2345 " =>
"";
FloatLit => FloatLit::Value(FloatValueLit("2345.2345"))
});
test!(should_parse_float_preceding_others { "3453.32334 string" =>
"string";
FloatLit => FloatLit::Value(FloatValueLit("3453.32334"))
});
test!(should_parse_neg_float { "-435.3435" =>
"";
FloatLit => FloatLit::Value(FloatValueLit("-435.3435"))
});
test!(should_parse_float_exp { "3e23" =>
"";
FloatLit => FloatLit::Value(FloatValueLit("3e23"))
});
test!(should_parse_float_exp_with_decimal { "5.3434e23" =>
"";
FloatLit => FloatLit::Value(FloatValueLit("5.3434e23"))
});
test!(should_parse_neg_infinity { "-Infinity" =>
"";
FloatLit => FloatLit::NegInfinity(term!(-Infinity))
});
test!(should_parse_infinity { "Infinity" =>
"";
FloatLit => FloatLit::Infinity(term!(Infinity))
});
test!(should_parse_string { r#""this is a string""# =>
"";
StringLit => StringLit("this is a string")
});
test!(should_parse_string_surround_with_spaces { r#" "this is a string" "# =>
"";
StringLit => StringLit("this is a string")
});
test!(should_parse_string_followed_by_string { r#" "this is first" "this is second" "# =>
r#""this is second" "#;
StringLit => StringLit("this is first")
});
test!(should_parse_string_with_spaces { r#" " this is a string " "# =>
"";
StringLit => StringLit(" this is a string ")
});
test!(should_parse_string_with_comment { r#" "// this is still a string"
"# =>
"";
StringLit => StringLit("// this is still a string")
});
test!(should_parse_string_with_multiline_comment { r#" "/*" "*/" "# =>
r#""*/" "#;
StringLit => StringLit("/*")
});
test!(should_parse_null { "null" =>
"";
Null => Null
});
test!(should_parse_empty_array { "[]" =>
"";
EmptyArrayLit => Default::default()
});
test!(should_parse_bool_true { "true" =>
"";
BooleanLit => BooleanLit(true)
});
test!(should_parse_bool_false { "false" =>
"";
BooleanLit => BooleanLit(false)
});
}