{"id":456276,"date":"2025-04-16T15:00:38","date_gmt":"2025-04-16T15:00:38","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=456276"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=456276","title":{"rendered":"<span>\u041f\u0438\u0448\u0435\u043c \u0441\u0430\u043c\u044b\u0439 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430 Python<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430 Python. \u041c\u0430\u043b\u043e \u0447\u0435\u0433\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0443\u043c\u0435\u0442\u044c, \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0439\u0434\u0451\u0442.<\/p>\n<h2>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/h2>\n<p>\u0412\u0441\u0435\u0433\u043e 4 \u044d\u0442\u0430\u043f\u0430:<\/p>\n<ul>\n<li>\n<p>\u041b\u0435\u043a\u0441\u0435\u0440 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0441\u043e \u0441\u0432\u043e\u0438\u043c <abbr class=\"habraabbr\" title=\"\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (\u0410\u0421\u0414)\" data-title=\"&lt;p&gt;\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (\u0410\u0421\u0414)&lt;\/p&gt;\" data-abbr=\"AST\">AST<\/abbr><\/p>\n<\/li>\n<li>\n<p>\u0421\u0430\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0431\u0430\u0439\u0442\u043a\u043e\u0434\u043e\u043c<\/p>\n<\/li>\n<li>\n<p>\u0418 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041b\u0435\u043a\u0441\u0435\u0440 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 (\u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 a = 5)<\/p>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0434\u0435\u043b\u0430\u0435\u0442 \u0410\u0421\u0414 \u0430 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u043d \u0441\u0430\u043c<\/p>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0410\u0421\u0414 \u0432 \u0431\u0430\u0439\u0442 \u043a\u043e\u0434 (PUSH 5 STORE a HALT)<\/p>\n<p>\u0410 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0431\u0430\u0439\u0442\u043a\u043e\u0434.<\/p>\n<h2>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/h2>\n<p>\u0412\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u0426\u0438\u043a\u043b while, \u0443\u0441\u043b\u043e\u0432\u0438\u0435 if-else. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e for<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u043a: a = 5 \u0435\u0441\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435, \u0438\u043d\u0430\u0447\u0435 a = 5; &#8230;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f 2+2 \u043d\u043e \u043d\u0435 \u043a\u0430\u043a \u043d\u0435 2+2==4 \u0438 \u043e\u043d\u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u0440\u043e\u0431\u0435\u043b\u0430\u043c\u0438 (2 + 2)<\/p>\n<\/li>\n<li>\n<p>RelOp (Relation operation, \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f): &lt;, &gt;, !=, ==<\/p>\n<\/li>\n<li>\n<p>BinOp (Binary operation, \u0431\u0438\u043d\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f): +, -, *, \/<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0446\u0438\u043a\u043b\u0435 while \u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 if-else \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0434\u043d\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u043b\u044e\u0431\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (&#171;pass&#187;) \u0438 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (&#171;exit&#187;)<\/p>\n<\/li>\n<li>\n<p>\u041e\u0434\u0438\u043d \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445: int<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441\u043b\u043e\u0432\u0430\u0440\u0435\u0439 \u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e. \u0412\u043e\u0442 \u0442\u0430\u043a\u0430\u044f BNF \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c:<\/p>\n<pre><code class=\"python\">&lt;program&gt; ::= &lt;statement&gt; &lt;statement&gt; ::= &lt;while&gt; | &lt;if&gt; | &lt;assign&gt; &lt;while&gt; ::= \"while \" &lt;paren_expr&gt; \" \" &lt;statement&gt; &lt;if&gt; ::= \"if \" &lt;paren_expr&gt; \" \" &lt;statement&gt; | \"if \" &lt;paren_expr&gt; \" \" &lt;statement&gt; \" else \" &lt;statement&gt; &lt;paren_expr&gt; ::= \"(\" &lt;exp&gt; \")\" &lt;assign&gt; ::= &lt;indent&gt; \" = \" &lt;exp&gt; \"; \" | &lt;indent&gt; \" = \" &lt;exp&gt; &lt;indent&gt; ::= [a-z] | [A-Z] &lt;digit&gt; ::= [0-9] &lt;exit&gt; = \"exit\" &lt;pass&gt; = \"pass\" &lt;exp&gt; ::= &lt;term&gt; | &lt;bexp&gt; | &lt;aexp&gt; &lt;term&gt; ::= &lt;digit&gt; | &lt;indent&gt; &lt;bexp&gt; ::= &lt;term&gt; \" &gt; \" &lt;term&gt; | &lt;term&gt; \" &lt; \" &lt;term&gt; | &lt;term&gt; \" == \" &lt;term&gt; | &lt;term&gt; \" != \" &lt;term&gt; &lt;aexp&gt; ::= &lt;term&gt; \" + \" &lt;term&gt; | &lt;term&gt; \" - \" &lt;term&gt; | &lt;term&gt; \" * \" &lt;term&gt; | &lt;term&gt; \" \/ \" &lt;term&gt;<\/code><\/pre>\n<p>(\u0435\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0442\u043e \u0441\u043a\u0430\u0436\u0438\u0442\u0435, \u044f \u043c\u0430\u043b\u043e BNF \u043f\u043e\u043d\u0438\u043c\u0430\u044e) \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:<\/p>\n<pre><code class=\"python\">a = 5; if (a &lt; 10) a = 10; else a = 5<\/code><\/pre>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043b\u0435\u043a\u0441\u0435\u0440<\/h2>\n<p>\u041a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0440\u0430\u043d\u0435\u0435, \u043b\u0435\u043a\u0441\u0435\u0440 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u0442\u043e\u043a\u0435\u043d \u043d\u043e \u0438\u0437-\u0437\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0412\u043e\u0442 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u0435\u043a\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"python\">#\u0434\u043b\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043e\u043a import re  #\u043b\u0435\u043a\u0441\u0435\u0440 class Lexer:     def __init__(self):         pass      #\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0442\u0435\u0440\u043c (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0438\u043b\u0438 \u0447\u0438\u0441\u043b\u043e)     def lexterm(self, term):         #\u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439         if re.match(r'[a-zA-Z][a-zA-Z0-9_]*', term):             return ('id', term)         #\u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430 \u0434\u043b\u044f \u0447\u0438\u0441\u0435\u043b         elif re.match(r'[0-9]+', term):             return ('num', term)      #\u0432\u043e\u0437\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0432\u0430 \u0442\u0435\u0440\u043c\u0430 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043f\u043e \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 (\u0438\u043d\u0434\u0435\u043a\u0441 1)     def lex_expr(self, exp):         res = exp.split(' ')         if len(res) == 1:             return (self.lexterm(res[0]), res[0])         first = self.lexterm(res[0])         second = self.lexterm(res[2])         return [first, res[1], second]          def lex_token(self, string):         #\u0437\u0434\u0435\u0441\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442         self.sum = None                  d = string.split(' ')         #\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430         if d[0] == 'while':             d = string.split(')')             try:                 cond = d[0][d[0].index('while') + 6:] + ')'             except:                 raise SyntaxError('Invalid paren expression')             try:                 stmt = d[1][1:]             except:                 raise SyntaxError('Invalid \"while\" statement')             self.sum = (\"while\", cond, stmt)             return None         elif d[0] == 'if':             d = string.split(')')             try:                 cond = d[0][d[0].index('if') + 3:] + ')'             except:                 raise SyntaxError('Invalid paren expression')             try:                 stmt = d[1][1:]             except:                 raise SyntaxError('Invalid \"if\" statement')             self.sum = (\"if\", cond, stmt)             return None         #\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0438\u043b\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u044d\u0439\u0442\u043c\u0435\u043d\u0442\u044b         elif d[0] == 'pass':             self.sum = (\"pass\", None)             return None         #\u0438\u043d\u0430\u0447\u0435         elif d[0] == 'else':             stmt = string.replace('else ', '')             if stmt == '':                 raise SyntaxError('Invalid \"else\" statement')             self.sum = (\"else\", stmt)             return None         elif d[0] == 'exit':             self.sum = ('exit', None)             return None         try:             #\u043f\u0440\u0438\u0441\u0432\u0430\u043d\u0438\u0435             if d[1] == '=':                 name = d[0]                 valu = d[2:]                 pos = 0                 value = ''                 while pos &lt; len(valu):                     if pos + 1 == len(valu):                         value += valu[pos]                     else:                         value += valu[pos] + ' '                     pos += 1                 self.sum = (\"assign\", name, value)                 return None         except:             pass         #\u0438\u043d\u0430\u0447\u0435         raise SyntaxError('Invalid syntax: '+str(string))<\/code><\/pre>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u044f \u0432 try-except? \u041f\u043e\u0442\u043e\u043c\u0443-\u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435\u0442\u0443 \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 &#171;d&#187;.<\/p>\n<p>\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435 \u0437\u0430 \u0442\u0430\u043a\u0438\u0435 \u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u044e.<\/p>\n<p>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<pre><code class=\"python\">#\u0432 PyShell &gt;&gt;&gt; lexer = Lexer() &gt;&gt;&gt; lexer.lex_token('a = 5') &gt;&gt;&gt; token = lexer.sum &gt;&gt;&gt; token ('assign', 'a', '5')<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u0440 \u043c\u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e, \u0430 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 (\u043b\u043e\u0433\u0438\u0447\u043d\u043e)<\/p>\n<h2>\u041f\u0430\u0440\u0441\u0435\u0440<\/h2>\n<p>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 (\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u0430\u044f, \u044f \u043d\u0435 \u043f\u0440\u043e\u0431\u044b\u0432\u0430\u043b) \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"python\">a = 5; while (a &lt; 10) a = a + 1<\/code><\/pre>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u044d\u0442\u0438 \u0442\u043e\u043a\u0435\u043d\u044b:<\/p>\n<pre><code class=\"python\">('assign', 'a', '5') ('while', '(a &lt; 10)', 'a = a + 1')<\/code><\/pre>\n<p>\u0418 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0438\u0445 \u0432 \u044d\u0442\u043e AST:<\/p>\n<pre><code class=\"python\">Node('ASSIGN', 'a',      op2=Node('INT', '5') ) Node('WHILE',       Node('&lt;', Node('ID', 'a'), op2=Node('INT', '10')),       op2=Node('ASSIGN', 'a', op2=Node('+', Node('ID', 'a'), Node('INT', '1'))   ) )<\/code><\/pre>\n<p>AST \u043e\u0447\u0435\u043d\u044c \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u044b\u0439 \u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0438 \u043a\u0430\u0439\u0444\u0443\u0439\u0442\u0435. AST &#8212; \u044d\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0443\u0437\u043b\u0430 AST:<\/p>\n<pre><code class=\"python\">class Node:   def __init__(self, name, op1, op2=None, op3=None):     self.name = name     self.op1 = op1     self.op2 = op2     self.op3 = op3    def __repr__(self):     return f'Node(\"{self.name}\"\\n {self.op1}\\n {self.op2}\\n {self.op3})'<\/code><\/pre>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 op3 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043a\u0430\u043a else.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u043a\u043e\u0434 \u043f\u0430\u0440\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"python\">class Parser:     def __init__(self, lexer):         self.pos = 0         self.lexer = lexer      #\u0442\u0435\u0440\u043c     def term(self, value):         if value[0] == 'id':             return 'ID'         elif value[0] == 'num':             return 'INT'      #\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     def parse_expr(self, token):         try:             left = token[0]             right = token[2]             op = token[1]              result = Node(op, Node(self.term(left), left[1]), Node(self.term(right), right[1]))             return result         except:             try:                 return Node(self.term(left), left[1])             except:                 raise SyntaxError('Invalid expression')      #\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043a\u043e\u0431\u043a\u0430\u0445     def paren_expr(self, expr):         d = expr[expr.index('(') + 1:expr.index(')')]         return self.parse_expr(self.lexer.lex_expr(d))      #\u043f\u0430\u0440\u0441\u0438\u043d\u0433     def parse(self, program):         try:             self.prog = program.split('; ')         except:             self.prog = program         astpos = 0         ast = []         while self.pos &lt; len(self.prog):             if self.prog[self.pos] == '':                 self.pos += 1                 continue             d = self.prog[len(self.prog) - 1]             r = len(d) - 1             if d[r] == ';':                 raise SyntaxError('The \";\" sign is not needed at the end')             self.lexer.next_token(self.prog[self.pos])             token = self.lexer.sum             if token[0] == 'assign':                 ast.append(Node('ASSIGN', token[1], op2=self.parse_expr(self.lexer.lex_expr(token[2]))))             elif token[0] == 'if':                 d = Lexer()                 r = Parser(d)                 ast.append(Node('IF', self.paren_expr(token[1]), op2=r.parse(token[2])[0]))             elif token[0] == 'while':                 d = Lexer()                 r = Parser(d)                 ast.append(Node('WHILE', self.paren_expr(token[1]), op2=r.parse(token[2])[0]))             elif token[0] == 'else':                 d = Lexer()                 r = Parser(d)                 if ast[astpos - 1].name == 'IF':                     ast[astpos - 1].name = 'ELSE'                     ast[astpos - 1].op3 = r.parse(token[1])[0]                 else:                     raise SyntaxError('Invalid \"else\" statement')             elif token[0] == 'exit':                 ast.append(Node('EXIT', None))             elif token[0] == 'pass':                 ast.append(Node('PASS', None))             self.pos += 1             astpos += 1         self.pos = 0         return ast<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 term \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 &#8216;ID&#8217; \u0435\u0441\u043b\u0438 \u043e\u043d \u0443\u0432\u0438\u0434\u0435\u043b \u0442\u043e \u0447\u0442\u043e \u043b\u0435\u043a\u0441\u0435\u0440 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043b \u0438\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 &#8216;INT&#8217; \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e.<\/p>\n<p>parse_expr &#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u0437\u0435\u043b AST \u0433\u0434\u0435 \u0438\u043c\u044f \u044d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0430 op1 \u044d\u0442\u043e term \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0430 op2 \u044d\u0442\u043e term \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. \u0415\u0441\u043b\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0430: \u0432\u0435\u0440\u043d\u0451\u0442 term \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<p>paren_expr &#8212; \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 parse_expr<\/p>\n<p>parse &#8212; \u0441\u0430\u043c \u043f\u0430\u0440\u0441\u0435\u0440, \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u043f\u0430\u0440\u0441\u0438\u0442 \u0438\u0445. \u0410 \u0442\u043e\u0447\u043d\u0435\u0435 \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441 \u0446\u0438\u043a\u043b\u043e\u043c while (a = 5; while (a &lt; 10) a = a + 1) \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0432 \u043d\u0435\u0439 \u043d\u0435 &#171;;&#187; \u0430 &#171;;&#187; \u0441 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c. \u0418 \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"python\">['a = 5', 'while (a &lt; 10) a = a + 1']<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u0437\u043d\u0430\u0435\u0442 \u0447\u0442\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u0435 \u043d\u0435 &#171;;&#187; \u0442\u043e \u043e\u043d \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438. \u0418\u043d\u0430\u0447\u0435: \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e \u0442\u0438\u043f\u0443 \u044d\u0442\u043e\u0433\u043e: &#171;\u0437\u0430\u0447\u0435\u043c \u0442\u0435\u0431\u0435 &#171;;&#187; \u0432 \u043a\u043e\u043d\u0446\u0435?&#187;.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u043e \u044d\u0442\u0438\u043c \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0443\u0437\u0435\u043b. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e &#171;else&#187; \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u043d \u043d\u0430\u0439\u0442\u0438 if \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0443\u0437\u043b\u0435 (\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f astpos). \u041f\u043e\u0442\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441 AST.<\/p>\n<h2>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/h2>\n<p>\u042d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0432\u0435\u0434\u044c \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440. \u0412\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"fsharp\">FETCH \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f - \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0435\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 PUSH \u0447\u0438\u0441\u043b\u043e - \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0435\u043a \u0447\u0438\u0441\u043b\u043e POP - \u044f \u043d\u0435 \u043f\u043e\u043c\u043d\u044e \u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u0432\u0435\u0434\u044c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043c ADD, SUB, MUL, DIV - \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 NOTEQ, EQ, LT, GT - \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 JMP \u0430\u0434\u0440\u0435\u0441 - \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 JNZ \u0430\u0434\u0440\u0435\u0441 - \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u0435\u0441\u043b\u0438 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0435 \u0441\u0442\u0435\u043a\u0430 \u043d\u0435 0 JZ \u0430\u0434\u0440\u0435\u0441 - \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u0435\u0441\u043b\u0438 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0435 \u0441\u0442\u0435\u043a\u0430 0 PASS - \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c STORE \u0438\u043c\u044f - \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e HALT - \u043a\u043e\u043d\u0435\u0446 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043e\u043f\u043a\u043e\u0434\u044b \u0434\u043b\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439:<\/p>\n<pre><code class=\"python\">FETCH, STORE, PUSH, POP, ADD, SUB, MUL, DIV, LT, GT, EQ, NOTEQ, JZ, JNZ, JMP, PASS, HALT = range(17)<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 &#171;a = 1 + 2&#187;, \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u044d\u0442\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"1c\">PUSH 1 PUSH 2 ADD STORE a<\/code><\/pre>\n<p>\u041d\u043e. \u042d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e. \u041f\u043e \u043d\u0430\u0448\u0435\u043c \u043e\u043f\u043a\u043e\u0434\u0430\u043c \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">[2, 1, 2, 2, 4, 1, 'a']<\/code><\/pre>\n<p>2 \u044d\u0442\u043e PUSH<\/p>\n<p>4 \u044d\u0442\u043e ADD<\/p>\n<p>1 \u044d\u0442\u043e STORE.<\/p>\n<p>\u0418 \u0432\u043e\u0442 \u043a\u043e\u0434 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430:<\/p>\n<pre><code class=\"python\">class Compiler:     def __init__(self):         self.program = []         self.pc = 0      def gen(self, command):         self.program.append(command)         self.pc = self.pc + 1      def compilenode(self, node):         name = node.name         if name == 'INT':             self.gen(PUSH)             self.gen(int(node.op1))         elif name == 'ID':             self.gen(FETCH)             self.gen(node.op1)         elif name == '+':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(ADD)         elif name == '-':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(SUB)         elif name == '\/':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(DIV)         elif name == '*':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(MUL)         elif name == '&lt;':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(LT)         elif name == '&gt;':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(GT)         elif name == '!=':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(NOTEQ)         elif name == '==':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(EQ)         elif name == 'ASSIGN':             self.compilenode(node.op2)             self.gen(STORE)             self.gen(node.op1)         elif name == 'IF':             self.compilenode(node.op1)             self.gen(JZ)             addr = self.pc             self.gen(0)             self.compilenode(node.op2)             self.program[addr] = self.pc         elif name == 'ELSE':             self.compilenode(node.op1)             self.gen(JZ)             addr1 = self.pc             self.gen(0)             self.compilenode(node.op2)             self.gen(JMP)             addr2 = self.pc             self.gen(0)             self.program[addr1] = self.pc             self.compilenode(node.op3)             self.program[addr2] = self.pc         elif name == 'WHILE':             if node.op1.op2:                 try:                     r = node.op1.op2                     d = str(int(r.op1) - 1)                     r.op1 = d                 except:                     r = node.op1.op1                     d = str(int(r.op1) - 1)                     r.op1 = d             addr1 = self.pc             self.compilenode(node.op1)             self.gen(JZ)             addr2 = self.pc             self.gen(1)             self.compilenode(node.op2)             self.gen(JMP)             self.gen(addr1)             self.program[addr2] = self.pc         elif name == 'EXIT':             self.gen(HALT)         elif name == 'PASS':             self.gen(PASS)                          def compileast(self, ast):         for i in ast:             self.compilenode(i)         self.gen(HALT)         return self.program<\/code><\/pre>\n<p>\u041a\u0430\u043a \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 WHILE, \u0434\u043b\u044f \u0447\u0438\u0441\u0435\u043b \u044f \u043e\u0442\u043d\u0438\u043c\u0430\u044e \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e \u0443 \u044d\u0442\u043e\u0433\u043e \u0447\u0438\u0441\u043b\u0430, \u043f\u043e\u0447\u0435\u043c\u0443? \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a\u043e\u0433\u0434\u0430 \u044f \u0434\u0435\u043b\u0430\u043b \u044d\u0442\u043e \u0442\u043e while \u0434\u0435\u043b\u0430\u043b \u043d\u0435 5 \u0430 6 \u0440\u0430\u0437. \u0418, \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0441\u0442\u0430\u0442\u044c\u0435 <a href=\"https:\/\/habr.com\/ru\/articles\/133780\/\" rel=\"noopener noreferrer nofollow\">\u041f\u0438\u0448\u0435\u043c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0438 \u043d\u0438\u043a\u043e\u043c\u0443 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \/ \u0425\u0430\u0431\u0440<\/a> (\u043d\u0435 \u0440\u0435\u043a\u043b\u0430\u043c\u0430) \u0437\u0430 \u0442\u043e \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0430\u043b\u0430 \u043c\u043d\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f if, while, else. \u0412\u0435\u0441\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 compileast. gen \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u043e\u043f\u043a\u043e\u0434. \u0410 compilenode \u044d\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0431\u0430\u043b\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443:<\/p>\n<pre><code class=\"python\">#\u0432 PyShell &gt;&gt;&gt; lexer = Lexer() &gt;&gt;&gt; parser = Parser(lexer) &gt;&gt;&gt; compiler = Compiler() &gt;&gt;&gt;  &gt;&gt;&gt; ast = parser.parse('a = 5; b = 5') &gt;&gt;&gt; print(compiler.compileast(ast)) [2, 5, 1, 'a', 2, 5, 1, 'b'] &gt;&gt;&gt; <\/code><\/pre>\n<p>\u041d\u043e \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u043a\u043e\u043d\u0446\u0443.<\/p>\n<h2>\u0412\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430<\/h2>\n<p>\u0418 \u043a\u043e\u043d\u0435\u0446 \u043d\u0430\u0448\u0435\u0439 \u043f\u043e\u0434\u0435\u043b\u043a\u0438, \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430!<\/p>\n<p>\u0412\u0441\u0435 \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0442\u043e \u0447\u0442\u043e \u0431\u0430\u0439\u0442\u043a\u043e\u0434 \u0441\u0430\u043c \u0441\u0435\u0431\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430. \u0412\u043e\u0442 \u043a\u043e\u0434 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b:<\/p>\n<pre><code class=\"python\">class VirtualMachine:     def __init__(self):         pass          def run(self, program):         env = {}         stack = []         pc = 0         while True:             op = program[pc]             if pc &lt; len(program) - 1:                 arg = program[pc + 1]              if op == FETCH:                 try:                     stack.append(env[arg])                 except:                     stack.append(0)                 pc += 2             elif op == STORE:                 env[arg] = stack.pop()                 pc += 2             elif op == PUSH:                 stack.append(arg)                 pc += 2             elif op == ADD:                 stack[-2] += stack[-1]                 stack.pop()                 pc += 1             elif op == SUB:                 stack[-2] -= stack[-1]                 stack.pop()                 pc += 1             elif op == MUL:                 stack[-2] *= stack[-1]                 stack.pop()                 pc += 1             elif op == DIV:                 stack[-2] \/= stack[-1]                 stack.pop()                 pc += 1             elif op == LT:                 if stack[-2] &lt;= stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == GT:                 if stack[-2] &gt;= stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == EQ:                 if stack[-2] == stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == NOTEQ:                 if stack[-2] != stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == POP:                 stack.append(arg)                 stack.pop()                 pc += 1             elif op == JZ:                 if stack.pop() == 0:                     pc = arg                 else:                     pc += 2             elif op == JNZ:                    if stack.pop() != 0:                       pc = arg                   else:                       pc += 2             elif op == JMP:                 pc = arg             elif op == PASS:                 pc += 1             elif op == HALT:                 break          print('Execution finished')         for i in env.keys():             print(i+': '+str(env[i])) <\/code><\/pre>\n<p>\u041e\u043f\u0438\u0441\u044b\u0432\u0430\u044e \u044d\u0442\u043e\u0442 \u043a\u043e\u0434:<\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f stack \u044d\u0442\u043e \u0441\u0430\u043c \u0441\u0442\u0435\u043a \u0432\u0435\u0434\u044c \u043d\u0430\u0448\u0430 \u043c\u0430\u0448\u0438\u043d\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u0430\u044f.<\/p>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f env \u044d\u0442\u043e \u0441\u043b\u043e\u0432\u0430\u0440\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445.<\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0435\u0441\u043b\u0438 \u043e\u043d \u0435\u0441\u0442\u044c. \u0418 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u043e\u043f\u043a\u043e\u0434. \u0412 \u043a\u043e\u043d\u0446\u0435 \u043f\u043e\u0440\u0430\u0434\u0443\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0447\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u0440\u0430\u0434\u043e\u0441\u0442\u043d\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043a\u043b\u044e\u0447 \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432 env.<\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0431\u0430\u043b\u043e\u0432\u0430\u043b\u0438\u0441\u044c \u0441 \u0432\u044b\u0432\u043e\u0434\u043e\u043c \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435 \u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"python\">&gt;&gt;&gt; bytecode = compiler.compileast(ast) &gt;&gt;&gt; vm = VirtualMachine() &gt;&gt;&gt; vm.run(bytecode) Execution finished a: 5 b: 5 &gt;&gt;&gt; <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0432 \u0431\u043e\u043d\u0443\u0441 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043a\u043e\u043c\u0430\u043d\u0434\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443.<\/p>\n<pre><code class=\"python\">import sys  def run_compiler(prog):     lexer = Lexer()     parser = Parser(lexer)     ast = parser.parse(prog)      compiler = Compiler()     bytecode = compiler.compileast(ast)      vm = VirtualMachine()     vm.run(bytecode)  def cli():     while True:         com = input('&gt;&gt;&gt; ')         try:             run_compiler(com)         except Exception as err:             print('Error: ', end=\"\")             sys.stderr.write(str(err)+'\\n')  if __name__ == '__main__':     cli()<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0439 \u043d\u0435 \u043d\u0430\u0434\u043e \u0432\u0435\u0434\u044c \u0442\u0443\u0442 \u0438 \u0442\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u043d\u043e.<\/p>\n<h2>\u0412\u0435\u0441\u044c \u043a\u043e\u0434<\/h2>\n<pre><code class=\"python\">import re import sys  FETCH, STORE, PUSH, POP, ADD, SUB, MUL, DIV, LT, GT, EQ, NOTEQ, JZ, JNZ, JMP, PASS, HALT = range(17)  class Lexer:     def __init__(self):         pass      def lexterm(self, term):         if re.match(r'[a-zA-Z][a-zA-Z0-9_]*', term):             return ('id', term)         elif re.match(r'[0-9]+', term):             return ('num', term)      def lex_expr(self, exp):         res = exp.split(' ')         if len(res) == 1:             return (self.lexterm(res[0]), res[0])         first = self.lexterm(res[0])         second = self.lexterm(res[2])         return [first, res[1], second]          def next_token(self, string):         self.sum = None                  d = string.split(' ')         if d[0] == 'while':             d = string.split(')')             try:                 cond = d[0][d[0].index('while') + 6:] + ')'             except:                 raise SyntaxError('Invalid paren expression')             try:                 stmt = d[1][1:]             except:                 raise SyntaxError('Invalid \"while\" statement')             self.sum = (\"while\", cond, stmt)             return None         elif d[0] == 'if':             d = string.split(')')             try:                 cond = d[0][d[0].index('if') + 3:] + ')'             except:                 raise SyntaxError('Invalid paren expression')             try:                 stmt = d[1][1:]             except:                 raise SyntaxError('Invalid \"if\" statement')             self.sum = (\"if\", cond, stmt)             return None         elif d[0] == 'pass':             self.sum = (\"pass\", None)             return None         elif d[0] == 'else':             stmt = string.replace('else ', '')             if stmt == '':                 raise SyntaxError('Invalid \"else\" statement')             self.sum = (\"else\", stmt)             return None         elif d[0] == 'exit':             self.sum = ('exit', None)             return None         try:             if d[1] == '=':                 name = d[0]                 valu = d[2:]                 pos = 0                 value = ''                 while pos &lt; len(valu):                     if pos + 1 == len(valu):                         value += valu[pos]                     else:                         value += valu[pos] + ' '                     pos += 1                 self.sum = (\"assign\", name, value)                 return None         except:             pass         raise SyntaxError('Invalid syntax: '+str(string))  class Node:     def __init__(self, name, op1, op2=None, op3=None):         self.name = name         self.op1 = op1         self.op2 = op2         self.op3 = op3      def __repr__(self):         return f\"Node(\\n name='{self.name}',\\n op1={self.op1},\\n op2={self.op2},\\n op3={self.op3}\\n)\"  class Parser:     def __init__(self, lexer):         self.pos = 0         self.lexer = lexer      def term(self, value):         if value[0] == 'id':             return 'ID'         elif value[0] == 'num':             return 'INT'      def parse_expr(self, token):         try:             left = token[0]             right = token[2]             op = token[1]              result = Node(op, Node(self.term(left), left[1]), Node(self.term(right), right[1]))             return result         except:             try:                 return Node(self.term(left), left[1])             except:                 raise SyntaxError('Invalid expression')      def paren_expr(self, expr):         d = expr[expr.index('(') + 1:expr.index(')')]         return self.parse_expr(self.lexer.lex_expr(d))      def parse(self, program):         try:             self.prog = program.split('; ')         except:             self.prog = program         astpos = 0         ast = []         while self.pos &lt; len(self.prog):             if self.prog[self.pos] == '':                 self.pos += 1                 continue             d = self.prog[len(self.prog) - 1]             r = len(d) - 1             if d[r] == ';':                 raise SyntaxError('The \";\" sign is not needed at the end')             self.lexer.next_token(self.prog[self.pos])             token = self.lexer.sum             if token[0] == 'assign':                 ast.append(Node('ASSIGN', token[1], op2=self.parse_expr(self.lexer.lex_expr(token[2]))))             elif token[0] == 'if':                 d = Lexer()                 r = Parser(d)                 ast.append(Node('IF', self.paren_expr(token[1]), op2=r.parse(token[2])[0]))             elif token[0] == 'while':                 d = Lexer()                 r = Parser(d)                 ast.append(Node('WHILE', self.paren_expr(token[1]), op2=r.parse(token[2])[0]))             elif token[0] == 'else':                 d = Lexer()                 r = Parser(d)                 if ast[astpos - 1].name == 'IF':                     ast[astpos - 1].name = 'ELSE'                     ast[astpos - 1].op3 = r.parse(token[1])[0]                 else:                     raise SyntaxError('Invalid \"else\" statement')             elif token[0] == 'exit':                 ast.append(Node('EXIT', None))             elif token[0] == 'pass':                 ast.append(Node('PASS', None))             self.pos += 1             astpos += 1         self.pos = 0         return ast  class Compiler:     def __init__(self):         self.program = []         self.pc = 0      def gen(self, command):         self.program.append(command)         self.pc = self.pc + 1      def compilenode(self, node):         name = node.name         if name == 'INT':             self.gen(PUSH)             self.gen(int(node.op1))         elif name == 'ID':             self.gen(FETCH)             self.gen(node.op1)         elif name == '+':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(ADD)         elif name == '-':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(SUB)         elif name == '\/':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(DIV)         elif name == '*':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(MUL)         elif name == '&lt;':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(LT)         elif name == '&gt;':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(GT)         elif name == '!=':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(NOTEQ)         elif name == '==':             self.compilenode(node.op1)             self.compilenode(node.op2)             self.gen(EQ)         elif name == 'ASSIGN':             self.compilenode(node.op2)             self.gen(STORE)             self.gen(node.op1)         elif name == 'IF':             self.compilenode(node.op1)             self.gen(JZ)             addr = self.pc             self.gen(0)             self.compilenode(node.op2)             self.program[addr] = self.pc         elif name == 'ELSE':             self.compilenode(node.op1)             self.gen(JZ)             addr1 = self.pc             self.gen(0)             self.compilenode(node.op2)             self.gen(JMP)             addr2 = self.pc             self.gen(0)             self.program[addr1] = self.pc             self.compilenode(node.op3)             self.program[addr2] = self.pc         elif name == 'WHILE':             if node.op1.op2:                 try:                     r = node.op1.op2                     d = str(int(r.op1) - 1)                     r.op1 = d                 except:                     r = node.op1.op1                     d = str(int(r.op1) - 1)                     r.op1 = d             addr1 = self.pc             self.compilenode(node.op1)             self.gen(JZ)             addr2 = self.pc             self.gen(1)             self.compilenode(node.op2)             self.gen(JMP)             self.gen(addr1)             self.program[addr2] = self.pc         elif name == 'EXIT':             self.gen(HALT)         elif name == 'PASS':             self.gen(PASS)                          def compileast(self, ast):         for i in ast:             self.compilenode(i)         self.gen(HALT)         return self.program  class VirtualMachine:     def run(self, program):         env = {}         stack = []         pc = 0         while True:             op = program[pc]             if pc &lt; len(program) - 1:                 arg = program[pc + 1]              if op == FETCH:                 try:                     stack.append(env[arg])                 except:                     stack.append(0)                 pc += 2             elif op == STORE:                 env[arg] = stack.pop()                 pc += 2             elif op == PUSH:                 stack.append(arg)                 pc += 2             elif op == ADD:                 stack[-2] += stack[-1]                 stack.pop()                 pc += 1             elif op == SUB:                 stack[-2] -= stack[-1]                 stack.pop()                 pc += 1             elif op == MUL:                 stack[-2] *= stack[-1]                 stack.pop()                 pc += 1             elif op == DIV:                 stack[-2] \/= stack[-1]                 stack.pop()                 pc += 1             elif op == LT:                 if stack[-2] &lt;= stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == GT:                 if stack[-2] &gt;= stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == EQ:                 if stack[-2] == stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == NOTEQ:                 if stack[-2] != stack[-1]:                     stack[-2] = 1                 else:                     stack[-2] = 0                 stack.pop()                 pc += 1             elif op == POP:                 stack.append(arg)                 stack.pop()                 pc += 1             elif op == JZ:                     if stack.pop() == 0:                           pc = arg                     else:                         pc += 2             elif op == JNZ:                      if stack.pop() != 0:                           pc = arg                     else:                           pc += 2             elif op == JMP:                 pc = arg             elif op == PASS:                 pc += 1             elif op == HALT:                 break          print('Execution finished')         for i in env.keys():             print(i+': '+str(env[i]))  def run_compiler(prog):     lexer = Lexer()     parser = Parser(lexer)     ast = parser.parse(prog)      compiler = Compiler()     bytecode = compiler.compileast(ast)      vm = VirtualMachine()     vm.run(bytecode)  def cli():     while True:         com = input('&gt;&gt;&gt; ')         try:             run_compiler(com)         except Exception as err:             print('Error: ', end=\"\")             sys.stderr.write(str(err)+'\\n')  if __name__ == '__main__':     cli()<\/code><\/pre>\n<p>\u0412\u0441\u0435\u0433\u043e 379 \u0441\u0442\u0440\u043e\u0447\u0435\u043a \u043a\u043e\u0434\u0430. \u041d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e.<\/p>\n<p>\u0418 \u0432\u043e\u0442 \u0432\u0430\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u044b:<\/p>\n<pre><code>a = 5; if (a &lt; 10) a = 10; else a = 5 a = 5; b = 5; c = a + b x = 0; while (x &lt; 10) x = x + 1<\/code><\/pre>\n<p>\u0414\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041c\u044b \u0441 \u0432\u0430\u043c\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0438 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u044b \u0443\u0436\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043e\u043f\u044b\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u0432 \u0441 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u043e\u0439. \u0418, \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \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\/901324\/\"> https:\/\/habr.com\/ru\/articles\/901324\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442, \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043c\u044b \u0441 \u0432\u0430\u043c\u0438 \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0430 Python. \u041c\u0430\u043b\u043e \u0447\u0435\u0433\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0443\u043c\u0435\u0442\u044c, \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0439\u0434\u0451\u0442.<\/p>\n<h2>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/h2>\n<p>\u0412\u0441\u0435\u0433\u043e 4 \u044d\u0442\u0430\u043f\u0430:<\/p>\n<ul>\n<li>\n<p>\u041b\u0435\u043a\u0441\u0435\u0440 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0441\u043e \u0441\u0432\u043e\u0438\u043c <abbr class=\"habraabbr\" title=\"\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (\u0410\u0421\u0414)\" data-title=\"&lt;p&gt;\u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (\u0410\u0421\u0414)&lt;\/p&gt;\" data-abbr=\"AST\">\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (\u0410\u0421\u0414)&lt;\/p&gt;&#187; data-abbr=&#187;AST&#187;>AST<\/abbr><\/p>\n<\/li>\n<li>\n<p>\u0421\u0430\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u043e \u0441\u0432\u043e\u0438\u043c\u0438 \u0431\u0430\u0439\u0442\u043a\u043e\u0434\u043e\u043c<\/p>\n<\/li>\n<li>\n<p>\u0418 \u043d\u0430\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u043a \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041b\u0435\u043a\u0441\u0435\u0440 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0447\u0430\u0441\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 (\u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 a = 5)<\/p>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0434\u0435\u043b\u0430\u0435\u0442 \u0410\u0421\u0414 \u0430 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043e\u043d \u0441\u0430\u043c<\/p>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0410\u0421\u0414 \u0432 \u0431\u0430\u0439\u0442 \u043a\u043e\u0434 (PUSH 5 STORE a HALT)<\/p>\n<p>\u0410 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0430\u0448\u0438\u043d\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0431\u0430\u0439\u0442\u043a\u043e\u0434.<\/p>\n<h2>\u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/h2>\n<p>\u0412\u043e\u0442 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430:<\/p>\n<ul>\n<li>\n<p>\u0426\u0438\u043a\u043b while, \u0443\u0441\u043b\u043e\u0432\u0438\u0435 if-else. \u041d\u0438\u043a\u0430\u043a\u043e\u0433\u043e for<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u0435\u043b\u0430\u044e\u0442\u0441\u044f \u0442\u0430\u043a: a = 5 \u0435\u0441\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435, \u0438\u043d\u0430\u0447\u0435 a = 5; &#8230;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f 2+2 \u043d\u043e \u043d\u0435 \u043a\u0430\u043a \u043d\u0435 2+2==4 \u0438 \u043e\u043d\u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u043f\u0440\u043e\u0431\u0435\u043b\u0430\u043c\u0438 (2 + 2)<\/p>\n<\/li>\n<li>\n<p>RelOp (Relation operation, \u0440\u0435\u043b\u044f\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f): &lt;, &gt;, !=, ==<\/p>\n<\/li>\n<li>\n<p>BinOp (Binary operation, \u0431\u0438\u043d\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f): +, -, *, \/<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0446\u0438\u043a\u043b\u0435 while \u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 if-else \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u0435 \u0438 \u043e\u0434\u043d\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u043b\u044e\u0431\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u043c\u0430\u043d\u0434\u0430 \u0434\u043b\u044f \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f (&#171;pass&#187;) \u0438 \u0434\u043b\u044f \u0432\u044b\u0445\u043e\u0434\u0430 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (&#171;exit&#187;)<\/p>\n<\/li>\n<li>\n<p>\u041e\u0434\u0438\u043d \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445: int<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u0430, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u043f\u0438\u0441\u043a\u043e\u0432, \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0441\u043b\u043e\u0432\u0430\u0440\u0435\u0439 \u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e. \u0412\u043e\u0442 \u0442\u0430\u043a\u0430\u044f BNF \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c:<\/p>\n<pre><code class=\"python\">&lt;program&gt; ::= &lt;statement&gt; &lt;statement&gt; ::= &lt;while&gt; | &lt;if&gt; | &lt;assign&gt; &lt;while&gt; ::= \"while \" &lt;paren_expr&gt; \" \" &lt;statement&gt; &lt;if&gt; ::= \"if \" &lt;paren_expr&gt; \" \" &lt;statement&gt; | \"if \" &lt;paren_expr&gt; \" \" &lt;statement&gt; \" else \" &lt;statement&gt; &lt;paren_expr&gt; ::= \"(\" &lt;exp&gt; \")\" &lt;assign&gt; ::= &lt;indent&gt; \" = \" &lt;exp&gt; \"; \" | &lt;indent&gt; \" = \" &lt;exp&gt; &lt;indent&gt; ::= [a-z] | [A-Z] &lt;digit&gt; ::= [0-9] &lt;exit&gt; = \"exit\" &lt;pass&gt; = \"pass\" &lt;exp&gt; ::= &lt;term&gt; | &lt;bexp&gt; | &lt;aexp&gt; &lt;term&gt; ::= &lt;digit&gt; | &lt;indent&gt; &lt;bexp&gt; ::= &lt;term&gt; \" &gt; \" &lt;term&gt; | &lt;term&gt; \" &lt; \" &lt;term&gt; | &lt;term&gt; \" == \" &lt;term&gt; | &lt;term&gt; \" != \" &lt;term&gt; &lt;aexp&gt; ::= &lt;term&gt; \" + \" &lt;term&gt; | &lt;term&gt; \" - \" &lt;term&gt; | &lt;term&gt; \" * \" &lt;term&gt; | &lt;term&gt; \" \/ \" &lt;term&gt;<\/code><\/pre>\n<p>(\u0435\u0441\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0442\u043e \u0441\u043a\u0430\u0436\u0438\u0442\u0435, \u044f \u043c\u0430\u043b\u043e BNF \u043f\u043e\u043d\u0438\u043c\u0430\u044e) \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b:<\/p>\n<pre><code class=\"python\">a = 5; if (a &lt; 10) a = 10; else a = 5<\/code><\/pre>\n<h2>\u041f\u0438\u0448\u0435\u043c \u043b\u0435\u043a\u0441\u0435\u0440<\/h2>\n<p>\u041a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0440\u0430\u043d\u0435\u0435, \u043b\u0435\u043a\u0441\u0435\u0440 \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043b\u0438\u0448\u044c \u043e\u0434\u0438\u043d \u0442\u043e\u043a\u0435\u043d \u043d\u043e \u0438\u0437-\u0437\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0412\u043e\u0442 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u0435\u043a\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"python\">#\u0434\u043b\u044f \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043e\u043a import re  #\u043b\u0435\u043a\u0441\u0435\u0440 class Lexer:     def __init__(self):         pass      #\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c \u0442\u0435\u0440\u043c (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0438\u043b\u0438 \u0447\u0438\u0441\u043b\u043e)     def lexterm(self, term):         #\u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439         if re.match(r'[a-zA-Z][a-zA-Z0-9_]*', term):             return ('id', term)         #\u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430 \u0434\u043b\u044f \u0447\u0438\u0441\u0435\u043b         elif re.match(r'[0-9]+', term):             return ('num', term)      #\u0432\u043e\u0437\u0440\u0430\u0449\u0430\u0435\u0442 \u0434\u0432\u0430 \u0442\u0435\u0440\u043c\u0430 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043f\u043e \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u0435 (\u0438\u043d\u0434\u0435\u043a\u0441 1)     def lex_expr(self, exp):         res = exp.split(' ')         if len(res) == 1:             return (self.lexterm(res[0]), res[0])         first = self.lexterm(res[0])         second = self.lexterm(res[2])         return [first, res[1], second]          def lex_token(self, string):         #\u0437\u0434\u0435\u0441\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442         self.sum = None                  d = string.split(' ')         #\u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430         if d[0] == 'while':             d = string.split(')')             try:                 cond = d[0][d[0].index('while') + 6:] + ')'             except:                 raise SyntaxError('Invalid paren expression')             try:                 stmt = d[1][1:]             except:                 raise SyntaxError('Invalid \"while\" statement')             self.sum = (\"while\", cond, stmt)             return None         elif d[0] == 'if':             d = string.split(')')             try:                 cond = d[0][d[0].index('if') + 3:] + ')'             except:                 raise SyntaxError('Invalid paren expression')             try:                 stmt = d[1][1:]             except:                 raise SyntaxError('Invalid \"if\" statement')             self.sum = (\"if\", cond, stmt)             return None         #\u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0438\u043b\u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u0442\u044d\u0439\u0442\u043c\u0435\u043d\u0442\u044b         elif d[0] == 'pass':             self.sum = (\"pass\", None)             return None         #\u0438\u043d\u0430\u0447\u0435         elif d[0] == 'else':             stmt = string.replace('else ', '')             if stmt == '':                 raise SyntaxError('Invalid \"else\" statement')             self.sum = (\"else\", stmt)             return None         elif d[0] == 'exit':             self.sum = ('exit', None)             return None         try:             #\u043f\u0440\u0438\u0441\u0432\u0430\u043d\u0438\u0435             if d[1] == '=':                 name = d[0]                 valu = d[2:]                 pos = 0                 value = ''                 while pos &lt; len(valu):                     if pos + 1 == len(valu):                         value += valu[pos]                     else:                         value += valu[pos] + ' '                     pos += 1                 self.sum = (\"assign\", name, value)                 return None         except:             pass         #\u0438\u043d\u0430\u0447\u0435         raise SyntaxError('Invalid syntax: '+str(string))<\/code><\/pre>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u044f \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u043b \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u043d\u0438\u044f \u0432 try-except? \u041f\u043e\u0442\u043e\u043c\u0443-\u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435\u0442\u0443 \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 &#171;d&#187;.<\/p>\n<p>\u0418\u0437\u0432\u0438\u043d\u0438\u0442\u0435 \u0437\u0430 \u0442\u0430\u043a\u0438\u0435 \u043e\u0442\u0432\u0440\u0430\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u044e.<\/p>\n<p>\u041a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c:<\/p>\n<pre><code class=\"python\">#\u0432 PyShell &gt;&gt;&gt; lexer = Lexer() &gt;&gt;&gt; lexer.lex_token('a = 5') &gt;&gt;&gt; token = lexer.sum &gt;&gt;&gt; token ('assign', 'a', '5')<\/code><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u0440 \u043c\u043d\u0435 \u0431\u044b\u043b\u043e \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0435\u0433\u043e, \u0430 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u044b\u043b\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 (\u043b\u043e\u0433\u0438\u0447\u043d\u043e)<\/p>\n<h2>\u041f\u0430\u0440\u0441\u0435\u0440<\/h2>\n<p>\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442:<\/p>\n<p>\u041d\u0430 \u0432\u0445\u043e\u0434 \u043f\u043e\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u0430\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 (\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u0430\u044f, \u044f \u043d\u0435 \u043f\u0440\u043e\u0431\u044b\u0432\u0430\u043b) \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"python\">a = 5; while (a &lt; 10) a = a + 1<\/code><\/pre>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u044d\u0442\u0438 \u0442\u043e\u043a\u0435\u043d\u044b:<\/p>\n<pre><code class=\"python\">('assign', 'a', '5') ('while', '(a &lt; 10)', 'a = a + 1')<\/code><\/pre>\n<p>\u0418 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0438\u0445 \u0432 \u044d\u0442\u043e AST:<\/p>\n<pre><code class=\"python\">Node('ASSIGN', 'a',      op2=Node('INT', '5') ) Node('WHILE',       Node('&lt;', Node('ID', 'a'), op2=Node('INT', '10')),       op2=Node('ASSIGN', 'a', op2=Node('+', Node('ID', 'a'), Node('INT', '1'))   ) )<\/code><\/pre>\n<p>AST \u043e\u0447\u0435\u043d\u044c \u0437\u0430\u043f\u0443\u0442\u0430\u043d\u043d\u044b\u0439 \u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u0438 \u043a\u0430\u0439\u0444\u0443\u0439\u0442\u0435. AST &#8212; \u044d\u0442\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u043e \u043a\u043e\u0434 \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0443\u0437\u043b\u0430 AST:<\/p>\n<pre><code class=\"python\">class Node:   def __init__(self, name, op1, op2=None, op3=None):     self.name = name     self.op1 = op1     self.op2 = op2     self.op3 = op3    def __repr__(self):     return f'Node(\"{self.name}\"\\n {self.op1}\\n {self.op2}\\n {self.op3})'<\/code><\/pre>\n<p>\u041f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 op3 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043a\u0430\u043a else.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0432\u0430\u043c \u043a\u043e\u0434 \u043f\u0430\u0440\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"python\">class Parser:     def __init__(self, lexer):         self.pos = 0         self.lexer = lexer      #\u0442\u0435\u0440\u043c     def term(self, value):         if value[0] == 'id':             return 'ID'         elif value[0] == 'num':             return 'INT'      #\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     def parse_expr(self, token):         try:             left = token[0]             right = token[2]             op = token[1]              result = Node(op, Node(self.term(left), left[1]), Node(self.term(right), right[1]))             return result         except:             try:                 return Node(self.term(left), left[1])             except:                 raise SyntaxError('Invalid expression')      #\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0441\u043a\u043e\u0431\u043a\u0430\u0445     def paren_expr(self, expr):         d = expr[expr.index('(') + 1:expr.index(')')]         return self.parse_expr(self.lexer.lex_expr(d))      #\u043f\u0430\u0440\u0441\u0438\u043d\u0433     def parse(self, program):         try:             self.prog = program.split('; ')         except:             self.prog = program         astpos = 0         ast = []         while self.pos &lt; len(self.prog):             if self.prog[self.pos] == '':                 self.pos += 1                 continue             d = self.prog[len(self.prog) - 1]             r = len(d) - 1             if d[r] == ';':                 raise SyntaxError('The \";\" sign is not needed at the end')             self.lexer.next_token(self.prog[self.pos])             token = self.lexer.sum             if token[0] == 'assign':                 ast.append(Node('ASSIGN', token[1], op2=self.parse_expr(self.lexer.lex_expr(token[2]))))             elif token[0] == 'if':                 d = Lexer()                 r = Parser(d)                 ast.append(Node('IF', self.paren_expr(token[1]), op2=r.parse(token[2])[0]))             elif token[0] == 'while':                 d = Lexer()                 r = Parser(d)                 ast.append(Node('WHILE', self.paren_expr(token[1]), op2=r.parse(token[2])[0]))             elif token[0] == 'else':                 d = Lexer()                 r = Parser(d)                 if ast[astpos - 1].name == 'IF':                     ast[astpos - 1].name = 'ELSE'                     ast[astpos - 1].op3 = r.parse(token[1])[0]                 else:                     raise SyntaxError('Invalid \"else\" statement')             elif token[0] == 'exit':                 ast.append(Node('EXIT', None))             elif token[0] == 'pass':                 ast.append(Node('PASS', None))             self.pos += 1             astpos += 1         self.pos = 0         return ast<\/code><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 term \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 &#8216;ID&#8217; \u0435\u0441\u043b\u0438 \u043e\u043d \u0443\u0432\u0438\u0434\u0435\u043b \u0442\u043e \u0447\u0442\u043e \u043b\u0435\u043a\u0441\u0435\u0440 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043b \u0438\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 &#8216;INT&#8217; \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e.<\/p>\n<p>parse_expr &#8212; \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u0437\u0435\u043b AST \u0433\u0434\u0435 \u0438\u043c\u044f \u044d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0430 op1 \u044d\u0442\u043e term \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0430 op2 \u044d\u0442\u043e term \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. \u0415\u0441\u043b\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0430: \u0432\u0435\u0440\u043d\u0451\u0442 term \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430<\/p>\n<p>paren_expr &#8212; \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 parse_expr<\/p>\n<p>parse &#8212; \u0441\u0430\u043c \u043f\u0430\u0440\u0441\u0435\u0440, \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0432\u0441\u0435 \u0447\u0430\u0441\u0442\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b \u0438 \u043f\u0430\u0440\u0441\u0438\u0442 \u0438\u0445. \u0410 \u0442\u043e\u0447\u043d\u0435\u0435 \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441 \u0446\u0438\u043a\u043b\u043e\u043c while (a = 5; while (a &lt; 10) a = a + 1) \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u0432 \u043d\u0435\u0439 \u043d\u0435 &#171;;&#187; \u0430 &#171;;&#187; \u0441 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u043c. \u0418 \u043d\u0430\u0448\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code class=\"python\">['a = 5', 'while (a &lt; 10) a = a + 1']<\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u0437\u043d\u0430\u0435\u0442 \u0447\u0442\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0435, \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u0435 \u043d\u0435 &#171;;&#187; \u0442\u043e \u043e\u043d \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0447\u0430\u0441\u0442\u0438. \u0418\u043d\u0430\u0447\u0435: \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043f\u043e \u0442\u0438\u043f\u0443 \u044d\u0442\u043e\u0433\u043e: &#171;\u0437\u0430\u0447\u0435\u043c \u0442\u0435\u0431\u0435 &#171;;&#187; \u0432 \u043a\u043e\u043d\u0446\u0435?&#187;.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u043e \u044d\u0442\u0438\u043c \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u043e\u043d \u043d\u0430\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0443\u0437\u0435\u043b. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e &#171;else&#187; \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u044f\u0437\u0430\u043d \u043d\u0430\u0439\u0442\u0438 if \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u043c \u0443\u0437\u043b\u0435 (\u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f astpos). \u041f\u043e\u0442\u043e\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0441 AST.<\/p>\n<h2>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/h2>\n<p>\u042d\u0442\u0430 \u0447\u0430\u0441\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u0430\u044f \u0432\u0435\u0434\u044c \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440. \u0412\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<pre><code class=\"fsharp\">FETCH \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f - \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0435\u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 PUSH \u0447\u0438\u0441\u043b\u043e - \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u043d\u0430 \u0441\u0442\u0435\u043a \u0447\u0438\u0441\u043b\u043e POP - \u044f \u043d\u0435 \u043f\u043e\u043c\u043d\u044e \u0437\u0430\u0447\u0435\u043c \u044d\u0442\u043e \u0432\u0435\u0434\u044c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043c ADD, SUB, MUL,<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-456276","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/456276","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=456276"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/456276\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=456276"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=456276"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=456276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}