You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

ident.rs 2.3 kB

5 months ago
1 year ago
1 year ago
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. use nom::{
  2. IResult,
  3. branch::alt,
  4. character::complete::{alphanumeric0, char, one_of},
  5. combinator::{opt, recognize},
  6. multi::{many1, separated_list0, separated_list1},
  7. sequence::{pair, tuple},
  8. };
  9. fn upperalpha(s: &str) -> IResult<&str, char> {
  10. one_of("ABCDEFGHIJKLMNOPQRSTUVWXYZ")(s)
  11. }
  12. fn loweralpha(s: &str) -> IResult<&str, char> {
  13. one_of("abcdefghijklmnopqrstuvwxyz")(s)
  14. }
  15. fn numeric(s: &str) -> IResult<&str, char> {
  16. one_of("0123456789")(s)
  17. }
  18. pub fn package_name(s: &str) -> IResult<&str, &str> {
  19. recognize(tuple((
  20. loweralpha,
  21. opt(char('_')),
  22. separated_list1(char('_'), many1(alt((loweralpha, numeric)))),
  23. )))(s)
  24. }
  25. pub fn member_name(s: &str) -> IResult<&str, &str> {
  26. recognize(tuple((
  27. loweralpha,
  28. opt(char('_')),
  29. separated_list0(char('_'), many1(alt((loweralpha, numeric)))),
  30. )))(s)
  31. }
  32. pub fn message_name(s: &str) -> IResult<&str, &str> {
  33. recognize(pair(upperalpha, alphanumeric0))(s)
  34. }
  35. pub fn constant_name(s: &str) -> IResult<&str, &str> {
  36. recognize(separated_list1(
  37. char('_'),
  38. many1(alt((upperalpha, numeric))),
  39. ))(s)
  40. }
  41. #[cfg(test)]
  42. mod test {
  43. use anyhow::Result;
  44. use super::*;
  45. #[test]
  46. fn parse_member_name() -> Result<()> {
  47. assert_eq!(member_name("abc034_fs3_u3")?.1, "abc034_fs3_u3");
  48. Ok(())
  49. }
  50. #[test]
  51. fn parse_member_name_should_fail_if_starting_with_underscore() {
  52. assert!(member_name("_invalid_identifier").is_err());
  53. }
  54. #[test]
  55. fn parse_member_name_should_fail_if_starting_with_number() {
  56. assert!(member_name("0invalid_identifier").is_err());
  57. }
  58. #[test]
  59. fn parse_message_name() -> Result<()> {
  60. assert_eq!(message_name("StdMsgs12")?.1, "StdMsgs12");
  61. Ok(())
  62. }
  63. #[test]
  64. fn parse_message_name_should_fail_if_starting_with_wrong_char() {
  65. assert!(message_name("aStdMsgs12").is_err());
  66. }
  67. #[test]
  68. fn parse_constant_name() -> Result<()> {
  69. assert_eq!(constant_name("C_O_N_STAN_T")?.1, "C_O_N_STAN_T");
  70. Ok(())
  71. }
  72. #[test]
  73. fn parse_constant_name_should_fail_if_starting_with_underscore() {
  74. assert!(constant_name("_C_O_N_STAN_Ta").is_err());
  75. }
  76. }