11extern crate lalrpop_util;
22
3- use std:: error:: Error ;
4- use std:: fs:: File ;
5- use std:: io:: Read ;
63use std:: iter;
74use std:: mem;
8- use std:: path:: Path ;
9-
10- use self :: lalrpop_util:: ParseError ;
115
126use super :: ast;
7+ use super :: error:: ParseError ;
138use super :: lexer;
149use super :: python;
1510use super :: token;
1611
17- pub fn read_file ( filename : & Path ) -> Result < String , String > {
18- info ! ( "Loading file {:?}" , filename) ;
19- match File :: open ( & filename) {
20- Ok ( mut file) => {
21- let mut s = String :: new ( ) ;
22-
23- match file. read_to_string ( & mut s) {
24- Err ( why) => Err ( String :: from ( "Reading file failed: " ) + why. description ( ) ) ,
25- Ok ( _) => Ok ( s) ,
26- }
27- }
28- Err ( why) => Err ( String :: from ( "Opening file failed: " ) + why. description ( ) ) ,
29- }
30- }
31-
3212/*
3313 * Parse python code.
3414 * Grammar may be inspired by antlr grammar for python:
3515 * https://github.com/antlr/grammars-v4/tree/master/python3
3616 */
3717
38- pub fn parse ( filename : & Path ) -> Result < ast:: Program , String > {
39- info ! ( "Parsing: {}" , filename. display( ) ) ;
40- let txt = read_file ( filename) ?;
41- debug ! ( "Read contents of file: {}" , txt) ;
42- parse_program ( & txt)
43- }
44-
4518macro_rules! do_lalr_parsing {
4619 ( $input: expr, $pat: ident, $tok: ident) => { {
4720 let lxr = lexer:: make_tokenizer( $input) ;
4821 let marker_token = ( Default :: default ( ) , token:: Tok :: $tok, Default :: default ( ) ) ;
4922 let tokenizer = iter:: once( Ok ( marker_token) ) . chain( lxr) ;
5023
5124 match python:: TopParser :: new( ) . parse( tokenizer) {
52- Err ( why ) => Err ( format! ( "{:?}" , why ) ) ,
25+ Err ( err ) => Err ( ParseError :: from ( err ) ) ,
5326 Ok ( top) => {
5427 if let ast:: Top :: $pat( x) = top {
5528 Ok ( x)
@@ -61,11 +34,11 @@ macro_rules! do_lalr_parsing {
6134 } } ;
6235}
6336
64- pub fn parse_program ( source : & str ) -> Result < ast:: Program , String > {
37+ pub fn parse_program ( source : & str ) -> Result < ast:: Program , ParseError > {
6538 do_lalr_parsing ! ( source, Program , StartProgram )
6639}
6740
68- pub fn parse_statement ( source : & str ) -> Result < ast:: LocatedStatement , String > {
41+ pub fn parse_statement ( source : & str ) -> Result < ast:: LocatedStatement , ParseError > {
6942 do_lalr_parsing ! ( source, Statement , StartStatement )
7043}
7144
@@ -91,21 +64,22 @@ pub fn parse_statement(source: &str) -> Result<ast::LocatedStatement, String> {
9164/// expr);
9265///
9366/// ```
94- pub fn parse_expression ( source : & str ) -> Result < ast:: Expression , String > {
67+ pub fn parse_expression ( source : & str ) -> Result < ast:: Expression , ParseError > {
9568 do_lalr_parsing ! ( source, Expression , StartExpression )
9669}
9770
71+ // TODO: consolidate these with ParseError
9872pub enum FStringError {
9973 UnclosedLbrace ,
10074 UnopenedRbrace ,
10175 InvalidExpression ,
10276}
10377
104- impl From < FStringError > for ParseError < lexer:: Location , token:: Tok , lexer:: LexicalError > {
78+ impl From < FStringError >
79+ for lalrpop_util:: ParseError < lexer:: Location , token:: Tok , lexer:: LexicalError >
80+ {
10581 fn from ( _err : FStringError ) -> Self {
106- // TODO: we should have our own top-level ParseError to properly propagate f-string (and
107- // other) syntax errors
108- ParseError :: User {
82+ lalrpop_util:: ParseError :: User {
10983 error : lexer:: LexicalError :: StringError ,
11084 }
11185 }
@@ -196,7 +170,6 @@ mod tests {
196170 #[ test]
197171 fn test_parse_empty ( ) {
198172 let parse_ast = parse_program ( & String :: from ( "\n " ) ) ;
199-
200173 assert_eq ! ( parse_ast, Ok ( ast:: Program { statements: vec![ ] } ) )
201174 }
202175
0 commit comments