Skip to content
Extraits de code Groupes Projets
Non vérifiée Valider 2b8d155d rédigé par Kubat's avatar Kubat
Parcourir les fichiers

Parse the AST with a location span! for debug & info purpuses

parent 2520ce80
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
use crate::ast::Location;
#[derive(Debug)]
pub enum VarOrConstant {
Var(String),
Constant(Constant),
}
#[derive(Debug)]
pub enum Constant {
Int(i32),
Flt(f32),
Bool(bool),
......@@ -14,9 +11,9 @@ pub enum Constant {
#[derive(Debug)]
pub enum Expression {
Binary(Box<Expression>, BinOp, Box<Expression>),
Unary(UnOp, Box<Expression>),
Leaf(VarOrConstant),
Binary(Location, Location, Box<Expression>, BinOp, Box<Expression>),
Unary(Location, Location, UnOp, Box<Expression>),
Leaf(Location, Location, VarOrConstant),
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
......
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Location {
offset: usize,
line: u32,
}
pub mod expr;
mod location;
pub use location::Location;
pub mod ast;
pub mod error;
pub mod expr;
pub mod parser;
pub mod spell;
pub mod state;
use crate::parser::span::{Location, Span};
use crate::{ast::Location, parser::Span};
use nom::{IResult, error::*};
use std::num::{ParseFloatError, ParseIntError};
......
use crate::{
expr::{BinOp, Expression, UnOp},
ast::{Location, expr::*},
parser::*,
};
use nom::{
Parser, branch::alt, bytes::complete::tag, character::complete::multispace0, combinator::map,
multi::many0, sequence::preceded,
Parser,
branch::alt,
bytes::complete::tag,
character::complete::{digit1, multispace0},
combinator::map,
multi::many0,
sequence::preceded,
};
fn var_or_constant(s: Span) -> ParserResult<Expression> {
utils::map_with_locaiton(
alt((
map(digit1, |digits| todo!()),
map(utils::identifier("true"), |_| todo!()),
map(utils::identifier("false"), |_| todo!()),
)),
|begin, end, var_or_constant| todo!(),
)
.parse(s)
}
fn leaf(s: Span) -> ParserResult<Expression> {
// Note: the order is important!
alt((
// 1
unop(UnOp::Not, expression),
unop(UnOp::Neg, expression),
// 2
utils::parse_paren(expression),
var_or_constant,
))
.parse(s)
}
......@@ -23,27 +40,37 @@ fn unop<'a>(
op: UnOp,
next: impl Parser<Span<'a>, Output = Expression, Error = ParserError>,
) -> impl Parser<Span<'a>, Output = Expression, Error = ParserError> {
map((multispace0, tag(op.as_str()), next), move |(.., expr)| {
Expression::Unary(op, Box::new(expr))
})
utils::map_with_locaiton(
(multispace0, tag(op.as_str()), next),
move |begin, end, (.., expr)| Expression::Unary(begin, end, op, Box::new(expr)),
)
}
fn binop<'a>(
op: BinOp,
next: impl Parser<Span<'a>, Output = Expression, Error = ParserError>,
) -> impl Parser<Span<'a>, Output = (BinOp, Expression), Error = ParserError> {
preceded(multispace0, (map(tag(op.as_str()), move |_| op), next))
) -> impl Parser<Span<'a>, Output = (Location, Location, BinOp, Expression), Error = ParserError> {
preceded(
multispace0,
utils::with_location((map(tag(op.as_str()), move |_| op), next))
.map(|(begin, end, (op, expr))| (begin, end, op, expr)),
)
}
fn fold_exprs(initial: Expression, remainder: Vec<(BinOp, Expression)>) -> Expression {
remainder.into_iter().fold(initial, |acc, (op, expr)| {
Expression::Binary(Box::new(acc), op, Box::new(expr))
fn fold_exprs(
initial: Expression,
remainder: Vec<(Location, Location, BinOp, Expression)>,
) -> Expression {
remainder
.into_iter()
.fold(initial, |acc, (begin, end, op, expr)| {
Expression::Binary(begin, end, Box::new(acc), op, Box::new(expr))
})
}
fn terms(s: Span) -> ParserResult<Expression> {
let (s, initial) = leaf(s)?;
let (s, remainder): (Span, Vec<(BinOp, Expression)>) = many0(alt((
let (s, remainder): (Span, Vec<_>) = many0(alt((
binop(BinOp::Mul, leaf),
binop(BinOp::Div, leaf),
binop(BinOp::Mod, leaf),
......
use crate::ast::Location;
use nom::{Compare, Input, Offset as _};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Location {
offset: usize,
line: u32,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Span<'a> {
/// The offset represents the position of the fragment relatively to
......
use crate::parser::{error::*, span::*};
use crate::{
ast::Location,
parser::{error::*, span::*},
};
use nom::{
Parser,
bytes::complete::tag,
......@@ -11,3 +14,33 @@ pub fn parse_paren<'a, T>(
) -> impl Parser<Span<'a>, Output = T, Error = ParserError> {
preceded(multispace0, delimited(tag("("), inner, tag(")")))
}
pub fn with_location<'a, O>(
mut parser: impl Parser<Span<'a>, Output = O, Error = ParserError>,
) -> impl Parser<Span<'a>, Output = (Location, Location, O), Error = ParserError> {
move |span: Span<'a>| {
let begin_s = multispace0(span)?.0;
let (end_s, res) = parser.parse(span)?;
Ok((end_s, (begin_s.get_location(), end_s.get_location(), res)))
}
}
pub fn map_with_locaiton<'a, F, O>(
mut parser: F,
mut cb: impl FnMut(Location, Location, <F as Parser<Span<'a>>>::Output) -> O,
) -> impl Parser<Span<'a>, Output = O, Error = ParserError>
where
F: Parser<Span<'a>, Error = ParserError>,
{
move |span: Span<'a>| {
let begin_s = multispace0(span)?.0;
let (end_s, res) = parser.parse(span)?;
Ok((end_s, cb(begin_s.get_location(), end_s.get_location(), res)))
}
}
pub fn identifier<'a>(
ident: &'static str,
) -> impl Parser<Span<'a>, Output = Span<'a>, Error = ParserError> {
todo!()
}
use crate::expr::Expression;
use crate::ast::expr::Expression;
use std::collections::HashMap;
/// Allowed types for arguments.
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter