{"id":347133,"date":"2023-03-23T09:02:06","date_gmt":"2023-03-23T09:02:06","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=347133"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=347133","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0432\u043e\u0439 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c LLVM. \u0427\u0430\u0441\u0442\u044c 4: \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u00a0\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"https:\/\/habr.com\/ru\/post\/717886\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043d\u0430\u00a0\u0442\u043e\u043c, \u0447\u0442\u043e\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u043e\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0432\u00a0\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0435\u0441\u0442\u044c \u0446\u0435\u043b\u044b\u0435 \u0438 \u0432\u0435\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: \u0446\u0438\u043a\u043b\u044b, \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435. \u0412\u00a0\u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u00a0\u043d\u0435\u0433\u043e: \u0441\u0442\u0440\u043e\u043a\u0438, \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438, \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0430\u00a0\u0442\u0430\u043a\u00a0\u0436\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u043d\u0438\u043c\u0438.<\/p>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0438\u0448\u0435\u043c, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435.<\/p>\n<ol>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u0430 &#171;char&#187; \u0438 &#171;string&#187;;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u0432\u0443\u0445 \u043d\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442:<\/p>\n<\/li>\n<\/ol>\n<ul>\n<li>\n<p>\u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#171;Hello, world&#187;);<\/p>\n<\/li>\n<li>\n<p>\u0421\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8216;d&#8217;).<\/p>\n<\/li>\n<\/ul>\n<ol start=\"3\">\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 int[10]) \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 int*) \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438 (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: ++\/&#8212;, &amp; \u0438 *), \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 struct A { a: int; b: float; }), \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0447\u043b\u0435\u043d\u0430\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 &#171;.&#187;.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0441\u0435 4 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430: \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439, \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430.  <\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/dc-sinpo\/simple\/tree\/part02\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0412 \u044f\u0437\u044b\u043a\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0442.\u00a0\u0435. \u0434\u043b\u044f &#171;int*[2][3]&#187; \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 3 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 2 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 int. \u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u0445 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442.\u00a0\u043a. \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c a[2][1], \u043d\u043e \u043d\u0435 a[1][2] (\u0442.\u00a0\u043a. \u0434\u043b\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a-\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u2014 2, \u043d\u0435 3).<\/p>\n<h3>\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437<\/h3>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u043b\u0435\u043a\u0441\u0435\u043c \u0432 include\/Basic\/TokenKinds.def.<\/p>\n<p>\u041d\u043e\u0432\u044b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430:<\/p>\n<pre><code class=\"cpp\">KEYWORD(String, \"string\")  KEYWORD(Char, \"char\")  KEYWORD(Struct, \"struct\")  KEYWORD(New, \"new\")  KEYWORD(Delete, \"del\") <\/code><\/pre>\n<p>\u041d\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b:<\/p>\n<pre><code class=\"cpp\">TOK(CharLiteral, \"\") TOK(StringConstant, \"\") <\/code><\/pre>\n<p>\u041d\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b:<\/p>\n<pre><code class=\"cpp\">TOK(Dot, \".\") TOK(OpenBrace, \"[\") TOK(CloseBrace, \"]\")<\/code><\/pre>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 Name:<\/p>\n<pre><code class=\"cpp\">struct Name {    ...   static Name *New;    \/\/\/&lt; \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \"new\"   static Name *Delete; \/\/\/&lt; \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \"del\"  }; <\/code><\/pre>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 Lexer \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">void NamesMap::addKeywords() {    if (IsInit) {      return;    }   #define KEYWORD(NAME, TEXT)                               \\    addName(StringRef(TEXT), tok::NAME);  #include \"simple\/Basic\/TokenKinds.def\"     Name::New = getName(\"new\");    Name::Delete = getName(\"delete\");     IsInit = true;  }<\/code><\/pre>\n<p>\u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b, \u0442.\u00a0\u043a. \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0441 \u044d\u0442\u0438\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438, \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432 \u0432 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435 (\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u043e\u0432\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u0432 \u043d\u0435\u043c \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442):<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">void Lexer::next(Token &amp;Result) {    \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e   Result.Kind = tok::Invalid;     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u0431\u0443\u0434\u0435\u043c    \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c    \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430   const char *p = CurPos;     \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u044b, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d   while (Result.Kind == tok::Invalid) {      const char *tokenStart = p;     ...     \/\/ \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0443, \u043d\u043e \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438      \/\/ \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u0441\u0438\u043c\u0432\u043e\u043b     switch (char ch = *p++) {        ...       \/\/ \u0410\u043d\u0430\u043b\u0438\u0437 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430       CHECK_ONE('[', tok::OpenBrace);        CHECK_ONE(']', tok::CloseBrace);        CHECK_ONE('.', tok::Dot);         ...       case '\\'': {          \/\/ \u042d\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b         char resultCh = ' ';          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430, \u0438 \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e          \/\/ \u0441\u0438\u043c\u0432\u043e\u043b, \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e         if (*p != '\\'') {            resultCh = *p;            ++p;          }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b \u0438\u043c\u0435\u0435\u0442 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0443\u044e '         if (*p != '\\'') {            Diags.report(getLoc(p),                         diag::ERR_UnterminatedCharOrString);          }           ++p;          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438         Result.Length = (int)(p - tokenStart);          Result.Chr = resultCh;          Result.Kind = tok::CharLiteral;          break;        }         case '\"': {          \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b         llvm::SmallString&lt;32> str;          \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c, \u043f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435         while (*p != 0) {            \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \"           if (*p == '\"') {              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \"             if (p[1] != '\"') {                \/\/ \u0417\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430               break;              }               \/\/ \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \"\" \u043d\u0430 \"             p += 2;              str.push_back('\"');            } else if (*p == '\\\\') {              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u044d\u0441\u043a\u0435\u0439\u043f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c             ++p;              \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \\n              if (*p == 'n') {                str.push_back('\\n');                ++p;               \/\/ \u0438 \\\\             } else if (*p == '\\\\') {                str.push_back('\\\\');                ++p;              } else {                Diags.report(getLoc(p),                             diag::ERR_InvalidEscapeSequence);              }           } else if (*p == '\\r' || *p == '\\n') {              \/\/ \u041c\u044b \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0438 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0435, \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043e\u0431              \/\/ \u043e\u0448\u0438\u0431\u043a\u0435             Diags.report(getLoc(p), diag::ERR_NewLineInString);            } else {              \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b \u043a \u0441\u0442\u0440\u043e\u043a\u0435             str.push_back(*p);              ++p;            }          }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \"          if (*p != '\"') {            Diags.report(getLoc(p),                        diag::ERR_UnterminatedCharOrString);          }          \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"         ++p;          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438         Result.Kind = tok::StringConstant;          Result.Length = str.size();          Result.Literal = new char[Result.Length + 1];          memcpy(Result.Literal, str.c_str(), Result.Length);          Result.Literal[Result.Length] = 0;          break;        }        ...     }      Result.Ptr = tokenStart;    }     \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435   CurPos = p;  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u0441\u0435\u0445 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u043e\u0432\u044b\u0445 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ primary-expr  \/\/\/   ::= floating-point-literal  \/\/\/   ::= integral-literal  \/\/\/   ::= '.'? identifier  \/\/\/   ::= char-literal  \/\/\/   ::= string-literal  \/\/\/   ::= '(' expr ')'  ExprAST *Parser::parsePrimaryExpr() {    ExprAST *result = nullptr;     switch (CurPos->getKind()) {      ...     case tok::CharLiteral:        \/\/ \u042d\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430. \u0421\u0442\u0440\u043e\u0438\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430 \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c       \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d       result = new IntExprAST(CurPos.getLocation(),                                CurPos->getChar());        ++CurPos;        return result;      case tok::StringConstant:        \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430. \u0421\u0442\u0440\u043e\u0438\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430 \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c       \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d       result = new StringExprAST(CurPos.getLocation(),                                   CurPos->getLiteral());        ++CurPos;        return result;      case tok::Dot:        \/\/ \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \".\", \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u044d\u0442\u043e\u0442        \/\/ \u0441\u043b\u0443\u0447\u0430\u0439       if ((CurPos + 1) != tok::Identifier) {          check(tok::Identifier);        }        \/\/ \u0421\u0430\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d \u0432 parsePostfixExpr, \u0437\u0434\u0435\u0441\u044c        \/\/ \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c       \/\/ \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438        return new IdExprAST(CurPos.getLocation(), nullptr);        ...   }  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0447\u043b\u0435\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ call-arguments  \/\/\/   ::= assign-expr  \/\/\/   ::= call-arguments ',' assign-expr  \/\/\/ postfix-expr  \/\/\/   ::= primary-expr  \/\/\/   ::= postfix-expr '++'  \/\/\/   ::= postfix-expr '--'  \/\/\/   ::= postfix-expr '(' call-arguments ? ')'  \/\/\/   ::= postfix-expr '[' expr ']'  \/\/\/   ::= postfix-expr '.' identifier  ExprAST *Parser::parsePostfixExpr() {    ExprAST *result = parsePrimaryExpr();     for (;;) {      llvm::SMLoc loc = CurPos.getLocation();       switch (int op = CurPos->getKind()) {        ...       case tok::OpenBrace: {          \/\/ \u042d\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c [          check(tok::OpenBrace);          \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435         ExprAST *expr = parseExpr();          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 ]         check(tok::CloseBrace);          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430         result = new IndexExprAST(loc, result, expr);          continue;        }         case tok::Dot: {          \/\/ \u042d\u0442\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u0447\u043b\u0435\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0430, \u0438\u0445 \u043c\u043e\u0436\u0435\u0442         \/\/ \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u0446\u0438\u043a\u043b\u0435         while (CurPos == tok::Dot) {            \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c .           ++CurPos;             Name *name = nullptr;            \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e           if (CurPos == tok::Identifier) {              name = CurPos->getIdentifier();            }            \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438\u043b\u0438 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435           check(tok::Identifier);            \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430           result = new MemberAccessExprAST(loc, result, name);          }           continue;        }         default:          return result;      }    }  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043e\u0434\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: \u0432\u0437\u044f\u0442\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430, \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ unary-expr  \/\/\/   ::= postfix-expr  \/\/\/   ::= '+' unary-expr  \/\/\/   ::= '-' unary-expr  \/\/\/   ::= '++' unary-expr  \/\/\/   ::= '--' unary-expr  \/\/\/   ::= '~' unary-expr  \/\/\/   ::= '!' unary-expr  \/\/\/   ::= '*' unary-expr  \/\/\/   ::= '&amp;' unary-expr  \/\/\/   ::= 'del' unary-expr  \/\/\/   ::= 'new' type ('[' assign-expr ']')?  ExprAST *Parser::parseUnaryExpr() {    ExprAST *result = nullptr;    llvm::SMLoc loc = CurPos.getLocation();     switch (int op = CurPos->getKind()) {      ...     case tok::Mul:        \/\/ \u042d\u0442\u043e \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"*\" \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c        \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c       ++CurPos;        result = parseUnaryExpr();        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430       return new DerefExprAST(loc, result);       case tok::BitAnd:        \/\/ \u042d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"&amp;\" \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c        \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c       ++CurPos;        result = parseUnaryExpr();        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430       return new AddressOfExprAST(loc, result);       case tok::Delete: {        \/\/ \u042d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"del\" \u0438        \/\/ \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u043e\u0434\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c       ++CurPos;        result = parsePostfixExpr();        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430       return new DeleteExprAST(loc, result);      }       case tok::New: {        \/\/ \u042d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"new\"       ++CurPos;        \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u0438\u043f       TypeAST *type = parseType();        ExprList args;        ExprAST *dynamicSize = nullptr;         \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \"[\" expression \"]\" , \u0442.\u043a. \"[\" integral-literal \"]\"       \/\/ \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043e \u0440\u0430\u043d\u0435\u0435 \u0432 parseType        if (CurPos == tok::OpenBrace) {          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0441\u043b\u0435\u0432\u0430 \u043e\u0442 \"[\" \u0443 \u043d\u0430\u0441 \u043d\u0435\u0442\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u043b\u0438          \/\/ \u043a\u043b\u0430\u0441\u0441\u0430, \u0442.\u00a0\u043a. \u043c\u044b \u0438\u0445 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u043c         if (isa&lt;QualifiedTypeAST>(type)) {            getDiagnostics().report(CurPos.getLocation(),                                    diag::ERR_DynArrayAggregate);          }          \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"[\" \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043c\u0435\u0436\u0434\u0443 \"[\" \u0438 \"]\"         ++CurPos;          dynamicSize = parseAssignExpr();          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \"]\"         check(tok::CloseBrace);        }        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430       return new NewExprAST(loc, type, dynamicSize, args);      }       default:        return parsePostfixExpr();    }  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0432 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f\u0445:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ basic-type  \/\/\/  ::= 'int'  \/\/\/  ::= 'float'  \/\/\/  ::= 'void'  \/\/\/  ::= 'char'  \/\/\/  ::= 'string'  \/\/\/  ::= '.'? identifier ('.' identifier)*  \/\/\/ type  \/\/\/   ::= basic-type  \/\/\/   ::= type '*'  \/\/\/   ::= type '[' integral-literal ']'  TypeAST *Parser::parseType() {    TypeAST *type = nullptr;    bool isVoid = false;    llvm::SMLoc loc = CurPos.getLocation();     switch (CurPos->getKind()) {      ...      case tok::Char:        \/\/ \"char\"       ++CurPos;        type = BuiltinTypeAST::get(TypeAST::TI_Char);        break;       case tok::String:        \/\/ \"string\"       ++CurPos;        type = BuiltinTypeAST::get(TypeAST::TI_String);        break;       case tok::Dot:      case tok::Identifier: {        \/\/ \u042d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 A.B \u0438\u043b\u0438 .A       Name *name = nullptr;        QualifiedName qualName;         if (CurPos == tok::Identifier) {          \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0431\u044b\u043b \u043e\u043d (\u0442.\u00a0\u043a. \u043c\u043e\u0433\u043b\u0430          \/\/ \u0431\u044b\u0442\u044c \".\")         name = CurPos->getIdentifier();          ++CurPos;        }        \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0440\u0430\u043d\u0435\u0435 \u0441\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438\u043b\u0438 \".\" \u0432 \u0441\u043f\u0438\u0441\u043e\u043a       qualName.push_back(name);        \/\/ \u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0441\u0435\u0440\u0438\u0438        \/\/ \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \".\". \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432\u0441\u0435       while (CurPos == tok::Dot) {          ++CurPos;           \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f         if (CurPos == tok::Identifier) {            name = CurPos->getIdentifier();          }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0438 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a          \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443         check(tok::Identifier);          \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a \u043f\u043e\u043b\u043d\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u0438         qualName.push_back(name);        }        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430       type = new QualifiedTypeAST(qualName);        break;      }       default:        getDiagnostics().report(CurPos.getLocation(),                                diag::ERR_InvalidType);        return nullptr;    }    \/\/ \u041f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b   for (;;) {      switch (CurPos->getKind()) {        case tok::OpenBrace: {          \/\/ \u042d\u0442\u043e \"[\", \u043d\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441 \"void[\"         if (isVoid) {            getDiagnostics().report(loc, diag::ERR_VoidAsNonPointer);            return nullptr;          }          \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"[\"         ++CurPos;           int dim = 0;           if (CurPos == tok::IntNumber) {            \/\/ \u042d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b. \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e            \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435           dim = atoi(CurPos->getLiteral().data());          } else {            \/\/ \u0421\u0447\u0438\u0442\u0430\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \"[\" expression \"]\", \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c            \/\/ \u0441\u0447\u0438\u0442\u0430\u043d\u043e \u043f\u043e\u0437\u0436\u0435 \u0438\u043b\u0438 \u0432\u044b\u0434\u0430\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b            \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443 \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0440\u0430\u0437\u0431\u043e\u0440           \/\/ \u0442\u0438\u043f\u0430            --CurPos;            break;          }         \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c integral-literal \u0438 \"]\"         check(tok::IntNumber);          check(tok::CloseBrace);         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430         type = new ArrayTypeAST(type, dim);          continue;        }         case tok::Mul:          \/\/ \u042d\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c. \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443 \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c          \/\/ \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430         ++CurPos;          type = new PointerTypeAST(type, false);          continue;         default:          break;      }        break;    }     if (type == BuiltinTypeAST::get(TypeAST::TI_Void)) {      getDiagnostics().report(loc, diag::ERR_VoidAsNonPointer);      return nullptr;    }     return type;  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0440\u0430\u0437\u0431\u043e\u0440\u0435 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u0432\u0443\u0445 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 &#171;new&#187; \u0438 &#171;del&#187; (\u043d\u0430 \u0434\u0430\u043d\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043d\u043e \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0438\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043e):<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ parameter ::= identifier ':' type  \/\/\/ parameters-list  \/\/\/   ::= parameter  \/\/\/   ::= parameter-list ',' parameter  \/\/\/ return-type ::= ':' type  \/\/\/ func-proto \/\/\/   ::= identifier '(' parameters-list ? ')' return-type ?  SymbolAST *Parser::parseFuncProto() {    Name *name = nullptr;    TypeAST *returnType = BuiltinTypeAST::get(TypeAST::TI_Void);    ParameterList params;    int Tok = CurPos->getKind();    llvm::SMLoc loc = CurPos.getLocation();    \/\/ \u041f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0432\u0441\u0435\u0433\u0434\u0430 \"fn\" (\u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c    \/\/ \u044d\u0442\u043e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d)   ++CurPos;     \/\/ \u041f\u043e\u0441\u043b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c    \/\/ \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440   if (CurPos == tok::Identifier) {      \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u043c\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0435\u0435 \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0430 \u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a      \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443     name = CurPos->getIdentifier();      ++CurPos;    \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \"new\" \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043c\u0435\u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   } else if (CurPos == tok::New) {      ++CurPos;      name = Name::New;    \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \"del\" \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043c\u0435\u043d\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438   } else if (CurPos == tok::Delete) {      ++CurPos;      name = Name::Delete;    } else {      check(tok::Identifier);    }     ... } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f\u0445 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ decls  \/\/\/  ::= func-decl  \/\/\/  ::= decls func-decl  \/\/\/  ::= struct-decl  \/\/\/  \/\/\/ struct-decl  \/\/\/   ::= 'struct' identifier '{' decl-stmt * '}'  SymbolList Parser::parseDecls() {    SymbolList result;    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0430\u043d\u0430\u043b\u0438\u0437 \u0432\u0441\u0435\u0445 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439   for (;;) {      SymbolList tmp;      llvm::SMLoc loc = CurPos.getLocation();       switch (int Tok = CurPos->getKind()) {        ...         case tok::Struct: {          \/\/ \u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b         ++CurPos;          Name *name = nullptr;           \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u043c\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f         if (CurPos == tok::Identifier) {            name = CurPos->getIdentifier();          }           \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0438 \"{\"         check(tok::Identifier);          check(tok::BlockStart);           \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u0430\u043a \u0435\u0435 \u0447\u043b\u0435\u043d\u044b         while (CurPos != tok::BlockEnd) {            SymbolList tmp2 = parseDecl(true, true);            tmp.append(tmp2.begin(), tmp2.end());          }           \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \"}\" \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430         check(tok::BlockEnd);          result.push_back(new StructDeclAST(loc, name, tmp));          continue;        }         case tok::EndOfFile:          break;         default:          break;      }       break;    }     return result;  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0440\u0430\u0437\u0431\u043e\u0440\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u044b \u043a\u0430\u043a \u0447\u043b\u0435\u043d\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ var-init ::= '=' assign-expr  \/\/\/ var-decl ::= identifier ':' type var-init?  \/\/\/ var-decls  \/\/\/   ::= var-decl  \/\/\/   ::= var-decls ',' var-decl  \/\/\/ decl-stmt ::= var-decls ';'  SymbolList Parser::parseDecl(bool needSemicolon,                              bool isClassMember) {    SymbolList result;    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0430\u043d\u0430\u043b\u0438\u0437 \u0441\u043f\u0438\u0441\u043a\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445   for (;;) {      llvm::SMLoc loc = CurPos.getLocation();       if (CurPos != tok::Identifier) {        \/\/ \u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430, \u0435\u0441\u043b\u0438       \/\/ \u044d\u0442\u043e \u0447\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0435, \u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435       getDiagnostics().report(CurPos.getLocation(),                                diag::ERR_ExpectedIdentifierInDecl);      } else {        \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0438\u043c\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439       Name *name = CurPos->getIdentifier();        ExprAST *value = nullptr;        \/\/ \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443       ++CurPos;        \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \":\"       check(tok::Colon);        \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u0438\u043f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439       TypeAST *type = parseType();         if (CurPos == tok::Assign) {          \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\/\u043a\u043b\u0430\u0441\u0441\u043e\u0432         if (isa&lt;ArrayTypeAST>(type) || isa&lt;QualifiedTypeAST>(type)) {            getDiagnostics().report(             CurPos.getLocation(),              diag::ERR_AggregateOrArrayInitializer           );            return result;          }           \/\/ \u0415\u0441\u043b\u0438 \u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0435\u0441\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440, \u0442\u043e \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \"=\" \u0438          \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         ++CurPos;          value = parseAssignExpr();        }        \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u043a \u0441\u043f\u0438\u0441\u043a\u0443       result.push_back(new VarDeclAST(loc, type, name, value,                                        isClassMember));         if (CurPos != tok::Comma) {          \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \",\", \u0442\u043e \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d         break;        }        \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \",\"       ++CurPos;      }    }     if (needSemicolon) {     \/\/ \u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0442\u044c\u0441\u044f \";\", \u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0435\u0433\u043e      \/\/ \u043d\u0430\u043b\u0438\u0447\u0438\u0435      check(tok::Semicolon);    }     return result;  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u043f\u0440\u0430\u0432\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u0440\u0430\u0437\u0431\u043e\u0440\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ block-stmt ::= '{' stmt* '}'  \/\/\/ for-init  \/\/\/   ::= 'let' decl-stmt  \/\/\/   ::= expr  \/\/\/ for-stmt ::= 'for' for-init? ';' expr? ';' expr? block-stmt  \/\/\/ stmt  \/\/\/   ::= expr? ';'  \/\/\/   ::= 'let' decl-stmt  \/\/\/   ::= 'if' expr block-stmt ( 'else' block-stmt )?  \/\/\/   ::= 'while' expr block-stmt  \/\/\/   ::= for-stmt  \/\/\/   ::= 'break'  \/\/\/   ::= 'continue'  \/\/\/   ::= 'return' expr? ';'  \/\/\/   ::= block-stmt  StmtAST *Parser::parseStmt() {    StmtAST *result = nullptr;    llvm::SMLoc loc = CurPos.getLocation();     switch (CurPos->getKind()) {      ...     case tok::Plus:      case tok::Minus:      case tok::PlusPlus:      case tok::MinusMinus:      case tok::Tilda:      case tok::Not:      case tok::Identifier:      case tok::IntNumber:      case tok::FloatNumber:      \/\/ \u041d\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     case tok::OpenParen:      case tok::Delete:      case tok::Mul:      case tok::BitAnd:      case tok::New:      case tok::Dot: {        ExprAST *expr = parseExpr();        check(tok::Semicolon);        return new ExprStmtAST(loc, expr);      }      ...   }  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 AST<\/h3>\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0432\u0441\u0435\u0445 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u044f\u0437\u044b\u043a\u0435 \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0430\u0432\u043a\u0438 \u0432 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043a\u043b\u0430\u0441\u0441 \u043a\u043e\u0440\u043d\u0435\u0432\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 AST. \u0414\u043b\u044f \u0442\u0438\u043f\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">struct TypeAST {    enum TypeId {      TI_Void,     \/\/\/&lt; void      TI_Bool,     \/\/\/&lt; \u0431\u0443\u043b\u0435\u0432\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435      TI_Int,      \/\/\/&lt; int     TI_Float,    \/\/\/&lt; float      TI_Char,     \/\/\/&lt; char     TI_String,   \/\/\/&lt; string      TI_Pointer,  \/\/\/&lt; \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c      TI_Array,    \/\/\/&lt; \u043c\u0430\u0441\u0441\u0438\u0432      TI_Struct,   \/\/\/&lt; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430      TI_Function, \/\/\/&lt; \u0444\u0443\u043d\u043a\u0446\u0438\u044f      TI_Qualified \/\/\/&lt; \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f (\u043f\u043e\u043b\u043d\u043e\u0435 \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430 \u0438\u043b\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b)   };    ...   \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0438\u043f \u0441\u0442\u0440\u043e\u043a\u0438   bool isString() {      return TypeKind == TI_String;    }    \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0438\u043f \u0441\u0438\u043c\u0432\u043e\u043b\u0430   bool isChar() {      return TypeKind == TI_Char;    }    \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0442\u0438\u043f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0430   bool isAggregate() {      return TypeKind == TI_Struct;    }     \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c SymbolAST \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0439 \u0441 \u0434\u0430\u043d\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c (\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f   \/\/\/   StructTypeAST)    virtual SymbolAST* getSymbol();    ... }; <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<pre><code class=\"cpp\">struct ExprAST {    \/\/\/ Expression's identifiers    enum ExprId {      EI_Int,         \/\/\/&lt; \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b     EI_Float,       \/\/\/&lt; \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0434\u043b\u044f \u0447\u0438\u0441\u0435\u043b \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439     EI_Char,          \/\/\/&lt; \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430     EI_String,        \/\/\/&lt; \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430     EI_Proxy,         \/\/\/&lt; \u043f\u0440\u043e\u043a\u0441\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435     EI_Id,          \/\/\/&lt; \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439      EI_Cast,        \/\/\/&lt; \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432     EI_Index,         \/\/\/&lt; \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f     EI_MemberAccess,  \/\/\/&lt; \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0447\u043b\u0435\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0430     \/\/\/ \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0447\u043b\u0435\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0430, \u0435\u0441\u043b\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f      \/\/\/ \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c     EI_PointerAccess,     EI_Deref,         \/\/\/&lt; \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f     EI_AddressOf,     \/\/\/&lt; \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430     EI_Unary,       \/\/\/&lt; \u0443\u043d\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f     EI_Binary,      \/\/\/&lt; \u0431\u0438\u043d\u0430\u0440\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f     EI_Call,        \/\/\/&lt; \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438     EI_New,           \/\/\/&lt; \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043c\u044f\u0442\u0438     EI_Delete,        \/\/\/&lt; \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u0440\u0430\u043d\u0435\u0435 \u043f\u0430\u043c\u044f\u0442\u0438     EI_Cond         \/\/\/&lt; \u0442\u0435\u0440\u043d\u0430\u0440\u043d\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440    };     ...   \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439    bool isConst() {      return ExprKind == EI_Int       || ExprKind == EI_Float       || ExprKind == EI_String;    }    \/\/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c SymbolAST \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0443   virtual SymbolAST *getAggregate(Scope *scope);    \/\/\/ \u041c\u043e\u0436\u0435\u0442 \u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u044b\u0442\u044c null    virtual bool canBeNull();    ... }; <\/code><\/pre>\n<p>\u0418 \u0434\u043b\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (\u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439):<\/p>\n<pre><code class=\"cpp\">struct SymbolAST {    enum SymbolId {      SI_Variable,    \/\/\/&lt; \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f     SI_Struct,      \/\/\/&lt; \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430     SI_Function,    \/\/\/&lt; \u0444\u0443\u043d\u043a\u0446\u0438\u044f      SI_Module,      \/\/\/&lt; \u043c\u043e\u0434\u0443\u043b\u044c      SI_Parameter,   \/\/\/&lt; \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u0444\u0443\u043d\u043a\u0446\u0438\u0438      SI_Block        \/\/\/&lt; \u0431\u043b\u043e\u0447\u043d\u0430\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f   };    ...   \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u043c   bool isAggregate() {      return SymbolKind == SI_Struct;    }    \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c this (true - \u0447\u043b\u0435\u043d class\/struct)    virtual bool needThis();    \/\/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0438\u043f \\c type    \/\/\/ \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438   \/\/\/ \\note \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0442\u044c \u043a\u043e\u043b\u044c\u0446\u0435\u0432\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438   virtual bool contain(TypeAST *type);    \/\/\/ \u041c\u043e\u0436\u0435\u0442 \u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0431\u044b\u0442\u044c null    \/\/\/ \\note \u0414\u043e\u043b\u0436\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c true \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0441 \u0442\u0438\u043f\u043e\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f   virtual bool canBeNull();   ... }; <\/code><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0430\u0432\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0440\u0430\u043d\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0432\u0435\u0442\u043e\u043a \u0434\u0435\u0440\u0435\u0432\u0430, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u044b\u0445 \u0432\u0435\u0442\u043e\u043a:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">struct BuiltinTypeAST : TypeAST {    ...   static bool classof(const TypeAST *T) {      return T->TypeKind == TI_Void ||        T->TypeKind == TI_Bool ||        T->TypeKind == TI_Int ||        T->TypeKind == TI_Float ||        T->TypeKind == TI_Char ||        T->TypeKind == TI_String;    }    ... };    \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \"\u043c\u0430\u0441\u0441\u0438\u0432\" struct ArrayTypeAST : TypeAST {    ArrayTypeAST(TypeAST* next, int dim) ;    TypeAST* semantic(Scope* scope);    bool implicitConvertTo(TypeAST* newType);    void toMangleBuffer(llvm::raw_ostream&amp; output);     llvm::Type* getType();     static bool classof(const TypeAST *T) {      return T->TypeKind == TI_Array;    }     TypeAST* Next; \/\/\/&lt; \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f   int Dim; \/\/\/&lt; \u0440\u0430\u0437\u043c\u0435\u0440 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \"\u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c\" struct PointerTypeAST : TypeAST {    PointerTypeAST(TypeAST* next, bool isConst) ;    TypeAST* semantic(Scope* scope);    bool implicitConvertTo(TypeAST* newType);    void toMangleBuffer(llvm::raw_ostream&amp; output);     llvm::Type* getType();     static bool classof(const TypeAST *T) {      return T->TypeKind == TI_Pointer;    }      TypeAST* Next; \/\/\/&lt; \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f   bool IsConstant; \/\/\/&lt; true - \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439 };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \"\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\" struct StructTypeAST : TypeAST {    StructTypeAST(SymbolAST* thisDecl) ;    TypeAST* semantic(Scope* scope);    bool implicitConvertTo(TypeAST* newType);    void toMangleBuffer(llvm::raw_ostream&amp; output);    SymbolAST* getSymbol();     llvm::Type* getType();     static bool classof(const TypeAST *T) {      return T->TypeKind == TI_Struct;    }     SymbolAST* ThisDecl; \/\/\/&lt; \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b };   \/\/\/ \u041a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f typedef llvm::SmallVector&lt; Name*, 4 > QualifiedName;   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0433\u043e \u0438\u043c\u0435\u043d\u0438  \/\/\/ \\note \u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043c\u0435\u043d\u0435\u043d \u043d\u0430 \u0442\u0438\u043f  \/\/\/ \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u043f\u043e\u0441\u043b\u0435 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0430  \/\/\/ StructTypeAST) struct QualifiedTypeAST : TypeAST {    QualifiedTypeAST(const QualifiedName&amp; qualName);    TypeAST* semantic(Scope* scope);    bool implicitConvertTo(TypeAST* newType);    void toMangleBuffer(llvm::raw_ostream&amp; output);     llvm::Type* getType();     static bool classof(const TypeAST *T) {      return T->TypeKind == TI_Qualified;    }     QualifiedName QualName; \/\/\/&lt; \u043a\u0432\u0430\u043b\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438\u043c\u044f };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b struct StringExprAST : ExprAST {    StringExprAST(llvm::SMLoc loc, llvm::StringRef str) ;    bool isTrue();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_String;    }     llvm::SmallString&lt; 32 > Val; \/\/\/&lt; \u0445\u0440\u0430\u043d\u0438\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u0440\u043e\u043a\u0441\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \/\/\/ \\note \u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \/\/\/ \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430. \u042d\u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442  \/\/\/ \u0437\u0430\u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435, \u043f\u0443\u0442\u0435\u043c \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0435\u0431\u044f,  \/\/\/ \u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 struct ProxyExprAST : ExprAST {    ProxyExprAST(llvm::SMLoc loc, ExprAST *orig) ;    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_Proxy;    }     ExprAST* OriginalExpr; \/\/\/&lt; \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \"new\" struct NewExprAST : ExprAST {    NewExprAST(llvm::SMLoc loc, TypeAST *type, ExprAST *dynamicSize,      const ExprList&amp; args) ;    ~NewExprAST();    bool canBeNull();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_New;    }     TypeAST* NewType; \/\/\/&lt; \u0442\u0438\u043f, \u043f\u043e\u0434 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u043f\u0430\u043c\u044f\u0442\u044c   ExprList Args; \/\/\/&lt; \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430   ExprAST* CallExpr; \/\/\/&lt; \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 allocMem   ExprAST* DynamicSize; \/\/\/&lt; \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c   \/\/\/ \u0440\u0430\u0437\u043c\u0435\u0440 \u0434\u043b\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430   IntExprAST* SizeExpr;   \/\/\/ true \u2014 \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435    \/\/\/ \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043f\u0430\u043c\u044f\u0442\u0438   bool NeedCast; };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \"del\" struct DeleteExprAST : ExprAST {    DeleteExprAST(llvm::SMLoc loc, ExprAST *val) ;    ~DeleteExprAST();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_Delete;    }     ExprAST* Val; \/\/\/&lt; \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043f\u0430\u043c\u044f\u0442\u0438   ExprAST* DeleteCall; \/\/\/&lt; \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 freeMem };   struct IdExprAST : ExprAST {    ...   SymbolAST* getAggregate(Scope *scope);    bool canBeNull();    ... };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430 struct IndexExprAST : ExprAST {    IndexExprAST(llvm::SMLoc loc, ExprAST *left, ExprAST *right) ;    ~IndexExprAST();    bool isLValue();    SymbolAST* getAggregate(Scope *scope);    bool canBeNull();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getLValue(SLContext&amp; Context);    llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_Index;    }     ExprAST* Left; \/\/\/&lt; \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   ExprAST* Right; \/\/\/&lt; \u0438\u043d\u0434\u0435\u043a\u0441 };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0447\u043b\u0435\u043d\u0443 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b struct MemberAccessExprAST : ExprAST {    MemberAccessExprAST(llvm::SMLoc loc, ExprAST *val,                       Name *memberName) ;    ~MemberAccessExprAST();    bool isLValue();    SymbolAST* getAggregate(Scope *scope);    bool canBeNull();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getLValue(SLContext&amp; Context);    llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_MemberAccess;    }     ExprAST* Val; \/\/\/&lt; \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   Name* MemberName; \/\/\/&lt; \u0438\u043c\u044f \u0447\u043b\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   \/\/\/ \u0441\u0438\u043c\u0432\u043e\u043b \u0441 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0447\u043b\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   SymbolAST* ThisSym;   \/\/\/ \u0441\u0438\u043c\u0432\u043e\u043b \u0441 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b    SymbolAST* ThisAggr;    bool SemaDone; \/\/\/&lt; true \u2014 \u0435\u0441\u043b\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0431\u044b\u043b \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u0447\u043b\u0435\u043d\u0443 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0447\u0435\u0440\u0435\u0437 \/\/\/ \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c struct PointerAccessExprAST : ExprAST {    PointerAccessExprAST(llvm::SMLoc loc,      ExprAST *val,      Name *memberName) ;    ~PointerAccessExprAST();    bool isLValue();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getLValue(SLContext&amp; Context);    llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_PointerAccess;    }     ExprAST* Val; \/\/\/&lt; \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   Name* MemberName; \/\/\/&lt; \u0438\u043c\u044f \u0447\u043b\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   \/\/\/ \u0441\u0438\u043c\u0432\u043e\u043b \u0441 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u0447\u043b\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   SymbolAST* ThisSym; };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f struct DerefExprAST : ExprAST {    DerefExprAST(llvm::SMLoc loc, ExprAST *val) ;    ~DerefExprAST();    bool isLValue();    SymbolAST* getAggregate(Scope *scope);    bool canBeNull();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getLValue(SLContext&amp; Context);    llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_Deref;    }     ExprAST* Val; \/\/\/&lt; \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u0435\u0440\u0435\u0432\u0430 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u0437\u044f\u0442\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 struct AddressOfExprAST : ExprAST {    AddressOfExprAST(llvm::SMLoc loc, ExprAST *val) ;    ~AddressOfExprAST();    SymbolAST* getAggregate(Scope *scope);    bool canBeNull();    ExprAST* semantic(Scope* scope);    ExprAST* clone();     llvm::Value* getRValue(SLContext&amp; Context);     static bool classof(const ExprAST *E) {      return E->ExprKind == EI_AddressOf;    }     ExprAST* Val; \/\/\/&lt; \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0430\u0434\u0440\u0435\u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0438\u043b\u0438 \u0447\u043b\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b struct VarDeclAST : SymbolAST {    VarDeclAST(llvm::SMLoc loc, TypeAST *varType, Name *id,      ExprAST* value, bool inClass) ;   ...   bool needThis();    bool canBeNull();    bool contain(TypeAST* type);    ...   int OffsetOf; \/\/\/&lt; \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u043e\u043b\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435   bool NeedThis; \/\/\/&lt; true \u2014 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0447\u043b\u0435\u043d \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b  };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b struct StructDeclAST : ScopeSymbol {    StructDeclAST(llvm::SMLoc loc, Name *id,                  const SymbolList &amp;vars) ;    ~StructDeclAST();    TypeAST* getType();    void doSemantic(Scope* scope);    void doSemantic3(Scope* scope);    bool contain(TypeAST* type);     llvm::Value* generateCode(SLContext&amp; Context);    llvm::Value* getValue(SLContext&amp; Context);     static bool classof(const SymbolAST *T) {      return T->SymbolKind == SI_Struct;    }     SymbolList Vars; \/\/\/&lt; \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u0447\u043b\u0435\u043d\u043e\u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   TypeAST* ThisType; \/\/\/&lt; \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f };   \/\/\/ \u0412\u0435\u0442\u043a\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 struct ParameterSymbolAST : SymbolAST {    ...   bool canBeNull();    ... }; <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0435 \u0434\u043b\u044f AST<\/h3>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u044f\u0437\u044b\u043a \u0441 \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043d\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439.<\/p>\n<ol>\n<li>\n<p>\u0422\u0438\u043f char \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0431\u0430\u0439\u0442\u043d\u044b\u043c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c \u0442\u0438\u043f\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0434\u0438\u043d \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u0441\u0442\u0440\u043e\u043a\u0435;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u043e\u043a\u0430 \u2014 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u0442\u0438\u043f\u0430 char, \u0441 \u0442\u0435\u043c \u043e\u0442\u043b\u0438\u0447\u0438\u0435\u043c \u043e\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439, \u0447\u0442\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b (\u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043d\u0430\u0434 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438). \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u043c\u0438 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u2014 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u0440\u0435\u0441\u043e\u043c \u043d\u0430 \u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 ++\/&#8212;, \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438, +\/- \u0441 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f *. \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0438\u043b\u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043e\u0439 0. \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 char \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d \u0432 \u0441\u0442\u0440\u043e\u043a\u0443;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b \u2014 \u0431\u043b\u043e\u043a \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0438\u0437 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u0434\u043d\u043e\u0433\u043e \u0438 \u0442\u043e\u0433\u043e \u0436\u0435 \u0442\u0438\u043f\u0430. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u041d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432. \u041c\u0430\u0441\u0441\u0438\u0432 char \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d \u0432 \u0441\u0442\u0440\u043e\u043a\u0443. \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u2014 \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u043e\u043b\u0435\u0439 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432. \u041f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u043c \u043f\u043e\u043b\u044f\u043c. \u0414\u0430\u043d\u043d\u044b\u0439 \u0442\u0438\u043f \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0441\u0441\u044b\u043b\u043a\u0438 (\u0437\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u044f \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0441\u044b\u043b\u043e\u043a \u0447\u0435\u0440\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438);<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043f\u043e\u043b\u044f\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c \u0441 \u0442\u0438\u043f\u043e\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c \u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u044b \u043a \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0438\u043c\u0435\u044e\u0442 \u043e\u0431\u0449\u0438\u0439 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f;<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043a lvalue \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c;<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 new \u0438 del \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u043b\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0431\u043b\u043e\u043a\u043e\u0432 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e.<\/p>\n<p>\u0421\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">SymbolAST* TypeAST::getSymbol() {   return nullptr; }  TypeAST *BuiltinTypeAST::get(int type) {   static TypeAST *builtinTypes[] = {     new BuiltinTypeAST(TI_Void),     new BuiltinTypeAST(TI_Bool),     new BuiltinTypeAST(TI_Int),     new BuiltinTypeAST(TI_Float),     new BuiltinTypeAST(TI_Char),     new BuiltinTypeAST(TI_String)   };    assert(type >= TI_Void &amp;&amp; type &lt;= TI_String);   return builtinTypes[type]; }  bool BuiltinTypeAST::implicitConvertTo(TypeAST* newType) {   \/\/ \u0421\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0439   static bool convertResults[TI_String + 1][TI_String + 1] = {     \/\/ void  bool   int    float  char   string     { false, false, false, false, false, false }, \/\/ void     { false, true,  true,  true,  true,  false }, \/\/ bool     { false, true,  true,  true,  true,  false }, \/\/ int     { false, true,  true,  true,  false, false }, \/\/ float     { false, true,  true,  true,  true,  false }, \/\/ char     { false, true,  false, false, false, true  }  \/\/ string   };   \/\/ \u0422\u043e\u043b\u044c\u043a\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u044b \u0434\u0440\u0443\u0433 \u0432 \u0434\u0440\u0443\u0433\u0430   if (newType->TypeKind > TI_String) {     return false;   }    return convertResults[TypeKind][newType->TypeKind]; }  void BuiltinTypeAST::toMangleBuffer(llvm::raw_ostream&amp; output) {   switch (TypeKind) {     case TI_Void : output &lt;&lt; \"v\"; break;     case TI_Bool : output &lt;&lt; \"b\"; break;     case TI_Int : output &lt;&lt; \"i\"; break;     case TI_Float : output &lt;&lt; \"f\"; break;     case TI_Char : output &lt;&lt; \"c\"; break;     case TI_String : output &lt;&lt; \"PKc\"; break;     default: assert(0 &amp;&amp; \"Should never happen\"); break;   } }  TypeAST* ArrayTypeAST::semantic(Scope* scope) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0442\u0438\u043f\u0430   Next = Next->semantic(scope);   \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c MangleName   calcMangle();   return this; }  bool ArrayTypeAST::implicitConvertTo(TypeAST* newType) {   TypeAST* next1 = Next;   TypeAST* next2 = nullptr;    \/\/ char[] \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 string   if (Next->isChar() &amp;&amp; newType->isString()) {     return true;   }    \/\/ \u0415\u0441\u043b\u0438 newType \u043d\u0435 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c, \u0442\u043e \u043c\u044b \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c    \/\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435   if (!(isa&lt;PointerTypeAST>(newType)         || isa&lt;ArrayTypeAST>(newType))) {     return false;   }    \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432   if (isa&lt;PointerTypeAST>(newType)) {     next2 = ((PointerTypeAST*)newType)->Next;   } else if (isa&lt;ArrayTypeAST>(newType)) {     ArrayTypeAST* arrayType = (ArrayTypeAST*)newType;      \/\/ \u0414\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0435\u0449\u0435 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u044b     if (arrayType->Dim != Dim) {       return false;     }      next2 = arrayType->Next;   }    \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043b\u044e\u0431\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432 void*   if (next2->isVoid()) {     return true;   }    \/\/ \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f   return next1->equal(next2); }  void ArrayTypeAST::toMangleBuffer(llvm::raw_ostream&amp; output) {   output &lt;&lt; \"A\" &lt;&lt; Dim &lt;&lt; \"_\";   Next->toMangleBuffer(output); }  TypeAST* PointerTypeAST::semantic(Scope* scope) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u0431\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0442\u0438\u043f\u0430   Next = Next->semantic(scope);   \/\/ \u0441\u043e\u0437\u0434\u0430\u0435\u043c MangleName   calcMangle();   return this; }  bool PointerTypeAST::implicitConvertTo(TypeAST* newType) {   \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u0432 bool   if (newType->isBool()) {     return true;   }      \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 char* \u0432 string   if (Next->isChar() &amp;&amp; newType->isString()) {     return true;   }      \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043b\u044e\u0431\u043e\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0442\u0438\u043f \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f   if (!isa&lt;PointerTypeAST>(newType)) {     return false;   }    PointerTypeAST* ptr2 = (PointerTypeAST*)newType;   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0442\u0438\u043f \u0434\u043b\u044f newType   TypeAST* next2 = ptr2->Next;    \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0442\u0438\u043f\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442   if (Next->equal(next2)) {     return true;   }    TypeAST* next1 = Next;    \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432 void*   if (next2->isVoid()) {     return true;   }    return false; }  void PointerTypeAST::toMangleBuffer(llvm::raw_ostream&amp; output) {   output &lt;&lt; \"P\";   Next->toMangleBuffer(output); }  void mangleAggregateName(llvm::raw_ostream&amp; output,                          SymbolAST* thisSym) {   assert(thisSym &amp;&amp; thisSym->isAggregate());   SymbolAST* sym = thisSym;    output &lt;&lt; \"N\";    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u0438\u0434\u0430 N \u0414\u043b\u0438\u043d\u0430 \u0418\u043c\u044f E \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u043e\u0432\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0438\u043b\u0438    \/\/ N \u0414\u043b\u0438\u043d\u04301 \u0418\u043c\u044f1 \u0414\u043b\u0438\u043d\u04302 \u0418\u043c\u044f2 E \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440   \/\/ \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:   \/\/   A.B.C \u0431\u0443\u0434\u0435\u0442 N1A1B1CE   \/\/   A \u0431\u0443\u0434\u0435\u0442 N1AE    for ( ; ; ) {     if (!sym || !sym->isAggregate()) {       output &lt;&lt; \"E\";       return;     }      output &lt;&lt; sym->Id->Length &lt;&lt; StringRef(sym->Id->Id,                                            sym->Id->Length);     sym = sym->Parent;   } }  TypeAST* StructTypeAST::semantic(Scope* scope) {   calcMangle();   return this; }  bool StructTypeAST::implicitConvertTo(TypeAST* newType) {   return false; }  void StructTypeAST::toMangleBuffer(llvm::raw_ostream&amp; output) {   mangleAggregateName(output, ThisDecl); }  SymbolAST* StructTypeAST::getSymbol() {   return ThisDecl; }  TypeAST* FuncTypeAST::semantic(Scope* scope) {   if (!ReturnType) {     \/\/ \u0415\u0441\u043b\u0438 \u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043d\u0435 \u0431\u044b\u043b \u0437\u0430\u0434\u0430\u043d \u0442\u0438\u043f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u043e      \/\/ \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u0430\u043a \"void\"     ReturnType = BuiltinTypeAST::get(TypeAST::TI_Void);   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043b\u044f \u0442\u0438\u043f\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e    \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f   ReturnType = ReturnType->semantic(scope);      \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432   for (ParameterList::iterator it = Params.begin(),        end = Params.end(); it != end; ++it) {     (*it)->Param = (*it)\u2192Param\u2192semantic(scope);      \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435      \/\/ \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438      if ((*it)->Param->isAggregate()) {       scope->report(SMLoc(),                     diag::ERR_SemaAggregateAsFunctionParameter);       return nullptr;     }   }        \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0438 \u043a\u043b\u0430\u0441\u0441\u043e\u0432\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435   \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439   if (ReturnType &amp;&amp; (ReturnType->isAggregate()                      || isa&lt;ArrayTypeAST>(ReturnType))) {     scope->report(SMLoc(),                   diag::ERR_SemaArrayOrAggregateAsReturnType);     return nullptr;   }    calcMangle();   return this; }  TypeAST* QualifiedTypeAST::semantic(Scope* scope) {   SymbolAST* sym = nullptr;      \/\/ \u041c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0439\u0442\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043f\u043e\u043b\u043d\u043e\u043c\u0443 \u0438\u043c\u0435\u043d\u0438   for (QualifiedName::iterator it = QualName.begin(),        end = QualName.end(); it != end; ++it) {      if (sym) {       \/\/ \u0418\u0449\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e       sym = sym->find((*it));        if (!sym) {         scope->report(SMLoc(), diag::ERR_SemaUndefinedIdentifier,                        (*it)->Id);         return nullptr;       }     } else {       \/\/ \u0418\u0449\u0435\u043c \u0438\u043c\u044f \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438       sym = scope->find((*it));        if (!sym) {         scope->report(SMLoc(), diag::ERR_SemaUndefinedIdentifier,                        (*it)->Id);         return nullptr;       }     }   }    \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u0438\u043f \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430   return sym->getType(); }  bool QualifiedTypeAST::implicitConvertTo(TypeAST* ) {   assert(0 &amp;&amp; \"QualifiedTypeAST::implicitConvertTo should never \"          \" be reached\");   return false; }  void QualifiedTypeAST::toMangleBuffer(llvm::raw_ostream&amp; ) {   assert(0 &amp;&amp; \"QualifiedTypeAST::toMangleBuffer should never be \"          \"reached\"); }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">SymbolAST* ExprAST::getAggregate(Scope *) {   assert(0 &amp;&amp; \"ExprAST::getAggregaet should never be reached\");   return nullptr; }  bool ExprAST::canBeNull() {   return false; }  bool StringExprAST::isTrue() {   return true; }  ExprAST* StringExprAST::semantic(Scope* ) {   return this; }  ExprAST* StringExprAST::clone() {   return new StringExprAST(Loc, StringRef(Val)); }  ExprAST* ProxyExprAST::semantic(Scope* scope) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0431\u044b\u043b\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u043e \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043d\u0435    \/\/ \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0435\u0431\u044f \u043f\u043e\u0441\u043b\u0435 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   ExprAST* tmp = OriginalExpr->semantic(scope);   assert(tmp == OriginalExpr);   ExprType = OriginalExpr->ExprType;   return this; }  ExprAST* ProxyExprAST::clone() {   return new ProxyExprAST(Loc, OriginalExpr); }  bool NewExprAST::canBeNull() {   return true; }  ExprAST* NewExprAST::semantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   if (ExprType) {     return this;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043b\u044f \u0442\u0438\u043f\u0430   NewType = NewType->semantic(scope);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c   if (isa&lt;ArrayTypeAST>(NewType) &amp;&amp; !DynamicSize) {     \/\/ \u041c\u044b \u0432\u044b\u0434\u0435\u043b\u044f\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u044c \u043a\u0430\u043a \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f      \/\/ \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c     ArrayTypeAST* arrayType = (ArrayTypeAST*)NewType;     ExprType = new PointerTypeAST(arrayType->Next, false);     ExprType = ExprType->semantic(scope);   } else {     \/\/ \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c     ExprType = new PointerTypeAST(NewType, false);     ExprType = ExprType->semantic(scope);   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 NewType \u043d\u0430    \/\/ \u0446\u0435\u043b\u0435\u0432\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435 \u0438 \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043f\u0440\u043e\u043a\u0441\u0438, \u0442.\u00a0\u043a.    \/\/ \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430   SizeExpr = new IntExprAST(Loc, 0);   ExprAST* proxy = new ProxyExprAST(Loc, SizeExpr);    \/\/ \u0414\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c   \/\/ \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440   if (DynamicSize) {     proxy = new BinaryExprAST(Loc, tok::Mul, DynamicSize, proxy);   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 allocMem \u0434\u043b\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438   \/\/ \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430   ExprList args;   args.push_back(proxy);   CallExpr = new CallExprAST(Loc, new IdExprAST(Loc, Name::New),                              args);    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430   \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u0438   CallExpr = CallExpr->semantic(scope);    return this; }  ExprAST* NewExprAST::clone() {   ExprList exprs;   ExprList::iterator it = Args.begin();   ExprList::iterator end = Args.end();    \/\/ \u0414\u0435\u043b\u0430\u0435\u043c \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0441\u0435\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 (\u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0435\u0441\u0442\u044c)   for ( ; it != end; ++it) {     exprs.push_back((*it)->clone());   }    return new NewExprAST(Loc, NewType, DynamicSize, exprs); }  ExprAST* DeleteExprAST::semantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   if (DeleteCall) {     return this;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043e\u0447\u0438\u0441\u0442\u043a\u0438   Val = Val->semantic(scope);    \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u0442\u0438\u043f\u043e\u043c void   if (!Val->ExprType || Val->ExprType->isVoid()) {     scope->report(Loc, diag::ERR_SemaCantDeleteVoid);     return nullptr;   }    \/\/ \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043e\u0447\u0438\u0441\u0442\u043a\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439   if (!isa&lt;PointerTypeAST>(Val->ExprType)) {     scope->report(Loc, diag::ERR_SemaCantDeleteNonPointer);     return nullptr;   }    PointerTypeAST* ptrType = (PointerTypeAST*)Val->ExprType;    ExprAST* deleteArg = Val->clone();   ExprList args;    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 freeMem   \/\/ \u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u0438\u0431\u043e Val, \u043b\u0438\u0431\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0437\u043e\u0432\u0430    \/\/ \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430   args.push_back(deleteArg);      \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0432\u044b\u0437\u043e\u0432\u0430 freeMem \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0435\u0433\u043e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438   DeleteCall = new CallExprAST(     Loc,     new IdExprAST(Loc, Name::Delete),     args   );   DeleteCall = DeleteCall->semantic(scope);   \/\/ \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 void   ExprType = BuiltinTypeAST::get(TypeAST::TI_Void);    return this; }  ExprAST* DeleteExprAST::clone() {   return new DeleteExprAST(Loc, Val->clone()); }  bool IdExprAST::isLValue() {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043d\u0435\u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438, \u0442.\u00a0\u043a. \u043c\u044b \u0438\u0445 \u043d\u0435 \u043c\u043e\u0436\u0435\u043c    \/\/ \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c   if (isa&lt;PointerTypeAST>(ExprType)) {     return !((PointerTypeAST*)ExprType)->IsConstant;   }    return true; }  SymbolAST* IdExprAST::getAggregate(Scope *) {   return ThisSym; }  bool IdExprAST::canBeNull() {   return ThisSym->canBeNull(); }  bool IndexExprAST::isLValue() {   \/\/ \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438   if (Left->ExprType->isString()) {     return false;   }    return true; }  SymbolAST* IndexExprAST::getAggregate(Scope *scope) {   \/\/ \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b \u0434\u043b\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435    \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441   if (!ExprType->isAggregate()) {     scope->report(Loc, diag::ERR_SemaNonAggregateDotOperand);     return nullptr;   }   \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f   return ExprType->getSymbol(); }  bool IndexExprAST::canBeNull() {   \/\/ \u0415\u0441\u043b\u0438 \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c, \u0442\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442    \/\/ \u0431\u044b\u0442\u044c null   if (isa&lt;PointerTypeAST>(ExprType)) {     return true;   }    return false; }  ExprAST* IndexExprAST::semantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   if (ExprType) {     return this;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u043e\u0431\u043e\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432   Left = Left->semantic(scope);   Right = Right->semantic(scope);    \/\/ \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u044b, \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 \u0438 \u0441\u0442\u0440\u043e\u043a\u0438   if (Left->ExprType &amp;&amp; !isa&lt;ArrayTypeAST>(Left->ExprType)     &amp;&amp; !isa&lt;PointerTypeAST>(Left->ExprType)     &amp;&amp; !Left->ExprType->isString()) {     scope->report(Loc, diag::ERR_SemaNonIndexableType);     return nullptr;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043a int, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e    \/\/ \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e   if (!Right->ExprType->isInt()) {     Right = new CastExprAST(       Right->Loc,       Right,       BuiltinTypeAST::get(TypeAST::TI_Int)     );     Right = Right->semantic(scope);   }    \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f   if (isa&lt;ArrayTypeAST>(Left->ExprType)) {     ExprType = ((ArrayTypeAST*)Left->ExprType)->Next;   } else if (isa&lt;PointerTypeAST>(Left->ExprType)) {     ExprType = ((PointerTypeAST*)Left->ExprType)->Next;   } else {     ExprType = BuiltinTypeAST::get(TypeAST::TI_Char);   }    return this; }  ExprAST* IndexExprAST::clone() {   return new IndexExprAST(Loc, Left->clone(), Right->clone()); }  bool MemberAccessExprAST::isLValue() {   return true; }  SymbolAST* MemberAccessExprAST::getAggregate(Scope *) {   return ThisSym; }  bool MemberAccessExprAST::canBeNull() {   return Val->canBeNull(); }  ExprAST* MemberAccessExprAST::semantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   if (SemaDone) {     return this;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u043b\u0435\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   Val = Val->semantic(scope);    \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0432 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438    \/\/ \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438   if (isa&lt;IdExprAST>(Val) &amp;&amp; !((IdExprAST*)Val)->Val) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u044f     SymbolAST* moduleSym = scope->find(0);     assert(moduleSym);     \/\/ \u041f\u043e\u0438\u0441\u043a \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0434\u0443\u043b\u0435     SymbolAST* thisSym = moduleSym->find(MemberName);      \/\/ \u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 \u043e\u0448\u0438\u0431\u043a\u0438, \u0435\u0441\u043b\u0438 \u0441\u0438\u043c\u0432\u043e\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d     if (!thisSym) {       scope->report(Loc, diag::ERR_SemaUndefinedMember,                     MemberName->Id);       return nullptr;     }      \/\/ \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c MemberAccessExprAST \u043d\u0430 IdExprAST \u0441 \u043f\u0440\u0435\u0434\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438     \/\/ \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438     IdExprAST* newExpr = new IdExprAST(Loc, MemberName);      newExpr->ExprType = thisSym->getType();      newExpr->ThisSym = thisSym;     delete this;     return newExpr;   }      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   if (!Val->ExprType) {     scope->report(Loc, diag::ERR_SemaInvalidOperandForMemberAccess);     return nullptr;   }    \/\/ \u0415\u0441\u043b\u0438 Val \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430 \u0430\u0433\u0440\u0435\u0433\u0430\u0442, \u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e    \/\/ \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f. \u0422.\u0435. \u0432 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438 C++,   \/\/ \u043c\u044b \u0441\u0447\u0438\u0442\u0430\u0435\u043c agg->a \u044d\u043a\u0432\u0438\u0432\u0430\u043b\u0435\u043d\u0442\u043e\u043c (*agg).a   if (isa&lt;PointerTypeAST>(Val->ExprType) &amp;&amp;      ((PointerTypeAST*)Val->ExprType)->Next->isAggregate()) {     \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0435\u0433\u043e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438     Val = new DerefExprAST(Loc, Val);     Val = Val->semantic(scope);   }    \/\/ Val \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c lvalue   if (!Val->isLValue()) {     scope->report(Loc, diag::ERR_SemaNonLValueForMemberAccess);     return nullptr;   }    \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0433\u0440\u0435\u0433\u0430\u0442   SymbolAST* aggSym = Val->getAggregate(scope);    \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 A.b, \u0433\u0434\u0435 A \u2014 \u043a\u043b\u0430\u0441\u0441 \u0438\u043b\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430.    \/\/ \u042d\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c a.b, \u0433\u0434\u0435 a \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 A   if (isa&lt;IdExprAST>(Val) &amp;&amp; aggSym &amp;&amp; aggSym->isAggregate()) {     scope->report(Loc, diag::ERR_SemaMemberAccessOnAggregateType);     return nullptr;   }      \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u043c\u0438   if (!aggSym || !aggSym->getType()->isAggregate()) {     scope->report(Loc, diag::ERR_SemaNonAggregateDotOperand);     return nullptr;   }    \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430   if (!aggSym->isAggregate()) {     aggSym = aggSym->getType()->getSymbol();   }    \/\/ \u041f\u043e\u0438\u0441\u043a \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0432 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0435   ThisSym = aggSym->find(MemberName);   ThisAggr = aggSym;    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0439 \u0430\u0433\u0440\u0435\u0433\u0430\u0442 \u0438\u043c\u0435\u0435\u0442 \u0447\u043b\u0435\u043d \u0441 \u0442\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u0435\u043c   if (!ThisSym) {     scope->report(Loc, diag::ERR_SemaUndefinedMember,                   MemberName->Id);     return nullptr;   }      \/\/ \u0417\u0430\u043f\u0440\u0435\u0442 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0432\u0438\u0434\u0430 a.A, \u0433\u0434\u0435 A \u044d\u0442\u043e \u0430\u0433\u0440\u0435\u0433\u0430\u0442   if (ThisSym->isAggregate()) {     scope->report(Loc,                   diag::ERR_SemaAggregateTypeAsMemberAccessOperand);     return nullptr;   }    \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0438\u043f\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438   ExprType = ThisSym->getType();   SemaDone = true;    return this; }  ExprAST* MemberAccessExprAST::clone() {   return new MemberAccessExprAST(Loc, Val->clone(), MemberName); }  bool PointerAccessExprAST::isLValue() {   return true; }  ExprAST* PointerAccessExprAST::semantic(Scope* scope) {   \/\/ \u041f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c expr->member \u0432 \u0432\u0438\u0434\u0435 (*expr).member, \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c    \/\/ \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0441\u0442\u0430\u0440\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435    ExprAST* newExpr = new DerefExprAST(Loc, Val);   newExpr = new MemberAccessExprAST(Loc, newExpr, MemberName);   Val = nullptr;   delete this;   return newExpr->semantic(scope); }  ExprAST* PointerAccessExprAST::clone() {   return new PointerAccessExprAST(Loc, Val->clone(), MemberName); }  bool DerefExprAST::isLValue() {   return true; }  SymbolAST* DerefExprAST::getAggregate(Scope *scope) {   \/\/ \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b \u0434\u043b\u044f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435    \/\/ \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441   if (!ExprType->isAggregate()) {     scope->report(Loc, diag::ERR_SemaNonAggregateDotOperand);     return nullptr;   }   \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f   return ExprType->getSymbol(); }  bool DerefExprAST::canBeNull() {   return true; }  ExprAST* DerefExprAST::semantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   if (ExprType) {     return this;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   Val = Val->semantic(scope);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430   if (isa&lt;AddressOfExprAST>(Val)) {     \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c * \u0438 &amp;     ExprAST* result = ((AddressOfExprAST*)Val)->Val->clone();     delete this;     return result->semantic(scope);   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u043e\u0432   if (Val->ExprType) {     \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a     if (Val->ExprType->isString()) {       \/\/ \u0417\u0430\u043f\u0440\u0435\u0442 \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a       if (Val->isConst()) {         scope->report(Loc, diag::ERR_SemaConstStringDeRef);         return nullptr;       }       \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u0438\u043f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u043a\u0430\u043a char       ExprType = BuiltinTypeAST::get(TypeAST::TI_Char);       return this;     \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438     } else if (!isa&lt;PointerTypeAST>(Val->ExprType)) {       scope->report(Loc, diag::ERR_SemaUnDereferencableType);       return nullptr;     }   } else {     scope->report(Loc, diag::ERR_SemaUnDereferencableType);     return nullptr;   }   \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0442\u0438\u043f\u0430 \u0434\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438   ExprType = ((PointerTypeAST*)Val->ExprType)->Next;   return this; }  ExprAST* DerefExprAST::clone() {   return new DerefExprAST(Loc, Val->clone()); }  SymbolAST* AddressOfExprAST::getAggregate(Scope *scope) {   return Val->getAggregate(scope); }  bool AddressOfExprAST::canBeNull() {   \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0434\u043b\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432   if (isa&lt;IdExprAST>(Val) &amp;&amp; !Val->canBeNull()) {     return false;   }    return true; }  ExprAST* AddressOfExprAST::semantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0439 \u0437\u0430\u043f\u0443\u0441\u043a \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430   if (ExprType) {     return this;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   Val = Val->semantic(scope);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   if (!Val->ExprType) {     scope->report(Loc, diag::ERR_SemaAddressExpressionNoType);     return nullptr;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435   if (isa&lt;DerefExprAST>(Val)) {     \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c &amp; \u0438 *     ExprAST* result = ((DerefExprAST*)Val)->Val->clone();     delete this;     return result->semantic(scope);   }    \/\/ \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0437\u044f\u0442\u044c \u0430\u0434\u0440\u0435\u0441 \u0442\u043e\u043b\u044c\u043a\u043e \u0443 lvalue   if (!Val->isLValue()) {     scope->report(Loc, diag::ERR_SemaAddressOfNonLValue);     return nullptr;   }    \/\/ \u0422\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u043d\u0430 \u0442\u0438\u043f \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   ExprType = new PointerTypeAST(Val->ExprType, false);   ExprType = ExprType->semantic(scope);    return this; }  ExprAST* AddressOfExprAST::clone() {   return new AddressOfExprAST(Loc, Val->clone()); }  ExprAST* CastExprAST::semantic(Scope* scope) {   ...    \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432   if (isa&lt;ArrayTypeAST>(ExprType)) {     scope->report(Loc, diag::ERR_SemaArrayInCast);     return nullptr;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u0438 \u0438\u0445 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c   if (isa&lt;PointerTypeAST>(ExprType) &amp;&amp;      !Val->ExprType->implicitConvertTo(ExprType)) {     scope->report(Loc, diag::ERR_SemaIncompatiblePointerTypes);     return nullptr;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0438\u043f\u044b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b   if (!Val->ExprType->implicitConvertTo(ExprType)) {     scope->report(Loc, diag::ERR_SemaInvalidCast);     return nullptr;   }    SemaDone = true;   return this; }  ExprAST* UnaryExprAST::semantic(Scope* scope) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0431\u044b\u043b \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0437\u0430\u0434\u0430\u043d   if (!Val) {     assert(0 &amp;&amp; \"Invalid expression value\");     return nullptr;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   Val = Val->semantic(scope);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0442\u0438\u043f\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430, \u0442.\u00a0\u043a. \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c    \/\/ \"void\"   if (!Val->ExprType || Val->ExprType->isVoid()) {     scope->report(Loc, diag::ERR_SemaOperandIsVoid);     return nullptr;   }    \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\u043c\u0438 \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438   if (Val->ExprType->isAggregate()) {     scope->report(Loc, diag::ERR_SemaAggregateAsExpression);     return nullptr;   }    \/\/ \u0414\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e ++\/--   if (Val->ExprType->isString() &amp;&amp; (Op != tok::MinusMinus                                      &amp;&amp; Op != tok::PlusPlus)) {     scope->report(Loc,                   diag::ERR_SemaInvalidUnaryExpressionForString);     return nullptr;   }    \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u043c\u0438   if (isa&lt;ArrayTypeAST>(Val->ExprType)) {     scope->report(Loc,                   diag::ERR_SemaInvalidUnaryExpressionForArray);     return nullptr;   }    \/\/ \u0414\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e ++\/--   if (isa&lt;PointerTypeAST>(Val->ExprType)      &amp;&amp; (Op != tok::MinusMinus &amp;&amp; Op != tok::PlusPlus)) {     scope->report(Loc,                   diag::ERR_SemaInvalidUnaryExpressionForPointer);     return nullptr;   }    \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u0431\u0443\u043b\u0435\u0432\u044b\u043c\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438   if (Val->ExprType->isBool() &amp;&amp; (Op == tok::Plus                                    || Op == tok::Minus)) {     scope->report(Loc, diag::ERR_SemaInvalidBoolForUnaryOperands);     return nullptr;   }    \/\/ \u0421\u043f\u0438\u0441\u043e\u043a \u0437\u0430\u043c\u0435\u043d:   \/\/  +Val to Val   \/\/  -Val to 0 - Val   \/\/  ~intVal to intVal ^ -1   \/\/  ++id to id = id + 1    \/\/  --id to id = id - 1   \/\/  !Val to Val == 0    ExprAST* result = this;    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u0438\u043f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430, \u0434\u043b\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0439 \u0437\u0430\u043c\u0435\u043d\u044b   switch (Op) {     \/\/ \"+\" - noop     case tok::Plus: result = Val; break;      case tok::Minus:        \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0432 0 - Val \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u0442\u0438\u043f\u0430 Val       if (Val->ExprType->isFloat()) {         result = new BinaryExprAST(           Val->Loc,            tok::Minus,            new FloatExprAST(Val->Loc, 0),            Val         );       } else {         result = new BinaryExprAST(           Val->Loc,            tok::Minus,            new IntExprAST(Val->Loc, 0),            Val         );       }       break;      case tok::Tilda:       \/\/ ~ \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u043c       if (!Val->ExprType->isInt()) {         scope->report(Loc,                        diag::ERR_SemaInvalidOperandForComplemet);         return nullptr;       } else {         \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0432 Val ^ -1         result = new BinaryExprAST(           Val->Loc,            tok::BitXor,            Val,            new IntExprAST(Val->Loc, -1)         );         break;       }      case tok::PlusPlus:     case tok::MinusMinus:       if ((!Val->ExprType->isInt()          &amp;&amp; !isa&lt;PointerTypeAST>(Val->ExprType)         &amp;&amp; !Val->ExprType->isString()) || !Val->isLValue()) {         scope->report(Loc,                        diag::ERR_SemaInvalidPostfixPrefixOperand);         return nullptr;       } else {         \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f IndexExprAST \u0438 MemberAccessAST          \/\/ \u0438 \u0441\u0442\u0440\u043e\u043a         if (isa&lt;IndexExprAST>(Val) || isa&lt;MemberAccessExprAST>(Val)           || Val->ExprType->isString()) {           ExprType = Val->ExprType;           return this;         }         \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439         if (isa&lt;PointerTypeAST>(Val->ExprType)) {           \/\/ \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c ++ ptr \u0438\u043b\u0438 -- ptr \u043d\u0430 ptr = &amp;ptr[1] \u0438\u043b\u0438            \/\/ ptr = &amp;ptr[-1]           ExprAST* val = Val;           ExprAST* valCopy = Val->clone();           result = new BinaryExprAST(             Val->Loc,             tok::Assign,             val,             new AddressOfExprAST(               Val->Loc,               new IndexExprAST(                 Val->Loc,                 valCopy,                  new IntExprAST(                   Val->Loc,                   (Op == tok::PlusPlus) ? 1 : -1                 )               )             )           );         } else {           \/\/ \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \"++\" id \u0438\u043b\u0438 \"--\" id \u043d\u0430 id = id + 1            \/\/ or id = id + -1           ExprAST* val = Val;           ExprAST* valCopy = Val->clone();           result = new BinaryExprAST(             Val->Loc,             tok::Assign,              val,             new BinaryExprAST(               Val->Loc,               tok::Plus,               valCopy,               new IntExprAST(                 Val->Loc,                 (Op == tok::PlusPlus) ? 1 : -1               )             )           );         }       }       break;      case tok::Not:       \/\/ \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043d\u0430 Val == 0       result = new BinaryExprAST(         Val->Loc,         tok::Equal,         Val,         new IntExprAST(Val->Loc, 0)       );       break;      default:       \/\/ \u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438       assert(0 &amp;&amp; \"Invalid unary expression\");       return nullptr;   }    if (result != this) {     \/\/ \u0422.\u043a. \u0441\u0442\u0430\u0440\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0431\u044b\u043b\u043e \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u043e, \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u043f\u0430\u043c\u044f\u0442\u044c \u0438      \/\/ \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u043d\u043e\u0432\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     Val = nullptr;     delete this;     return result->semantic(scope);   }    return result; }  ExprAST* BinaryExprAST::semantic(Scope* scope) {   \/\/ \u0421\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0443\u0436\u0435 \u0431\u044b\u043b \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d \u0440\u0430\u043d\u0435\u0435   if (ExprType) {     return this;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0441 \u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b   LeftExpr = LeftExpr->semantic(scope);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \"++\" \u0438\u043b\u0438 \"--\", \u0442.\u00a0\u043a. \u044d\u0442\u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0438\u043c\u0435\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e    \/\/ \u043e\u0434\u0438\u043d \u043e\u043f\u0435\u0440\u0430\u043d\u0434   if (Op == tok::PlusPlus || Op == tok::MinusMinus) {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u0438 \u0442\u0438\u043f\u043e\u0432 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 ++\/--     if (!LeftExpr->isLValue() || (!LeftExpr->ExprType->isInt()       &amp;&amp; !isa&lt;PointerTypeAST>(LeftExpr->ExprType)       &amp;&amp; !LeftExpr->ExprType->isString())) {       scope->report(Loc, diag::ERR_SemaInvalidPostfixPrefixOperand);       return nullptr;     }      \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     ExprType = LeftExpr->ExprType;     return this;   }    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b   RightExpr = RightExpr->semantic(scope);    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u0431\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0438\u043c\u0435\u044e\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0442\u0438\u043f\u044b   if (!LeftExpr->ExprType || !RightExpr->ExprType) {     scope->report(Loc,                    diag::ERR_SemaUntypedBinaryExpressionOperands);     return nullptr;   }    \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u043c\u0438   if (LeftExpr->ExprType->isAggregate()       || RightExpr->ExprType->isAggregate()) {     scope->report(Loc, diag::ERR_SemaAggregateAsExpression);     return nullptr;   }    \/\/ \",\" \u0438\u043c\u0435\u0435\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0438 \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441    \/\/ \u0442\u0438\u043f\u043e\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b   if (Op == tok::Comma) {     ExprType = RightExpr->ExprType;     return this;   }    \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f \"void\"   if (LeftExpr->ExprType->isVoid()     || RightExpr->ExprType->isVoid()) {     scope->report(Loc, diag::ERR_SemaOperandIsVoid);     return nullptr;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f, \u0442.\u00a0\u043a. \u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u0441\u0435\u0433\u0434\u0430    \/\/ \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0442\u0438\u043f \"bool\"   switch (Op) {     case tok::Less:     case tok::Greater:     case tok::LessEqual:     case tok::GreaterEqual:     case tok::Equal:     case tok::NotEqual:       \/\/ \u0417\u0430\u043f\u0440\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a, \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0432        \/\/ \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432 \u0434\u043b\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f       if (LeftExpr->ExprType->isString()         || isa&lt;PointerTypeAST>(LeftExpr->ExprType)         || isa&lt;ArrayTypeAST>(LeftExpr->ExprType)         || RightExpr->ExprType->isString()         || isa&lt;PointerTypeAST>(RightExpr->ExprType)         || isa&lt;ArrayTypeAST>(RightExpr->ExprType)) {         scope->report(Loc, diag::ERR_SemaInvalidTypeForComparison);         return nullptr;       }        \/\/ \u0415\u0441\u043b\u0438 \u043b\u0435\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \"bool\", \u0442\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432        \/\/ \"int\"       if (LeftExpr->ExprType->isBool()) {         LeftExpr = new CastExprAST(LeftExpr->Loc, LeftExpr,            BuiltinTypeAST::get(TypeAST::TI_Int));         LeftExpr = LeftExpr->semantic(scope);       }        \/\/ \u0415\u0441\u043b\u0438 \u043b\u0435\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f char, \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e       \/\/ \u0432 int       if (LeftExpr->ExprType->isChar()) {         LeftExpr = new CastExprAST(LeftExpr->Loc, LeftExpr,            BuiltinTypeAST::get(TypeAST::TI_Int));         LeftExpr = LeftExpr->semantic(scope);       }        \/\/ \u041e\u043f\u0435\u0440\u0430\u043d\u0434\u044b \u0434\u043b\u044f \"&lt;\", \"&lt;=\", \">\", \">=\", \"==\" \u0438 \"!=\" \u0432\u0441\u0435\u0433\u0434\u0430        \/\/ \u0434\u043e\u043b\u0436\u043d\u044b \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u0442\u043e       \/\/ \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435       if (!LeftExpr->ExprType->equal(RightExpr->ExprType)) {         \/\/ Perform conversion         RightExpr = new CastExprAST(           RightExpr->Loc,            RightExpr,            LeftExpr->ExprType         );         RightExpr = RightExpr->semantic(scope);       }              \/\/ \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u2014 \"bool\"       ExprType = BuiltinTypeAST::get(TypeAST::TI_Bool);       return this;      case tok::LogOr:     case tok::LogAnd:       \/\/ \u0414\u043b\u044f \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439 \u043e\u0431\u0430 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f       \/\/ \u0432 \"bool\"       if (!LeftExpr->ExprType->implicitConvertTo(           BuiltinTypeAST::get(TypeAST::TI_Bool)         ) || !RightExpr->ExprType->implicitConvertTo(           BuiltinTypeAST::get(TypeAST::TI_Bool)         )       ) {         scope->report(Loc, diag::ERR_SemaCantConvertToBoolean);         return nullptr;       }        \/\/ \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u2014 \"bool\"       ExprType = BuiltinTypeAST::get(TypeAST::TI_Bool);       return this;      default:       \/\/ \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u043d\u0438\u0436\u0435       break;   }    \/\/ \u0415\u0441\u043b\u0438 \u043b\u0435\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \"bool\", \u0442\u043e \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0433\u043e \u0432 \"int\"   if (LeftExpr->ExprType == BuiltinTypeAST::get(TypeAST::TI_Bool)) {     LeftExpr = new CastExprAST(LeftExpr->Loc, LeftExpr,        BuiltinTypeAST::get(TypeAST::TI_Int));     LeftExpr = LeftExpr->semantic(scope);   }    \/\/ \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u0442\u0438\u043f\u043e\u043c \u043b\u0435\u0432\u043e\u0433\u043e   \/\/ \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   ExprType = LeftExpr->ExprType;    \/\/ \u0414\u043b\u044f \"=\" \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430   if (Op == tok::Assign) {     \/\/ \u0415\u0441\u043b\u0438 \u0442\u0438\u043f \u043b\u0435\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c      \/\/ \u043f\u0440\u0430\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434     if (isa&lt;PointerTypeAST>(ExprType)) {       \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 \u0438 \u043e\u043d\u0430 \u043d\u0435        \/\/ \u0440\u0430\u0432\u043d\u0430 0       if (RightExpr->isIntConst()         &amp;&amp; ((IntExprAST*)RightExpr)->Val != 0) {         scope->report(Loc, diag::ERR_SemaPointerInitialization);         return nullptr;       \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u044b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b \u043f\u043e \u0442\u0438\u043f\u0430\u043c       } else if (!RightExpr->ExprType->implicitConvertTo(         ExprType)) {         scope->report(Loc, diag::ERR_SemaPointerInitialization);         return nullptr;       } else {         \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435         RightExpr = new CastExprAST(           RightExpr->Loc,            RightExpr,            LeftExpr->ExprType         );         RightExpr = RightExpr->semantic(scope);       }     } else {       \/\/ \u0415\u0441\u043b\u0438 \u0442\u0438\u043f\u044b \u043b\u0435\u0432\u043e\u0433\u043e \u0438 \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f, \u0442\u043e \u043d\u0443\u0436\u043d\u043e        \/\/ \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435       if (!LeftExpr->ExprType->equal(RightExpr->ExprType)) {         RightExpr = new CastExprAST(           RightExpr->Loc,            RightExpr,            LeftExpr->ExprType);         RightExpr = RightExpr->semantic(scope);       }     }      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0441 \u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0430\u0434\u0440\u0435\u0441\u043e\u043c     if (!LeftExpr->isLValue()) {       scope->report(Loc, diag::ERR_SemaMissingLValueInAssignment);       return nullptr;     }      \/\/ \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e, \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u0430\u043d\u0430\u043b\u0438\u0437     return this;   }    \/\/ \u0417\u0430\u043f\u0440\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445   if (isa&lt;ArrayTypeAST>(LeftExpr->ExprType)      || isa&lt;ArrayTypeAST>(RightExpr->ExprType)) {     scope->report(Loc,                    diag::ERR_SemaCantUseArrayInBinaryExpression);     return nullptr;   }    \/\/ \u0414\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438 \u0441\u0442\u0440\u043e\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e    \/\/ \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439   if (isa&lt;PointerTypeAST>(LeftExpr->ExprType)     || LeftExpr->ExprType->isString()     || isa&lt;PointerTypeAST>(RightExpr->ExprType)     || RightExpr->ExprType->isString()) {     \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \"-\" \u0438\u043b\u0438 \"+\", \u0442\u043e \u044d\u0442\u043e \u043e\u0448\u0438\u0431\u043a\u0430     if (Op != tok::Plus &amp;&amp; Op != tok::Minus) {       scope->report(Loc,         diag::ERR_SemaPointerOrStringInBinaryExpression);       return nullptr;     }      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043b\u0435\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438\u043b\u0438      \/\/ \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c     if (isa&lt;PointerTypeAST>(LeftExpr->ExprType)       || LeftExpr->ExprType->isString()) {       \/\/ \u041f\u0440\u0430\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c       if (!RightExpr->ExprType->isInt()) {         scope->report(Loc,                       diag::ERR_SemaPointerArithmeticsForNonInt);         return nullptr;       }        ExprType = LeftExpr->ExprType;       return this;     } else {       scope->report(Loc,                     diag::ERR_SemaPointerArithmeticsForNonInt);       return nullptr;     }   }    \/\/ \u0415\u0441\u043b\u0438 \u043b\u0435\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f char \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u0435\u0433\u043e \u0432 int   if (LeftExpr->ExprType->isChar()) {     LeftExpr = new CastExprAST(LeftExpr->Loc, LeftExpr,        BuiltinTypeAST::get(TypeAST::TI_Int));     LeftExpr = LeftExpr->semantic(scope);     ExprType = LeftExpr->ExprType;   }    \/\/ \u0415\u0441\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u044b \u0438\u043c\u0435\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0442\u0438\u043f\u044b, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438    \/\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f   if (!LeftExpr->ExprType->equal(RightExpr->ExprType)) {     \/\/ \u0415\u0441\u043b\u0438 \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f \"float\", \u0442\u043e      \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \"float\"     if (RightExpr->ExprType->isFloat()) {       ExprType = RightExpr->ExprType;       LeftExpr = new CastExprAST(         LeftExpr->Loc,          LeftExpr,          RightExpr->ExprType       );       LeftExpr = LeftExpr->semantic(scope);     } else {       \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434 \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u043a \u0442\u0438\u043f\u0443 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430 \u0441        \/\/ \u043b\u0435\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b       RightExpr = new CastExprAST(         RightExpr->Loc,          RightExpr,          LeftExpr->ExprType       );       RightExpr = RightExpr->semantic(scope);     }   }    \/\/ \"int\" \u0438 \"float\" \u0438\u043c\u0435\u044e\u0442 \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0445    \/\/ \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439   if (ExprType == BuiltinTypeAST::get(TypeAST::TI_Int)) {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \"int\"     switch (Op) {       case tok::Plus:       case tok::Minus:       case tok::Mul:       case tok::Div:       case tok::Mod:       case tok::BitOr:       case tok::BitAnd:       case tok::BitXor:       case tok::LShift:       case tok::RShift:         return this;        default:         \/\/ \u041d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u044e\u0434\u0430 \u043f\u043e\u043f\u0430\u0441\u0442\u044c, \u0435\u0441\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438          \/\/ \u0432 \u043f\u0430\u0440\u0441\u0435\u0440\u0435         assert(0 &amp;&amp; \"Invalid integral binary operator\");          return nullptr;     }   } else {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \"float\"     switch (Op) {       case tok::Plus:        case tok::Minus:        case tok::Mul:        case tok::Div:        case tok::Mod:        case tok::Less:          return this;        default:         \/\/ \u0421\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435, \u0442.\u00a0\u043a. \u0434\u0430\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430         scope->report(Loc,           diag::ERR_SemaInvalidBinaryExpressionForFloatingPoint);         return nullptr;     }   } }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0421\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">bool SymbolAST::needThis() {   return false; }  bool SymbolAST::canBeNull() {   return true; }  bool SymbolAST::contain(TypeAST* type) {   return false; }  bool VarDeclAST::needThis() {   return NeedThis; }  void VarDeclAST::doSemantic(Scope* scope) {   \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445   if (needThis()) {     \/\/ \u041d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f\u0445     if (scope->findMember(Id, 1)) {       scope->report(Loc, diag::ERR_SemaIdentifierRedefinition);       return;     }   } else {     if (scope->find(Id)) {       scope->report(Loc, diag::ERR_SemaIdentifierRedefinition);       return;     }   }    ... }  void VarDeclAST::doSemantic3(Scope* scope) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430   if (Val) {     \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     Val = Val->semantic(scope);      \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441, \u0442\u043e \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e     if (ThisType->isAggregate()) {       scope->report(Loc, diag::ERR_SemaConstructionCallInStruct);       return;     }      \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u0442\u0438\u043f\u043e\u0432 \"void\" \u0432     \/\/ \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438     if (!Val->ExprType || Val->ExprType->isVoid()) {       scope->report(Loc, diag::ERR_SemaVoidInitializer);       return;     }      \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439     if (isa&lt;PointerTypeAST>(ThisType)) {       \/\/ \u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u043c\u0435\u0435\u0442 \u0442\u0438\u043f int       if (Val->ExprType->isInt()) {         \/\/ \u0420\u0430\u0437\u0440\u0435\u0448\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u0438\u0435 0         if (Val->isIntConst() &amp;&amp; ((IntExprAST*)Val)->Val != 0) {           scope->report(Loc, diag::ERR_SemaPointerInitialization);         }          return;       \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0438\u043f\u044b \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b       } else if (!Val->ExprType->implicitConvertTo(ThisType)) {         scope->report(Loc, diag::ERR_SemaPointerInitialization);         return;       }     }      \/\/ \u0415\u0441\u043b\u0438 \u0442\u0438\u043f\u044b \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435     if (!Val->ExprType->equal(ThisType)) {       Val = new CastExprAST(Loc, Val, ThisType);       Val = Val->semantic(scope);     }   } }  bool VarDeclAST::contain(TypeAST* type) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0438\u043f\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442   if (ThisType->equal(type)) {     return true;   }    return false; }  bool VarDeclAST::canBeNull() {   \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c false   if (!isa&lt;PointerTypeAST>(ThisType)) {     return false;   }   \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c true, \u0442.\u00a0\u043a. \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 null   return true; }  TypeAST* StructDeclAST::getType() {   return ThisType; }  void StructDeclAST::doSemantic(Scope* scope) {   \/\/ \u0417\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u043c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435   if (scope->find(Id)) {     scope->report(Loc, diag::ERR_SemaIdentifierRedefinition);     return;   }    \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438   Scope* s = scope->push(this);   \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0442\u0438\u043f\u0430   ThisType = ThisType->semantic(s);    \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0438    \/\/ \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044f   ((ScopeSymbol*)scope->CurScope)->Decls[Id] = this;   Parent = scope->CurScope;      \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f   s->pop(); }  void StructDeclAST::doSemantic3(Scope* scope) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438   Scope* s = scope->push(this);   int curOffset = 0;    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0432\u0441\u0435\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439   for (SymbolList::iterator it = Vars.begin(), end = Vars.end();     it != end; ++it) {     VarDeclAST* var = (VarDeclAST*)(*it);          \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0434\u043b\u044f \u0447\u043b\u0435\u043d\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b     \/\/ \u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0447\u043b\u0435\u043d\u0430     var->semantic(s);     var->OffsetOf = curOffset++;   }    \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0446\u0438\u043a\u043b\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439   if (contain(ThisType)) {     scope->report(Loc, diag::ERR_SemaCricularReference, Id->Id);     return;   }    \/\/ \u0423\u0434\u0430\u043b\u044f\u0435\u043c \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f   s->pop(); }  bool StructDeclAST::contain(TypeAST* type) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0432\u0441\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0447\u043b\u0435\u043d\u044b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043d\u0430 \u0446\u0438\u043a\u043b\u044b   for (SymbolList::iterator it = Vars.begin(), end = Vars.end();    it != end; ++it) {     if ((*it)->contain(type)) {       return true;     }   }    return false; }  bool ParameterSymbolAST::canBeNull() {   \/\/ \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c, \u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c false   if (!isa&lt;PointerTypeAST>(Param->Param)) {     return false;   }   \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c true, \u0442.\u00a0\u043a. \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 null   return true; }  \/\/ \u0424\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0438\u0437 simple extern \"C\" void lle_X_printInt(int val) {   outs() &lt;&lt; val; }  extern \"C\" void lle_X_printDouble(double val) {   outs() &lt;&lt; val; }  extern \"C\" void lle_X_printChar(char val) {   outs() &lt;&lt; val; }  extern \"C\" void lle_X_printString(char* str) {   outs() &lt;&lt; str; }  extern \"C\" void lle_X_printLine(char* str) {   outs() &lt;&lt; str &lt;&lt; \"\\n\"; }  extern \"C\" void* lle_X_new(int size) {   return malloc(size); }  extern \"C\" void lle_X_delete(void* block) {   free(block); }  void initRuntimeFuncs(ModuleDeclAST* modDecl) {   addDynamicFunc(     \"fn printChar(_: char)\",      \"lle_X_printChar\",      modDecl,      (void*)lle_X_printChar   );   addDynamicFunc(     \"fn printInt(_: int)\",      \"lle_X_printInt\",      modDecl,      (void*)lle_X_printInt   );   addDynamicFunc(     \"fn printFloat(_: float)\",      \"lle_X_printDouble\",      modDecl,      (void*)lle_X_printDouble   );   addDynamicFunc(     \"fn printString(_: string)\",      \"lle_X_printString\",     modDecl,      (void*)lle_X_printString   );   addDynamicFunc(     \"fn printLn(_: string)\",     \"lle_X_printLine\",      modDecl,      (void*)lle_X_printLine   );   addDynamicFunc(     \"fn new(_: int) : void*\",     \"lle_X_new\",     modDecl,      (void*)lle_X_new   );   addDynamicFunc(     \"fn delete(_: void*)\",      \"lle_X_delete\",      modDecl,      (void*)lle_X_delete   ); }  void ModuleDeclAST::semantic() {   Scope s(this);      \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f runtime \u0444\u0443\u043d\u043a\u0446\u0438\u0439   initRuntimeFuncs(this);    \/\/ \u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437 \u0432\u0441\u0435\u0445 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u043e\u0432   for (int i = TypeAST::TI_Void; i &lt;= TypeAST::TI_String; ++i) {     BuiltinTypeAST::get(i)->semantic(&amp;s);   }    ... }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>GetElementPtr<\/h3>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438\u043b\u0438 \u043f\u043e\u043b\u044e \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435, \u0432 LLVM \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f GetElementPtr. \u041e\u043d\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u042d\u0442\u0430 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0441\u0447\u0435\u0442 \u0430\u0434\u0440\u0435\u0441\u0430 \u0438 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a \u0441\u0430\u043c\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u044d\u0442\u043e\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0438\u043c\u0435\u0435\u0442 \u0432\u0438\u0434 (\u043d\u0438\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u0435\u0435 \u0437\u0430\u043f\u0438\u0441\u0438, \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [1]:<\/p>\n<pre><code>&lt;result> = getelementptr &lt;ty>, ptr &lt;ptrval>{, [inrange] &lt;ty> &lt;idx>}*<\/code><\/pre>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0438\u043f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0437\u0430 \u043e\u0441\u043d\u043e\u0432\u0443 \u043f\u0440\u0438 \u0440\u0430\u0441\u0447\u0435\u0442\u0435. \u0412\u0442\u043e\u0440\u043e\u0439 \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u043c \u0438\u043b\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u0430\u0434\u0440\u0435\u0441 \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0441\u0447\u0435\u0442. \u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0438\u0434\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u041f\u0435\u0440\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0432\u0441\u0435\u0433\u0434\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u0438\u0437 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0438\u043f\u0430, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 (\u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u044f\u043c\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0442.\u00a0\u043a. \u043f\u0435\u0440\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u043c \u043e\u0442 0) \u0438 \u0442.\u00a0\u0434. \u041f\u0435\u0440\u0432\u044b\u0439 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0442\u0438\u043f \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f, \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c, \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u0438\u043b\u0438 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u043c. \u041d\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c\u044b\u0435 \u0442\u0438\u043f\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438, \u0442.\u00a0\u043a. \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0434\u043b\u044f \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 3 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 %arr \u0438\u0437 10 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 i32, \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>%1 = getelementptr inbounds [10 x i32], ptr %arr, i64 0, i64 3<\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 %arr \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u0435\u0440\u043d\u044b\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c 10&#215;10, \u0442\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 2 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 1 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c:<\/p>\n<pre><code>%1 = getelementptr inbounds [10 x [10 x i32]], ptr %arr, i64 0, i64 1, i64 2<\/code><\/pre>\n<p>\u0427\u0442\u043e \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0432\u0438\u0434\u0435:<\/p>\n<pre><code>%1 = getelementptr inbounds [10 x [10 x i32]], ptr %arr, i64 0, i64 1 %2 = getelementptr inbounds [10 x i32], ptr %1, i64 0, i64 2<\/code><\/pre>\n<p><strong>\u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0412 \u043d\u0430\u0448\u0435\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u0434\u043b\u0438\u043d\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0438\u0437 2-\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e \u0438 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430\u043c\u0438. \u0414\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432\u0438\u0434\u0430 %struct.C = type { i32, i32 }, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u043f\u043e\u043b\u044f, \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c:<\/p>\n<pre><code>%1 = getelementptr inbounds %struct.C, ptr %c, i32 0, i32 1<\/code><\/pre>\n<p>\u0411\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u043f\u0440\u043e \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [2], \u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 [3].<\/p>\n<h3>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430<\/h3>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">Type* BuiltinTypeAST::getType() {   static Type* builtinTypes[] = {     Type::getVoidTy(getGlobalContext()),     Type::getInt1Ty(getGlobalContext()),     Type::getInt32Ty(getGlobalContext()),     Type::getDoubleTy(getGlobalContext()),     Type::getInt8Ty(getGlobalContext()),     PointerType::get(       getGlobalContext(),       getSLContext().TheTarget->getProgramAddressSpace()     )   };    if (ThisType) {     return ThisType;   }    return ThisType = builtinTypes[TypeKind]; }  Type* ArrayTypeAST::getType() {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (ThisType) {     return ThisType;   }    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430   return ThisType = ArrayType::get(Next->getType(), Dim); }  Type* PointerTypeAST::getType() {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (ThisType) {     return ThisType;   }    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f   return ThisType = PointerType::get(     getGlobalContext(),     getSLContext().TheTarget->getProgramAddressSpace()   ); }  \/\/\/ \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \/\/\/ \\param[in] output \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \/\/\/ \\param[in] thisSym \u2014 \u0430\u0433\u0440\u0435\u0433\u0430\u0442 \u0438\u043c\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \/\/\/ \\note \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0443 \u0432\u0438\u0434\u0430 A.B.C \u0434\u043b\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432 void calcAggregateName(llvm::raw_ostream&amp; output,                        SymbolAST* thisSym) {   assert(thisSym &amp;&amp; thisSym->isAggregate());   SymbolAST* sym = thisSym;    \/\/ \u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445    \/\/ \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u043e\u0432   for ( ; ; ) {     output &lt;&lt; StringRef(sym->Id->Id, sym->Id->Length);     sym = sym->Parent;      if (!sym || !sym->isAggregate()) {       return;     }      output &lt;&lt; \".\";   } }  Type* StructTypeAST::getType() {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437   if (ThisType) {     return ThisType;   }    llvm::SmallString&lt; 128 > s;   llvm::raw_svector_ostream output(s);    \/\/ \u0414\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 \u0438\u043c\u044f \u0442\u0438\u043f\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \"struct.\"   output &lt;&lt; \"struct.\";   calcAggregateName(output, ThisDecl);    \/\/ \u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0442\u0438\u043f \u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430 \u0441\u0435\u0439\u0447\u0430\u0441, \u0442.\u00a0\u043a.    \/\/ \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0441\u0441\u044b\u043b\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0430\u043c\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443   ThisType = StructType::create(getGlobalContext(), output.str());    std::vector&lt; Type* > vars;   StructDeclAST* structDecl = (StructDeclAST*)ThisDecl;    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439   for (SymbolList::iterator it = structDecl->Vars.begin(),      end = structDecl->Vars.end(); it != end; ++it) {     vars.push_back(((VarDeclAST*)(*it))->ThisType->getType());   }    \/\/ \u0415\u0441\u043b\u0438 \u0432 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0435 \u043d\u0435\u0442 \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u0447\u043b\u0435\u043d\u0430, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u0435   \/\/ \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c \u0432 \u043e\u0434\u0438\u043d \u0431\u0430\u0439\u0442, \u0447\u0442\u043e \u0431\u044b \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0438\u043f\u0430 \u043e\u0442\u043b\u0438\u0447\u0430\u043b\u0441\u044f \u043e\u0442 0   if (vars.empty()) {     vars.push_back(Type::getInt8Ty(getGlobalContext()));   }    \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c   \/\/ \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f   ((StructType*)ThisType)->setBody(vars);   return ThisType; }  Type* QualifiedTypeAST::getType() {   assert(0 &amp;&amp; \"QualifiedTypeAST::getType should never be reached\");   return nullptr; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432\u0438\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ \u041a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \"bool\" \/\/\/ \\param[in] val \u2014 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u0438 \/\/\/ \\param[in] type \u2014 \u0442\u0438\u043f \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \/\/\/ \\param[in] builder \u2014 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 LLVM IR Value* promoteToBool(Value* val, TypeAST* type,                      IRBuilder&lt; >&amp; builder) {   if (type == BuiltinTypeAST::get(TypeAST::TI_Bool)) {     \/\/ \u042d\u0442\u043e \u0443\u0436\u0435 \"bool\"     return val;   }    if (type->isInt() || type->isChar()) {     \/\/ \u0414\u043b\u044f \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 0     return builder.CreateICmpNE(       val,       ConstantInt::get(type->getType(), 0)     );   } else if (isa&lt;PointerTypeAST>(type) || type->isString()) {     \/\/ \u0414\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0438\u043b\u0438 \u0441\u0442\u0440\u043e\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 null     return builder.CreateICmpNE(val,        ConstantPointerNull::get((PointerType*)type->getType()));   } else {     assert(type->isFloat());     \/\/ \u0414\u043b\u044f \u0447\u0438\u0441\u043b\u0430 \u0441 \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0441 0.0     return builder.CreateFCmpUNE(val, ConstantFP::get(       Type::getDoubleTy(getGlobalContext()), 0.0));   } }  Value* StringExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443   GlobalValue* val = Context.TheBuilder->CreateGlobalString(Val);   std::vector&lt; Value* > idx;    idx.push_back(getConstInt(0));   idx.push_back(getConstInt(0));    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 \u0440\u0430\u043d\u0435\u0435    \/\/ \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b   return Context.TheBuilder->CreateInBoundsGEP(     val->getValueType(),     val,     idx   ); }  Value* ProxyExprAST::getRValue(SLContext&amp; Context) {   return OriginalExpr->getRValue(Context); }  Value* NewExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u041d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0442\u0438\u043f\u0430 \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c 0, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b    \/\/ \u0443\u043a\u0430\u0437\u0430\u043b\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c   uint64_t allocSize = Context.TheTarget->getTypeAllocSize(     NewType->getType());   SizeExpr->Val = (int)allocSize;   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430   \/\/ \u043f\u0430\u043c\u044f\u0442\u0438   Value* val = CallExpr->getRValue(Context);    if (NeedCast) {     \/\/ \u041d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u043e\u0432     return Context.TheBuilder->CreateBitCast(       val,       ExprType->getType()     );   }      return val; }  Value* DeleteExprAST::getRValue(SLContext&amp; Context) {   Value* val = DeleteCall->getRValue(Context);   return val; }  Value* IndexExprAST::getLValue(SLContext&amp; Context) {   \/\/ \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c 2 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0449\u0438\u0445\u0441\u044f \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430: \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432   \/\/ \u0438 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439   if (isa&lt;ArrayTypeAST>(Left->ExprType)) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u0430\u043a lvalue \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430     Value* val = Left->getLValue(Context);     Value* index = Right->getRValue(Context);      std::vector&lt; Value* > idx;      idx.push_back(getConstInt(0));     idx.push_back(index);     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr     return Context.TheBuilder->CreateInBoundsGEP(       Left->ExprType->getType(),       val,       idx     );   } else {     \/\/ \u0414\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e rvalue \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435      \/\/ \u0441\u0430\u043c\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430     Value* val = Left->getRValue(Context);     Value* index = Right->getRValue(Context);      std::vector&lt; Value* > idx;      idx.push_back(index);     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr     return Context.TheBuilder->CreateInBoundsGEP(       ExprType->getType(),       val,       idx     );   } }  Value* IndexExprAST::getRValue(SLContext&amp; Context) {   Value* val = getLValue(Context);   return Context.TheBuilder->CreateLoad(ExprType->getType(), val); }  Value* MemberAccessExprAST::getLValue(SLContext&amp; Context) {   \/\/ \u0414\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0435 \u0442\u0438\u043f   if (isa&lt;FuncTypeAST>(ExprType)) {     return ThisSym->getValue(Context);   }    \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 (this)   Value* val = Val->getLValue(Context);    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u043c \u0438\u043d\u0434\u0435\u043a\u0441 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u0447\u043b\u0435\u043d\u0430 \u043a\u043b\u0430\u0441\u0441\u0430\/\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b   Value* index = getConstInt(((VarDeclAST*)ThisSym)->OffsetOf);    std::vector&lt; Value* > idx;    idx.push_back(getConstInt(0));   idx.push_back(index);    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr   return Context.TheBuilder->CreateGEP(     ThisSym->Parent->getType()->getType(),     val,      idx   ); }  Value* MemberAccessExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 (this)   Value* val = getLValue(Context);    \/\/ \u0414\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   if (isa&lt;FuncTypeAST>(ExprType)) {     return val;   }    \/\/ \u0414\u043b\u044f rvalue \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\"   return Context.TheBuilder->CreateLoad(ExprType->getType(), val); }  Value* PointerAccessExprAST::getLValue(SLContext&amp; Context) {   assert(0 &amp;&amp; \"PointerAccessExprAST::getLValue should never be \"          \"reached\");   return nullptr; }  Value* PointerAccessExprAST::getRValue(SLContext&amp; Context) {   assert(0 &amp;&amp; \"PointerAccessExprAST::getRValue should never be \"          \"reached\");   return nullptr; }  Value* DerefExprAST::getLValue(SLContext&amp; Context) {   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e lvalue   if (Val->isLValue()) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\"     Value* val = Val->getLValue(Context);     return Context.TheBuilder->CreateLoad(       PointerType::get(         getGlobalContext(),         Context.TheTarget->getProgramAddressSpace()       ),       val     );   } else {     \/\/ \u0414\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0438 \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c rvalue     return Val->getRValue(Context);    } }  Value* DerefExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue   Value* val = getLValue(Context);    \/\/ \u0414\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435   if (isa&lt;FuncTypeAST>(ExprType)) {     return val;   }    \/\/ \u0414\u043b\u044f rvalue \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\"   return Context.TheBuilder->CreateLoad(ExprType->getType(), val); }  Value* AddressOfExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0414\u043b\u044f rvalue \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c   \/\/ lvalue \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430   \/\/ \u0417\u0430\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0414\u0430\u043d\u043d\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 lvalue   return Val->getLValue(Context); }  Value* CastExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0439 \u0442\u0438\u043f   if (ExprType->isInt()) {     if (Val->ExprType->isBool() || Val->ExprType->isChar()) {       \/\/ \u0415\u0441\u043b\u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0438\u043f \"bool\" \u0438\u043b\u0438 \"char\", \u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u043c 0       return Context.TheBuilder->CreateZExt(         Val->getRValue(Context),          ExprType->getType()       );     }      assert(Val->ExprType->isFloat());     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"float\" \u0432 \"int\"     return Context.TheBuilder->CreateFPToSI(       Val->getRValue(Context),        ExprType->getType()     );   }    if (ExprType->isBool()) {     \/\/ \u0414\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \"bool\"     return promoteToBool(Val->getRValue(Context), Val->ExprType,        *Context.TheBuilder);     \/\/ \u0414\u043b\u044f \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \"char\"   } else if (ExprType->isChar()) {     \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \"bool\", \u0442\u043e \u0434\u043e\u043f\u043e\u043b\u043d\u044f\u0435\u043c 0     if (Val->ExprType->isBool()) {       return Context.TheBuilder->CreateZExt(         Val->getRValue(Context),         ExprType->getType()       );     }      assert(Val->ExprType->isInt());     \/\/ \u041e\u0431\u0440\u0435\u0437\u0430\u0435\u043c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     return Context.TheBuilder->CreateTrunc(       Val->getRValue(Context),       ExprType->getType()     );   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443   } else if (ExprType->isString()) {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432     if (isa&lt;ArrayTypeAST>(Val->ExprType)) {       \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f       Value* val = Val->getLValue(Context);       Value* tmp = getConstInt(0);        std::vector&lt; Value* > idx;        idx.push_back(tmp);       idx.push_back(tmp);        \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439       if (isa&lt;AllocaInst>(val)) {         AllocaInst *alloca = (AllocaInst*)val;         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr         return Context.TheBuilder->CreateGEP(           alloca->getAllocatedType(),           val,           idx         );       } else {         assert(0);       }     } else {       \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c rvalue \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f       Value* val = Val->getRValue(Context);       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432 \u043d\u043e\u0432\u044b\u0439 \u0442\u0438\u043f       return Context.TheBuilder->CreateBitCast(         val,         ExprType->getType()       );     }   \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044e   } else if (isa&lt;PointerTypeAST>(ExprType)) {     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f     if (isa&lt;PointerTypeAST>(Val->ExprType)) {       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c rvalue       return Val->getRValue(Context);     \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430     } else if (isa&lt;ArrayTypeAST>(Val->ExprType)) {       \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f       Value* val = Val->getLValue(Context);       Value* tmp = getConstInt(0);        std::vector&lt; Value* > idx;        idx.push_back(tmp);       idx.push_back(tmp);        \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439       if (isa&lt;AllocaInst>(val)) {         AllocaInst *alloca = (AllocaInst*)val;         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr         tmp = Context.TheBuilder->CreateGEP(           alloca->getAllocatedType(),           val,           idx         );       } else {         assert(0);       }        PointerTypeAST* ptrType = (PointerTypeAST*)ExprType;        if (ptrType->Next->isVoid()) {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435         tmp = Context.TheBuilder->CreateBitCast(           tmp,           ptrType->getType()         );       }        return tmp;     } else {       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c rvalue       Value* val = Val->getRValue(Context);       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435       return Context.TheBuilder->CreateBitCast(         val,         ExprType->getType()       );     }   } else if (Val->ExprType->isInt() || Val->ExprType->isChar()) {     \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"int\" \u0438\u043b\u0438 \"char\" \u0432\u043e \"float\"      return Context.TheBuilder->CreateSIToFP(       Val->getRValue(Context),        ExprType->getType()     );   } else if (Val->ExprType->isBool()) {     \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \"bool\" \u0432 \"float\"     return Context.TheBuilder->CreateUIToFP(       Val->getRValue(Context),       ExprType->getType()     );   }    assert(0 &amp;&amp; \"should never be reached\");   return nullptr; }  Value* UnaryExprAST::getRValue(SLContext&amp; Context) {   assert(Op == tok::PlusPlus || Op == tok::MinusMinus);   assert(isa&lt;IndexExprAST>(Val) || isa&lt;MemberAccessExprAST>(Val)     || ExprType->isString());   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c lvalue   Value* val = Val->getLValue(Context);   \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\" \u0438 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 1 \u0438\u043b\u0438 -1   Value* res = Context.TheBuilder->CreateLoad(     ExprType->getType(),     val   );   Value* tmp = getConstInt((Op == tok::PlusPlus) ? 1ULL : ~0ULL);    if (isa&lt;PointerTypeAST>(ExprType) || ExprType->isString()) {     Type *resType;      \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c     if (isa&lt;PointerTypeAST>(ExprType)) {       PointerTypeAST *ptrType = (PointerTypeAST*)ExprType;        \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430       if (ptrType->Next->isVoid()) {         resType = Type::getInt8Ty(getGlobalContext());       } else {         resType = ptrType->Next->getType();       }     } else {       \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c       resType = Type::getInt8Ty(getGlobalContext());     }      \/\/ \u0414\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr     res = Context.TheBuilder->CreateGEP(resType, res, tmp);   } else {     \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"add\"     res = Context.TheBuilder->CreateAdd(res, tmp);   }    \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\" \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430   Context.TheBuilder->CreateStore(res, val);   return res; }  Value* BinaryExprAST::getRValue(SLContext&amp; Context) {   \/\/ \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438    \/\/ =   if (Op == tok::Assign) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f     Value* right;          \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439     if (isa&lt;PointerTypeAST>(ExprType)) {       \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430 0, \u0442\u043e \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0435\u0435 \u0432 null       if (RightExpr->ExprType->isInt()) {         right = ConstantPointerNull::get(           (PointerType*)ExprType->getType()         );       } else {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c rvalue         right = RightExpr->getRValue(Context);       }     } else {       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c rvalue       right = RightExpr->getRValue(Context);     }      \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     Value* res = LeftExpr->getLValue(Context);      \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\"     Context.TheBuilder->CreateStore(right, res);     return right;   }    \/\/ ,   if (Op == tok::Comma) {     \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0433\u043e \u0438 \u043f\u0440\u0430\u0432\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430     LeftExpr->getRValue(Context);     Value* rhs = RightExpr->getRValue(Context);     \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u043f\u0440\u0430\u0432\u044b\u0439 \u043e\u043f\u0435\u0440\u0430\u043d\u0434     return rhs;   }    \/\/ \u041f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 ++ \u0438 --   if (Op == tok::PlusPlus || Op == tok::MinusMinus) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435     Value* var = LeftExpr->getLValue(Context);     Value* val = nullptr;      \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f IndexExprAST \u0438 MemberAccessExprAST     if (isa&lt;IndexExprAST>(LeftExpr)         || isa&lt;MemberAccessExprAST>(LeftExpr)) {       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"load\"       val = Context.TheBuilder->CreateLoad(         ExprType->getType(),         var       );     } else {       \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c rvalue       val = LeftExpr->getRValue(Context);     }      if (!LeftExpr->ExprType->isInt()) {       \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439, \u0442.\u043a \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b        \/\/ \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr       Value* tmp = getConstInt(         (Op == tok::PlusPlus) ? 1ULL : ~0ULL       );       Type *resType;           \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0442\u0438\u043f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c       if (isa&lt;PointerTypeAST>(ExprType)) {         PointerTypeAST *ptrType = (PointerTypeAST*)ExprType;          \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430         if (ptrType->Next->isVoid()) {           resType = Type::getInt8Ty(getGlobalContext());         } else {           resType = ptrType->Next->getType();         }       } else {         \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c         resType = Type::getInt8Ty(getGlobalContext());       }        \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr       tmp = Context.TheBuilder->CreateGEP(resType, val, tmp);       \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"store\" \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0441\u0442\u0430\u0440\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435       Context.TheBuilder->CreateStore(tmp, var);       return val;     } else {       if (Op == tok::PlusPlus) {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 1 \u0438 \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u043a          \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e         Value* tmp = getConstInt(1);         tmp = Context.TheBuilder->CreateAdd(val, tmp, \"inctmp\");         \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         Context.TheBuilder->CreateStore(tmp, var);         return val;       } else {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443 -1 \u0438 \u043f\u0440\u0438\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0435 \u043a          \/\/ \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u043e\u043c\u0443 \u0440\u0430\u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e         Value* tmp = getConstInt(~0ULL);         tmp = Context.TheBuilder->CreateAdd(val, tmp, \"dectmp\");         \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0442\u0430\u0440\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         Context.TheBuilder->CreateStore(tmp, var);         return val;       }     }   }    ...    \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f +\/- \u043d\u0430\u0434 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044f\u043c\u0438   if (isa&lt;PointerTypeAST>(ExprType)) {     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043b\u0435\u0432\u043e\u0439 \u0438 \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438     Value* ptr = LeftExpr->getRValue(Context);     Value* index = RightExpr->getRValue(Context);      \/\/ \u0414\u043b\u044f \u043c\u0438\u043d\u0443\u0441\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \"sub\"     if (Op == tok::Minus) {       index = Context.TheBuilder->CreateSub(getConstInt(0), index);     }      \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u0442\u0438\u043f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438     PointerTypeAST *ptrType = (PointerTypeAST*)ExprType;     Type *resType = ptrType->Next->isVoid()       ? Type::getInt8Ty(getGlobalContext())       : ptrType->Next->getType();          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr     return Context.TheBuilder->CreateGEP(resType, ptr, index);   }    \/\/ \u042d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441 \u0434\u0432\u0443\u043c\u044f \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430\u043c\u0438    \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434 \u0434\u043b\u044f \u043e\u0431\u043e\u0438\u0445 \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u0432   Value* lhs = LeftExpr->getRValue(Context);   Value* rhs = RightExpr->getRValue(Context);   ... }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0430\u0432\u043a\u0438 \u0434\u043b\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">Value* VarDeclAST::generateCode(SLContext&amp; Context) {   assert(SemaState >= 5);   \/\/ \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0434\u0440\u0435\u0441 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 (\u0442.\u00a0\u043a. \u043f\u0430\u043c\u044f\u0442\u044c \u043f\u043e\u0434 \u0441\u0430\u043c\u0443 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0443\u0436\u0435    \/\/ \u0434\u043e\u043b\u0436\u043d\u0430 \u0431\u044b\u043b\u0430 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0430 \u0440\u0430\u043d\u0435\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438)   Value* val = getValue(Context);    \/\/ \u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0435\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438   if (Val) {     Value* init;      \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439     if (isa&lt;PointerTypeAST>(ThisType)) {       \/\/ \u0414\u043b\u044f \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b 0, \u0441\u043e\u0437\u0434\u0430\u0435\u043c null       if (Val->isIntConst()) {         init = ConstantPointerNull::get(           (PointerType*)ThisType->getType()         );       } else {         \/\/ \u0421\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u043b\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u0432         if (isa&lt;ArrayTypeAST>(Val->ExprType)) {           \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c lvalue \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438           init = Val->getLValue(Context);           Value* tmp = getConstInt(0);            std::vector&lt; Value* > idx;            idx.push_back(tmp);           idx.push_back(tmp);            \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439           if (isa&lt;AllocaInst>(init)) {             AllocaInst *alloca = (AllocaInst*)init;             \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e GetElementPtr             init = Context.TheBuilder->CreateGEP(               alloca->getAllocatedType(),                init,               idx             );           } else {             assert(0);           }         } else {           \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f           init = Val->getRValue(Context);         }       }     } else {       \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043a\u043e\u0434\u0430 \u0434\u043b\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f       init = Val->getRValue(Context);     }      \/\/ \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \"store\"     return Context.TheBuilder->CreateStore(init, val);   }    return val; }  Value* StructDeclAST::getValue(SLContext&amp; Context) {   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430   ThisType->getType();   return nullptr; }  Value* StructDeclAST::generateCode(SLContext&amp; Context) {   assert(SemaState >= 5);   \/\/ \u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f \u0434\u043b\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430   ThisType->getType();   return nullptr; }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u0434\u0430\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432 \u043d\u0430\u0448 \u0443\u0447\u0435\u0431\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u043e\u0432, \u0442\u0430\u043a\u0438\u0445 \u043a\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u0421\u0442\u0440\u043e\u043a\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438;<\/p>\n<\/li>\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<\/ol>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0432 \u044f\u0437\u044b\u043a, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a:<\/p>\n<ol>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 (&#171;*&#187; \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430);<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0432\u0437\u044f\u0442\u0438\u044f \u0430\u0434\u0440\u0435\u0441\u0430 (&#171;&amp;&#187; \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u0430);<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438 (\u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430);<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u043f\u043e\u043b\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b;<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b &#171;new&#187; \u0438 &#171;del&#187; \u0434\u043b\u044f \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 <a href=\"https:\/\/github.com\/dc-sinpo\/simple\/tree\/part02\" rel=\"noopener noreferrer nofollow\">github<\/a> (\u0432 \u043f\u0430\u043f\u043a\u0435 tests \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u044e\u0442 \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u044f\u0437\u044b\u043a\u0430). \u0412 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043d\u0430\u0448 \u044f\u0437\u044b\u043a \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043a\u043b\u0430\u0441\u0441\u043e\u0432 \u0441 \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u0434\u0438\u0441\u043f\u0435\u0442\u0447\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0437\u043a\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<h3> \u041f\u043e\u043b\u0435\u0437\u043d\u044b\u0435 \u0441\u0441\u044b\u043b\u043a\u0438<\/h3>\n<ol>\n<li>\n<p><a href=\"https:\/\/llvm.org\/docs\/LangRef.html#getelementptr-instruction\" rel=\"noopener noreferrer nofollow\">https:\/\/llvm.org\/docs\/LangRef.html#getelementptr-instruction<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/llvm.org\/docs\/GetElementPtr.html\" rel=\"noopener noreferrer nofollow\">https:\/\/llvm.org\/docs\/GetElementPtr.html<\/a><\/p>\n<\/li>\n<li>\n<p><a href=\"https:\/\/blog.yossarian.net\/2020\/09\/19\/LLVMs-getelementptr-by-example\" rel=\"noopener noreferrer nofollow\">https:\/\/blog.yossarian.net\/2020\/09\/19\/LLVMs-getelementptr-by-example<\/a><\/p>\n<\/li>\n<\/ol>\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\/post\/724010\/\"> https:\/\/habr.com\/ru\/post\/724010\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u00a0\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 <a href=\"https:\/\/habr.com\/ru\/post\/717886\/\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a> \u043c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u043d\u0430\u00a0\u0442\u043e\u043c, \u0447\u0442\u043e\u00a0\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u043e\u0435 \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u043d\u0430\u0448\u0435\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0432\u00a0\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0435\u0441\u0442\u044c \u0446\u0435\u043b\u044b\u0435 \u0438 \u0432\u0435\u0449\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0435 \u0447\u0438\u0441\u043b\u0430, \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0449\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: \u0446\u0438\u043a\u043b\u044b, \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0432\u0435\u0442\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435. \u0412\u00a0\u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u043c \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0439 \u044f\u0437\u044b\u043a \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u00a0\u043d\u0435\u0433\u043e: \u0441\u0442\u0440\u043e\u043a\u0438, \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438, \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0430\u00a0\u0442\u0430\u043a\u00a0\u0436\u0435 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0434\u043b\u044f\u00a0\u0440\u0430\u0431\u043e\u0442\u044b \u0441\u00a0\u043d\u0438\u043c\u0438.<\/p>\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0438\u0448\u0435\u043c, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435.<\/p>\n<ol>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0432\u0430 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u0430 &#171;char&#187; \u0438 &#171;string&#187;;<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0434\u0432\u0443\u0445 \u043d\u043e\u0432\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442:<\/p>\n<\/li>\n<\/ol>\n<ul>\n<li>\n<p>\u0421\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#171;Hello, world&#187;);<\/p>\n<\/li>\n<li>\n<p>\u0421\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#8216;d&#8217;).<\/p>\n<\/li>\n<\/ul>\n<ol start=\"3\">\n<li>\n<p>\u041c\u0430\u0441\u0441\u0438\u0432\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 int[10]) \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443;<\/p>\n<\/li>\n<li>\n<p>\u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 int*) \u0438 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u0434 \u043d\u0438\u043c\u0438 (\u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: ++\/&#8212;, &amp; \u0438 *), \u0430 \u0442\u0430\u043a \u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 struct A { a: int; b: float; }), \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u0442\u044c\u0441\u044f \u043a \u0447\u043b\u0435\u043d\u0430\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0447\u0435\u0440\u0435\u0437 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 &#171;.&#187;.<\/p>\n<\/li>\n<\/ol>\n<p>\u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0441\u0435 4 \u0447\u0430\u0441\u0442\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0442\u043e\u0440\u0430: \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439, \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u043a\u043e\u0434\u0430.  <\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u0441\u0435\u0445 \u0432\u044b\u0448\u0435\u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432, \u043f\u043e\u043b\u043d\u044b\u0439 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u043d\u0430 <a href=\"https:\/\/github.com\/dc-sinpo\/simple\/tree\/part02\" rel=\"noopener noreferrer nofollow\">github<\/a>.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435<\/strong>: \u0412 \u044f\u0437\u044b\u043a\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u044b\u0435 \u0442\u0438\u043f\u044b \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b, \u0442.\u00a0\u0435. \u0434\u043b\u044f &#171;int*[2][3]&#187; \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 3 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 2 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 int. \u0427\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0443\u0434\u043e\u0431\u043d\u044b\u043c \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u0445 \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0442.\u00a0\u043a. \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c a[2][1], \u043d\u043e \u043d\u0435 a[1][2] (\u0442.\u00a0\u043a. \u0434\u043b\u044f \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u043a-\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u2014 2, \u043d\u0435 3).<\/p>\n<h3>\u041b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437<\/h3>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0442\u0438\u043f\u044b \u043b\u0435\u043a\u0441\u0435\u043c \u0432 include\/Basic\/TokenKinds.def.<\/p>\n<p>\u041d\u043e\u0432\u044b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430:<\/p>\n<pre><code class=\"cpp\">KEYWORD(String, \"string\")  KEYWORD(Char, \"char\")  KEYWORD(Struct, \"struct\")  KEYWORD(New, \"new\")  KEYWORD(Delete, \"del\") <\/code><\/pre>\n<p>\u041d\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b:<\/p>\n<pre><code class=\"cpp\">TOK(CharLiteral, \"\") TOK(StringConstant, \"\") <\/code><\/pre>\n<p>\u041d\u043e\u0432\u044b\u0435 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u044b:<\/p>\n<pre><code class=\"cpp\">TOK(Dot, \".\") TOK(OpenBrace, \"[\") TOK(CloseBrace, \"]\")<\/code><\/pre>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 Name:<\/p>\n<pre><code class=\"cpp\">struct Name {    ...   static Name *New;    \/\/\/&lt; \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \"new\"   static Name *Delete; \/\/\/&lt; \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \"del\"  }; <\/code><\/pre>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432 Lexer \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432:<\/p>\n<pre><code class=\"cpp\">void NamesMap::addKeywords() {    if (IsInit) {      return;    }   #define KEYWORD(NAME, TEXT)                               \\    addName(StringRef(TEXT), tok::NAME);  #include \"simple\/Basic\/TokenKinds.def\"     Name::New = getName(\"new\");    Name::Delete = getName(\"delete\");     IsInit = true;  }<\/code><\/pre>\n<p>\u041e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u044d\u0442\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b, \u0442.\u00a0\u043a. \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0431\u044b \u0441\u0432\u044f\u0437\u0430\u0442\u044c \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438 \u0441 \u044d\u0442\u0438\u043c\u0438 \u0438\u043c\u0435\u043d\u0430\u043c\u0438, \u043f\u043e\u0437\u0436\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0438 \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u0438 \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.<\/p>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u044d\u0442\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0438 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432 \u0432 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435 (\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u043e\u0432\u044b\u0445 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0441\u043b\u043e\u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u043e\u043a \u0432 \u043d\u0435\u043c \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442):<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">void Lexer::next(Token &amp;Result) {    \/\/ \u0423\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e   Result.Kind = tok::Invalid;     \/\/ \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0438 \u0431\u0443\u0434\u0435\u043c    \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f, \u0447\u0442\u043e \u0431\u044b \u043d\u0435 \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c    \/\/ \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430   const char *p = CurPos;     \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u044b, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d   while (Result.Kind == tok::Invalid) {      const char *tokenStart = p;     ...     \/\/ \u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0443, \u043d\u043e \u0437\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438      \/\/ \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u044d\u0442\u043e \u0437\u0430 \u0441\u0438\u043c\u0432\u043e\u043b     switch (char ch = *p++) {        ...       \/\/ \u0410\u043d\u0430\u043b\u0438\u0437 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430       CHECK_ONE('[', tok::OpenBrace);        CHECK_ONE(']', tok::CloseBrace);        CHECK_ONE('.', tok::Dot);         ...       case '\\'': {          \/\/ \u042d\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b         char resultCh = ' ';          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430, \u0438 \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e          \/\/ \u0441\u0438\u043c\u0432\u043e\u043b, \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e         if (*p != '\\'') {            resultCh = *p;            ++p;          }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b \u0438\u043c\u0435\u0435\u0442 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0443\u044e '         if (*p != '\\'') {            Diags.report(getLoc(p),                         diag::ERR_UnterminatedCharOrString);          }           ++p;          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438         Result.Length = (int)(p - tokenStart);          Result.Chr = resultCh;          Result.Kind = tok::CharLiteral;          break;        }         case '\"': {          \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b         llvm::SmallString&lt;32> str;          \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c, \u043f\u043e\u043a\u0430 \u0443 \u043d\u0430\u0441 \u0432\u043e \u0432\u0445\u043e\u0434\u043d\u043e\u043c \u043f\u043e\u0442\u043e\u043a\u0435 \u0435\u0449\u0435 \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435         while (*p != 0) {            \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \"           if (*p == '\"') {              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435 \"             if (p[1] != '\"') {                \/\/ \u0417\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u0447\u0442\u0435\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430               break;              }               \/\/ \u0417\u0430\u043c\u0435\u043d\u044f\u0435\u043c \"\" \u043d\u0430 \"             p += 2;              str.push_back('\"');            } else if (*p == '\\\\') {              \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u044d\u0441\u043a\u0435\u0439\u043f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c             ++p;              \/\/ \u041e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \\n              if (*p == 'n') {                str.push_back('\\n');                ++p;               \/\/ \u0438 \\\\             } else if (*p == '\\\\') {                str.push_back('\\\\');                ++p;              } else {                Diags.report(getLoc(p),                             diag::ERR_InvalidEscapeSequence);              }           } else if (*p == '\\r' || *p == '\\n') {              \/\/ \u041c\u044b \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0438 \u043a\u043e\u043d\u0435\u0446 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0435, \u0441\u043e\u043e\u0431\u0449\u0430\u0435\u043c \u043e\u0431              \/\/ \u043e\u0448\u0438\u0431\u043a\u0435             Diags.report(getLoc(p), diag::ERR_NewLineInString);            } else {              \/\/ \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0438\u043c\u0432\u043e\u043b \u043a \u0441\u0442\u0440\u043e\u043a\u0435             str.push_back(*p);              ++p;            }          }          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \"          if (*p != '\"') {            Diags.report(getLoc(p),                        diag::ERR_UnterminatedCharOrString);          }          \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \"         ++p;          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438         Result.Kind = tok::StringConstant;          Result.Length = str.size();          Result.Literal = new char[Result.Length + 1];          memcpy(Result.Literal, str.c_str(), Result.Length);          Result.Literal[Result.Length] = 0;          break;        }        ...     }      Result.Ptr = tokenStart;    }     \/\/ \u041e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0432 \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435   CurPos = p;  }<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432\u0441\u0435\u0445 \u043d\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u041f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u043d\u043e\u0432\u044b\u0445 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ primary-expr  \/\/\/   ::= floating-point-literal  \/\/\/   ::= integral-literal  \/\/\/   ::= '.'? identifier  \/\/\/   ::= char-literal  \/\/\/   ::= string-literal  \/\/\/   ::= '(' expr ')'  ExprAST *Parser::parsePrimaryExpr() {    ExprAST *result = nullptr;     switch (CurPos->getKind()) {      ...     case tok::CharLiteral:        \/\/ \u042d\u0442\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430. \u0421\u0442\u0440\u043e\u0438\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430 \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c       \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d       result = new IntExprAST(CurPos.getLocation(),                                CurPos->getChar());        ++CurPos;        return result;      case tok::StringConstant:        \/\/ \u042d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430. \u0421\u0442\u0440\u043e\u0438\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430 \u0438 \u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c       \/\/ \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d       result = new StringExprAST(CurPos.getLocation(),                                   CurPos->getLiteral());        ++CurPos;        return result;      case tok::Dot:        \/\/ \u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0441 \".\", \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u044d\u0442\u043e\u0442        \/\/ \u0441\u043b\u0443\u0447\u0430\u0439       if ((CurPos + 1) != tok::Identifier) {          check(tok::Identifier);        }        \/\/ \u0421\u0430\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d \u0432 parsePostfixExpr, \u0437\u0434\u0435\u0441\u044c        \/\/ \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u043e \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c       \/\/ \u0432\u0438\u0434\u0438\u043c\u043e\u0441\u0442\u0438        return new IdExprAST(CurPos.getLocation(), nullptr);        ...   }  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043f\u043e\u0441\u0442\u0444\u0438\u043a\u0441\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0447\u043b\u0435\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ call-arguments  \/\/\/   ::= assign-expr  \/\/\/   ::= call-arguments ',' assign-expr  \/\/\/ postfix-expr  \/\/\/   ::= primary-expr  \/\/\/   ::= postfix-expr '++'  \/\/\/   ::= postfix-expr '--'  \/\/\/   ::= postfix-expr '(' call-arguments ? ')'  \/\/\/   ::= postfix-expr '[' expr ']'  \/\/\/   ::= postfix-expr '.' identifier  ExprAST *Parser::parsePostfixExpr() {    ExprAST *result = parsePrimaryExpr();     for (;;) {      llvm::SMLoc loc = CurPos.getLocation();       switch (int op = CurPos->getKind()) {        ...       case tok::OpenBrace: {          \/\/ \u042d\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u0446\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435. \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c [          check(tok::OpenBrace);          \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435         ExprAST *expr = parseExpr();          \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 ]         check(tok::CloseBrace);          \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430         result = new IndexExprAST(loc, result, expr);          continue;        }         case tok::Dot: {          \/\/ \u042d\u0442\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u0447\u043b\u0435\u043d\u0443 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0430, \u0438\u0445 \u043c\u043e\u0436\u0435\u0442         \/\/ \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0445 \u0432 \u0446\u0438\u043a\u043b\u0435         while (CurPos == tok::Dot) {            \/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c .           ++CurPos;             Name *name = nullptr;            \/\/ \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0435\u0433\u043e           if (CurPos == tok::Identifier) {              name = CurPos->getIdentifier();            }            \/\/ \u0421\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438\u043b\u0438 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0440\u0443\u0435\u043c \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435           check(tok::Identifier);            \/\/ \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0432\u0435\u0442\u043a\u0443 \u0434\u0435\u0440\u0435\u0432\u0430           result = new MemberAccessExprAST(loc, result, name);          }           continue;        }         default:          return result;      }    }  } <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0430\u043d\u0430\u043b\u0438\u0437\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043e\u0434\u043d\u0438\u043c \u043e\u043f\u0435\u0440\u0430\u043d\u0434\u043e\u043c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u043d\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a: \u0432\u0437\u044f\u0442\u0438\u0435 \u0430\u0434\u0440\u0435\u0441\u0430, \u0440\u0430\u0437\u044b\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u0438\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0435\u0439, \u0430 \u0442\u0430\u043a \u0436\u0435 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0438 \u043e\u0441\u0432\u043e\u0431\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0431\u043b\u043e\u043a\u0430 \u043f\u0430\u043c\u044f\u0442\u0438:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"cpp\">\/\/\/ unary-expr  \/\/\/   ::= postfix-expr  \/\/\/   ::= '+' unary-expr  \/\/\/   ::= '-' unary-expr  \/\/\/   ::= '++' unary-expr  \/\/\/   ::= '--'<\/code><\/pre>\n<\/div>\n<\/details>\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-347133","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/347133","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=347133"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/347133\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=347133"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=347133"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=347133"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}