{"id":482769,"date":"2026-06-08T08:22:17","date_gmt":"2026-06-08T08:22:17","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=482769"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=482769","title":{"rendered":"\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0432\u043e\u0435\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 Rust #3: \u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u044b\u0432\u043e\u0434\u0430 \u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041f\u0440\u0438\u0432\u0435\u0442 \u0447\u0438\u0442\u0430\u044e\u0449\u0438\u043c!<\/p>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u0440\u043e\u0447\u0435 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445, \u0438 \u0431\u0443\u0434\u0443\u0449\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0430\u043a \u043b\u0435\u0433\u0447\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438. \u0422\u0430\u043a\u0436\u0435, \u0434\u0443\u043c\u0430\u044e, \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u0435\u0435.<\/p>\n<h2>\u041a\u0430\u043a \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c?<\/h2>\n<p>\u042f \u043c\u043d\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435, \u0438 \u043d\u0430\u0448\u0435\u043b \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0441\u043f\u043e\u0441\u043e\u0431.<\/p>\n<p>\u0423 Stmt \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 <code>define(&amp;Parser)<\/code>. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b \u0438 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 <code>peek<\/code> \u0438 <code>error<\/code> \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u0432\u043d\u0435. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f &#8212; <code>StmtKind<\/code>. \u0412 \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 stmt, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u043b <code>define<\/code> \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u0430.<\/p>\n<h2>\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c!<\/h2>\n<p>\u0421\u0440\u0430\u0437\u0443 \u0441\u0434\u0435\u043b\u0430\u0435\u043c <code>peek<\/code> \u0438 <code>error<\/code> \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438:<\/p>\n<pre><code class=\"rust\">pub fn error(&amp;self, msg: &amp;str, token: Token) -&gt; String { ... }pub fn peek(&amp;self, offset: i8) -&gt; Token { ... }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043f\u0430\u043a\u0435\u0442\u0435 parser \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b &#8212; <code>ast.rs<\/code>. <\/p>\n<details class=\"spoiler\">\n<summary>parser\/ast.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use super::Parser;use super::expr::Expr;use crate::lexer::token::TKind;#[derive(Debug)]pub enum Stmt {    Assign(String, AssignOp, Expr),    Print(Vec&lt;Expr&gt;),}#[derive(Debug)]pub enum StmtKind {    Assign,    Print,}#[derive(Debug, Default)]pub enum AssignOp {    #[default]    Assign,}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u0442\u0435 \u0437\u0430\u0447\u0435\u043c \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 <code>AssignOp<\/code>? \u0412\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 <code>+=<\/code>, \u0442\u043e\u043b\u044c\u043a\u043e <code>=<\/code>, \u0438 \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 1 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0434\u0440\u0443\u0433\u0438\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>\u041f\u043e\u044f\u0441\u043d\u044e \u0437\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 <code>Stmt<\/code>:<\/p>\n<p><code>Assign(String, AssignOp, Expr)<\/code> &#8212; <strong>String<\/strong> \u0442\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. <strong>AssignOp<\/strong> \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u0438\u043f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f. <strong>Expr<\/strong> \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c.<\/p>\n<p><code>Print(Vec&lt;Expr&gt;)<\/code> &#8212; \u0432\u0435\u043a\u0442\u043e\u0440 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0442\u0443\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0435 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c.<\/p>\n<h2>\u041c\u0435\u0442\u043e\u0434 define<\/h2>\n<pre><code class=\"rust\">impl Stmt {    pub fn define(pr: &amp;Parser) -&gt; StmtKind {        match (pr.peek(0).kind, pr.peek(1).kind) {            (TKind::Id(_), TKind::Assign) =&gt; StmtKind::Assign,            (TKind::Print, _) =&gt; StmtKind::Print,            _ =&gt; panic!(\"{}\", pr.error(\"Unknown statement\", pr.peek(0))),        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0442\u043e\u0436\u0435 \u0432\u0441\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0435 2 \u0442\u0438\u043f\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u0442\u043e\u043a\u0435\u043d\u044b. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438 \u0437\u043d\u0430\u043a \u0440\u0430\u0432\u043d\u043e (\u041c\u044b \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u043a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0440\u0430\u043d\u0435\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b), \u0442\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043a\u0435\u0439\u0432\u043e\u0440\u0434 <code>print<\/code>, \u0442\u043e \u044d\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e <code>Print<\/code>. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u0442\u043e \u043f\u0430\u043d\u0438\u043a\u0443\u0435\u043c \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043e \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u043c \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u0435.<\/p>\n<h2>Print \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442<\/h2>\n<p>\u041e\u043d \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0447\u0435\u043c <code>Assign<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043d\u0435\u0433\u043e. \u0421\u0440\u0430\u0437\u0443 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432<\/p>\n<details class=\"spoiler\">\n<summary>parser\/parser.rs: Parser<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">fn parse_args(&amp;mut self) -&gt; Vec&lt;Expr&gt; {    let mut args = Vec::new();    while self.peek(0).kind != TKind::Eof {        let value = self.expr();        args.push(value);        let current = self.peek(0);        if current.kind == TKind::RParen {            break;        }        if !self.check(TKind::Comma) {            panic!(                \"{}\",                self.error(                    &amp;format!(\"Expected ')' or ',', found {:?}\", current),                    current                )            );        }    }    args}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435, \u043f\u043e\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u0440\u0430\u0432\u0435\u043d <strong>EOF<\/strong>: \u043f\u0430\u0440\u0441\u0438\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0437\u0430\u043f\u044f\u0442\u0430\u044f, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430, \u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0446\u0438\u043a\u043b. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u044f\u0442\u0430\u044f \u0438 \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430, \u0442\u043e \u0432\u044b\u0434\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u043e \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0435.<\/p>\n<pre><code class=\"rust\">fn parse_print(&amp;mut self) -&gt; Stmt {    self.advance(1);    if !self.check(TKind::LParen) {        let current = self.peek(0);        panic!(            \"{}\",            self.error(&amp;format!(\"Expected '(', found {:?}\", current), current)        );    }    let args = self.parse_args();    if !self.check(TKind::RParen) {        let current = self.peek(0);        panic!(            \"{}\",            self.error(&amp;format!(\"Expected ')', found {:?}\", current), current)        );    }    Stmt::Print(args)}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>Assign \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442<\/h2>\n<pre><code class=\"rust\">fn parse_assign(&amp;mut self) -&gt; Stmt {    let id = match self.peek(0).kind {        TKind::Id(id) =&gt; {            self.advance(1);            id        }        _ =&gt; unreachable!(\"{:?}\", self.peek(0).kind),    };    let assign = AssignOp::default();    self.advance(1);    let value = self.expr();    Stmt::Assign(id, assign, value)}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440. \u041e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a <code>define<\/code> \u044d\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b, \u0442\u0430\u043a \u0447\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u043c <code>unreachable<\/code> \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432. <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u0438\u0434\u0435\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430. \u0423 \u043d\u0430\u0441 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u043a \u0440\u0430\u0432\u043d\u043e, \u0442\u0430\u043a \u0447\u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0430\u043d\u0438\u043a\u0443\u0435\u043c. \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0437\u043d\u0430\u043a \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u0438 \u043f\u0430\u0440\u0441\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442.<\/p>\n<h2>\u041f\u0430\u0440\u0441\u0438\u043d\u0433<\/h2>\n<pre><code class=\"rust\">fn stmt(&amp;mut self) -&gt; Stmt {    match Stmt::define(self) {        StmtKind::Assign =&gt; self.parse_assign(),        StmtKind::Print =&gt; self.parse_print(),    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u043e\u0432, \u043e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0442\u0438\u043f \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b. <\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u043e\u0432:<\/p>\n<pre><code class=\"rust\">pub fn parse(&amp;mut self) -&gt; Vec&lt;Stmt&gt; {    let mut stmts = vec![];    while self.peek(0).kind != TKind::Eof {        let expr = self.stmt();        stmts.push(expr);    }    stmts}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 <strong>EOF <\/strong>\u043f\u0430\u0440\u0441\u0438\u043c \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u0441\u0442 \u0432 <code>tests\/parsert.rs<\/code><\/p>\n<pre><code class=\"rust\">fn statement() {    let source = \"a = 4print(\\\"a is \\\", a)\"    .trim();    let tokens = Lexer::new(source).tokenize();    println!(\"Source: {}\", source);    let stmts = Parser::new(tokens, source).parse();    println!(\"Statements:\");    for stmt in stmts {        println!(\"{:?}\", stmt);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>Source: a = 4print(\"a is \", a)Statements:Assign(\"a\", Assign, Num(4.0, Info { line: 0, offset: 4, len: 1 }))Print([Str(\"a is \", Info { line: 1, offset: 6, len: 7 }), Id(\"a\", Info { line: 1, offset: 15, len: 3 })])<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0418\u0442\u043e\u0433<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u044b! \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0434\u043b\u044f <strong>if-elif-else<\/strong>.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1044772\/\">https:\/\/habr.com\/ru\/articles\/1044772\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u0432\u0435\u0442 \u0447\u0438\u0442\u0430\u044e\u0449\u0438\u043c!\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043a\u043e\u0440\u043e\u0447\u0435 \u0434\u0432\u0443\u0445 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445, \u0438 \u0431\u0443\u0434\u0443\u0449\u0438\u0435 \u0441\u0442\u0430\u0442\u044c\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0430\u043a \u043b\u0435\u0433\u0447\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0438\u0441\u043a\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438. \u0422\u0430\u043a\u0436\u0435, \u0434\u0443\u043c\u0430\u044e, \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u043e\u0431\u043d\u0435\u0435.\u041a\u0430\u043a \u0431\u0443\u0434\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c?\u042f \u043c\u043d\u043e\u0433\u043e \u043a\u0430\u043a \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u043e \u0440\u0430\u043d\u044c\u0448\u0435, \u0438 \u043d\u0430\u0448\u0435\u043b \u043d\u0430\u0438\u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u0441\u043f\u043e\u0441\u043e\u0431.\u0423 Stmt \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 define(&amp;Parser). \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b \u0438 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043d\u044f\u043b, \u043a\u0430\u043a\u043e\u0439 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 peek \u0438 error \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0437\u0432\u043d\u0435. \u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u0437 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f &#8212; StmtKind. \u0412 \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u0442\u043e\u0434 stmt, \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u043b define \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u0430.\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u043f\u0438\u0441\u0430\u0442\u044c!\u0421\u0440\u0430\u0437\u0443 \u0441\u0434\u0435\u043b\u0430\u0435\u043c peek \u0438 error \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438:pub fn error(&amp;self, msg: &amp;str, token: Token) -&gt; String { &#8230; }pub fn peek(&amp;self, offset: i8) -&gt; Token { &#8230; }\u0412 \u043f\u0430\u043a\u0435\u0442\u0435 parser \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b &#8212; ast.rs. parser\/ast.rsuse super::Parser;use super::expr::Expr;use crate::lexer::token::TKind;#[derive(Debug)]pub enum Stmt {    Assign(String, AssignOp, Expr),    Print(Vec&lt;Expr&gt;),}#[derive(Debug)]pub enum StmtKind {    Assign,    Print,}#[derive(Debug, Default)]pub enum AssignOp {    #[default]    Assign,}\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0432\u044b \u043f\u043e\u0434\u0443\u043c\u0430\u0435\u0442\u0435 \u0437\u0430\u0447\u0435\u043c \u044f \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 AssignOp? \u0412\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e. \u041d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430 +=, \u0442\u043e\u043b\u044c\u043a\u043e =, \u0438 \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 1 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0434\u0440\u0443\u0433\u0438\u0435, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u0437\u0436\u0435.\u041f\u043e\u044f\u0441\u043d\u044e \u0437\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 Stmt:Assign(String, AssignOp, Expr) &#8212; String \u0442\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439. AssignOp \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u0438\u043f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f. Expr \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0442\u044c.Print(Vec&lt;Expr&gt;) &#8212; \u0432\u0435\u043a\u0442\u043e\u0440 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0442\u0443\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0441\u0435 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c.\u041c\u0435\u0442\u043e\u0434 defineimpl Stmt {    pub fn define(pr: &amp;Parser) -&gt; StmtKind {        match (pr.peek(0).kind, pr.peek(1).kind) {            (TKind::Id(_), TKind::Assign) =&gt; StmtKind::Assign,            (TKind::Print, _) =&gt; StmtKind::Print,            _ =&gt; panic!(&#171;{}&#187;, pr.error(&#171;Unknown statement&#187;, pr.peek(0))),        }    }}\u0422\u0443\u0442 \u0442\u043e\u0436\u0435 \u0432\u0441\u0435 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0435\u0440\u0432\u044b\u0435 2 \u0442\u0438\u043f\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 \u0441 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u0438 \u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u0442\u043e\u043a\u0435\u043d\u044b. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438 \u0437\u043d\u0430\u043a \u0440\u0430\u0432\u043d\u043e (\u041c\u044b \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c, \u043a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0440\u0430\u043d\u0435\u0435, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b), \u0442\u043e \u044d\u0442\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043a\u0435\u0439\u0432\u043e\u0440\u0434 print, \u0442\u043e \u044d\u0442\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e Print. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0435 \u043d\u0430\u0448\u043b\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043f\u0430\u0442\u0442\u0435\u0440\u043d, \u0442\u043e \u043f\u0430\u043d\u0438\u043a\u0443\u0435\u043c \u0441 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435\u043c \u043e \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u043c \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u0435.Print \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u041e\u043d \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u0447\u0435\u043c Assign, \u0442\u0430\u043a \u0447\u0442\u043e \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043d\u0435\u0433\u043e. \u0421\u0440\u0430\u0437\u0443 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043c\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432parser\/parser.rs: Parserfn parse_args(&amp;mut self) -&gt; Vec&lt;Expr&gt; {    let mut args = Vec::new();    while self.peek(0).kind != TKind::Eof {        let value = self.expr();        args.push(value);        let current = self.peek(0);        if current.kind == TKind::RParen {            break;        }        if !self.check(TKind::Comma) {            panic!(                &#171;{}&#187;,                self.error(                    &amp;format!(&#171;Expected &#8216;)&#8217; or &#8216;,&#8217;, found {:?}&#187;, current),                    current                )            );        }    }    args}\u0412 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e\u043c \u0446\u0438\u043a\u043b\u0435, \u043f\u043e\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u0440\u0430\u0432\u0435\u043d EOF: \u043f\u0430\u0440\u0441\u0438\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0437\u0430\u043f\u044f\u0442\u0430\u044f, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u043c \u0446\u0438\u043a\u043b, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430, \u0442\u043e \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0446\u0438\u043a\u043b. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0437\u0430\u043f\u044f\u0442\u0430\u044f \u0438 \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430, \u0442\u043e \u0432\u044b\u0434\u0430\u0435\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u043e \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0435.fn parse_print(&amp;mut self) -&gt; Stmt {    self.advance(1);    if !self.check(TKind::LParen) {        let current = self.peek(0);        panic!(            &#171;{}&#187;,            self.error(&amp;format!(&#171;Expected &#8216;(&#8216;, found {:?}&#187;, current), current)        );    }    let args = self.parse_args();    if !self.check(TKind::RParen) {        let current = self.peek(0);        panic!(            &#171;{}&#187;,            self.error(&amp;format!(&#171;Expected &#8216;)&#8217;, found {:?}&#187;, current), current)        );    }    Stmt::Print(args)}Assign \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442fn parse_assign(&amp;mut self) -&gt; Stmt {    let id = match self.peek(0).kind {        TKind::Id(id) =&gt; {            self.advance(1);            id        }        _ =&gt; unreachable!(&#171;{:?}&#187;, self.peek(0).kind),    };    let assign = AssignOp::default();    self.advance(1);    let value = self.expr();    Stmt::Assign(id, assign, value)}\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440. \u041e\u043d \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c, \u0442\u0430\u043a \u043a\u0430\u043a define \u044d\u0442\u043e \u0443\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u043b, \u0442\u0430\u043a \u0447\u0442\u043e \u0441\u0442\u0430\u0432\u0438\u043c unreachable \u0434\u043b\u044f \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u0438\u0434\u0435\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430. \u0423 \u043d\u0430\u0441 \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u043d\u0430\u043a \u0440\u0430\u0432\u043d\u043e, \u0442\u0430\u043a \u0447\u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043f\u0430\u043d\u0438\u043a\u0443\u0435\u043c. \u0414\u0430\u043b\u0435\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0437\u043d\u0430\u043a \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f \u0438 \u043f\u0430\u0440\u0441\u0438\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u044f. \u0412 \u043a\u043e\u043d\u0446\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442.\u041f\u0430\u0440\u0441\u0438\u043d\u0433fn stmt(&amp;mut self) -&gt; Stmt {    match Stmt::define(self) {        StmtKind::Assign =&gt; self.parse_assign(),        StmtKind::Print =&gt; self.parse_print(),    }}\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u043e\u0432, \u043e\u043d \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0442\u0438\u043f \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u043f\u0438\u0441\u043a\u0430 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u043e\u0432:pub fn parse(&amp;mut self) -&gt; Vec&lt;Stmt&gt; {    let mut stmts = vec![];    while self.peek(0).kind != TKind::Eof {        let expr = self.stmt();        stmts.push(expr);    }    stmts}\u041f\u043e\u043a\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 EOF \u043f\u0430\u0440\u0441\u0438\u043c \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u044b \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u043f\u0438\u0441\u043e\u043a.\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0442\u0435\u0441\u0442 \u0432 tests\/parsert.rsfn statement() {    let source = &#171;a = 4print(\\&#187;a is \\&#187;, a)&#187;    .trim();    let tokens = Lexer::new(source).tokenize();    println!(&#171;Source: {}&#187;, source);    let stmts = Parser::new(tokens, source).parse();    println!(&#171;Statements:&#187;);    for stmt in stmts {        println!(&#171;{:?}&#187;, stmt);    }}Source: a = 4print(&#171;a is &#171;, a)Statements:Assign(&#171;a&#187;, Assign, Num(4.0, Info { line: 0, offset: 4, len: 1 }))Print([Str(&#171;a is &#171;, Info { line: 1, offset: 6, len: 7 }), Id(&#171;a&#187;, Info { line: 1, offset: 15, len: 3 })])\u0418\u0442\u043e\u0433\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0435 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u044b! \u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0434\u043b\u044f if-elif-else.\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 https:\/\/habr.com\/ru\/articles\/1044772\/<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-482769","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/482769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=482769"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/482769\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=482769"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=482769"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=482769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}