{"id":407781,"date":"2024-06-29T19:45:31","date_gmt":"2024-06-29T19:45:31","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=407781"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=407781","title":{"rendered":"<span>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0438\u0442\u043e\u0433)<\/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<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/c8d\/bef\/344\/c8dbef344a9b0a2a0820d65577e4d2b5.jpg\" width=\"1024\" height=\"768\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c8d\/bef\/344\/c8dbef344a9b0a2a0820d65577e4d2b5.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043e\u043a\u043e\u043b\u043e \u043c\u0435\u0441\u044f\u0446\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 (\u0432\u0435\u0447\u0435\u0440\u0430\u043c\u0438), \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0442\u0435\u043c\u0430\u043c\u0438 \u043a\u0430\u043a <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0\" rel=\"noopener noreferrer nofollow\">BNF (Backus Naur Form)<\/a>,  <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B5_%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\">Abstract Syntax Tree (AST)<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Symbol_table\" rel=\"noopener noreferrer nofollow\">Symbol Table<\/a>, \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 (front-end, back-end), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/560356\/\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b CVM<\/a>. \u0420\u0430\u043d\u0435\u0435 \u0441 \u044d\u0442\u0438\u043c\u0438 \u0442\u0435\u043c\u0430\u043c\u0438 \u0431\u044b\u043b \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c, \u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0442\u043e\u0440\u0430\u043c \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u043b\u0441\u044f. \u0425\u043e\u0442\u044c \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0442\u0435\u043c \u043c\u043d\u043e\u0433\u043e, \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u043e. \u041d\u043e \u043e\u0431\u043e \u0432\u0441\u0451\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0447\u0438\u0442\u0430\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439, \u0432\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0438:<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/560356\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0447\u0430\u0441\u0442\u044c I)<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/560986\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0447\u0430\u0441\u0442\u044c II)<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/563196\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0447\u0430\u0441\u0442\u044c III)<\/a><\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/11b\/fd4\/9ac\/11bfd49ac52b4d391e07fb3275c2752b.png\" width=\"962\" height=\"716\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/11b\/fd4\/9ac\/11bfd49ac52b4d391e07fb3275c2752b.png\"\/><figcaption><\/figcaption><\/figure>\n<h2>1. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0421\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430<\/h2>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043a\u0430\u043a \u043e\u0442\u043c\u0435\u0442\u0438\u043b\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0442\u043e\u0440\u044b, \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u0432\u044b\u043f\u0438\u0441\u0430\u0432 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 (BNF\/EBNF) &#8212; \u043f\u0440\u044f\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u043b\u043e\u0445\u0430\u044f \u0438\u0434\u0435\u044f. \u0422\u0443\u043f\u0438\u043a \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d. \u041f\u043e\u0442\u043e\u043c\u0443 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043b \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0421\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0412\u043a\u0440\u0430\u0442\u0446\u0435: \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0443\u043c\u0435\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043e\u0434\u0438\u043d \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; int, \u0431\u0435\u0437 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0441\u0441\u044b\u043b\u043e\u043a (\u0441\u0442\u0440\u043e\u043a \u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e), \u043d\u043e \u0443\u043c\u0435\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e. \u0422\u0430\u043a\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430\u0445 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. \u0418\u0442\u0430\u043a, \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u044f\u0437\u044b\u043a\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f (EBNF):<\/p>\n<pre><code>&lt;module>      ::= {&lt;function>}* &lt;type>        ::= 'int' &lt;function>    ::= &lt;type> &lt;identifier> '(' &lt;argument> {, &lt;argument>}* ')' &lt;block> &lt;argument>    ::= &lt;type> &lt;identifier> &lt;statement>   ::= &lt;block> | &lt;declaration> | &lt;assign> | &lt;if-else> | &lt;while> | &lt;jump> | &lt;call> &lt;declaration> ::= &lt;type> &lt;identifier> {','&lt;identifier>}* ';' &lt;block>       ::= '{' {&lt;statement>}* '}' &lt;call>        ::= &lt;identifier> '(' {&lt;expression>} {, expression}* ')' &lt;if-else>     ::= 'if' '(' &lt;condition> ')' &lt;statement> { 'else' &lt;statement> } &lt;while>       ::= 'while' '(' &lt;condition> ')' &lt;statement> &lt;jump>        ::= 'return' &lt;expression> ';' | 'break' ';' &lt;assign>      ::= &lt;identifier> = &lt;expression> ';' &lt;logical>     ::= &lt;comparison> {( &amp;&amp; | '||') &lt;comparison>} &lt;comparison>  ::= &lt;expression> {( == | != | > | >= | &lt; | &lt;= ) &lt;expression>} &lt;expression>  ::= &lt;term> {(+|-) &lt;term>} &lt;term>        ::= &lt;bitwise> {(*|\/) &lt;bitwise>} &lt;bitwise>     ::= &lt;factor> {( &amp; | '|' | ^ | &lt;&lt; | >> ) &lt;factor>} &lt;factor>      ::= ({~|!|-|+} &lt;number>) | &lt;identifer> | &lt;call><\/code><\/pre>\n<p>\u041f\u043e \u0445\u043e\u0434\u0443 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u0430, \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043d\u043e\u0442\u0430\u0446\u0438\u044f (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u043d\u0435 \u0437\u043d\u0430\u044e):<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/185\/3aa\/7f7\/1853aa7f7212e97b22a135f2e82e8527.png\" alt=\"\" title=\"\" width=\"881\" height=\"491\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/185\/3aa\/7f7\/1853aa7f7212e97b22a135f2e82e8527.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u043c (tokens), \u043e \u0447\u0435\u043c \u0431\u044b\u043b\u043e <a href=\"https:\/\/habr.com\/ru\/post\/560986\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 II (\u0432\u043e\u0442 \u0442\u0443\u0442)<\/a>. \u0417\u0430\u0442\u0435\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043b\u0435\u043a\u0441\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (AST) \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430.<\/p>\n<h2>2. \u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (AST)<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e <strong>Abstract Syntax Tree (AST)<\/strong> &#8212; \u044d\u0442\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <em>\u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438<\/em>, \u0430 \u043b\u0438\u0441\u0442\u044c\u044f \u2014 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 <em>\u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430\u043c\u0438<\/em>. \u042d\u0442\u043e \u0442\u043e, \u0432\u043e \u0447\u0442\u043e \u043d\u0430\u0434\u043e &#171;\u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438&#187; \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430, Abstract Syntax Tree \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u0445\u0435\u043c\u0435:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c6a\/1a8\/da2\/c6a1a8da2f5eaa978ffc5b49d10f3cc5.png\" width=\"693\" height=\"504\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c6a\/1a8\/da2\/c6a1a8da2f5eaa978ffc5b49d10f3cc5.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u043c\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0441\u044f \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b \u0431\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0443\u0437\u0435\u043b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430, \u0441 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f \u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0442\u0438\u043f\u043e\u043c \u0443\u0437\u043b\u0430 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438:<\/p>\n<pre><code class=\"cpp\">\/\/------------------------------------------------------------------------ \/\/ Abstract Syntax Tree Node \/\/------------------------------------------------------------------------  enum class TreeNodeType {     UNKNOWN = 0, MODULE, CONSTANT, TYPE, SYMBOL, UNARY_OP, BINARY_OP, CALL,     FUNCTION, BLOCK, ASSIGNMENT, IF_ELSE, WHILE, RETURN, BREAK };  constexpr char* const TREE_NODE_TYPE_MNEMONIC[] = {     \"UNKNOWN\", \"MODULE\", \"CONSTANT\", \"TYPE\", \"SYMBOL\", \"UNARY_OP\", \"BINARY_OP\", \"CALL\",     \"FUNCTION\", \"BLOCK\", \"ASSIGNMENT\", \"IF_ELSE\", \"WHILE\", \"RETURN\", \"BREAK\" };  class TreeNode {     public:         TreeNode(Token token, TreeNodeType type, SymbolTable* scope);         ~TreeNode();         TreeNode* addChild(TreeNode* node);         bool removeChild(TreeNode* node);         void removeAll();         TreeNodeType getType();         Token getToken();         TreeNode* getParent();         TreeNode* getChild(size_t index);         size_t getChildCount();         size_t getDepth();         void print();         inline void setSymbolTable(SymbolTable* scope) { symbols = scope; }         inline SymbolTable* getSymbolTable() { return symbols; }     private:         Token token;         SymbolTable* symbols = NULL;         vector&lt;TreeNode*> childs;         TreeNode* parent;         TreeNodeType type;         void print(int tab); };<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434: <a href=\"https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/TreeNode.cpp\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/TreeNode.cpp<\/a><\/p>\n<h2>3. \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (Symbol Tree)<\/h2>\n<p>\u041d\u0430\u0440\u044f\u0434\u0443, \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u0422\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. <strong>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (Symbol Table)<\/strong> &#8212; \u044d\u0442\u043e \u0434\u0440\u0435\u0432\u043e\u0432\u0438\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u0438\u0445 \u0442\u0438\u043f\u044b, \u0430\u0434\u0440\u0435\u0441\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u044f\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c, \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u041b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u043e\u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435. <\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cpp\">void pro_one() {    int one_1;    int one_2;    {                 \\       int one_3;      |_  inner scope 1        int one_4;      |     }                 \/    int one_5;     {                 \\          int one_6;      |_  inner scope 2       int one_7;      |    }                 \/ }  void pro_two() {    int two_1;    int two_2;    {                 \\       int two_3;      |_  inner scope 3       int two_4;      |    }                 \/    int two_5; }  <\/code><\/pre>\n<p>\u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u043e\u0434\u0443 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0422\u0430\u0431\u043b\u0438\u0446 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0433\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w780q1\/getpro\/habr\/upload_files\/5f9\/3d6\/2aa\/5f93d62aa876c21be57c818a53cdb73f.jpg\" width=\"884\" height=\"479\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/5f9\/3d6\/2aa\/5f93d62aa876c21be57c818a53cdb73f.jpg\" data-blurred=\"true\"\/><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u0442\u0430\u0431\u043b\u0438\u0446, \u043e\u043f\u0438\u0448\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 SymbolTable \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0442\u0438\u043f, \u0438\u0441\u043a\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043a\u0430\u043a \u0432 \u0441\u0430\u043c\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0442\u0430\u043a \u0438 \u0432 \u0435\u0451 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0443\u0437\u043b\u0430\u0445 \u0432\u043f\u043b\u043e\u0442\u044c \u0434\u043e \u043a\u043e\u0440\u043d\u044f. \u0412\u043e\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cpp\">\/\/------------------------------------------------------------------------ \/\/ Symbol table \/\/------------------------------------------------------------------------ enum class SymbolType {     UNKNOWN, CONSTANT, FUNCTION, ARGUMENT, VARIABLE };  constexpr char* const  SYMBOL_TYPE_MNEMONIC[] = {     \"UNKNOWN\", \"CONSTANT\", \"FUNCTION\", \"ARGUMENT\", \"VARIABLE\" };  class Symbol {     public:         string name = \"\";         SymbolType type = SymbolType::UNKNOWN;         WORD localIndex = -1;         WORD address = -1;         WORD argCount = 0; };  class SymbolTable {     public:         SymbolTable(string name = \"GLOBAL\");         ~SymbolTable();         bool addChild(SymbolTable* child);         void removeChild(SymbolTable* child);         SymbolTable* getChildAt(size_t index);         size_t getChildCount();         inline const char* getName() { return name.c_str(); };         void clearSymbols();         size_t getSymbolsCount();         bool addSymbol(Token&amp; token, SymbolType type);         Symbol* lookupSymbol(Token&amp; token);         Symbol* lookupSymbol(char* name, SymbolType type);         Symbol* getSymbolAt(size_t index);         void printSymbols();     private:         string name;         vector&lt;Symbol> symbols;         vector&lt;SymbolTable*> childs;         SymbolTable* parent;         int getNextIndex(SymbolType type);         void printRecursive(int depth); };<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434: <a href=\"https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/SymbolTable.cpp\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/SymbolTable.cpp<\/a><\/p>\n<h2>4. Parser &#8212; \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c AST \u0438 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0438\u043c\u0435\u044f \u043d\u0430 \u0440\u0443\u043a\u0430\u0445 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u044f\u0437\u044b\u043a\u0430, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f <em>\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 (AST)<\/em> \u0438 <em>\u0434\u0435\u0440\u0435\u0432\u0430 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (Symbol Table)<\/em>, \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c Parser, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 <em>\u043d\u0430 \u0432\u0445\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/em>, \u0430 <em>\u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/em>. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, Lexer \u0438 Parser &#8212; \u0434\u0432\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c.<\/p>\n<pre><code class=\"cpp\">\/\/------------------------------------------------------------------------ \/\/ Syntax Parser (Abstract Syntax Tree Builder) \/\/------------------------------------------------------------------------ class SourceParser {     public:         SourceParser(const char* sourceCode);         ~SourceParser();         inline size_t getTokenCount() { return tokens.size(); }         Token&amp; getToken(size_t index) { return tokens[index]; }         SymbolTable&amp; getSymbolTable() { return rootSymbolTable; }         TreeNode* getSyntaxTree() { return root; }     private:         vector&lt;Token> tokens;         TreeNode* root = NULL;         SymbolTable rootSymbolTable;         size_t currentToken = 0;         int blockCounter = 0;          void parseToTokens(const char* sourceCode);         bool isBlank(char value) { return strchr(BLANKS, value) != NULL; };         bool isDelimeter(char value) { return strchr(DELIMETERS, value) != NULL; };         bool pushToken(char* text, int length, int row, int col);         TokenType getTokenType(char* text, int length);         TokenType validateNumber(char* text, int length);         TokenType validateIdentifier(char* text, int length);         TokenType validateString(char* text, int length);          void buildSyntaxTree();         TreeNode* parseModule(SymbolTable* scope);         TreeNode* parseDeclaration(SymbolTable* scope);         TreeNode* parseFunction(SymbolTable* scope);         TreeNode* parseArgument(SymbolTable* scope);         TreeNode* parseBlock(SymbolTable* scope, bool isFunction, bool whileBlock);         TreeNode* parseStatement(SymbolTable* scope, bool whileBlock);         TreeNode* parseCall(SymbolTable* scope);         TreeNode* parseIfElse(SymbolTable* scope, bool whileBlock);         TreeNode* parseWhile(SymbolTable* scope);         TreeNode* parseAssignment(SymbolTable* scope);         TreeNode* parseLogical(SymbolTable* scope);         TreeNode* parseComparison(SymbolTable* scope);         TreeNode* parseExpression(SymbolTable* scope);         TreeNode* parseTerm(SymbolTable* scope);         TreeNode* parseBitwise(SymbolTable* scope);         TreeNode* parseFactor(SymbolTable* scope);          inline bool next() { currentToken++; return currentToken &lt; getTokenCount(); }         inline Token getToken() { return getToken(currentToken); }         inline Token getNextToken() { return getToken(currentToken + 1); }         inline bool isTokenType(TokenType type) { return getToken().type == type; }          inline bool isComparison(TokenType type) { return type >= TokenType::EQUAL &amp;&amp; type &lt;= TokenType::LS_EQUAL; }         inline bool isLogical(TokenType type) { return type >= TokenType::LOGIC_AND &amp;&amp; type &lt;= TokenType::LOGIC_OR; }         inline bool isBitwise(TokenType type) { return type >= TokenType::AND &amp;&amp; type &lt;= TokenType::SHR; }         inline bool isDataType(TokenType type) { return type == TokenType::INT; }         inline void checkToken(TokenType type, const char* msg) { if (!isTokenType(type)) raiseError(msg); }         inline void raiseError(Token&amp; tkn, const char* msg) { throw ParserException{ tkn, msg }; }         inline void raiseError(const char* msg) { throw ParserException{ getToken(), msg }; } };<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434: <a href=\"https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/SourceParser.cpp\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/SourceParser.cpp<\/a><\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043a\u0443\u043b\u044c\u043c\u0438\u043d\u0430\u0446\u0438\u0438 &#8212; \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<h2>4. \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0438\u043c\u0435\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 AST \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0447\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434, \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0431\u0445\u043e\u0434\u044f AST. \u041f\u043e \u0445\u043e\u0434\u0443 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u043c \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0430\u0445 \u043c\u043e\u0433\u043b\u0438 \u0438\u0445 \u043d\u0430\u0439\u0442\u0438 \u0438 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cpp\">class CodeGenerator {     public:         CodeGenerator();         ~CodeGenerator();         bool generateCode(ExecutableImage* img, TreeNode* rootNode);         void emitModule(ExecutableImage* img, TreeNode* rootNode);         void emitFunction(ExecutableImage* img, TreeNode* node);         void emitStatement(ExecutableImage* img, TreeNode* body);         void emitBlock(ExecutableImage* img, TreeNode* body);         void emitDeclaration(ExecutableImage* img, TreeNode* node);         void emitCall(ExecutableImage* img, TreeNode* node);         void emitIfElse(ExecutableImage* img, TreeNode* node);         void emitWhile(ExecutableImage* img, TreeNode* node);         void emitReturn(ExecutableImage* img, TreeNode* node);         void emitBreak(ExecutableImage* img, TreeNode* node);         void emitAssignment(ExecutableImage* img, TreeNode* assignment);         void emitExpression(ExecutableImage* img, TreeNode* expression);         void emitSymbol(ExecutableImage* img, TreeNode* node);         WORD emitOpcode(ExecutableImage* img, Token&amp; token);     private:         inline void raiseError(char* msg) { throw CodeGeneratorException{msg }; } };<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0442\u0440\u044b\u0432\u043a\u043e\u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u043e\u0432 \u043f\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0431\u043b\u043e\u043a\u0430, IF-ELSE \u0438 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432:<\/p>\n<pre><code class=\"cpp\"> void CodeGenerator::emitBlock(ExecutableImage* img, TreeNode* body) {     size_t count = body->getChildCount();     TreeNode* statement;     for (int j = 0; j &lt; count; j++) {         statement = body->getChild(j);         emitStatement(img, statement);     } }  void CodeGenerator::emitStatement(ExecutableImage* img, TreeNode* statement) {     switch (statement->getType()) {     case TreeNodeType::TYPE:       break; \/\/ skip because already emitted     case TreeNodeType::ASSIGNMENT: emitAssignment(img, statement); break;     case TreeNodeType::IF_ELSE:    emitIfElse(img, statement); break;     case TreeNodeType::WHILE:      emitWhile(img, statement); break;     case TreeNodeType::CALL:       emitCall(img, statement); break;     case TreeNodeType::BLOCK:      emitBlock(img, statement); break;     case TreeNodeType::RETURN:     emitReturn(img, statement); break;     case TreeNodeType::BREAK:      emitBreak(img, statement); break;     default: raiseError(\"Unknown structure in syntax tree.\");     } }   void CodeGenerator::emitIfElse(ExecutableImage* img, TreeNode* node) {     TreeNode* condition = node->getChild(0);     TreeNode* thenBlock = node->getChild(1);     TreeNode* elseBlock = node->getChild(2);     ExecutableImage conditionCode, thenCode, elseCode;     WORD offset;          emitExpression(&amp;conditionCode, condition);          \/\/ generate condition code     emitStatement(&amp;thenCode, thenBlock);                \/\/ generate then block code     if (elseBlock) {                                    \/\/ if there is else block         emitStatement(&amp;elseCode, elseBlock);            \/\/ generate else block code     }      \/\/ IF: emit conditional jump code     offset = thenCode.getSize() + 1;                    \/\/ calculate next address after then block      if (elseBlock) offset += JUMP_OFFSET;               \/\/ if there is an else block add JMP offset     img->emit(conditionCode);     img->emit(OP_IFZERO, offset);                            \/\/ THEN: emit then block code     img->emit(thenCode);     if (elseBlock) {                                    \/\/ if there is an else block         offset = elseCode.getSize() + 1;                \/\/ calculate next address after else block         img->emit(OP_JMP, offset);                      \/\/ emit unconditional jump over else block     }      \/\/ ELSE: emit else block code     if (elseBlock) img->emit(elseCode);  }  ...  WORD CodeGenerator::emitOpcode(ExecutableImage* img, Token&amp; token) {     switch (token.type) {     case TokenType::PLUS:      img->emit(OP_ADD);     break;     case TokenType::MINUS:     img->emit(OP_SUB);     break;     case TokenType::MULTIPLY:  img->emit(OP_MUL);     break;     case TokenType::DIVIDE:    img->emit(OP_DIV);     break;     case TokenType::EQUAL:     img->emit(OP_EQUAL);   break;     case TokenType::NOT_EQUAL: img->emit(OP_NEQUAL);  break;     case TokenType::GREATER:   img->emit(OP_GREATER); break;     case TokenType::GR_EQUAL:  img->emit(OP_GREQUAL); break;     case TokenType::LESS:      img->emit(OP_LESS);    break;     case TokenType::LS_EQUAL:  img->emit(OP_LSEQUAL); break;     case TokenType::LOGIC_AND: img->emit(OP_LAND);    break;     case TokenType::LOGIC_OR:  img->emit(OP_LOR);     break;     case TokenType::LOGIC_NOT: img->emit(OP_LNOT);    break;     case TokenType::NOT:       img->emit(OP_NOT);     break;     case TokenType::AND:       img->emit(OP_AND);     break;     case TokenType::OR:        img->emit(OP_OR);      break;     case TokenType::XOR:       img->emit(OP_XOR);     break;     case TokenType::SHL:       img->emit(OP_SHL);     break;     case TokenType::SHR:       img->emit(OP_SHR);     break;     default:         cout &lt;&lt; \"UNKNOWN OPERATION: \";         cout.write(token.text, token.length);         cout &lt;&lt; endl;         break;     }     return 0; }<\/code><\/pre>\n<p>\u041d\u0430\u0440\u044f\u0434\u0443 \u0441 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u0434\u043b\u044f \u0432\u0432\u043e\u0434\u0430 \u0438 \u0432\u044b\u0432\u043e\u0434\u0430 \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438, \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 &#171;\u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435&#187; \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <strong>iput<\/strong> (integer put) \u0438 <strong>iget<\/strong> (integer get). \u0410 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043e\u043d\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0438 \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b <strong>syscall<\/strong>.<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434: <a href=\"https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/CodeGenerator.cpp\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/CodeGenerator.cpp<\/a><\/p>\n<h2>5. \u0418\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430: \u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0430\u043b<\/h2>\n<p>\u0412\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0444\u0430\u043a\u0442\u043e\u0440\u0438\u0430\u043b\u0430 \u043d\u0430 C \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u043c \u044f\u0437\u044b\u043a\u0435 (\u0441\u043a\u0440\u0438\u043f\u0442 factorial.cvm). \u0412 \u043a\u043e\u0434\u0435 \u0435\u0441\u0442\u044c \u043b\u0438\u0448\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0445 \u0440\u0430\u0431\u043e\u0442\u044b (if-else, break):<\/p>\n<pre><code class=\"cpp\">int fact(int n) {    int x;    if (n) {       x = n * fact(n-1);       return x;    } else {       x = 10;       return 1;    }    return 0; }   int main() {     int n, i;     i = 1;     while (i&lt;=100) {         if (i&lt;12) {             n = fact(i);             iput(n);             i = i + 1;         } else break;     } return n; } <\/code><\/pre>\n<p>\u0412 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0440\u0435\u0432\u043e:<\/p>\n<pre><code>----------------------------------------------------- Parsed abstract syntax tree ----------------------------------------------------- ''(MODULE) GLOBAL |-'fact'(FUNCTION) GLOBAL | |-'int'(TYPE) GLOBAL | |-''(SYMBOL) fact | | |-'int'(TYPE) fact | | | |-'n'(SYMBOL) fact | |-'BLOCK'(BLOCK) fact | | |-'int'(TYPE) fact | | | |-'x'(SYMBOL) fact | | |-'if'(IF_ELSE) fact | | | |-'n'(SYMBOL) fact | | | |-'BLOCK'(BLOCK) block0 | | | | |-'='(ASSIGNMENT) block0 | | | | | |-'x'(SYMBOL) block0 | | | | | |-'*'(BINARY_OP) block0 | | | | | | |-'n'(SYMBOL) block0 | | | | | | |-'fact'(CALL) block0 | | | | | | | |-'-'(BINARY_OP) block0 | | | | | | | | |-'n'(SYMBOL) block0 | | | | | | | | |-'1'(CONSTANT) block0 | | | | |-'return'(RETURN) block0 | | | | | |-'x'(SYMBOL) block0 | | | |-'BLOCK'(BLOCK) block1 | | | | |-'='(ASSIGNMENT) block1 | | | | | |-'x'(SYMBOL) block1 | | | | | |-'10'(CONSTANT) block1 | | | | |-'return'(RETURN) block1 | | | | | |-'1'(CONSTANT) block1 | | |-'return'(RETURN) fact | | | |-'0'(CONSTANT) fact |-'main'(FUNCTION) GLOBAL | |-'int'(TYPE) GLOBAL | |-''(SYMBOL) main | |-'BLOCK'(BLOCK) main | | |-'int'(TYPE) main | | | |-'n'(SYMBOL) main | | | |-'i'(SYMBOL) main | | |-'='(ASSIGNMENT) main | | | |-'i'(SYMBOL) main | | | |-'1'(CONSTANT) main | | |-'while'(WHILE) main | | | |-'&lt;='(BINARY_OP) main | | | | |-'i'(SYMBOL) main | | | | |-'100'(CONSTANT) main | | | |-'BLOCK'(BLOCK) block2 | | | | |-'if'(IF_ELSE) block2 | | | | | |-'&lt;'(BINARY_OP) block2 | | | | | | |-'i'(SYMBOL) block2 | | | | | | |-'12'(CONSTANT) block2 | | | | | |-'BLOCK'(BLOCK) block3 | | | | | | |-'='(ASSIGNMENT) block3 | | | | | | | |-'n'(SYMBOL) block3 | | | | | | | |-'fact'(CALL) block3 | | | | | | | | |-'i'(SYMBOL) block3 | | | | | | |-'iput'(CALL) block3 | | | | | | | |-'n'(SYMBOL) block3 | | | | | | |-'='(ASSIGNMENT) block3 | | | | | | | |-'i'(SYMBOL) block3 | | | | | | | |-'+'(BINARY_OP) block3 | | | | | | | | |-'i'(SYMBOL) block3 | | | | | | | | |-'1'(CONSTANT) block3 | | | | | |-'break'(BREAK) block2 | | |-'return'(RETURN) main | | | |-'n'(SYMBOL) main<\/code><\/pre>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432:<\/p>\n<pre><code>----------------------------------------------------- Symbol table ----------------------------------------------------- GLOBAL: iput    FUNCTION at [0] args=1 iget    FUNCTION at [0] args=1 fact    FUNCTION at [4] args=1 main    FUNCTION at [38] args=0         fact:         n       ARGUMENT #0         x       VARIABLE #0                 block0:                 block1:         main:         n       VARIABLE #0         i       VARIABLE #1                 block2:                         block3:<\/code><\/pre>\n<p>\u0418 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b:<\/p>\n<pre><code>----------------------------------------------------- Virtual machine executable image disassembly ----------------------------------------------------- [     0]    call    [38], 0 [     3]    ---- halt ---- [     4]    iconst  0 [     6]    iarg    #0 [     8]    ifzero  [+19] [    10]    iarg    #0 [    12]    iarg    #0 [    14]    iconst  1 [    16]    isub [    17]    call    [4], 1 [    20]    imul [    21]    istore  #0 [    23]    iload   #0 [    25]    ret [    26]    jmp     [+8] [    28]    iconst  10 [    30]    istore  #0 [    32]    iconst  1 [    34]    ret [    35]    iconst  0 [    37]    ret [    38]    iconst  0 [    40]    iconst  0 [    42]    iconst  1 [    44]    istore  #1 [    46]    iload   #1 [    48]    iconst  100 [    50]    lsequal [    51]    ifzero  [+32] [    53]    iload   #1 [    55]    iconst  12 [    57]    less [    58]    ifzero  [+21] [    60]    iload   #1 [    62]    call    [4], 1 [    65]    istore  #0 [    67]    iload   #0 [    69]    syscall 0x21 [    71]    iload   #1 [    73]    iconst  1 [    75]    iadd [    76]    istore  #1 [    78]    jmp     [+3] [    80]    jmp     [+3] [    82]    jmp     [-37] [    84]    iload   #0 [    86]    ret<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0432\u044b\u0434\u0430\u0451\u0442:<\/p>\n<pre><code>----------------------------------------------------- Virtual machine runtime ----------------------------------------------------- 1 2 6 24 120 720 5040 40320 362880 3628800 39916800 VM: IP=4 FP=16383 LP=16382 SP=16382 STACK=[39916800] -> TOP Execution time: 0.0037108s<\/code><\/pre>\n<h2>6. \u0418\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430: \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0447\u0438\u0441\u043b\u0430<\/h2>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0447\u0438\u0441\u0435\u043b (primenumber.cvm):<\/p>\n<pre><code class=\"cpp\">int isPrime(int n) {    int i,a,b;    i = 2;    while (i &lt; n) {       a = n \/ i;       b = a * i;       if (b == n) return 0;       i = i + 1;    }    return 1; }   int main() {      int j;     j = 2;     while (j &lt; 100) {        if (isPrime(j)) iput(j);        j = j + 1;     }      return 0; }<\/code><\/pre>\n<p>\u0441\u0442\u0440\u043e\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0440\u0435\u0432\u043e:<\/p>\n<pre><code>----------------------------------------------------- Parsed abstract syntax tree ----------------------------------------------------- ''(MODULE) GLOBAL |-'isPrime'(FUNCTION) GLOBAL | |-'int'(TYPE) GLOBAL | |-''(SYMBOL) isPrime | | |-'int'(TYPE) isPrime | | | |-'n'(SYMBOL) isPrime | |-'BLOCK'(BLOCK) isPrime | | |-'int'(TYPE) isPrime | | | |-'i'(SYMBOL) isPrime | | | |-'a'(SYMBOL) isPrime | | | |-'b'(SYMBOL) isPrime | | |-'='(ASSIGNMENT) isPrime | | | |-'i'(SYMBOL) isPrime | | | |-'2'(CONSTANT) isPrime | | |-'while'(WHILE) isPrime | | | |-'&lt;'(BINARY_OP) isPrime | | | | |-'i'(SYMBOL) isPrime | | | | |-'n'(SYMBOL) isPrime | | | |-'BLOCK'(BLOCK) block0 | | | | |-'='(ASSIGNMENT) block0 | | | | | |-'a'(SYMBOL) block0 | | | | | |-'\/'(BINARY_OP) block0 | | | | | | |-'n'(SYMBOL) block0 | | | | | | |-'i'(SYMBOL) block0 | | | | |-'='(ASSIGNMENT) block0 | | | | | |-'b'(SYMBOL) block0 | | | | | |-'*'(BINARY_OP) block0 | | | | | | |-'a'(SYMBOL) block0 | | | | | | |-'i'(SYMBOL) block0 | | | | |-'if'(IF_ELSE) block0 | | | | | |-'=='(BINARY_OP) block0 | | | | | | |-'b'(SYMBOL) block0 | | | | | | |-'n'(SYMBOL) block0 | | | | | |-'return'(RETURN) block0 | | | | | | |-'0'(CONSTANT) block0 | | | | |-'='(ASSIGNMENT) block0 | | | | | |-'i'(SYMBOL) block0 | | | | | |-'+'(BINARY_OP) block0 | | | | | | |-'i'(SYMBOL) block0 | | | | | | |-'1'(CONSTANT) block0 | | |-'return'(RETURN) isPrime | | | |-'1'(CONSTANT) isPrime |-'main'(FUNCTION) GLOBAL | |-'int'(TYPE) GLOBAL | |-''(SYMBOL) main | |-'BLOCK'(BLOCK) main | | |-'int'(TYPE) main | | | |-'j'(SYMBOL) main | | |-'='(ASSIGNMENT) main | | | |-'j'(SYMBOL) main | | | |-'2'(CONSTANT) main | | |-'while'(WHILE) main | | | |-'&lt;'(BINARY_OP) main | | | | |-'j'(SYMBOL) main | | | | |-'100'(CONSTANT) main | | | |-'BLOCK'(BLOCK) block1 | | | | |-'if'(IF_ELSE) block1 | | | | | |-'isPrime'(CALL) block1 | | | | | | |-'j'(SYMBOL) block1 | | | | | |-'iput'(CALL) block1 | | | | | | |-'j'(SYMBOL) block1 | | | | |-'='(ASSIGNMENT) block1 | | | | | |-'j'(SYMBOL) block1 | | | | | |-'+'(BINARY_OP) block1 | | | | | | |-'j'(SYMBOL) block1 | | | | | | |-'1'(CONSTANT) block1 | | |-'return'(RETURN) main | | | |-'0'(CONSTANT) main<\/code><\/pre>\n<p>\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432:<\/p>\n<pre><code>----------------------------------------------------- Symbol table ----------------------------------------------------- GLOBAL: iput    FUNCTION at [0] args=1 iget    FUNCTION at [0] args=1 isPrime FUNCTION at [4] args=1 main    FUNCTION at [57] args=0         isPrime:         n       ARGUMENT #0         i       VARIABLE #0         a       VARIABLE #1         b       VARIABLE #2                 block0:         main:         j       VARIABLE #0                 block1:<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b:<\/p>\n<pre><code>----------------------------------------------------- Virtual machine executable image disassembly ----------------------------------------------------- [     0]    call    [57], 0 [     3]    ---- halt ---- [     4]    iconst  0 [     6]    iconst  0 [     8]    iconst  0 [    10]    iconst  2 [    12]    istore  #0 [    14]    iload   #0 [    16]    iarg    #0 [    18]    less [    19]    ifzero  [+34] [    21]    iarg    #0 [    23]    iload   #0 [    25]    idiv [    26]    istore  #1 [    28]    iload   #1 [    30]    iload   #0 [    32]    imul [    33]    istore  #2 [    35]    iload   #2 [    37]    iarg    #0 [    39]    equal [    40]    ifzero  [+4] [    42]    iconst  0 [    44]    ret [    45]    iload   #0 [    47]    iconst  1 [    49]    iadd [    50]    istore  #0 [    52]    jmp     [-39] [    54]    iconst  1 [    56]    ret [    57]    iconst  0 [    59]    iconst  2 [    61]    istore  #0 [    63]    iload   #0 [    65]    iconst  100 [    67]    less [    68]    ifzero  [+21] [    70]    iload   #0 [    72]    call    [4], 1 [    75]    ifzero  [+5] [    77]    iload   #0 [    79]    syscall 0x21 [    81]    iload   #0 [    83]    iconst  1 [    85]    iadd [    86]    istore  #0 [    88]    jmp     [-26] [    90]    iconst  0 [    92]    ret<\/code><\/pre>\n<p>\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f (\u0432\u0435\u0440\u043d\u044b\u0439):<\/p>\n<pre><code>----------------------------------------------------- Virtual machine runtime ----------------------------------------------------- 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97 VM: IP=4 FP=16383 LP=16382 SP=16382 STACK=[0] -> TOP Execution time: 0.0047877s<\/code><\/pre>\n<h2>7. \u0412 \u0437\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u041f\u043e\u0434\u044b\u0442\u043e\u0436\u0438\u0432\u0430\u044f \u0441\u0435\u0440\u0438\u044e \u0441\u0442\u0430\u0442\u0435\u0439 \u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 C \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043d\u0430\u0441\u044b\u0449\u0435\u043d\u043d\u044b\u043c \u043f\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u0432, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043d\u0435\u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u043d\u044b\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0432 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u043e\u0434\u043d\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0443\u0441\u043b\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 IFZERO [\u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0430\u0434\u0440\u0435\u0441], \u0442\u0430\u043a \u043a\u0430\u043a \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b IF-ELSE, WHILE \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u0445 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442 \u0431\u0443\u043b\u0435\u0432\u0443 \u043b\u043e\u0433\u0438\u043a\u0443 \u0438 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u044b\u0436\u043a\u0438 \u043d\u0430\u0434\u043e \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043d\u0430 \u0432\u0435\u0440\u0448\u0438\u043d\u0435 \u0441\u0442\u0435\u043a\u0430 \u043b\u0435\u0436\u0438\u0442 0 (\u043d\u043e\u043b\u044c &#8212; false). \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u043e\u043a\u0430\u0437\u0430\u043b\u0438\u0441\u044c \u043d\u0435 \u043d\u0443\u0436\u043d\u044b (\u0440\u0430\u043d\u044c\u0448\u0435 \u0431\u044b\u043b\u043e \u0430\u0436 6 \u0448\u0442\u0443\u043a).<\/p>\n<p>\u0427\u0435\u0433\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u043e\u0438\u043b\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/563196\/\" rel=\"noopener noreferrer nofollow\">\u043a\u043e\u043d\u0432\u0435\u043d\u0446\u0438\u0438 \u043f\u043e \u0432\u044b\u0437\u043e\u0432\u0430\u043c: \u043a\u0430\u043a \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u0442\u043e \u043e\u0447\u0438\u0449\u0430\u0435\u0442 \u0441\u0442\u0435\u043a<\/a>. \u041a\u0430\u043a \u0430\u043b\u043b\u043e\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u0441\u0442\u0435\u043a\u0435, \u0435\u0441\u043b\u0438 \u0438\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u0431\u0440\u043e\u0441\u0430\u043d\u043e \u043f\u043e \u0442\u0435\u043b\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0418 \u043c\u043d\u043e\u0433\u043e \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 \u0437\u0430\u0434\u0430\u0447.<\/p>\n<p>\u0415\u0449\u0435 \u043e\u0434\u043d\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u043c \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 &#171;break&#187;, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 &#171;\u0432\u044b\u043f\u0440\u044b\u0433\u0438\u0432\u0430\u044e\u0449\u0438\u0439&#187; \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c\u0443 \u0430\u0434\u0440\u0435\u0441\u0443, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b JMP \u0435\u0449\u0435 \u043d\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442\u0441\u044f. \u0420\u0435\u0448\u0438\u043b \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u043f\u043e\u0434\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 &#8212; \u043f\u043e\u043c\u0435\u0447\u0430\u0435\u043c \u043c\u0435\u0441\u0442\u043e \u043f\u0440\u044b\u0436\u043a\u0430 \u043e\u0441\u043e\u0431\u044b\u043c MAGIC WORD \u0438 \u0432 \u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u043b\u043e\u043a\u0430 \u043a\u043e\u0434\u0430 WHILE \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d, \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c JMP \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0430\u0434\u0440\u0435\u0441\u043e\u043c.<\/p>\n<p>\u041e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0445\u043e\u0431\u0431\u0438-\u043f\u0440\u043e\u0435\u043a\u0442! \u0418\u0441\u043f\u044b\u0442\u044b\u0432\u0430\u044e \u0432\u043e\u043e\u0434\u0443\u0448\u0435\u0432\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0435\u0433\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u0432\u044b\u043a\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f C\/C++. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0442\u043e\u0440\u0430\u043c, \u0432\u044b \u0432\u044b\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u043c\u0435\u043d\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u043d\u0430\u043f\u0440\u0430\u0432\u0438\u043b\u0438 \u0432 \u043d\u0443\u0436\u043d\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438!<\/p>\n<p>\u0425\u043e\u0442\u044c \u0432\u0441\u044f \u044d\u0442\u0430 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0445\u043e\u0431\u0431\u0438, \u0430 \u0434\u043d\u0451\u043c \u044f \u043f\u0440\u0435\u0434\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c, \u043e\u043f\u044f\u0442\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0432\u0435\u0447\u0435\u0440\u043e\u043c \u0432\u0437\u044f\u0442\u044c\u0441\u044f \u0437\u0430 \u043d\u043e\u0432\u0443\u044e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0443\u044e \u0438 \u043d\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u043f\u043e \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u043c\u0443 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e. \u0412\u0441\u0451 \u0442\u0430\u043a\u0438 \u0432 \u0433\u043b\u0443\u0431\u0438\u043d\u0435 \u0434\u0443\u0448\u0438 \u044d\u0442\u043e \u043c\u043e\u0451&#8230;<\/p>\n<p>\u0423\u0440\u0430!<\/p>\n<p><a href=\"https:\/\/github.com\/Basheyev\/CVM\" rel=\"noopener noreferrer nofollow\">\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a><\/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\/571758\/\"> https:\/\/habr.com\/ru\/articles\/571758\/<\/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<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0414\u043b\u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043e\u043a\u043e\u043b\u043e \u043c\u0435\u0441\u044f\u0446\u0430 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 (\u0432\u0435\u0447\u0435\u0440\u0430\u043c\u0438), \u0447\u0442\u043e\u0431\u044b \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0441 \u0442\u0430\u043a\u0438\u043c\u0438 \u0442\u0435\u043c\u0430\u043c\u0438 \u043a\u0430\u043a <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0\" rel=\"noopener noreferrer nofollow\">BNF (Backus Naur Form)<\/a>,  <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B5_%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\">Abstract Syntax Tree (AST)<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Symbol_table\" rel=\"noopener noreferrer nofollow\">Symbol Table<\/a>, \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 (front-end, back-end), \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0434\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/560356\/\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b CVM<\/a>. \u0420\u0430\u043d\u0435\u0435 \u0441 \u044d\u0442\u0438\u043c\u0438 \u0442\u0435\u043c\u0430\u043c\u0438 \u0431\u044b\u043b \u043d\u0435 \u0437\u043d\u0430\u043a\u043e\u043c, \u043d\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0442\u043e\u0440\u0430\u043c \u043f\u043e\u0433\u0440\u0443\u0437\u0438\u043b\u0441\u044f. \u0425\u043e\u0442\u044c \u0437\u0430\u0442\u0440\u0430\u0433\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0442\u0435\u043c \u043c\u043d\u043e\u0433\u043e, \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043b\u0430\u043a\u043e\u043d\u0438\u0447\u043d\u043e. \u041d\u043e \u043e\u0431\u043e \u0432\u0441\u0451\u043c \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443. \u0415\u0441\u043b\u0438 \u0432\u044b \u043d\u0435 \u0447\u0438\u0442\u0430\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439, \u0432\u043e\u0442 \u0441\u0441\u044b\u043b\u043a\u0438:<\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/560356\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0447\u0430\u0441\u0442\u044c I)<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/560986\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0447\u0430\u0441\u0442\u044c II)<\/a><\/p>\n<p><a href=\"https:\/\/habr.com\/ru\/post\/563196\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u0442\u0435\u043a\u043e\u0432\u043e\u0439 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u0430\u0448\u0438\u043d\u044b \u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u0434 \u043d\u0435\u0451 (\u0447\u0430\u0441\u0442\u044c III)<\/a><\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<h2>1. \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0421\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430<\/h2>\n<p>\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043a\u0430\u043a \u043e\u0442\u043c\u0435\u0442\u0438\u043b\u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0442\u043e\u0440\u044b, \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043d\u0435 \u0432\u044b\u043f\u0438\u0441\u0430\u0432 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 (BNF\/EBNF) &#8212; \u043f\u0440\u044f\u043c \u043e\u0447\u0435\u043d\u044c \u043f\u043b\u043e\u0445\u0430\u044f \u0438\u0434\u0435\u044f. \u0422\u0443\u043f\u0438\u043a \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d. \u041f\u043e\u0442\u043e\u043c\u0443 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0438\u0441\u0430\u043b \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0441\u0432\u043e\u0435\u0433\u043e \u0443\u043f\u0440\u043e\u0449\u0435\u043d\u043d\u043e\u0433\u043e \u0421\u0438 \u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0412\u043a\u0440\u0430\u0442\u0446\u0435: \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0443\u043c\u0435\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043e\u0434\u0438\u043d \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; int, \u0431\u0435\u0437 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432, \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0441\u0441\u044b\u043b\u043e\u043a (\u0441\u0442\u0440\u043e\u043a \u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e), \u043d\u043e \u0443\u043c\u0435\u0442\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e. \u0422\u0430\u043a\u0438\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430\u0445 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435 \u0435\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u0431\u043e\u043b\u0435\u0435 \u043c\u0435\u043d\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u043e. \u0418\u0442\u0430\u043a, \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u044f\u0437\u044b\u043a\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f (EBNF):<\/p>\n<pre><code>&lt;module>      ::= {&lt;function>}* &lt;type>        ::= 'int' &lt;function>    ::= &lt;type> &lt;identifier> '(' &lt;argument> {, &lt;argument>}* ')' &lt;block> &lt;argument>    ::= &lt;type> &lt;identifier> &lt;statement>   ::= &lt;block> | &lt;declaration> | &lt;assign> | &lt;if-else> | &lt;while> | &lt;jump> | &lt;call> &lt;declaration> ::= &lt;type> &lt;identifier> {','&lt;identifier>}* ';' &lt;block>       ::= '{' {&lt;statement>}* '}' &lt;call>        ::= &lt;identifier> '(' {&lt;expression>} {, expression}* ')' &lt;if-else>     ::= 'if' '(' &lt;condition> ')' &lt;statement> { 'else' &lt;statement> } &lt;while>       ::= 'while' '(' &lt;condition> ')' &lt;statement> &lt;jump>        ::= 'return' &lt;expression> ';' | 'break' ';' &lt;assign>      ::= &lt;identifier> = &lt;expression> ';' &lt;logical>     ::= &lt;comparison> {( &amp;&amp; | '||') &lt;comparison>} &lt;comparison>  ::= &lt;expression> {( == | != | > | >= | &lt; | &lt;= ) &lt;expression>} &lt;expression>  ::= &lt;term> {(+|-) &lt;term>} &lt;term>        ::= &lt;bitwise> {(*|\/) &lt;bitwise>} &lt;bitwise>     ::= &lt;factor> {( &amp; | '|' | ^ | &lt;&lt; | >> ) &lt;factor>} &lt;factor>      ::= ({~|!|-|+} &lt;number>) | &lt;identifer> | &lt;call><\/code><\/pre>\n<p>\u041f\u043e \u0445\u043e\u0434\u0443 \u0438\u0437\u0443\u0447\u0435\u043d\u0438\u044f \u0432\u043e\u043f\u0440\u043e\u0441\u0430, \u0437\u0430\u043c\u0435\u0442\u0438\u043b, \u0447\u0442\u043e \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0438 \u0443\u0434\u043e\u0431\u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0432\u043e\u0442 \u0442\u0430\u043a\u0430\u044f \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u043d\u043e\u0442\u0430\u0446\u0438\u044f (\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043d\u043e\u0442\u0430\u0446\u0438\u0438 \u043d\u0435 \u0437\u043d\u0430\u044e):<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043c\u044b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u043c \u0432\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u043c (tokens), \u043e \u0447\u0435\u043c \u0431\u044b\u043b\u043e <a href=\"https:\/\/habr.com\/ru\/post\/560986\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435 \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 II (\u0432\u043e\u0442 \u0442\u0443\u0442)<\/a>. \u0417\u0430\u0442\u0435\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0438\u0437 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043b\u0435\u043a\u0441\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (AST) \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430.<\/p>\n<h2>2. \u0410\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e (AST)<\/h2>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043a\u0440\u0430\u0442\u0446\u0435, \u0442\u043e <strong>Abstract Syntax Tree (AST)<\/strong> &#8212; \u044d\u0442\u043e \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0432\u0435\u0440\u0448\u0438\u043d\u044b \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f <em>\u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u043c\u0438<\/em>, \u0430 \u043b\u0438\u0441\u0442\u044c\u044f \u2014 \u0441 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 <em>\u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430\u043c\u0438<\/em>. \u042d\u0442\u043e \u0442\u043e, \u0432\u043e \u0447\u0442\u043e \u043d\u0430\u0434\u043e &#171;\u043f\u0435\u0440\u0435\u0432\u0435\u0441\u0442\u0438&#187; \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u043b\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0414\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430, Abstract Syntax Tree \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a, \u043a\u0430\u043a \u043d\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u0439 \u043d\u0438\u0436\u0435 \u0441\u0445\u0435\u043c\u0435:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u043c\u043d\u0435 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043b\u0441\u044f \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b \u0431\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 &#8212; \u0443\u0437\u0435\u043b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430, \u0441 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f \u0438 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0442\u0438\u043f\u043e\u043c \u0443\u0437\u043b\u0430 \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c\u0438 \u043c\u0435\u0442\u043e\u0434\u0430\u043c\u0438:<\/p>\n<pre><code class=\"cpp\">\/\/------------------------------------------------------------------------ \/\/ Abstract Syntax Tree Node \/\/------------------------------------------------------------------------  enum class TreeNodeType {     UNKNOWN = 0, MODULE, CONSTANT, TYPE, SYMBOL, UNARY_OP, BINARY_OP, CALL,     FUNCTION, BLOCK, ASSIGNMENT, IF_ELSE, WHILE, RETURN, BREAK };  constexpr char* const TREE_NODE_TYPE_MNEMONIC[] = {     \"UNKNOWN\", \"MODULE\", \"CONSTANT\", \"TYPE\", \"SYMBOL\", \"UNARY_OP\", \"BINARY_OP\", \"CALL\",     \"FUNCTION\", \"BLOCK\", \"ASSIGNMENT\", \"IF_ELSE\", \"WHILE\", \"RETURN\", \"BREAK\" };  class TreeNode {     public:         TreeNode(Token token, TreeNodeType type, SymbolTable* scope);         ~TreeNode();         TreeNode* addChild(TreeNode* node);         bool removeChild(TreeNode* node);         void removeAll();         TreeNodeType getType();         Token getToken();         TreeNode* getParent();         TreeNode* getChild(size_t index);         size_t getChildCount();         size_t getDepth();         void print();         inline void setSymbolTable(SymbolTable* scope) { symbols = scope; }         inline SymbolTable* getSymbolTable() { return symbols; }     private:         Token token;         SymbolTable* symbols = NULL;         vector&lt;TreeNode*> childs;         TreeNode* parent;         TreeNodeType type;         void print(int tab); };<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434: <a href=\"https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/TreeNode.cpp\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/TreeNode.cpp<\/a><\/p>\n<h2>3. \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (Symbol Tree)<\/h2>\n<p>\u041d\u0430\u0440\u044f\u0434\u0443, \u0441 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u0430\u044f \u0422\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. <strong>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (Symbol Table)<\/strong> &#8212; \u044d\u0442\u043e \u0434\u0440\u0435\u0432\u043e\u0432\u0438\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u0438\u0445 \u0442\u0438\u043f\u044b, \u0430\u0434\u0440\u0435\u0441\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438. \u041e\u043d\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0432\u044b\u044f\u0432\u043b\u044f\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c, \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u044e\u0449\u0438\u0435\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f, \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435. \u041b\u0443\u0447\u0448\u0435 \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u043e\u043d\u0430 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u043d\u0438\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u0435. <\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"cpp\">void pro_one() {    int one_1;    int one_2;    {                 \\       int one_3;      |_  inner scope 1        int one_4;      |     }                 \/    int one_5;     {                 \\          int one_6;      |_  inner scope 2       int one_7;      |    }                 \/ }  void pro_two() {    int two_1;    int two_2;    {                 \\       int two_3;      |_  inner scope 3       int two_4;      |    }                 \/    int two_5; }  <\/code><\/pre>\n<p>\u041f\u043e \u044d\u0442\u043e\u043c\u0443 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u043a\u043e\u0434\u0443 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0422\u0430\u0431\u043b\u0438\u0446 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043b\u0435\u0433\u043a\u043e \u043c\u043e\u0433\u043b\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432:<\/p>\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u0442\u0430\u0431\u043b\u0438\u0446, \u043e\u043f\u0438\u0448\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0434\u0430\u043d\u043d\u044b\u0445 SymbolTable \u0438 \u043c\u0435\u0442\u043e\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0435\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044f \u0442\u0438\u043f, \u0438\u0441\u043a\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043a\u0430\u043a \u0432 \u0441\u0430\u043c\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435, \u0442\u0430\u043a \u0438 \u0432 \u0435\u0451 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0443\u0437\u043b\u0430\u0445 \u0432\u043f\u043b\u043e\u0442\u044c \u0434\u043e \u043a\u043e\u0440\u043d\u044f. \u0412\u043e\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cpp\">\/\/------------------------------------------------------------------------ \/\/ Symbol table \/\/------------------------------------------------------------------------ enum class SymbolType {     UNKNOWN, CONSTANT, FUNCTION, ARGUMENT, VARIABLE };  constexpr char* const  SYMBOL_TYPE_MNEMONIC[] = {     \"UNKNOWN\", \"CONSTANT\", \"FUNCTION\", \"ARGUMENT\", \"VARIABLE\" };  class Symbol {     public:         string name = \"\";         SymbolType type = SymbolType::UNKNOWN;         WORD localIndex = -1;         WORD address = -1;         WORD argCount = 0; };  class SymbolTable {     public:         SymbolTable(string name = \"GLOBAL\");         ~SymbolTable();         bool addChild(SymbolTable* child);         void removeChild(SymbolTable* child);         SymbolTable* getChildAt(size_t index);         size_t getChildCount();         inline const char* getName() { return name.c_str(); };         void clearSymbols();         size_t getSymbolsCount();         bool addSymbol(Token&amp; token, SymbolType type);         Symbol* lookupSymbol(Token&amp; token);         Symbol* lookupSymbol(char* name, SymbolType type);         Symbol* getSymbolAt(size_t index);         void printSymbols();     private:         string name;         vector&lt;Symbol> symbols;         vector&lt;SymbolTable*> childs;         SymbolTable* parent;         int getNextIndex(SymbolType type);         void printRecursive(int depth); };<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434: <a href=\"https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/SymbolTable.cpp\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/Basheyev\/CVM\/blob\/master\/src\/compiler\/SymbolTable.cpp<\/a><\/p>\n<h2>4. Parser &#8212; \u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044c AST \u0438 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0438\u043c\u0435\u044f \u043d\u0430 \u0440\u0443\u043a\u0430\u0445 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u044f\u0437\u044b\u043a\u0430, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f <em>\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430 (AST)<\/em> \u0438 <em>\u0434\u0435\u0440\u0435\u0432\u0430 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (Symbol Table)<\/em>, \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c Parser, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 <em>\u043d\u0430 \u0432\u0445\u043e\u0434 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434<\/em>, \u0430 <em>\u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432<\/em>. \u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, Lexer \u0438 Parser &#8212; \u0434\u0432\u0430 \u0432 \u043e\u0434\u043d\u043e\u043c.<\/p>\n<pre><code class=\"cpp\">\/\/------------------------------------------------------------------------ \/\/ Syntax Parser (Abstract Syntax Tree Builder) \/\/------------------------------------------------------------------------ class SourceParser {     public:         SourceParser(const char* sourceCode);         ~SourceParser();         inline size_t getTokenCount() { return tokens.size(); }         Token&amp; getToken(size_t index) { return tokens[index]; }         SymbolTable&amp; getSymbolTable() { return rootSymbolTable; }         TreeNode* getSyntaxTree() { return root; }     private:         vector&lt;Token> tokens;         TreeNode* root = NULL;         SymbolTable rootSymbolTable;         size_t currentToken = 0;         int blockCounter = 0;          void parseToTokens(const char* sourceCode);         bool isBlank(char value) { return strchr(BLANKS, value) != NULL; };         bool isDelimeter(char value) { return strchr(DELIMETERS, value) != NULL; };         bool pushToken(char* text, int length, int row, int col);         TokenType getTokenType(char* text, int length);         TokenType validateNumber(char* text, int length);         TokenType validateIdentifier(char* text, int length);         TokenType validateString(char* text, int length);          void buildSyntaxTree();         TreeNode* parseModule(SymbolTable* scope);         TreeNode* parseDeclaration(SymbolTable* scope);         TreeNode* parseFunction(SymbolTable* scope);         TreeNode* parseArgument(SymbolTable* scope);         TreeNode* parseBlock(SymbolTable* scope, bool isFunction, bool whileBlock);         TreeNode* parseStatement(SymbolTable* scope, bool whileBlock);         TreeNode* parseCall(SymbolTable* scope);<\/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-407781","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/407781","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=407781"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/407781\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=407781"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=407781"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=407781"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}