mirror of
https://github.com/RustPython/Parser.git
synced 2025-07-12 23:55:21 +00:00
Parse for expr and stmt variants + identifier, constant
This commit is contained in:
parent
ae3a477c97
commit
0b40db0735
4 changed files with 1358 additions and 2 deletions
1243
parser/src/gen/parse.rs
Normal file
1243
parser/src/gen/parse.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -59,6 +59,9 @@ where
|
|||
fn parse(source: &str, source_path: &str) -> Result<Self, ParseError> {
|
||||
Self::parse_starts_at(source, source_path, TextSize::default())
|
||||
}
|
||||
fn parse_without_path(source: &str) -> Result<Self, ParseError> {
|
||||
Self::parse(source, "<unknown>")
|
||||
}
|
||||
fn parse_starts_at(
|
||||
source: &str,
|
||||
source_path: &str,
|
||||
|
@ -197,6 +200,52 @@ impl Parse for ast::Expr {
|
|||
}
|
||||
}
|
||||
|
||||
impl Parse for ast::Identifier {
|
||||
fn lex_starts_at(
|
||||
source: &str,
|
||||
offset: TextSize,
|
||||
) -> SoftKeywordTransformer<Lexer<std::str::Chars>> {
|
||||
ast::Expr::lex_starts_at(source, offset)
|
||||
}
|
||||
fn parse_tokens(
|
||||
lxr: impl IntoIterator<Item = LexResult>,
|
||||
source_path: &str,
|
||||
) -> Result<Self, ParseError> {
|
||||
let expr = ast::Expr::parse_tokens(lxr, source_path)?;
|
||||
match expr {
|
||||
ast::Expr::Name(name) => Ok(name.id),
|
||||
expr => Err(ParseError {
|
||||
error: ParseErrorType::InvalidToken,
|
||||
offset: expr.range().start(),
|
||||
source_path: source_path.to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Parse for ast::Constant {
|
||||
fn lex_starts_at(
|
||||
source: &str,
|
||||
offset: TextSize,
|
||||
) -> SoftKeywordTransformer<Lexer<std::str::Chars>> {
|
||||
ast::Expr::lex_starts_at(source, offset)
|
||||
}
|
||||
fn parse_tokens(
|
||||
lxr: impl IntoIterator<Item = LexResult>,
|
||||
source_path: &str,
|
||||
) -> Result<Self, ParseError> {
|
||||
let expr = ast::Expr::parse_tokens(lxr, source_path)?;
|
||||
match expr {
|
||||
ast::Expr::Constant(c) => Ok(c.value),
|
||||
expr => Err(ParseError {
|
||||
error: ParseErrorType::InvalidToken,
|
||||
offset: expr.range().start(),
|
||||
source_path: source_path.to_owned(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a full Python program usually consisting of multiple lines.
|
||||
///
|
||||
/// This is a convenience function that can be used to parse a full Python program without having to
|
||||
|
@ -505,6 +554,8 @@ pub(super) fn optional_range(start: TextSize, end: TextSize) -> OptionalRange<Te
|
|||
OptionalRange::<TextRange>::new(start, end)
|
||||
}
|
||||
|
||||
include!("gen/parse.rs");
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -1033,4 +1084,21 @@ def args_to_tuple(*args: *Ts) -> Tuple[*Ts]: ...
|
|||
.unwrap();
|
||||
insta::assert_debug_snapshot!(parse_ast);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_constant() {
|
||||
use num_traits::ToPrimitive;
|
||||
|
||||
let c = ast::Constant::parse_without_path("'string'").unwrap();
|
||||
assert_eq!(c.str().unwrap(), "string");
|
||||
|
||||
let c = ast::Constant::parse_without_path("10").unwrap();
|
||||
assert_eq!(c.int().unwrap().to_i32().unwrap(), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_parse_identifier() {
|
||||
let i = ast::Identifier::parse_without_path("test").unwrap();
|
||||
assert_eq!(i.as_str(), "test");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue