// SPDX-License-Identifier: Apache-2.0 //! Solidity file parser use crate::pt::CodeLocation; use diagnostics::Diagnostic; use lalrpop_util::ParseError; pub mod diagnostics; pub mod doccomment; mod lexer; pub mod pt; #[cfg(test)] mod test; #[allow(clippy::all)] mod solidity { include!(concat!(env!("OUT_DIR"), "/solidity.rs")); } /// Parse solidity file pub fn parse( src: &str, file_no: usize, ) -> Result<(pt::SourceUnit, Vec), Vec> { // parse phase let mut comments = Vec::new(); let lex = lexer::Lexer::new(src, file_no, &mut comments); let s = solidity::SourceUnitParser::new().parse(src, file_no, lex); if let Err(e) = s { let errors = vec![match e { ParseError::InvalidToken { location } => Diagnostic::parser_error( pt::Loc::File(file_no, location, location), "invalid token".to_string(), ), ParseError::UnrecognizedToken { token: (l, token, r), expected, } => Diagnostic::parser_error( pt::Loc::File(file_no, l, r), format!( "unrecognised token '{}', expected {}", token, expected.join(", ") ), ), ParseError::User { error } => Diagnostic::parser_error(error.loc(), error.to_string()), ParseError::ExtraToken { token } => Diagnostic::parser_error( pt::Loc::File(file_no, token.0, token.2), format!("extra token '{}' encountered", token.0), ), ParseError::UnrecognizedEOF { location, expected } => Diagnostic::parser_error( pt::Loc::File(file_no, location, location), format!("unexpected end of file, expecting {}", expected.join(", ")), ), }]; Err(errors) } else { Ok((s.unwrap(), comments)) } }