Skip to content

Commit a06bd3e

Browse files
committed
Add an example usecase of the parser.
1 parent 7d2a7a5 commit a06bd3e

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

examples/parse_folder.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/// This an example usage of the rustpython_parser crate.
2+
/// This program crawls over a directory of python files and
3+
/// tries to parse them into an abstract syntax tree (AST)
4+
///
5+
/// example usage:
6+
/// $ RUST_LOG=info cargo run --release parse_folder /usr/lib/python3.7
7+
8+
#[macro_use]
9+
extern crate clap;
10+
extern crate env_logger;
11+
#[macro_use]
12+
extern crate log;
13+
14+
use clap::{App, Arg};
15+
16+
use rustpython_parser::{ast, parser};
17+
use std::path::Path;
18+
19+
fn main() {
20+
env_logger::init();
21+
let app = App::new("RustPython")
22+
.version(crate_version!())
23+
.author(crate_authors!())
24+
.about("Walks over all .py files in a folder, and parses them.")
25+
.arg(
26+
Arg::with_name("folder")
27+
.help("Folder to scan")
28+
.required(true),
29+
);
30+
let matches = app.get_matches();
31+
32+
let folder = Path::new(matches.value_of("folder").unwrap());
33+
if folder.exists() && folder.is_dir() {
34+
println!("Parsing folder of python code: {:?}", folder);
35+
let res = parse_folder(&folder).unwrap();
36+
println!("Processed {:?} files", res.len());
37+
} else {
38+
println!("{:?} is not a folder.", folder);
39+
}
40+
}
41+
42+
fn parse_folder(path: &Path) -> std::io::Result<Vec<ast::Program>> {
43+
let mut res = vec![];
44+
info!("Parsing folder of python code: {:?}", path);
45+
for entry in path.read_dir()? {
46+
debug!("Entry: {:?}", entry);
47+
let entry = entry?;
48+
let metadata = entry.metadata()?;
49+
50+
let path = entry.path();
51+
if metadata.is_dir() {
52+
let x = parse_folder(&path)?;
53+
res.extend(x);
54+
}
55+
56+
if metadata.is_file() && path.extension().map(|s| s.to_str().unwrap()) == Some("py") {
57+
match parse_python_file(&path) {
58+
Ok(x) => res.push(x),
59+
Err(y) => error!("Erreur in file {:?} {:?}", path, y),
60+
}
61+
}
62+
}
63+
Ok(res)
64+
}
65+
66+
fn parse_python_file(filename: &Path) -> Result<ast::Program, String> {
67+
info!("Parsing file {:?}", filename);
68+
let source = std::fs::read_to_string(filename).map_err(|e| e.to_string())?;
69+
parser::parse_program(&source).map_err(|e| e.to_string())
70+
}

parser/src/lexer.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,9 +1157,12 @@ where
11571157
self.emit((tok_start, Tok::Newline, tok_end));
11581158
}
11591159
}
1160-
' ' => {
1160+
' ' | '\t' => {
11611161
// Skip whitespaces
11621162
self.next_char();
1163+
while self.chr0 == Some(' ') || self.chr0 == Some('\t') {
1164+
self.next_char();
1165+
}
11631166
}
11641167
_ => {
11651168
let c = self.next_char();

0 commit comments

Comments
 (0)