lib.rs 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. // SPDX-License-Identifier: Apache-2.0
  2. //! Solidity file parser
  3. use crate::pt::CodeLocation;
  4. use diagnostics::Diagnostic;
  5. use lalrpop_util::ParseError;
  6. pub mod diagnostics;
  7. pub mod doccomment;
  8. mod lexer;
  9. pub mod pt;
  10. #[cfg(test)]
  11. mod test;
  12. #[allow(clippy::all)]
  13. mod solidity {
  14. include!(concat!(env!("OUT_DIR"), "/solidity.rs"));
  15. }
  16. /// Parse solidity file
  17. pub fn parse(
  18. src: &str,
  19. file_no: usize,
  20. ) -> Result<(pt::SourceUnit, Vec<pt::Comment>), Vec<Diagnostic>> {
  21. // parse phase
  22. let mut comments = Vec::new();
  23. let lex = lexer::Lexer::new(src, file_no, &mut comments);
  24. let s = solidity::SourceUnitParser::new().parse(src, file_no, lex);
  25. if let Err(e) = s {
  26. let errors = vec![match e {
  27. ParseError::InvalidToken { location } => Diagnostic::parser_error(
  28. pt::Loc::File(file_no, location, location),
  29. "invalid token".to_string(),
  30. ),
  31. ParseError::UnrecognizedToken {
  32. token: (l, token, r),
  33. expected,
  34. } => Diagnostic::parser_error(
  35. pt::Loc::File(file_no, l, r),
  36. format!(
  37. "unrecognised token '{}', expected {}",
  38. token,
  39. expected.join(", ")
  40. ),
  41. ),
  42. ParseError::User { error } => Diagnostic::parser_error(error.loc(), error.to_string()),
  43. ParseError::ExtraToken { token } => Diagnostic::parser_error(
  44. pt::Loc::File(file_no, token.0, token.2),
  45. format!("extra token '{}' encountered", token.0),
  46. ),
  47. ParseError::UnrecognizedEOF { location, expected } => Diagnostic::parser_error(
  48. pt::Loc::File(file_no, location, location),
  49. format!("unexpected end of file, expecting {}", expected.join(", ")),
  50. ),
  51. }];
  52. Err(errors)
  53. } else {
  54. Ok((s.unwrap(), comments))
  55. }
  56. }