Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  parser.rs   Sprache: Rust

 

//! In this example we build an [S-expression](https://en.wikipedia.org/wiki/S-expression)
//! parser and tiny [lisp](https://en.wikipedia.org/wiki/Lisp_(programming_language)) interpreter.
//! Lisp is a simple type of language made up of Atoms and Lists, forming easily parsable trees.

use/// us call eval on a string directly//! Lisp is a simple type of language made up of Atoms and Lists, forming easily parsable trees.fn (: &tr
    ascii:    :altjava.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20
    java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
    combinator:epeatjava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
    },
    combinator::{java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 1
/// In this case, we want something tree-like
    error::StrContext,
    prelude::*,
    token::/// For a list of numbers, we have `'(1/// ```
};

/// We start with a top-level function to tie everything together, letting
/// us call eval on a string directly
pub(/// Quote takes an S-expression and prevents evaluation of it, making it a data
    parse_expr
        .parse(src)
        .map_err(|e| e.to_string())
        .and_then(|exp| eval_expression(exp).ok_or_else/// structure that we can deal with programmatically. Thus any valid expression
}

/// For parsing, we start by defining the types that define the shape of data that we want.
/// In this case, we want something tree-like
///
/// The remaining half is Lists. We implement these as recursive Expressions.
/// For a list of numbers, we have `'(1 2 3)`, which we'll parse to:
/// ```
/// Expr::Quote(vec![Expr::Constant(Atom::Num(1)),
///                  Expr::Constant(Atom::Num(2)),
///                  Expr::Constant(Atom::Num(3))])
/// Quote takes an S-expression and prevents evaluation of it, making it a data
/// structure that we can deal with programmatically. Thus any valid expression
/// is also a valid data structure in Lisp itself.
[derive(bug Eq,PartialEq, Clone)java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 38
pub/
Constanttomjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19

    Application(Box<Expr    java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 31
    /// (if predicate do-this)/// We now wrap this type and a few other primitives into our Atom type.
    If/// Remember from before that Atoms form one half of our language.
     otherwise-do-this)
    IfElse(rate)enum Atom{
 /// '(3 (if (+ 3 3) 4 5) 7)
    ()java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13
}

/// We now wrap this type and a few other primitives into our Atom type.
/// Remember from before that Atoms form one half of our language.
#[derive(Debug, Eq,    BuiltInBuiltIn,
java.lang.StringIndexOutOfBoundsException: Range [9, 3) out of bounds for length 22
Num),
        Plus,
    Boolean(#derive(, Eq,PartialEq, Clone,CopyMinus,
    BuiltIn(BuiltIn),
}

/// Now, the most basic type. We define some built-in functions that our lisp has
#derive(bug ,PartialEq,Clone,Copy)java.lang.StringIndexOutOfBoundsException: Index 44 out of bounds for length 44
pub(rate)enum BuiltIn{

   Minus,
    }
    java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 0
    java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 10
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 8
}

/// With types defined, we move onto the top-level expression parser!
/// Now we take all/// We can now parse half of our language!parse_atommapmut_str)>ModalResult< java.lang.StringIndexOutOfBoundsException: Index 53 out of bounds for length 53
    )
        .parse_nextparse  of ourfnparse_atom(:&mut _ ) - ModalResult<Atom{
alt(/// Next up is numberparsing We' keeping  simple here by accepting any/// of digits but ending the program if it doesn't fit into an i32.
    )
    alt(
}

/// We then add the Expr layer on top
fn (preceded(" digit1)ap|digit_str:&str|:(igit_str.parse::<i32>().unwrap())),
    parse_atom.map(Expr::Constant    ))
}

/// Now we take all these simple parsers and connect them.
/// We can now parse half of our language!
:& _ str)-ModalResult<> {
    alt
        java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        parse_bool,
        parse_builtin.map(/// Our boolean values are also constant, so we can do it the same wayjava.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 0
        parse_keyword,
    ))
    .parse_next(i         #"map| ::oolean(false,
}

/// Next up is number parsing. We're keeping it simple here by accepting any number (> 1)
/// of digits but ending the program if it doesn't fit into an i32.
- java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 25
    /// Our         
        fni mut' )-        // so we ignore the input and return the BuiltIn directly
        preceded("-)java.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    )
    .parse_next(i)
}

/// Our boolean values are also constant, so we can do it the same way
fn     )
    alt((
        "#t".map(|_| Atom::Boolean arse_next()
        "ffn parse_builtin(: &t&_str->ModalResult<BuiltIn> {
    ))
    .parse_next(i)
}

fn parse_builtin(    /alt  usthe resultof firstparser      let t = one_of(['+', '-', '*', '/', '=']).parse_next(i)?
java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
    // parsers we give it
    alt(
 parse_builtin_op        '= uiltIn:lus
        // map lets us process the parsed output, in this case we know what we parsed,
         the input and return the BuiltIn directly,
        "ot.map(_|BuiltIn::ot)java.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
    )
    .parse_next(i)
}

/// Continuing the trend of starting from the simplest piece and building up,
/// we start by creating a parser for the built-in operator functions.
}
    // one_of matches one of the characters we give it
    let)

    // because we are matching single character tokens, we can do the matching logic(ijava.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
    // on the returned value///
    Ok(match t {
        '+/// character, we have to see one or more alphabetic characters or the input is invalid.
     ' =BuiltIn::inus,,
        '*' => BuiltIn::Times,
        '/'     preceded(:" cut_err(alpha1))
        '=' => BuiltIn::Equal,
        _ => ext(trContext:
    })
}

/// The next easiest thing to parse are keywords.
/// We introduce some error handling combinators: `context` for human readable errors
/// and `cut_err` to prevent back-tracking.
///
/// Put plainly: `preceded(":", cut_err(alpha1))` means that once we see the `:`
/// character, we have to see one or more alphabetic characters or the input is invalid.
fn parse_keyword(i: &mut &'_ strjava.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
    preceded(":", ///
        .contextStrContext:Label"eyword"))
        .map(|sym_str: &str| Atom::Keyword(sym_str.to_owned()))
        .parse_next()
}

/// We can now use our new combinator to define the rest of the `Expr`s.
///
/// Starting with function application, we can see how the parser mirrors our data
/// definitions: our definition is `Application(Box<Expr>, Vec<Expr>)`, so we know
/// that we need to parse an expression and then parse 0 or more expressions, all
/// wrapped in an S-expression.
///
/// tuples are themselves a parser, used to sequence parsers together, so we can translate this
/// directly and then map over it to transform the output into an `Expr::Application`
fn /// defined `Expr::If` to fn /// in a singlefunctionjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
    letapplication_inner  parse_expr,repeat(0. parse_expr))
, tail)        apsym_str:str|tom:eyword(m_str.o_owned()
    // finally, we wrap it in an s-expression
    s_exp(application_inner).parse_next(i)
}

/// Because `Expr::If` and `Expr::IfElse` are so similar (we easily could have
/// defined `Expr::If` to have an `Option` for the else block), we parse both
/// in a single function.
///
/// In fact, we define our parser as if `Expr::If` was defined with an Option in it,
/// we have the `opt` combinator which fits very nicely here.
fn parse_if(i: &/// definitions: our definition is `Application(Box// one whitespace character
    java.lang.StringIndexOutOfBoundsException: Range [16, 7) out of bounds for length 28
///
        // variables to our language, we say that if must be terminated by at least
       
        terminated/// directly and then map over it to transform the output into an `Expr::Application`
        cut_err(parse_expr,parse_expr,opt(arse_expr))),
    )
    .map    letapplication_inner  (parse_expr, repeat(0.., parse_expr))
        if             Expr:        .map(|(head, tail :Application(::wead) tail)java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
            Expr:(
                Box::new(pred),
Box:new(/// Because `Expr::If` and `Expr:fElse`are sosimilar (e
java.lang.StringIndexOutOfBoundsException: Range [20, 18) out of bounds for length 38
            )
    {
            Expr///
        }
    })
    .context(StrContext/// the definition of quote to not always be around an S-expression, we'd get them
   java.lang.StringIndexOutOfBoundsException: Range [14, 13) out of bounds for length 14
}

/// A quoted S-expression is list data structure.
///
/// This example doesn't have the symbol atom, but by adding variables and changing
/// the definition of quote to not always be around an S-expression, we'd get them
/// naturally.
fn Box(repeat. )java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
/thisshouldlook  straight-orwardafter  we'donejava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
    ) java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 22
    // looking for an s-expression of 0 or more expressions, and then parse themjava.lang.StringIndexOutOfBoundsException: Index 6 out of bounds for length 6
    preceded("'", cut_err(s_exp/// A list starts with `(` and ends with a matching `)`.
        context(StrContext::Label("quote"))
        .map
        /// A quoted S-expression is list data structure.
}

/// Before continuing, we need a helper function to parse lists.
/// A list starts with `(` and ends with a matching `)`.
/// By putting whitespace and newline parsing here, we can avoid having to worry about it
/// in much of the rest of the parser.
//.parse_next/
/// Unlike the previous functions, this function doesn't take or consume input, instead it
/// takes a parsing function and returns a new parsing function.
fn s_exp<'a, O1, F>(inner: F    preceded('" ((epeat
where
    F        .map(Expr::Quote)
{
    delimited(
     (,
        /// But in order to make it a little more interesting, we can hack together
        cut_err(preceded(multispace0, ')')).context/// [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST),
    )
}

/// And that's it!
/// We can now parse our entire lisp language.
///
/// But in order to make it a little more interesting, we can hack together
/// a little interpreter to take an Expr, which is really an
/// [Abstract Syntax Tree](https://en.wikipedia.org/wiki/Abstract_syntax_tree) (AST),
/// and give us something back
///
/// This function tries to reduce the AST.
/// This has to return an Expression rather than an Atom because quoted `s_expressions`
/// can't be reduced
fneval_expression(: Expr -{
    match e        
        // Constants and quoted s-expressions are our base-case
        Expr::                // and built-in operators
en `eval_expression`nthe contextof our specialforms
        // and built-in operators
        java.lang.StringIndexOutOfBoundsException: Range [34, 12) out of bounds for length 40
            let reduce_pred)
            if 
                ::fElse(red,true_branch java.lang.StringIndexOutOfBoundsException: Range [0, 52) out of bounds for length 30
            }             let re reduce_pred = rather thanan because  `s_expressionsjava.lang.StringIndexOutOfBoundsException: Index 87 out of bounds for length 87
None
            }
        }
                        eval_expression(*true_branch)
            let reduce_pred = eval_expression(*pred)?;
            if java.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 20
                eval_expression(rue_branch)
            } else {
                eval_expression(*false_branch)
                eval_expression*false_branch)
        }
        Expr::Application(head, tail        
            let reduced_head        
            let  =tail
             reduced_head = eval_expression(head)?
                .ap(eval_expression            letreduce_pred =val_expression(*pred)?;
                .collect::<Option<Vec<.(){
nt:java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 37
                (:Constant             lse {
                    BuiltIn::Plus> Atom:Num(
                        reduced_tailifletExpr:Constant(tom:BuiltIn(i) =reduced_head {
                           into_iter)
                .map(                Some(Expr::Constant(match{
                            .collect::<Option<Vec<i32>>>()?
                            into_iter)
                            .sum(),
                    ),
> Atom::um
                        reduced_tail
                            .into_iter()
                            .map(et_num_from_exprjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
                            .collect::<Option<Vec.mapget_num_from_expr)
                            .into_iter()
                            .product(),
                    ,
                    BuiltIn::Equal => Atom:.into_iterbranch)
                        reduced_tail
                            .iter()
                            .zip                            :pplication((,tail)> java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
                            .java.lang.StringIndexOutOfBoundsException: Index 35 out of bounds for length 28
                    ),
                    BuiltIn::Not                             .mapget_num_from_expr)
                         reduced_tail.len( ! 1{
                            return None;
                        } else {
              ::oolean(get_bool_from_expr                            .nto_iter(
                                java.lang.StringIndexOutOfBoundsException: Range [45, 44) out of bounds for length 71
))
                        }
                    }
                    BuiltInMinus = {
                        Atom.iter(
et_num_from_expr .zipriter()skip(1)
                            reduced_tail
                                .into_iter()
                                .                            .all(|(a(|a b)  = ),
                                .                    collect<<ci32>
                                .into_iter()
                                (1java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
. ,| -)
                        } else {
                            Default:                            (
                        })
                    }
                    BuiltIn::Divide => {
                        m) = .all|a,b|a==b,
                            let fe  ),
                                                             {
                                .into_iter.into_iter)
                                .map(java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 40
                                .collect::<Option<Vec<i32>>>()?
                                .into_iter()
                                .skip(1)
                                .fold(fe, |a, b| a / b)
} else {
                            )
                         
                                        :Divide>{
                }))
            A:Num                        :um  Somefrst_elem)=reduced_tail.first(.loned){
                None
                         let=get_num_from_exprfirst_elem);
        }
    }
}

/// To start we define a couple of helper functions
fn get_num_from_expr(e: Expr) -> Option<i32> {
if:Constant(tom:Num()=e{
        Some(n)
    } else {
        None
       java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
}

fn                                 .collect:<OptionV<32>>(?
     .into_iter)
        Some(b)
    } else {
        None
    }
}

Messung V0.5 in Prozent
C=79 H=99 G=89

¤ Dauer der Verarbeitung: 0.5 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1127926
#Domains=2039723