{"id":305167,"date":"2020-06-10T21:00:22","date_gmt":"2020-06-10T21:00:22","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=305167"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=305167","title":{"rendered":"\u041f\u0430\u0440\u0441\u0435\u0440 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0432 400 \u0441\u0442\u0440\u043e\u043a"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/506188\/\">\n<p>\u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/www.antlr.org\/\" rel=\"nofollow\">ANTLR<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Yacc\" rel=\"nofollow\">Yacc<\/a>. \u041e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u044b \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u044d\u0442\u043e \u0442\u0430\u043a \u0441\u043b\u043e\u0436\u043d\u043e? \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u043f\u0443\u0441\u043a\u0430. \u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u044f \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e\u0431 ANTLR, \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e\u0442\u0441\u044f. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u043e\u0434\u0430, \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a, \u0430 \u043d\u0435 \u0438\u043d\u0430\u0447\u0435.<\/p>\n<p>  <\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0432 ANTLR-like \u0432\u0438\u0434\u0435. \u0412\u043e\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">C:     | A1? A2* A3     | B1? B2+ B3 ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0435\u043b\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 PHP. \u0410 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043d\u0430 C++.<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<p>\u0417\u0430\u0447\u0435\u043c? \u041d\u0443 \u0443 \u0442\u043e\u0433\u043e \u0436\u0435 ANTLR \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0438 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0434\u043b\u044f \u0430\u0441\u0441\u0435\u043c\u0431\u043b\u0435\u0440\u043d\u043e\u0439 \u0432\u0441\u0442\u0430\u0432\u043a\u0438 \u0432 \u044f\u0437\u044b\u043a\u0435 C++ <code>asm { ... }<\/code>, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441, \u0438\u043b\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 \u0441\u0442\u0440\u043e\u043a <a href=\"https:\/\/www.php.net\/manual\/en\/language.types.string.php#language.types.string.syntax.nowdoc\" rel=\"nofollow\">Nowdoc<\/a> \u0432 PHP. \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u043c\u0435\u043b\u043e\u0447\u0438, \u0432 \u0444\u0430\u0439\u043b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u0438\u0441\u0430\u0442\u044c &quot;:&quot; \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u043b\u043e\u0441\u044c \u0441 &quot;|&quot;. \u0418 \u0432\u043e\u043e\u0431\u0449\u0435, \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0438 \u0441\u043b\u043e\u0436\u043d\u0430\u044f \u0448\u0442\u0443\u043a\u0430, \u0432\u0434\u0440\u0443\u0433 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>  <\/p>\n<p>\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c\u0441\u044f \u0441 \u0442\u0435\u0440\u043c\u0438\u043d\u043e\u043b\u043e\u0433\u0438\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u2014 \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e (Rule). \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u043e C. \u041f\u0440\u0430\u0432\u0438\u043b\u043e \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u2014 \u044d\u0442\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 (Statement). \u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441\u043e &quot;statement&quot; \u0432 \u044f\u0437\u044b\u043a\u0430\u0445 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0438\u0437 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0447\u0430\u0441\u0442\u0435\u0439. \u0417\u0434\u0435\u0441\u044c \u0443 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 2 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0430\u0437\u0432\u0430\u0442\u044c Variant (\u0438\u043b\u0438 Alternative, \u043a\u0430\u043a \u0432 ANTLR), \u043d\u043e \u0443 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0430 \u043f\u0440\u0430\u0432\u0438\u043b \u043e\u0434\u0438\u043d \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u0438 \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u043a-\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442.<\/p>\n<p>  <\/p>\n<p>Statement \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 (Expression). \u041f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 regular expressions, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e\u0445\u043e\u0436\u0438 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0438 \u0441 \u044f\u0437\u044b\u043a\u0430\u043c\u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f, \u043a\u0430\u043a \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c statement. \u0417\u0434\u0435\u0441\u044c \u043f\u043e 3 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0435.<\/p>\n<p>  <\/p>\n<p>Expression \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 (Element) \u0438 \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 (Quantifier). Quantifier \u044d\u0442\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0439 \u0437\u043d\u0430\u0447\u043e\u043a \u0438\u0437 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u2014 <code>?<\/code>, <code>*<\/code>, <code>+<\/code>.<\/p>\n<p>  <\/p>\n<p>Element \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043b\u0438\u0431\u043e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u043c \u2014 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0432 \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u044b\u0445 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u0445 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 (<code>'a'<\/code>) \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430: \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0432 \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445 (<code>[a-z]<\/code>) \u0438\u043b\u0438 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0432 \u0432\u0438\u0434\u0435 \u0442\u043e\u0447\u043a\u0438 (<code>.<\/code>). \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u044b. \u0412 \u0442\u0435\u043a\u0441\u0442\u0435 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438, \u0435\u0441\u043b\u0438 \u0440\u0435\u0447\u044c \u0438\u0434\u0435\u0442 \u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435, \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c &quot;\u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435&quot; \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u043e\u0434\u0440\u0430\u0437\u0443\u043c\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430.<\/p>\n<p>  <\/p>\n<h3 id=\"grammatika\">\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430<\/h3>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u044f\u0437\u044b\u043a\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a. \u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">Grammar:     delimiter* Rule* ;  delimiter:     | space     | comment ;  space:     [\\s\\n\\t\\r]+ ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0431\u0443\u0434\u0435\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u0430\u0439\u0442, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043f\u0440\u043e\u0431\u0435\u043b\u044b. \u041f\u043e\u0442\u043e\u043c \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c. \u042f \u0441\u0434\u0435\u043b\u0430\u043b \u0434\u043b\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0447\u0442\u043e\u0431\u044b &quot;<code>\\s<\/code>&quot; \u043e\u0437\u043d\u0430\u0447\u0430\u043b \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u0440\u043e\u0431\u0435\u043b \u0441 \u043a\u043e\u0434\u043e\u043c 0x20, \u0430 \u043d\u0435 \u043b\u044e\u0431\u043e\u0439 \u043f\u0440\u043e\u0431\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b, \u043a\u0430\u043a \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u044b. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0442\u0430\u043a, \u0431\u0443\u0434\u0435\u043c \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u0431\u0443\u043a\u0432\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0438\u0445 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u043a\u0430\u043a \u0436\u0435 \u0431\u0435\u0437 \u043d\u0438\u0445.<\/p>\n<p>  <\/p>\n<p>\u0418 \u0442\u0443\u0442 \u043c\u044b \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u043c \u0445\u0438\u0442\u0440\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442. \u041b\u043e\u0433\u0438\u0447\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">comment:     '\/*' .* '*\/' ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>.*<\/code> \u0431\u0443\u0434\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043d\u0430\u0447\u0430\u043b\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 <code>'*'<\/code>, \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f. \u0417\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u0434\u043e \u043a\u0430\u043a-\u0442\u043e \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 &#8216;*&#8217; \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0441\u044f. \u0412 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u044d\u0442\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f lookahead.<\/p>\n<p>  <\/p>\n<p>\u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">comment:     '\/*' AnySymbol*&gt;&gt; '*\/' ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0430\u043e\u0434\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0435\u043c \u0442\u043e\u0447\u043a\u0443 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0439 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u0438. \u041e\u043d\u043e \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0438 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a.<br \/>  \u041d\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0431\u0435\u0437 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0435\u0433\u043e \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">comment:     '\/*' content '*\/' ;  content:     AnySymbol*&gt;'*\/' ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0441\u0442\u0440\u0435\u043b\u043e\u0447\u043a\u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0442, \u0447\u0442\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0434\u043b\u044f lookahead \u0431\u0435\u0440\u0435\u0442\u0441\u044f \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0430 \u043e\u0434\u043d\u0430 \u0447\u0442\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0443\u043a\u0430\u0437\u0430\u043d \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u043d\u0435\u0435 \u0438 \u0432 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u043d\u0435 \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442. \u041a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c \u0435\u0433\u043e 1 \u0440\u0430\u0437.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f 2 \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u043e\u0440\u043c\u044b, \u043b\u0435\u043d\u0438\u0432\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>'a*? b'<\/code> \u0438 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f <code>'a*(?=b)'<\/code>. \u0412\u0442\u043e\u0440\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043f\u0430\u0440\u0441\u0438\u0442\u044c, \u0430 \u043f\u0435\u0440\u0432\u0430\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 2 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430, \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430. \u041d\u0443 \u0442\u0443\u0442 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">Rule:     RuleName delimiter* ':' delimiter* RuleBody ';' delimiter* ;  RuleName:     ID ;  ID:     [a-zA-Z_] [a-zA-Z_0-9]* ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044c \u043d\u0430\u0434\u043e \u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0441\u0432\u043e\u0435\u043c \u0441\u043e\u0441\u0442\u0430\u0432\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f \u0432 \u043a\u043e\u043d\u0446\u0435. \u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u0435\u0441\u0442\u044c <code>delimiter*<\/code> \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 <code>Grammar<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0412\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">RuleBody:     '|'? delimiter* Statement ('|' delimiter* Statement)* ;  Statement:     Expression+ ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u0438\u044f inline-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0435\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f. \u041c\u043e\u0436\u043d\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043c\u0435\u043d\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438, \u043d\u043e \u0442\u0430\u043a \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u0435\u0435, \u0438 \u043a\u043e\u0434 \u0442\u0430\u043a \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">Expression:     Element Quantifier? LookAhead? delimiter* ;  Element:     | RuleName     | StringLiteral     | RegexpLiteral     | InlineRule ;  Quantifier:     | '*'     | '?'     | '+' ;  LookAhead:     | '&gt;&gt;'     | '&gt;' Element ;  InlineRule:     '(' RuleBody ')' ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u043b\u0435\u043c\u0435\u043d\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 4 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u0434\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443. \u041a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0442\u043e\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c, \u043d\u043e \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>  <\/p>\n<p>\u0421\u0442\u0440\u043e\u043a\u0438 \u0438 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">StringLiteral:     '\\'' Symbol+&gt;&gt; '\\'' ;  RegexpLiteral:     | '[' SymbolRange+&gt;&gt; ']'     | AnySymbolLiteral ;  SymbolRange:     Symbol&gt;']' ('-' Symbol&gt;']')? ;  Symbol:     | HexCodeSymbol     | EscapedSymbol     | AnySymbol ;  HexCodeSymbol:     '\\\\x' HexDigit HexDigit ;  HexDigit:     [0-9A-F] ;  EscapedSymbol:     '\\\\' AnySymbol ;  AnySymbol:     . ;  AnySymbolLiteral:     '.' ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u0434\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e RegexpLiteral \u0437\u0430\u0434\u0430\u0435\u0442 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b, \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u043b\u044e\u0431\u044b\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u043c. \u041f\u043e \u0441\u0443\u0442\u0438 \u043c\u044b \u0438 \u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u044b\u0439 \u0434\u0432\u0438\u0436\u043e\u043a \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u041f\u0443\u0441\u0442\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0438 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u044b \u0432 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0437\u0430\u043f\u0440\u0435\u0449\u0435\u043d\u044b. \u0414\u043b\u044f \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u0430 \u043d\u0430\u0434\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0447\u0435\u0440\u0435\u0437 lookahead \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u0438\u043d\u0430\u0447\u0435 \u0442\u0430\u043a\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043a <code>[]<\/code> \u0438\u043b\u0438 <code>[a-]<\/code> \u0431\u0443\u0434\u0443\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c\u0441\u044f \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0441\u0438\u043c\u0432\u043e\u043b \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0435\u0433\u043e \u0448\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u0435\u0440\u0438\u0447\u043d\u044b\u0439 \u043a\u043e\u0434. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0431\u0435\u043b \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 <code>\\x20<\/code>. \u042d\u0442\u043e \u0434\u0430\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0434\u0432\u043e\u0438\u0447\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0447\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430. \u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0435\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u043c, \u043d\u043e \u043f\u043e\u043a\u0430 \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e. <\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u044d\u0442\u043e\u0442 \u044f\u0437\u044b\u043a \u0438\u043c\u0435\u0435\u0442 \u0441\u0432\u043e\u0438 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438. \u042f \u043d\u0430\u0437\u0432\u0430\u043b \u0435\u0433\u043e GDL \u2014 Grammar Definition Language.<\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u044d\u0442\u043e \u0432 \u0444\u0430\u0439\u043b \u0438 \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <code>self.gdl<\/code>.<\/p>\n<p>  <\/p>\n<h3 id=\"parser\">\u041f\u0430\u0440\u0441\u0435\u0440<\/h3>\n<p>  <\/p>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u0432\u0438\u0434\u0430 <code>(\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430)<\/code>. \u041c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043b\u044e\u0431\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u0434\u0430\u0435\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435. \u041f\u0443\u0441\u0442\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0434\u043b\u044f \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 <code>*<\/code> \u0438 <code>?<\/code> \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043b\u0438\u0431\u043e \u043f\u0443\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u0438 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u043e\u0432. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0443 \u0432\u0441\u0435\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435, \u043d\u043e \u043f\u043b\u043e\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043c\u0430\u0441\u0441\u0438\u0432 \u043b\u0438\u0431\u043e \u0441\u0442\u0440\u043e\u043a\u0430. \u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u0435\u0440\u0435\u0432\u043e.<br \/>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u2014 \u044d\u0442\u043e \u043a\u043e\u043d\u043a\u0430\u0442\u0435\u043d\u0430\u0446\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u0441\u0435\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u0422\u0430\u043a\u043e\u0439 \u0436\u0435 \u043c\u0430\u0441\u0441\u0438\u0432, \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u043e\u043b\u044c\u0448\u0435.<\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u2014 \u044d\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f.<br \/>  \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u0442\u0440\u043e\u043a \u0438 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u043e\u0432 \u2014 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u0437 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0439, \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0432 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c null.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u0435\u0441\u043b\u0438 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0435 (\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0418\u041b\u0418).<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443, \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430 (\u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0418).<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0437\u0430\u0434\u0430\u043d\u043d\u044b\u043c \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435: <code>aaab<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/* \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 *\/ Data:     'a'* 'b' 'c'? ;  \/* \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 *\/ ['Data', [     ['', 'a'],     ['', 'a'],     ['', 'a'],     ['', 'b'], ]]  \/* \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 *\/ Data:     R1* R2 R3? ; R1: 'a'; R2: 'b'; R3: 'c';  \/* \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 *\/ ['Data', [     ['R1', [         ['', 'a'],     ]],     ['R1', [         ['', 'a'],     ]],     ['R1', [         ['', 'a'],     ]],     ['R2', [         ['', 'b'],     ]], ]]<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f, \u0447\u0442\u043e \u0441\u043a\u043e\u0431\u043e\u043a \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u043a\u043e\u0433\u0434\u0430 \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u0445 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443, \u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434 &quot;\u043c\u0430\u0441\u0441\u0438\u0432 \u043b\u0438\u0431\u043e \u0441\u0442\u0440\u043e\u043a\u0430&quot; \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 <code>R1:= 'a';<\/code> \u0438 \u0431\u0440\u0430\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0438\u0437 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u0442\u043e\u0433\u0434\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0431\u044b\u043b \u0431\u044b <code>['R1', 'a']<\/code>, \u043d\u043e \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0438\u043b\u0438 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u044d\u0442\u043e \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u0432\u043b\u0438\u044f\u0435\u0442, \u0438 \u0432\u0432\u043e\u0434\u0438\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u043d\u0435\u0442 \u0441\u043c\u044b\u0441\u043b\u0430.<\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0421 \u0447\u0435\u0433\u043e \u0431\u044b \u043d\u0430\u043c \u043d\u0430\u0447\u0430\u0442\u044c. \u0423 \u043d\u0430\u0441 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0441 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0442\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043e\u0434\u0435, \u043d\u043e \u0432\u0435\u0434\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430\u043c \u0438 \u043d\u0430\u0434\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0439\u0442\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u043c \u0438 \u0434\u043b\u0438\u043d\u043d\u044b\u043c \u043f\u0443\u0442\u0435\u043c \u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0441 <code>preg_match()<\/code> \u0438 <code>explode()<\/code>, \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0444\u0430\u0439\u043b, \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0432 PHP \u0444\u0430\u0439\u043b, \u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043a\u043e\u0434 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e. \u0410 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043b\u043e\u0436\u043d\u0435\u0435, \u043d\u043e \u043a\u043e\u0440\u043e\u0447\u0435 \u2014 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0434\u0432\u0438\u0436\u043e\u043a, \u043a\u0430\u043a\u043e\u0439 \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0432\u0440\u0443\u0447\u043d\u0443\u044e. \u0422\u0443\u0442 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043d\u0435 \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c\u0441\u044f \u0433\u0434\u0435 \u0447\u0442\u043e, \u0433\u0434\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u0430 \u0433\u0434\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0443 \u044d\u0442\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u0433\u0434\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e StringLiteral, \u0430 \u0433\u0434\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0430\u0432\u0438\u043b\u0443.<\/p>\n<p>  <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432-\u0434\u0435\u0440\u0435\u0432\u043e, \u0442\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0444\u0430\u0439\u043b <code>self.gdl<\/code> \u043d\u0430\u043c \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0443\u0436\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e. \u041d\u043e \u0444\u0430\u0439\u043b \u0441 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0431\u0430\u0439\u0442\u043e\u0432. \u0415\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u0434\u0432\u0438\u0436\u043e\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0433\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442 \u043f\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0438\u0437 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0433\u043e \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u043c\u0430\u0441\u0441\u0438\u0432\u0430, \u043c\u044b \u0441\u043c\u043e\u0436\u0435\u043c \u0438\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0432\u043e\u043e\u0431\u0449\u0435 \u043b\u044e\u0431\u044b\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u0448. \u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0430\u0440\u0441\u0438\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u043e\u0435\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0438\u0437 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0444\u0430\u0439\u043b \u0441 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439 PHP, \u0430 \u043f\u043e\u0442\u043e\u043c \u0442\u0435\u043c \u0436\u0435 \u0434\u0432\u0438\u0436\u043a\u043e\u043c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 PHP \u043f\u0430\u0440\u0441\u0438\u043c \u0444\u0430\u0439\u043b \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u043d\u0430 PHP.<\/p>\n<p>  <\/p>\n<p>\u0421 \u0443\u0447\u0435\u0442\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432:<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">$selfGrammar = ['Grammar', [   ['Rule', [     ['RuleName', 'Grammar'],     ['RuleBody', [       ['Statement', [         ['Expression', [           ['Element', [             ['RuleName', 'delimiter'],           ]],           ['Quantifier', [['', '*']]],         ]],         ['Expression', [           ['Element', [             ['RuleName', 'Rule'],           ]],           ['Quantifier', [['', '*']]],         ]],       ]],     ]],   ]],   ['Rule', [     ['RuleName', 'delimiter'],     ['RuleBody', [       ['Statement', [         ['Expression', [           ['Element', [             ['RuleName', 'space'],           ]],         ]],       ]],       ['Statement', [         ['Expression', [           ['Element', [             ['RuleName', 'comment'],           ]],         ]],       ]],     ]],   ]],   ['Rule', [     ['RuleName', 'space'],     ['RuleBody', [       ['Statement', [         ['Expression', [           ['Element', [             ['RegexpLiteral', [               ['SymbolRange', [                 ['Symbol', [['AnySymbol', [['', ' ']]]]],               ]],               ['SymbolRange', [                 ['Symbol', [['EscapedSymbol', [['AnySymbol', [['', 'n']]]]]]],               ]],               ['SymbolRange', [                 ['Symbol', [['EscapedSymbol', [['AnySymbol', [['', 't']]]]]]],               ]],               ['SymbolRange', [                 ['Symbol', [['EscapedSymbol', [['AnySymbol', [['', 'r']]]]]]],               ]],             ]],           ]],           ['Quantifier', [['', '+']]],         ]],       ]],     ]],   ]],   ... ]];<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 <a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\/blob\/master\/self.php\" rel=\"nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">['Symbol', [     ['EscapedSymbol', [         ['AnySymbol', [             ['', 'n'],         ]],     ]], ]],<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0431\u0435\u0437 \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a \u0432 \u043a\u043e\u0434\u0435 \u0434\u0432\u0438\u0436\u043a\u0430, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u043c\u044b \u043f\u043e \u0441\u0432\u043e\u0435\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0438\u043b\u0438 \u043f\u043e \u0434\u0440\u0443\u0433\u043e\u0439.<\/p>\n<p>  <\/p>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>RuleName<\/code> \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0442\u043e\u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u044b, \u043e\u0431 \u044d\u0442\u043e\u043c \u043d\u0438\u0436\u0435, \u043d\u043e \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0431\u0435\u043b\u044c\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u044b\u0441\u043b\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b <code>(\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430)<\/code> \u043d\u0430\u0434\u043e \u0437\u0430\u0432\u0435\u0441\u0442\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441. \u0422\u0430\u043a \u0438 \u0441\u0434\u0435\u043b\u0430\u0435\u043c. \u042d\u0442\u043e \u0443\u0437\u0435\u043b \u0434\u0435\u0440\u0435\u0432\u0430, \u043d\u0430\u0437\u043e\u0432\u0435\u043c \u0435\u0433\u043e <code>GdlNode<\/code>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">GdlNode<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class GdlNode {     \/** @var string *\/     protected $name;      \/** @var static[]|string *\/     protected $value;      protected $hashValue = [];      public function __construct($name, $value)     {         $this-&gt;name = $name;         $this-&gt;value = $value;          $this-&gt;init();     }      public function init()     {         if (is_array($this-&gt;value)) {             foreach ($this-&gt;value as &amp;$element) {                 $this-&gt;hashValue[$element-&gt;getName()][] = $element;             }             unset($element);         }     }      public function getName()     {         return $this-&gt;name;     }      public function getValue()     {         return $this-&gt;value;     }      public function setValue($value)     {         $this-&gt;value = $value;         $this-&gt;init();     }      public function get($name): ?GdlNode     {         return $this-&gt;hashValue[$name][0] ?? null;     }      public function getFirst()     {         return $this-&gt;value[0];     }      \/**      * @param string $name      * @return GdlNode[]      *\/     public function getArray($name): array     {         return $this-&gt;hashValue[$name] ?? [];     }      public function toString()     {         if (is_null($this-&gt;value)) {             return null;         }          if (is_string($this-&gt;value)) {             return $this-&gt;value;         }          $str = [];         foreach ($this-&gt;value as $n =&gt; $item) {             $str[] = $item-&gt;toString();         }          return implode('', $str);     }      public function toArray()     {         $name = $this-&gt;getName();         $value = [];          if (is_array($this-&gt;value)) {             foreach ($this-&gt;value as $element) {                 $elementRes = $element-&gt;toArray();                 $value[] = $elementRes;             }         }         else {             $value = $this-&gt;value;         }          return [$name, $value];     } }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0422\u0443\u0442 \u043d\u0430\u0434\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>get($name)<\/code> \u0438 <code>getArray($name)<\/code>. \u042d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0434\u0435\u0440\u0435\u0432\u043e\u043c, <code>$name<\/code> \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<p>  <\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">\/** @var GdlNode $grammar *\/ foreach ($grammar-&gt;getArray('Rule') as $rule) {     echo $rule-&gt;get('RuleName')-&gt;toString() . &quot;\\n&quot;; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0449\u0435 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>toString()<\/code>, \u0435\u0441\u043b\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0443\u0437\u043b\u0430 \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432, \u043e\u043d\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u043e\u043a\u0443. \u0415\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u043a\u043e\u0434\u0435 \u0438\u043b\u0438 \u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438.<\/p>\n<p>  <\/p>\n<p><code>RuleName<\/code> \u0432 \u043d\u0430\u0448\u0435\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u043c\u0442\u0438\u043a\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 <code>[a-zA-Z_] [a-zA-Z_0-9]*<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u043f\u0438\u0448\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u0432\u044b\u0448\u0435, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c <code>RuleName<\/code> \u0431\u0443\u0434\u0435\u0442 \u043c\u0430\u0441\u0441\u0438\u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0430 \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u0430, \u043a\u0430\u043a \u0437\u0430\u0434\u0430\u043d\u043e \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 <code>$selfGrammar<\/code>. <code>toString()<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0443\u0431\u0440\u0430\u0442\u044c \u044d\u0442\u043e \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435. \u041d\u043e \u0435\u0435 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0442\u043e\u043c \u043c\u044b \u0435\u0435 \u0443\u0431\u0435\u0440\u0435\u043c. \u0414\u043b\u044f \u0443\u0437\u043b\u043e\u0432 <code>Symbol<\/code> \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0442\u043e\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435 <code>['AnySymbol', [['', ' ']]]<\/code>, \u0430 <code>['AnySymbol', ' ']<\/code> \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>toString()<\/code>, \u043d\u043e \u044f \u043e\u043f\u0438\u0441\u0430\u043b \u0438\u0445 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u0438 \u043a\u0430\u043a \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u0445 \u0434\u0432\u0438\u0436\u043a\u0430.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 GdlNode \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 <code>new GdlNode(...)<\/code>, \u043d\u043e \u0441 \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u043b\u0443\u0447\u0448\u0435 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f, \u0438 \u0442\u0430\u043a \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0449\u0435.<\/p>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0434\u043b\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 <a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\/blob\/master\/Stream.php\" rel=\"nofollow\">Stream<\/a>. \u042d\u0442\u043e \u043d\u0435 \u0444\u0430\u0439\u043b\u043e\u0432\u044b\u0439 \u043f\u043e\u0442\u043e\u043a, \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u0430\u044f PHP-\u0441\u0442\u0440\u043e\u043a\u0430. \u041e\u043d \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u043f\u0440\u0438 \u0447\u0442\u0435\u043d\u0438\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0435\u0435. \u0415\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u043e\u043d\u0438 \u043d\u0443\u0436\u043d\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0430\u043c \u043f\u0430\u0440\u0441\u0435\u0440.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class GdlParser {     \/** @var GdlNode[]  Keys are rule names *\/     protected $ruleMap;      \/** @var Stream *\/     protected $stream;      public function __construct(GdlNode $grammar)     {         $this-&gt;initRules($grammar);     }      public function initRules(GdlNode $grammar)     {         $this-&gt;ruleMap = [];         foreach ($grammar-&gt;getArray('Rule') as $rule) {             $this-&gt;ruleMap[$rule-&gt;get('RuleName')-&gt;toString()] = $rule;         }     }      public function parse(string $mainRuleName, Stream $stream)     {         $this-&gt;stream = $stream;          $rule = $this-&gt;getRule($mainRuleName);         $result = $this-&gt;parseRule($rule);          return $result;     }      ... }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0438 \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430. \u0421\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u0438 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0438\u043c \u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected function parseRule(GdlNode $rule) {     $ruleName = $rule-&gt;get('RuleName');     $ruleNameStr = ($ruleName !== null ? $ruleName-&gt;toString() : '()');      $parsedRule = null;      $statementList = $rule-&gt;get('RuleBody')-&gt;getArray('Statement');     $initialPos = $this-&gt;stream-&gt;getPos();     foreach ($statementList as $statement) {         $parsedRule = $this-&gt;parseStatement($statement);         if ($parsedRule !== null) {             break;         }          \/\/ try parse next variant from same position         $this-&gt;stream-&gt;setPos($initialPos);     }      return ($parsedRule === null ? null : new GdlNode($ruleNameStr, $parsedRule)); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0418\u041b\u0418 \u0434\u043b\u044f Statement. \u0417\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u043f\u043e\u0442\u043e\u043a\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e \u043e\u0447\u0435\u0440\u0435\u0434\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 Statement, \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f, \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044e \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0441\u043b\u0435\u0434\u0443\u0449\u0438\u0439.<br \/>  <code>'()'<\/code> \u044d\u0442\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0434\u043b\u044f inline-\u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0435\u0437 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f. \u041e\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043c\u043e\u0433\u043b\u0430 \u043e\u0442\u043b\u0438\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043e\u0442 \u0441\u0442\u0440\u043e\u043a. \u041c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c \u0441 \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435, \u0443 \u043d\u0430\u0441 \u0436\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438. \u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0443, \u043d\u043e \u0442\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0430\u0434\u043e \u0432\u044b\u043d\u043e\u0441\u0438\u0442\u044c \u0432 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected function parseStatement(GdlNode $statement) {     $parsedStatement = [];      $expressionList = $statement-&gt;getArray('Expression');     foreach ($expressionList as $i =&gt; $expression) {         $lookAheadElement = null;         $lookAhead = $expression-&gt;get('LookAhead');         if ($lookAhead !== null) {             if ($lookAhead-&gt;get('Element') !== null) {                 $lookAheadElement = $lookAhead-&gt;get('Element');             }             elseif (isset($expressionList[$i + 1])) {                 $lookAheadElement = $expressionList[$i + 1]-&gt;get('Element');             }         }          $parsedExpression = $this-&gt;parseExpression($expression, $lookAheadElement);         if ($parsedExpression === null) {             $parsedStatement = null;             break;         }          if (!empty($parsedExpression)) {             \/\/ skip elements with name started with small letter             $name = $parsedExpression[0]-&gt;getName();  \/\/ all parsed elements in expression have same name             $isSmallLetter = (!empty($name) &amp;&amp; ($name[0] &gt;= 'a' &amp;&amp; $name[0] &lt;= 'z'));              if (!$isSmallLetter) {                 if ($name === '()') {                     foreach ($parsedExpression as $inlineRule) {                         $this-&gt;addToParsedStatement($parsedStatement, $inlineRule-&gt;getValue());                     }                 }                 else {                     $this-&gt;addToParsedStatement($parsedStatement, $parsedExpression);                 }             }         }     }      return $parsedStatement; }  protected function addToParsedStatement(array &amp;$parsedStatement, array $parsedExpression) {     foreach ($parsedExpression as $parsedElement) {         $parsedStatement[] = $parsedElement;     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 \u0418 \u0434\u043b\u044f Expression. \u041f\u0430\u0440\u0441\u0438\u043c \u043a\u0430\u0436\u0434\u044b\u0439 Expression, \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f, \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432\u0441\u0435\u0433\u043e Statement. \u0423\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u043c LookAhead. \u041d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b \u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u0431\u0443\u043a\u0432\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c. \u0414\u043b\u044f inline-\u043f\u0440\u0430\u0432\u0438\u043b \u0435\u0441\u0442\u044c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0443\u0437\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441 \u043f\u0443\u0441\u0442\u044b\u043c\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f\u043c\u0438 \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0451 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0441\u0442\u0440\u043e\u043a\u0430\u043c \u0438 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u0430\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected function parseExpression(GdlNode $expression, ?GdlNode $lookAheadElement = null) {     $element = $expression-&gt;get('Element');      $quantifier = $expression-&gt;get('Quantifier');     $quantifierType = null;     if ($quantifier !== null) {         $quantifierType = $quantifier-&gt;get('')-&gt;getValue();     }      $parsedElementList = [];     while (true) {         $initialElementPos = $this-&gt;stream-&gt;getPos();          $parsedLookAheadElement = null;         if ($lookAheadElement !== null) {             $parsedLookAheadElement = $this-&gt;parseElement($lookAheadElement);             $this-&gt;stream-&gt;setPos($initialElementPos);              if ($parsedLookAheadElement !== null) {                 break;             }         }          $parsedElement = $this-&gt;parseElement($element);          if ($parsedElement !== null) {             $parsedElementList[] = $parsedElement;         }         else {             $this-&gt;stream-&gt;setPos($initialElementPos);             break;         }          if ($quantifierType === null || $quantifierType === '?') {             break;         }     }      $countDoesNotMatch = (($quantifierType === null || $quantifierType === '+') ? empty($parsedElementList) : false);     if ($countDoesNotMatch) {         $parsedElementList = null;     }      return $parsedElementList; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0438 LookAhead. \u041d\u0435\u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected function parseElement(GdlNode $element) {     $specificElement = $element-&gt;getFirst();     $elementType = $specificElement-&gt;getName();      if ($elementType === 'RuleName') {         $rule = $this-&gt;getRule($specificElement-&gt;toString());         $parsedElement = $this-&gt;parseRule($rule);     }     elseif ($elementType === 'StringLiteral') {         $parsedElement = $this-&gt;parseStringLiteral($specificElement);     }     elseif ($elementType === 'RegexpLiteral') {         $parsedElement = $this-&gt;parseRegexpLiteral($specificElement);     }     elseif ($elementType === 'InlineRule') {         $parsedElement = $this-&gt;parseRule($specificElement);     }     else {         throw new Exception('Unknown element type: ' . $elementType);     }      return $parsedElement; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0432\u044b\u0431\u043e\u0440 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0442\u0438\u043f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043f\u0440\u0430\u0432\u0438\u043b\u0430. Inline-\u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0438 \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439.<\/p>\n<p>  <\/p>\n<p>\u0422\u0443\u0442 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0441\u043f\u043e\u0440\u043d\u044b\u0439 \u0432\u043e\u043f\u0440\u043e\u0441, \u0433\u0434\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0435\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 GdlNode, \u0432 <code>parseElement()<\/code> \u0438\u043b\u0438 \u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445. \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u043d\u0443\u0436\u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c label \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a \u0432 ANTLR, \u0442\u043e\u0433\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 <code>parseRule()<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u043d\u0443 \u0438\u043b\u0438 \u043d\u0430\u0434\u043e \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>setName()<\/code> \u0432 GdlNode, \u0447\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043d\u0435 \u0442\u0430\u043a \u0447\u0438\u0441\u0442\u043e.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected function parseStringLiteral(GdlNode $element) {     $parsedValue = null;      $symbolList = $element-&gt;getArray('Symbol');     foreach ($symbolList as $symbol) {         if ($this-&gt;stream-&gt;eof()) {             $parsedValue = null;             break;         }          $contentSymbol = $this-&gt;stream-&gt;readSymbol();         $str = $this-&gt;getSymbolStr($symbol);         if ($contentSymbol !== $str) {             $parsedValue = null;             break;         }          $parsedValue .= $contentSymbol;     }      return ($parsedValue === null ? null : new GdlNode('', $parsedValue)); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441\u0442\u0440\u043e\u043a\u0438, \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected function parseRegexpLiteral(GdlNode $element) {     $parsedValue = null;      if (!$this-&gt;stream-&gt;eof()) {         $contentSymbol = $this-&gt;stream-&gt;readSymbol();         if ($element-&gt;get('AnySymbolLiteral') !== null) {             $parsedValue = $contentSymbol;         }         else {             $symbolRangeList = $element-&gt;getArray('SymbolRange');             foreach ($symbolRangeList as $symbolRange) {                 $symbolList = $symbolRange-&gt;getArray('Symbol');                  if (count($symbolList) === 2) {                     $strFrom = $this-&gt;getSymbolStr($symbolList[0]);                     $strTo = $this-&gt;getSymbolStr($symbolList[1]);                      \/\/ use build-in PHP string comparison                     if ($contentSymbol &gt;= $strFrom &amp;&amp; $contentSymbol &lt;= $strTo) {                         $parsedValue = $contentSymbol;                         break;                     }                 }                 elseif (count($symbolList) === 1) {                     $str = $this-&gt;getSymbolStr($symbolList[0]);                      if ($contentSymbol === $str) {                         $parsedValue = $contentSymbol;                         break;                     }                 }             }         }     }      return ($parsedValue === null ? null : new GdlNode('', $parsedValue)); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0430\u0440\u0441\u0438\u043d\u0433 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043e\u0434\u0438\u043d \u0441\u0438\u043c\u0432\u043e\u043b. \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043b\u044e\u0431\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">protected $escapedSymbols = ['s' =&gt; ' ', 't' =&gt; &quot;\\t&quot;, 'r' =&gt; &quot;\\r&quot;, 'n' =&gt; &quot;\\n&quot;];  protected function getSymbolStr(GdlNode $symbol) {     $str = null;     $specificElement = $symbol-&gt;getFirst();     $elementType = $specificElement-&gt;getName();      if ($elementType === 'AnySymbol') {         $str = $specificElement-&gt;get('')-&gt;getValue();     }     elseif ($elementType === 'EscapedSymbol') {         $str = $specificElement-&gt;get('AnySymbol')-&gt;get('')-&gt;getValue();         $str = (isset($this-&gt;escapedSymbols[$str]) ? $this-&gt;escapedSymbols[$str] : $str);     }     elseif ($elementType === 'HexCodeSymbol') {         list($hexDigit1, $hexDigit2) = $specificElement-&gt;getArray('HexDigit');         $intValue1 = ord($hexDigit1-&gt;get('')-&gt;getValue()) - 0x30;         $intValue2 = ord($hexDigit2-&gt;get('')-&gt;getValue()) - 0x30;         $intValue1 -= ($intValue1 &gt;= 0x0A ? 0x07 : 0);         $intValue2 -= ($intValue2 &gt;= 0x0A ? 0x07 : 0);         $code = $intValue1 * 0x10 + $intValue2;         $str = chr($code);     }      return $str; }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0441 \u0443\u0447\u0435\u0442\u043e\u043c \u044d\u043a\u0440\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 hex-\u043a\u043e\u0434\u0430.<\/p>\n<p>  <\/p>\n<p>\u0412\u0441\u0435\u0433\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a. \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440 \u0441 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439 \u0438\u0437 <code>self.php<\/code>, \u043f\u0430\u0440\u0441\u0438\u043c \u0444\u0430\u0439\u043b <code>self.gdl<\/code>, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443. \u041b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c, \u043d\u043e \u0432 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0435\u0441\u0442\u044c \u0432\u0441\u044f\u043a\u0438\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c, \u043d\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0432 <code>self.php<\/code> \u0437\u0430 \u043d\u0435\u043d\u0430\u0434\u043e\u0431\u043d\u043e\u0441\u0442\u044c\u044e \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043a\u0430\u0432\u044b\u0447\u0435\u043a \u0432 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0445 StringLiteral. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0443\u0436\u0435\u043d \u0435\u0449\u0435 \u043e\u0434\u0438\u043d \u0448\u0430\u0433. \u041f\u0430\u0440\u0441\u0438\u043c \u043f\u043e \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0444\u0430\u0439\u043b <code>self.gdl<\/code> \u0435\u0449\u0435 \u0440\u0430\u0437, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0435\u0449\u0435 \u043e\u0434\u043d\u0443 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u044b \u0438 \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c. \u0415\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u043e\u043d\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043f\u043e\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u0431\u0430\u0433, \u043f\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e, \u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u044e\u0442 \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0442\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u043e\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u0441\u0441\u0438\u0432\u0430. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0439\u0442\u0438 \u0434\u0440\u0443\u0433\u0438\u043c \u043f\u0443\u0442\u0435\u043c \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u043c\u0438 \u0431\u0443\u043a\u0432\u0430\u043c\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442 \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u0445 \u0441 \u0431\u043e\u043b\u044c\u0448\u0438\u043c\u0438 \u0431\u0443\u043a\u0432\u0430\u043c\u0438. \u0418 \u0432\u0441\u0435 <code>RuleName<\/code> \u0440\u0430\u0437\u0431\u0438\u0442\u044c \u043d\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u044b. \u0422\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>testSelfParsing()<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">php parser_test.php testSelfParsing 0.077260971069336 0.12426900863647<\/code><\/pre>\n<p>  <\/p>\n<p>\u0426\u0438\u0444\u0440\u044b \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0432 \u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>microtime()<\/code>. \u041f\u0435\u0440\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0438\u0437 <code>self.php<\/code>, \u0432\u0442\u043e\u0440\u043e\u0435 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u043e \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435. \u0426\u0438\u0444\u0440\u044b \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u0436\u0435\u043b\u0435\u0437\u0430 \u043d\u0435\u0432\u0430\u0436\u043d\u0430. \u0417\u0434\u0435\u0441\u044c \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e <code>toString()<\/code> \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433. \u0412 <code>self.php<\/code> \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0438 \u043e\u043d\u0430 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442, \u0430 \u0432 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432, \u0438 \u043e\u043d\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u043d\u0435\u043c\u0443 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e.<\/p>\n<p>  <\/p>\n<h3 id=\"obrabotka-oshibok\">\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0448\u0438\u0431\u043e\u043a<\/h3>\n<p>  <\/p>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u043c\u0435\u0441\u0442\u0435 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435, \u0434\u0432\u0438\u0436\u043e\u043a \u043f\u0435\u0440\u0435\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u043f\u0440\u0430\u0432\u0438\u043b \u043d\u0430 \u0432\u0441\u0435\u0445 \u0443\u0440\u043e\u0432\u043d\u044f\u0445 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438, \u0438 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 null.<br \/>  \u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0441\u0435\u0447\u0435\u043d\u0438\u0435, \u043a\u0430\u043a \u0432 \u041f\u0440\u043e\u043b\u043e\u0433\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043c\u044b \u043d\u0430\u0447\u0430\u043b\u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u043e <code>ReturnStatement<\/code> \u0438 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0443 <code>return<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u044d\u0442\u043e \u0442\u043e\u0447\u043d\u043e <code>ReturnStatement<\/code>, \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0430\u043a\u043e\u0435-\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043b\u0438\u0431\u043e \u0441\u0440\u0430\u0437\u0443 <code>';'<\/code>. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0438 \u0442\u043e\u0433\u043e \u043d\u0438 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043d\u0435\u0442, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443 &quot;Expected &#8216;;&#8217;&quot;. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u043d\u0430\u0434\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0441\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435 <code>return<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u0430\u043a \u0432 \u041f\u0440\u043e\u043b\u043e\u0433\u0435, \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 <code>parseRule()<\/code>, \u044d\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e, \u0438 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0420\u0430\u0437 \u043c\u044b \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0442\u0430\u043c \u0442\u043e\u0447\u043d\u043e &quot;Expected &#8216;;&#8217;&quot;, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u043e\u0436\u043d\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0430 \u0442\u0430\u043c \u0435\u0441\u0442\u044c, \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0432 \u0432\u0441\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u0438, \u043c\u044b \u0432\u0435\u0440\u043d\u0435\u043c \u0442\u043e, \u0447\u0442\u043e \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0447\u0438\u0442\u0430\u0442\u044c\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c, \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442. \u042d\u0442\u043e \u0436\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043d\u0430\u043c \u0432\u044b\u0432\u043e\u0434\u0438\u0442\u044c \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438, \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u0443\u044e. \u042d\u0442\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0445\u0430\u043a, \u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432\u043f\u043e\u043b\u043d\u0435 \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e, \u0445\u043e\u0442\u044c \u0438 \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0442\u0430\u043a, \u043a\u0430\u043a \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435 \u043d\u0430\u0434\u043e \u0431\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c, \u0432 \u043a\u0430\u043a\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u0430 \u043e\u0448\u0438\u0431\u043a\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0442\u0435\u043a \u0432\u044b\u0437\u043e\u0432\u043e\u0432 \u043f\u0440\u0430\u0432\u0438\u043b. \u042d\u0442\u043e \u043f\u043e\u043c\u043e\u0436\u0435\u0442 \u0438 \u043f\u0440\u0438 \u043e\u0442\u043b\u0430\u0434\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u043e\u0436\u0443 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0434\u0435\u0442\u0430\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. \u0412\u0441\u0435 \u0448\u0430\u0433\u0438 \u0438\u0437 \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0434\u0435\u043b\u0430\u043d\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u043c\u0438\u0442\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">diff<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">GdlParser.php       protected function parseRule(GdlNode $rule)      {          $ruleName = $rule-&gt;get('RuleName');          $ruleNameStr = ($ruleName !== null ? $ruleName-&gt;toString() : '()'); +        $this-&gt;ruleCallStack[] = [$ruleNameStr, $this-&gt;stream-&gt;getPos()];           ...  +        array_pop($this-&gt;ruleCallStack); +          return ($parsedRule === null ? null : new GdlNode($ruleNameStr, $parsedRule));      }       protected function parseStatement(GdlNode $statement)      {          $parsedStatement = [];           $expressionList = $statement-&gt;getArray('Expression'); +        $cut = false;          foreach ($expressionList as $i =&gt; $expression) {              ...               $parsedExpression = $this-&gt;parseExpression($expression, $lookAheadElement);              if ($parsedExpression === null) { -                $parsedStatement = null; -                break; +                if ($cut) { +                    $this-&gt;handleError($expression); +                    continue; +                } +                else { +                    $parsedStatement = null; +                    break; +                }              } + +            if ($expression-&gt;get('Cut') !== null) { +                $cut = true; +            }              ...          }          ...      }  +    protected function handleError(GdlNode $expression) +    { +        $elementType = $expression-&gt;get('Element')-&gt;getFirst()-&gt;getName(); +        if ($elementType === 'StringLiteral' || $elementType === 'RegexpLiteral') { +            $name = $expression-&gt;toString(); +        } +        else { +            $name = $expression-&gt;get('Element')-&gt;getFirst()-&gt;toString(); +        } + +        $i = count($this-&gt;ruleCallStack) - 1; +        while ($this-&gt;ruleCallStack[$i][0] == '()') { $i--; } +        $ruleInfo = $this-&gt;ruleCallStack[$i]; + +        $this-&gt;errors[] = 'Expected ' . $name . ' at ' . implode(':', $this-&gt;stream-&gt;getLineAndColumn()) . ' (' . $this-&gt;stream-&gt;getPos() . ')' +            . ' in ' . $ruleInfo[0] . ' at ' . implode(':', $this-&gt;stream-&gt;getLineAndColumn($ruleInfo[1])) . ' (' . $ruleInfo[1] . ')'; +    }  self.gdl  Rule: -    RuleName delimiter* ':' delimiter* RuleBody ';' delimiter* +    RuleName! delimiter* ':' delimiter* RuleBody ';' delimiter* ; ...<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<pre><code class=\"php\">public function testParsingErrors() {     $mainRuleName = 'Grammar';     $gdlParser = new GdlParser($this-&gt;getSelfGrammar());      $grammarSource = &lt;&lt;&lt;'SRC' Program: ;  Test:;  SRC;     $languageGrammar = $gdlParser-&gt;parse($mainRuleName, new Stream($grammarSource));     foreach ($languageGrammar-&gt;getArray('Rule') as $rule) {         $rule-&gt;get('RuleName')-&gt;setValue($rule-&gt;get('RuleName')-&gt;toString());     }      $this-&gt;assertTrue($languageGrammar-&gt;toArray() === ['Grammar', [         ['Rule', [             ['RuleName', 'Program'],             ['', ':'],             ['', ';'],         ]],         ['Rule', [             ['RuleName', 'Test'],             ['', ':'],             ['', ';'],         ]],     ]]);     $this-&gt;assertTrue($gdlParser-&gt;getErrors() === [         'Expected RuleBody at 2:1 (9) in Rule at 1:1 (0)',         'Expected RuleBody at 4:6 (17) in Rule at 4:1 (12)',     ]);      $grammarSource = &lt;&lt;&lt;'SRC' SRC;     $languageGrammar = $gdlParser-&gt;parse($mainRuleName, new Stream($grammarSource));      $this-&gt;assertTrue($languageGrammar-&gt;toArray() === ['Grammar', []]);     $this-&gt;assertEmpty($gdlParser-&gt;getErrors()); }<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"dopolnitelnye-vozmozhnosti\">\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438<\/h3>\n<p>  <\/p>\n<p>\u0428\u0435\u0441\u0442\u043d\u0430\u0434\u0446\u0430\u0442\u0438\u0440\u0438\u0447\u043d\u044b\u0435 \u043a\u043e\u0434\u044b \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c UTF-8. \u0421\u0438\u043c\u0432\u043e\u043b\u044b UTF-8 \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u0445 \u0442\u0438\u043f\u0430 <code>AnySymbol*<\/code> \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u0432\u0438\u0434\u0443 \u043f\u0440\u0438\u0440\u043e\u0434\u044b UTF-8, \u0445\u043e\u0442\u044c \u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c\u0438 \u0431\u0430\u0439\u0442\u0430\u043c\u0438. <\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u0443 \u0431\u0430\u0439\u0442\u043e\u0432 \u043a\u0430\u043a \u043e\u0434\u0438\u043d \u0441\u0438\u043c\u0432\u043e\u043b, \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 UTF \u0432 \u043a\u043b\u0430\u0441\u0441 \u043f\u043e\u0442\u043e\u043a\u0430 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 Stream. \u041c\u044b \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">public function testUtf8() {     $mainRuleName = 'Grammar';     $gdlParser = new GdlParser($this-&gt;getSelfGrammar());      $grammarSource = &lt;&lt;&lt;'SRC' Grammar:     (Word={str} '\\n')* ;  Word:     Utf8RussianLetter+ ;  Utf8RussianLetter:     | [\\xD0][\\x90-\\xBF]  \/* \u0410-\u042f\u0430-\u043f *\/     | [\\xD1][\\x80-\\x8F]  \/* \u0440-\u044f *\/     | [\\xD0][\\x01]       \/* \u0401 *\/     | [\\xD1][\\x91]       \/* \u0451 *\/ ; SRC;     $languageGrammar = $gdlParser-&gt;parse($mainRuleName, new Stream($grammarSource));      $this-&gt;assertEmpty($gdlParser-&gt;getErrors());      $mainRuleName = $languageGrammar-&gt;get('Rule')-&gt;get('RuleName')-&gt;getValue();     $languageParser = new GdlParser($languageGrammar);      $source = &lt;&lt;&lt;'SRC' \u0442\u0435\u0441\u0442 \u0442\u0435\u0441\u0442 \u0430\u0431\u0432  SRC;     $tree = $languageParser-&gt;parse($mainRuleName, new Stream($source));      $this-&gt;assertEmpty($languageParser-&gt;getErrors());     $this-&gt;assertTrue($tree-&gt;toArray() === ['Grammar', [         ['Word', '\u0442\u0435\u0441\u0442'],         ['', &quot;\\n&quot;],         ['Word', '\u0442\u0435\u0441\u0442'],         ['', &quot;\\n&quot;],         ['Word', '\u0430\u0431\u0432'],         ['', &quot;\\n&quot;],     ]]); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0431\u0438\u043d\u0430\u0440\u043d\u044b\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0442\u0438\u043f\u0430 TCP-\u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f. \u0421\u0435\u0439\u0447\u0430\u0441 \u043c\u043e\u0436\u043d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0433\u0434\u0435 \u043d\u0430\u0447\u0430\u043b\u043e \u0438 \u043a\u043e\u043d\u0435\u0446 \u0443\u0437\u043b\u043e\u0432 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044f\u043c\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043d\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u0442\u0430\u043a\u0438\u0435, \u0433\u0434\u0435 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0443\u0437\u043b\u043e\u0432 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u043b\u0438 \u0441\u043c\u0435\u0449\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0435\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435, \u0433\u0434\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435, \u0430 \u043f\u043e\u0442\u043e\u043c \u0438\u0434\u0435\u0442 \u0438\u0445 \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">3 Element1 Element2 Element3<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0442\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0440\u0435\u0448\u0438\u0442\u044c. \u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438\u043b\u0438 \u0432 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u043c \u0432\u0438\u0434\u0435? \u0412 \u0434\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u043e\u0439 \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u0435? \u0412 big-endian \u0438\u043b\u0438 little-endian?<\/p>\n<p>  <\/p>\n<p>\u041d\u0443\u0436\u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<p>\u0412 ANTLR \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u0439 \u043a\u043e\u0434 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0445 \u0441\u043a\u043e\u0431\u043a\u0430\u0445. \u041d\u043e \u0444\u0438\u0433\u0443\u0440\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043a\u0438 \u0432 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f\u0445 \u0437\u0430\u0434\u0430\u044e\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u043c \u0442\u043e\u0436\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043c\u0435\u0434\u043b\u044f\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a, \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c \u044d\u0442\u0443 \u0447\u0430\u0441\u0442\u044c \u0441\u043e \u0437\u043d\u0430\u043a\u0430 <code>=<\/code>. \u0418 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0443 \u043a\u043e\u0434\u0430 \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443. \u0410 \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u043a\u0440\u0443\u0433\u043e\u043c \u041e\u041e\u041f, \u0442\u043e \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u043e\u0434\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u0443\u0437\u0435\u043b \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. \u041f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043b\u0443\u0447\u0448\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435, \u0447\u0442\u043e\u0431\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043c\u043e\u0433\u043b\u0430 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u0442\u044c \u0435\u043c\u0443 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 null, \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u0432 \u044d\u0442\u0438\u043c, \u0447\u0442\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f. \u041d\u0443 \u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">diff<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">GdlParser.php       protected function parseExpression(GdlNode $expression, ?GdlNode $lookAheadElement = null)      {          $element = $expression-&gt;get('Element');  +        $elementFunctionNameList = null; +        if ($expression-&gt;get('FunctionCall') !== null) { +            foreach ($expression-&gt;get('FunctionCall')-&gt;getArray('FunctionName') as $functionName) { +                $elementFunctionNameList[] = $functionName-&gt;toString(); +            } +        } +          $quantifier = $expression-&gt;get('Quantifier');          $quantifierType = null; +        $countVal = 0;          if ($quantifier !== null) { -            $quantifierType = $quantifier-&gt;get('')-&gt;getValue(); +            $count = $quantifier-&gt;get('Count'); +            if ($count === null) { +                $quantifierType = $quantifier-&gt;get('')-&gt;getValue(); +            } +            else { +                $quantifierType = '{}'; +                if ($count-&gt;get('IntValue') !== null) { +                    $countVal = intval($count-&gt;get('IntValue')-&gt;toString()); +                } +                elseif ($count-&gt;get('FunctionCall') !== null) { +                    $countFunctionName = $count-&gt;get('FunctionCall')-&gt;get('FunctionName')-&gt;toString(); +                    $countVal = $this-&gt;$countFunctionName(); +                } +            }          }               $parsedElement = $this-&gt;parseElement($element); +            if ($elementFunctionNameList !== null &amp;&amp; $parsedElement !== null) { +                foreach ($elementFunctionNameList as $elementFunctionName) { +                    $this-&gt;$elementFunctionName($parsedElement); +                    if ($parsedElement === null) { +                        break; +                    } +                } +            }  -            if ($quantifierType === null || $quantifierType === '?') { +            if ($quantifierType === null || $quantifierType === '?' || $quantifierType === '{}' &amp;&amp; count($parsedElementList) === $countVal) {                  break;              }          }  -        $countDoesNotMatch = (($quantifierType === null || $quantifierType === '+') ? empty($parsedElementList) : false); +        $countDoesNotMatch = (($quantifierType === null || $quantifierType === '+') ? empty($parsedElementList) +            : (($quantifierType === '{}') ? count($parsedElementList) !== $countVal : false) +        );          if ($countDoesNotMatch) {              $parsedElementList = null;          }  self.gdl   Expression: -    Element Quantifier? LookAhead? Cut? delimiter* +    Element FunctionCall? Quantifier? LookAhead? Cut? delimiter*  ;   Quantifier:      | '*'      | '?'      | '+' +    | '{' Count '}'  ; + +Count: +    | IntValue +    | FunctionCall +; + +IntValue: +    [0-9]+ +; + +FunctionCall: +    '={'! FunctionName (',' FunctionName)* '}' +; + +FunctionName: +    ID +;<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u043f\u0440\u0438\u0432\u044f\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443, \u0438 \u0434\u043b\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0441 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u043d\u043d\u043e\u0433\u043e \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430. \u041d\u0430\u0432\u0435\u0440\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c <code>Function<\/code> \u0432\u043d\u0443\u0442\u0440\u044c <code>Element<\/code>, \u043d\u043e \u043e\u0441\u043e\u0431\u043e\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 \u044d\u0442\u043e\u043c \u043d\u0435\u0442.<\/p>\n<p>  <\/p>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u0438 \u0434\u043b\u044f <code>Count<\/code> \u0438 <code>FunctionCall<\/code> \u0438\u043c\u0435\u044e\u0442 \u0440\u0430\u0437\u043d\u0443\u044e \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0443. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0434\u043b\u044f <code>Count<\/code> \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c int, \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0434\u043b\u044f \u043d\u0435\u0435 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0442\u0430\u043a.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">public function testCount() {     $mainRuleName = 'Grammar';     $gdlParser = new GdlParser($this-&gt;getSelfGrammar());      $grammarSource = &lt;&lt;&lt;'SRC' Data:     Count={setCount} '\\n' Element{={getCount}} ;  Count:     [0-9]{4} ;  Element:     [a-zA-Z0-9]+ '\\n' ; SRC;     $languageGrammar = $gdlParser-&gt;parse($mainRuleName, new Stream($grammarSource));      $this-&gt;assertEmpty($gdlParser-&gt;getErrors());      $mainRuleName = $languageGrammar-&gt;get('Rule')-&gt;get('RuleName')-&gt;toString();      $languageParser = new class($languageGrammar) extends GdlParser {         protected $cnt;          public function setCount(GdlNode &amp;$parsedElement)         {             $this-&gt;cnt = intval($parsedElement-&gt;toString());         }         public function getCount(): int         {             return $this-&gt;cnt;         }     };      $source = &lt;&lt;&lt;'SRC' 0006 Element1 Element2 Element3 Element4 Element5 Element6  SRC;     $tree = $languageParser-&gt;parse($mainRuleName, new Stream($source));     $tree-&gt;get('Count')-&gt;setValue($tree-&gt;get('Count')-&gt;toString());     $tree-&gt;get('')-&gt;setValue($tree-&gt;get('')-&gt;toString());     foreach ($tree-&gt;getArray('Element') as $element) {         $element-&gt;setValue($element-&gt;toString());     }      $this-&gt;assertEmpty($languageParser-&gt;getErrors());     $this-&gt;assertTrue($tree-&gt;toArray() === ['Data', [         ['Count', '0006'],         ['', &quot;\\n&quot;],         ['Element', &quot;Element1\\n&quot;],         ['Element', &quot;Element2\\n&quot;],         ['Element', &quot;Element3\\n&quot;],         ['Element', &quot;Element4\\n&quot;],         ['Element', &quot;Element5\\n&quot;],         ['Element', &quot;Element6\\n&quot;],     ]]); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0434\u0430\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u0448\u0438\u0440\u043e\u043a\u0438\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0431\u0440\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 <code>toString()<\/code> \u0438\u0437 \u043a\u043e\u0434\u0430, \u0432\u0435\u0440\u043d\u0435\u0435 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0435\u0435 \u0432 \u0434\u0440\u0443\u0433\u043e\u0435 \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u043b\u0438\u044f\u0442\u044c \u043d\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0414\u0435\u043b\u0430\u0435\u043c \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>str<\/code>, \u0433\u0434\u0435 \u0431\u0443\u0434\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c <code>toString()<\/code>, \u0438 \u0432 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0432\u0435\u0437\u0434\u0435 \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>RuleName<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>RuleName={str}<\/code>. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 <code>self.gdl<\/code> \u0442\u0430\u043c \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0440\u043e\u043a\u0430, \u0438 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0443\u044e <code>$ruleName-&gt;toString()<\/code> \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 \u0431\u044b\u0441\u0442\u0440\u0443\u044e <code>$ruleName-&gt;getValue()<\/code>. \u0414\u043b\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>symbolStr<\/code> \u0438 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0438\u0445 \u0432\u0441\u0435 \u0432 <code>self.php<\/code>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">diff<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"diff\">GdlParser.php       public function initRules(GdlNode $grammar)      {          $this-&gt;ruleMap = [];          foreach ($grammar-&gt;getArray('Rule') as $rule) { -            $this-&gt;ruleMap[$rule-&gt;get('RuleName')-&gt;toString()] = $rule; +            $this-&gt;ruleMap[$rule-&gt;get('RuleName')-&gt;getValue()] = $rule;          }      }       protected function parseRule(GdlNode $rule)      {          $ruleName = $rule-&gt;get('RuleName'); -        $ruleNameStr = ($ruleName !== null ? $ruleName-&gt;toString() : '()'); +        $ruleNameStr = ($ruleName !== null ? $ruleName-&gt;getValue() : '()');          $this-&gt;ruleCallStack[] = [$ruleNameStr, $this-&gt;stream-&gt;getPos()];               foreach ($expression-&gt;get('FunctionCall')-&gt;getArray('FunctionName') as $functionName) { -                $elementFunctionNameList[] = $functionName-&gt;toString(); +                $elementFunctionNameList[] = $functionName-&gt;getValue();  +    protected function str(GdlNode &amp;$parsedElement) +    { +        $parsedElement-&gt;setValue($parsedElement-&gt;toString()); +    } + +    protected function symbolStr(GdlNode &amp;$parsedElement) +    { +        $parsedElement-&gt;setValue($this-&gt;getSymbolStr($parsedElement)); +    } +      protected function parseStringLiteral(GdlNode $element)      {               $contentSymbol = $this-&gt;stream-&gt;readSymbol(); -            $str = $this-&gt;getSymbolStr($symbol); +            $str = $symbol-&gt;getValue();       protected function parseRegexpLiteral(GdlNode $element)      {                      if (count($symbolList) === 2) { -                        $strFrom = $this-&gt;getSymbolStr($symbolList[0]); -                        $strTo = $this-&gt;getSymbolStr($symbolList[1]); +                        $strFrom = $symbolList[0]-&gt;getValue(); +                        $strTo = $symbolList[1]-&gt;getValue();                       elseif (count($symbolList) === 1) { -                        $str = $this-&gt;getSymbolStr($symbolList[0]); +                        $str = $symbolList[0]-&gt;getValue();  self.gdl   Rule: -    RuleName! delimiter* ':' delimiter* RuleBody ';' delimiter* +    RuleName={str}! delimiter* ':' delimiter* RuleBody ';' delimiter*  ;   Element: -    | RuleName +    | RuleName={str}      | StringLiteral      | RegexpLiteral      | InlineRule  ;   Count: -    | IntValue +    | IntValue={str}      | FunctionCall  ;   FunctionCall: -    '={'! FunctionName (',' FunctionName)* '}' +    '={'! FunctionName={str} (',' FunctionName={str})* '}'  ;   StringLiteral: -    '\\''! Symbol+&gt;&gt; '\\'' +    '\\''! Symbol={symbolStr}+&gt;&gt; '\\''  ;   SymbolRange: -    Symbol&gt;']' ('-'! Symbol&gt;']')? +    Symbol={symbolStr}&gt;']' ('-'! Symbol={symbolStr}&gt;']')?  ;  self.php                           ['RegexpLiteral', [                              ['SymbolRange', [ -                                ['Symbol', [['AnySymbol', [['', ' ']]]]], +                                ['Symbol', &quot; &quot;],                              ]],                              ['SymbolRange', [ -                                ['Symbol', [['EscapedSymbol', [['AnySymbol', [['', 'n']]]]]]], +                                ['Symbol', &quot;\\n&quot;],                              ]],                              ['SymbolRange', [ -                                ['Symbol', [['EscapedSymbol', [['AnySymbol', [['', 't']]]]]]], +                                ['Symbol', &quot;\\t&quot;],                              ]],                              ['SymbolRange', [ -                                ['Symbol', [['EscapedSymbol', [['AnySymbol', [['', 'r']]]]]]], +                                ['Symbol', &quot;\\r&quot;],                              ]],                          ]],                      ]], ...<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0441 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u043e\u043c \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438?<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">php parser_test.php testSelfParsing 0.10463285446167 0.10712099075317<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0432\u044b\u0440\u043e\u0432\u043d\u044f\u043b\u043e\u0441\u044c \u0438 \u0441\u0442\u0430\u043b\u043e \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438\u0437 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0440\u0430\u0437\u0430 \u0438 \u043c\u0435\u043d\u044c\u0448\u0435 \u0432\u0442\u043e\u0440\u043e\u0433\u043e. \u041d\u0430\u043f\u043e\u043c\u043d\u044e, \u043f\u0435\u0440\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 <code>self.gdl<\/code> \u043f\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0438\u0437 <code>self.php<\/code>, \u0432\u0442\u043e\u0440\u043e\u0435 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0438\u0437 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0448\u043b\u044b\u0439 \u0440\u0430\u0437 \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u043c\u044b \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438 <code>toString()<\/code> \u043d\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430\u0445, \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b \u0432 <code>self.php<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u044b\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438. \u0421\u0435\u0439\u0447\u0430\u0441 \u0436\u0435 <code>toString()<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0443\u0437\u043b\u0430 <code>RuleName<\/code>, \u0433\u0434\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043c\u0430\u0441\u0441\u0438\u0432, \u0438 \u044d\u0442\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f.<\/p>\n<p>  <\/p>\n<p>\u0412\u0442\u043e\u0440\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u043e\u0431\u044b\u0447\u043d\u043e \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u0430\u043c \u0431\u043e\u043b\u044c\u0448\u0435 \u043c\u0435\u043b\u043a\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0438\u043f\u0430 \u043a\u0430\u0432\u044b\u0447\u0435\u043a \u0432\u043e\u043a\u0440\u0443\u0433 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0445 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0435\u0442 \u0432 <code>self.php<\/code>, \u043d\u043e \u0438\u043d\u043e\u0433\u0434\u0430 \u0431\u044b\u0432\u0430\u0435\u0442 \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. \u0422\u043e \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043f\u043e\u0433\u0440\u0435\u0448\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u0435\u0449\u0438. \u0421\u0434\u0435\u043b\u0430\u0435\u043c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0434\u043b\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 Nowdoc \u0432 PHP.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">public function testComplexString() {     $mainRuleName = 'Grammar';     $gdlParser = new GdlParser($this-&gt;getSelfGrammar());      $grammarSource = &lt;&lt;&lt;'SRC' Data:     ComplexString* ;  ComplexString:     '&lt;&lt;&lt;\\'' StringTag={str,setStringStart} '\\'' '\\n' Content={str} '\\n' StringTag={str,checkStringEnd} '\\n' ;  Content:     .*&gt;('\\n' StringTag={str,checkStringEnd}) ;  StringTag:     [a-zA-Z]+ ; SRC;     $languageGrammar = $gdlParser-&gt;parse($mainRuleName, new Stream($grammarSource));      $this-&gt;assertEmpty($gdlParser-&gt;getErrors());      $mainRuleName = $languageGrammar-&gt;get('Rule')-&gt;get('RuleName')-&gt;getValue();      $languageParser = new class($languageGrammar) extends GdlParser {         protected $complexStringTag;          public function setStringStart(GdlNode &amp;$parsedElement)         {             $this-&gt;complexStringTag = $parsedElement-&gt;getValue();         }          public function checkStringEnd(GdlNode &amp;$parsedElement)         {             if ($parsedElement-&gt;getValue() !== $this-&gt;complexStringTag) {                 $parsedElement = null;             }         }     };      $source = &lt;&lt;&lt;'SRC' &lt;&lt;&lt;'test' &lt;&lt;&lt;'abc' a b c abc test &lt;&lt;&lt;'tag' 1 2 3 4 tag  SRC;     $tree = $languageParser-&gt;parse($mainRuleName, new Stream($source));      $this-&gt;assertEmpty($languageParser-&gt;getErrors());     $this-&gt;assertTrue($tree-&gt;toArray() === ['Data', [         ['ComplexString', [             ['', '&lt;&lt;&lt;\\''],             ['StringTag', 'test'],             ['', '\\''],             ['', &quot;\\n&quot;],             ['Content', &quot;&lt;&lt;&lt;'abc'\\na b c\\nabc&quot;],             ['', &quot;\\n&quot;],             ['StringTag', 'test'],             ['', &quot;\\n&quot;],         ]],         ['ComplexString', [             ['', '&lt;&lt;&lt;\\''],             ['StringTag', 'tag'],             ['', '\\''],             ['', &quot;\\n&quot;],             ['Content', &quot;1 2 3 4&quot;],             ['', &quot;\\n&quot;],             ['StringTag', 'tag'],             ['', &quot;\\n&quot;],         ]],     ]]); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e <code>.*&gt;('\\n' StringTag={str,checkStringEnd})<\/code>. \u0412 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 LookAhead \u0441\u0434\u0435\u043b\u0430\u043d \u0434\u043b\u044f Element, \u0430 \u043d\u0435 \u0434\u043b\u044f Expression, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043c \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438\u043b\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c inline-\u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u043e, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043a\u0430\u043a \u044d\u0442\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043e <a href=\"https:\/\/github.com\/php\/php-src\/blob\/30c23887381a432cb501d63e25f79bce5e0e1570\/Zend\/zend_language_scanner.l#L2367\" rel=\"nofollow\">\u0432 \u0441\u0430\u043c\u043e\u043c PHP<\/a>.<\/p>\n<p>  <\/p>\n<h3 id=\"realnyy-primer\">\u0420\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/h3>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u0434\u043e \u0431\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u043c \u044f\u0437\u044b\u043a\u0435.<\/p>\n<p>  <\/p>\n<p>\u042f \u0441\u0434\u0435\u043b\u0430\u043b <a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\/blob\/master\/php.gdl\" rel=\"nofollow\">\u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443<\/a> \u0434\u043b\u044f PHP. \u041e\u043d\u0430 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0442\u043e\u0447\u043d\u0430\u044f, \u0442\u0430\u043c \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0444\u0430\u0439\u043b <code>GdlParser.php<\/code> \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u0442\u0443\u0442 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c. \u041f\u0430\u0440\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u043c, \u043a\u0430\u043a \u0432 <code>self.gdl<\/code>, \u044d\u0442\u043e \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443, \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>parseExpression()<\/code>, \u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0438\u0442\u0430\u0442\u044c <code>$this-&gt;stream<\/code> \u0438 \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043f\u0440\u043e\u0431\u0435\u043b\u044b. \u041d\u043e \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u0430\u0434\u0430\u044e\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441\u0442\u0440\u043e\u043a, \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043d\u0435\u043b\u044c\u0437\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0434\u043e \u043b\u0438\u0431\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043b\u0438\u0431\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0444\u043b\u0430\u0433, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u043a\u0430\u0432\u044b\u0447\u043a\u0438 \u0438 \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u043f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439. \u0422\u0430\u043a\u0436\u0435 \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u043b\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u043e\u0441\u043b\u0435 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u043a\u0430\u0432\u044b\u0447\u043a\u0438, \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a <code>count($this-&gt;ruleCallStack)<\/code>. \u041d\u0430\u0434\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u043f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c <code>parseStatement()<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f \u0438 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043c\u0435\u043d\u044c\u0448\u0435 \u0437\u0430\u043f\u043e\u043c\u043d\u0435\u043d\u043d\u043e\u0433\u043e (\u0442\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u0432\u044b\u0448\u043b\u0438 \u0438\u0437 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u043e\u043a\u0438 \u0438\u043b\u0438 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b), \u0441\u0442\u0438\u0440\u0430\u0442\u044c \u0444\u043b\u0430\u0433. \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440. \u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0435\u0439 \u044f\u0437\u044b\u043a\u0430 (<code>IfStatement | ReturnStatement | comment<\/code>), \u043b\u0438\u0431\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u043f\u0443\u0441\u043a\u0430 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0442\u0430\u043a \u043a\u0430\u043a \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430.<\/p>\n<p>  <\/p>\n<p>\u0412 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">SingleQuoteString:     '\\''={setKeepSpaces} Symbol*&gt;&gt; '\\''={clearKeepSpaces} ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u041a\u043e\u0434 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\/blob\/master\/GdlTextParser.php\" rel=\"nofollow\">GdlTextParser.php<\/a>.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">public function testPhp() {     $mainRuleName = 'Grammar';     $gdlParser = new GdlParser($this-&gt;getSelfGrammar());      $grammarSource = file_get_contents(__DIR__ . '\/php.gdl');     $stream = new Stream($grammarSource);      $t1 = microtime(1);     $languageGrammar = $gdlParser-&gt;parse($mainRuleName, $stream);     $t2 = microtime(1);     echo ($t2 - $t1) . &quot;\\n&quot;;      $this-&gt;assertEmpty($gdlParser-&gt;getErrors());      $mainRuleName = $languageGrammar-&gt;get('Rule')-&gt;get('RuleName')-&gt;getValue();      $languageParser = new class($languageGrammar) extends GdlTextParser {         protected $complexStringTag;          public function setStringStart(GdlNode &amp;$parsedElement)         {             $this-&gt;complexStringTag = $parsedElement-&gt;getValue();         }          public function checkStringEnd(GdlNode &amp;$parsedElement)         {             if ($parsedElement-&gt;getValue() !== $this-&gt;complexStringTag) {                 $parsedElement = null;             }         }          protected function handleError(GdlNode $expression)         {             parent::handleError($expression);              while (!$this-&gt;stream-&gt;eof()) {                 $symbol = $this-&gt;stream-&gt;readSymbol();                 if ($symbol === &quot;\\n&quot;) {                     break;                 }             }              $i = count($this-&gt;ruleCallStack) - 1;             while ($this-&gt;ruleCallStack[$i][0] == '()') { $i--; }             $ruleName = $this-&gt;ruleCallStack[$i][0];              if ($ruleName === 'FunctionDeclaration' || $ruleName === 'StatementBlock') {                 $level = 1;                 while (!$this-&gt;stream-&gt;eof()) {                     $symbol = $this-&gt;stream-&gt;readSymbol();                     if ($symbol === '{') {                         $level++;                     }                     else if ($symbol === '}') {                         $level--;                         if ($level == 0) {                             break;                         }                     }                 }             }         }     };      $source = file_get_contents(__DIR__ . '\/GdlParser.php');      $t1 = microtime(1);     $tree = $languageParser-&gt;parse($mainRuleName, new Stream($source));     $t2 = microtime(2);     echo ($t2 - $t1) . &quot;\\n&quot;;      $this-&gt;assertEmpty($languageParser-&gt;getErrors());     $this-&gt;assertTrue(!empty($tree)); }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>handleError()<\/code>. \u041f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435, \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430, \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c <code>handleError()<\/code> \u0438 \u043f\u0440\u043e\u043c\u0430\u0442\u044b\u0432\u0430\u0442\u044c <code>$this-&gt;stream<\/code> \u0434\u043e \u043d\u0443\u0436\u043d\u043e\u0439 \u043f\u043e\u0437\u0438\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 <code>';'<\/code> \u0438\u043b\u0438 &#8216;}&#8217; \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438.<br \/>  \u041d\u043e \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430\u0434\u043e \u0434\u043b\u044f \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0442\u0438\u043f\u0430 <code>'{'! Statement+ '}'<\/code> \u0438 \u043d\u0435\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u0433\u043e <code>Statement<\/code> \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435. \u041f\u0430\u0440\u0441\u0435\u0440 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0433\u043e <code>Statement<\/code>, \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c, \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c <code>'}'<\/code>, \u0438 \u0432\u044b\u0434\u0430\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 <code>Expected '}'<\/code>. \u0414\u043b\u044f \u044d\u0442\u043e \u043d\u0430\u0434\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a \u0432 <code>parseExpression()<\/code>, \u0447\u0442\u043e\u0431\u044b \u0435\u0441\u043b\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043d\u0435 \u0443\u0434\u0430\u043b\u0441\u044f, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0430\u044f \u0441 \u043d\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0430\u0441\u044c. \u0412 \u043d\u0435\u0439 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 null \u0438 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 GdlNode \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430\u043f\u043e\u0434\u043e\u0431\u0438\u0435 <code>IncompleteStatement<\/code>. \u041d\u043e \u044d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043d\u0430 null \u0432\u043e \u0432\u0441\u0435\u0445 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u0445, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043d\u0435 \u0441\u0442\u0430\u043b \u0442\u0430\u043a \u0434\u0435\u043b\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0434 \u0432 <code>GdlParser.php<\/code> \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 <code>handleError()<\/code> \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043e\u043d\u0430 \u0442\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u0434\u0435\u043c\u043e\u043d\u0441\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<p>  <\/p>\n<h3 id=\"proizvoditelnost\">\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c<\/h3>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e. \u041d\u043e \u043d\u0435 \u0442\u0430\u043a \u0447\u0442\u043e\u0431\u044b \u043e\u0447\u0435\u043d\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043a\u0430\u0436\u0434\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>parse*<\/code> \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0442\u044b\u0441\u044f\u0447 \u0440\u0430\u0437. \u0422\u0430\u043a \u043a\u0430\u043a \u044d\u0442\u043e \u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c, \u0442\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043d\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c <code>quantifierType<\/code>. \u0415\u0441\u0442\u044c \u0432\u0441\u0435\u0433\u043e 2 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043d\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c: \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0431\u0435\u0440\u0435\u0442\u0441\u044f \u0438\u0437 \u0432\u043d\u0435\u0448\u0435\u0433\u043e \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u2014 \u0444\u0430\u0439\u043b\u0430 \u0441 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439, \u0438 \u043d\u0430 \u0442\u0438\u043f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0430\u043c \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0443\u0436\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">php parser_test.php testPhp 0.44992613792419 1.7462248802185<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0434\u043b\u044f PHP, \u0432\u0442\u043e\u0440\u043e\u0435 \u044d\u0442\u043e \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 <code>GdlParser.php<\/code>.<br \/>  \u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442, \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u043f\u0430\u0440\u0441\u0438\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u0438 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043c\u043d\u043e\u0433\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0447\u0442\u0438 2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b \u044d\u0442\u043e \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e, \u043d\u043e \u044d\u0439, \u044d\u0442\u043e \u0436\u0435 PHP. \u0427\u0442\u043e \u0435\u0441\u043b\u0438 \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 C++?<\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\/tree\/master\/cpp\" rel=\"nofollow\">\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 C++<\/a><\/p>\n<p>  <\/p>\n<p>\u0412 C++ \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0435\u0442 \u0432\u0441\u0435\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u0442\u0430\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 PHP. \u0412\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>if<\/code> \u0441\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435\u043c \u0441\u0442\u0440\u043e\u043a. \u0414\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0435\u0441\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442 <code>make.sh<\/code>, \u0442\u0430\u043c \u043e\u0434\u043d\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u0441\u0431\u043e\u0440\u043a\u0430 \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 -O3.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0434 \u043d\u0435 \u043f\u0440\u0435\u0434\u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432 production! \u0412 \u043a\u043e\u0434\u0435 \u043c\u043d\u043e\u0433\u043e new \u0438 \u043d\u0438 \u043e\u0434\u043d\u043e\u0433\u043e delete. \u0412\u0435\u0440\u043d\u0435\u0435 \u043e\u0434\u0438\u043d \u0435\u0441\u0442\u044c, \u043d\u043e \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u0446\u0438\u0444\u0440\u044b, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 \u043e\u0434\u043d\u043e\u043c \u0438 \u0442\u043e\u043c \u0436\u0435 \u0436\u0435\u043b\u0435\u0437\u0435. \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u043b\u0441\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0444\u0430\u0439\u043b\u0430 <code>GdlParser.php<\/code> \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u043e\u0439 <code>php.gdl<\/code>.<\/p>\n<p>  <\/p>\n<p>GdlParser \u043d\u0430 PHP \u043f\u0430\u0440\u0441\u0438\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a \u0437\u0430 1.7 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<br \/>  GdlParser \u043d\u0430 C++ \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 -O3 \u0437\u0430 0.022 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<br \/>  PHP \u0447\u0435\u0440\u0435\u0437 eval \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430 0.001 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<br \/>  ANTLR \u043d\u0430 C++ \u0441 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0430\u0446\u0438\u0435\u0439 -O3 \u0437\u0430 0.2 \u0441\u0435\u043a\u0443\u043d\u0434\u044b.<\/p>\n<p>  <\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0434\u0430, GdlParser \u0432 10 \u0440\u0430\u0437 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 ANTLR.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">.\/parser  PHP grammar parsing OK PHP source parsing OK Duration: 0.022794<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f ANTLR \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 <a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\/blob\/master\/Php.g4\" rel=\"nofollow\">Php.g4<\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u0430 <code>php.gdl<\/code>.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u0430\u043a \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c ANTLR \u0434\u043b\u044f C++ \u043f\u043e\u0434 Linux<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c &quot;antlr-4.8-complete.jar&quot; <a href=\"https:\/\/www.antlr.org\/download.html\" rel=\"nofollow\">\u043e\u0442\u0441\u044e\u0434\u0430<\/a>, \u0440\u0430\u0437\u0434\u0435\u043b &quot;ANTLR tool and Java Target&quot;, \u0441\u0441\u044b\u043b\u043a\u0430 &quot;Complete ANTLR 4.8 Java binaries jar&quot;<\/p>\n<p>  <\/p>\n<p>\u0421\u043a\u0430\u0447\u0430\u0442\u044c runtime \u0438 demo \u043e\u0442\u0442\u0443\u0434\u0430 \u0436\u0435, \u0440\u0430\u0437\u0434\u0435\u043b &quot;C++ Target&quot;, \u0441\u0441\u044b\u043b\u043a\u0430 &quot;antlr4-cpp-runtime-4.8-source.zip (.h, .cpp)&quot;<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043c\u0435\u0441\u0442\u0438\u0442\u044c \u0432 \u043e\u0434\u043d\u0443 \u043f\u0430\u043f\u043a\u0443, \u0440\u0430\u0441\u043f\u0430\u043a\u043e\u0432\u0430\u0442\u044c \u0430\u0440\u0445\u0438\u0432 \u0441 runtime \u0438 demo \u0432 \u043f\u0430\u043f\u043a\u0443 &quot;antlr4-cpp-runtime-4.8-source&quot;, \u043e\u0442\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b \u0432 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435<\/p>\n<p>  <\/p>\n<p>\u0423\u0434\u0430\u043b\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b &quot;TLexer.g4&quot; \u0438 &quot;TParser.g4&quot;<br \/>  \u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c &quot;Php.g4&quot; \u0438 &quot;GdlParser.php&quot; \u0432 &quot;demo\/&quot;<br \/>  \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c &quot;TLexer&quot; \u0438 &quot;TParser&quot; \u043d\u0430 &quot;PhpLexer&quot; \u0438 &quot;PhpParser&quot; \u0432 &quot;demo\/Linux\/main.cpp, demo\/generate.sh, demo\/CMakeLists.txt&quot;, \u043d\u043e &quot;TParserBaseListener&quot; \u043d\u0430 &quot;PhpBaseListener&quot; \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 3 \u0444\u0430\u0439\u043b\u0430 \u0440\u044f\u0434\u043e\u043c \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0412 main.cpp \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#include &lt;chrono&gt;  #include &quot;PhpLexer.h&quot; #include &quot;PhpParser.h&quot;  std::ifstream stream; stream.open(&quot;..\/demo\/GdlParser.php&quot;); ANTLRInputStream input(stream);  PhpLexer lexer(&amp;input); CommonTokenStream tokens(&amp;lexer);  tokens.fill();  PhpParser parser(&amp;tokens); auto t1 = std::chrono::high_resolution_clock::now(); tree::ParseTree* tree = parser.program(); auto t2 = std::chrono::high_resolution_clock::now(); auto duration = std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(t2 - t1).count(); std::cout &lt;&lt; &quot;Duration: &quot; &lt;&lt; ((double)duration \/ 1000000) &lt;&lt; std::endl;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u0442\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u043c \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &quot;Compiling on Linux&quot; \u0432 \u0444\u0430\u0439\u043b\u0435 README.md<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">mkdir build &amp;&amp; mkdir run &amp;&amp; cd build cmake .. -DANTLR_JAR_LOCATION=..\/..\/antlr-4.8-complete.jar -DWITH_DEMO=True make demo\/antlr4-demo<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0427\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043b\u044f \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0432 \u043a\u043e\u0434\u0435 \u043d\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f enum \u0438\u043b\u0438 \u0438\u043d\u0434\u0435\u043a\u0441 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u043f\u0440\u0430\u0432\u0438\u043b. \u041f\u043e\u043b\u0435 <code>name<\/code> \u0432 GdlNode \u0442\u043e\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u044b\u043c.<\/li>\n<li>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0438\u0442\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u043c\u0435\u0441\u0442\u043e <code>getArray(name)<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>std::vector<\/code> \u0447\u0435\u0440\u0435\u0437 \u0441\u0442\u0435\u043a. \u042f \u0442\u0430\u043a \u043d\u0435 \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b, \u043d\u043e \u044f \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0432\u0435\u0437\u0434\u0435 \u0432\u043c\u0435\u0441\u0442\u043e \u0446\u0438\u043a\u043b\u0430 \u043f\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443 <code>getArray(name)<\/code> \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u043f\u043e <code>listValue<\/code> \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f, \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 20% \u0431\u044b\u0441\u0442\u0440\u0435\u0435.<\/li>\n<li>\u0421\u0434\u0435\u043b\u0430\u0442\u044c \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0430. \u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u0434\u043b\u044f \u043a\u0430\u0436\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 (\u0432\u043a\u043b\u044e\u0447\u0430\u044f inline) \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u043c \u043f\u043e \u0432\u0441\u0435\u043c \u0443\u0437\u043b\u0430\u043c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0434\u043e \u0441\u0442\u0440\u043e\u043a \u0438 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u043e\u0432, \u0431\u0435\u0440\u0435\u043c \u043d\u043e\u0434\u044b Symbol, \u0434\u043b\u044f \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u0432 \u0432 \u0440\u0435\u0433\u044d\u043a\u0441\u043f\u0430\u0445 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a, \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u043e\u0432. \u041f\u0440\u0438 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0435 \u0431\u0435\u0440\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438\u0437 \u043f\u043e\u0442\u043e\u043a\u0430, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c, \u043a\u0430\u043a\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0441 \u043d\u0435\u0433\u043e \u043c\u043e\u0433\u0443\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f, \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0445. \u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u0434\u043b\u044f \u0441\u0435\u0440\u0435\u0434\u0438\u043d\u044b \u0441\u0442\u0435\u0439\u0442\u043c\u0435\u043d\u0442\u0430, \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439 \u0432\u0438\u0434\u0430 <code>A* B? C<\/code>. \u042f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b \u0432 \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0430 PHP \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432, \u044d\u0442\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0440\u0430\u0437\u0430 \u0432 \u043f\u043e\u043b\u0442\u043e\u0440\u0430.<\/li>\n<li>\u0420\u0430\u0437\u0431\u0438\u0432\u0430\u0442\u044c \u043d\u0430 \u043b\u0435\u043a\u0441\u0435\u043c\u044b \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u0434\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u0444\u0430\u0439\u043b Stream \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432. \u0412 \u0441\u043e\u0447\u0435\u0442\u0430\u043d\u0438\u0438 \u0441 \u0437\u0430\u043c\u0435\u043d\u043e\u0439 \u043d\u0430 enum \u0438 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c GdlParser \u043a\u0430\u043a \u0435\u0441\u0442\u044c, \u0430 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043f\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e <code>parseRule(getRule('Program'))<\/code> \u0431\u0443\u0434\u0435\u0442 <code>parseProgram()<\/code>, \u0432\u043c\u0435\u0441\u0442\u043e <code>parseExpression()<\/code> \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043a\u0432\u0430\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u043e\u0434\u0438\u043d \u0432\u044b\u0437\u043e\u0432 <code>parseRule()<\/code> \u0438\u043b\u0438 \u0446\u0438\u043a\u043b <code>while<\/code>, \u0438 \u0442.\u0434.<\/p>\n<p>  <\/p>\n<h3 id=\"obschaya-informaciya\">\u041e\u0431\u0449\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f<\/h3>\n<p>  <\/p>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0439, \u0432 \u0442\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>class<\/code>. \u041d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044e <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%9A%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%BD%D0%BE-%D0%B7%D0%B0%D0%B2%D0%B8%D1%81%D0%B8%D0%BC%D0%B0%D1%8F_%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0\" rel=\"nofollow\">\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/a> \u044d\u0442\u043e \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442. \u0422\u0430\u043c \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 <code>a...b...c...<\/code>, \u0433\u0434\u0435 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 a, b, c \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c, \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044d\u0442\u043e\u0442 \u043f\u0430\u0440\u0441\u0435\u0440 \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0442\u0430\u043a\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u0421 \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c\u0438 \u044d\u0442\u043e \u0442\u0440\u0438\u0432\u0438\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430, \u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A1%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%B8_%D1%83%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D1%8F%D0%B5%D0%BC%D0%B0%D1%8F_%D1%82%D1%80%D0%B0%D0%BD%D1%81%D0%BB%D1%8F%D1%86%D0%B8%D1%8F\" rel=\"nofollow\">c\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u0430\u044f \u0442\u0440\u0430\u043d\u0441\u043b\u044f\u0446\u0438\u044f<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c\u0438 \u0441\u043b\u043e\u0432\u0430\u043c\u0438 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f.<br \/>  \u0412\u043e\u0437\u044c\u043c\u0435\u043c \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">return [2];<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 <code>return<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0438\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u043c 2 \u0438\u0437 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u0441 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>return<\/code>?<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">a[2]; return[2];<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 <code>ReturnStatement<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0448\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0434\u043b\u044f \u043e\u0434\u0438\u043d\u043e\u0447\u043d\u043e\u0439 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0435\u0433\u0434\u0430 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a <code>ReturnStatement<\/code>, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0442\u0430\u043a\u043c\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043b\u044c\u0437\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0435 \u0432\u0441\u0435 \u0440\u0430\u0432\u043d\u043e \u043d\u0430\u0434\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u043d\u0435 \u0431\u044b\u043b\u043e \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c.<\/p>\n<p>  <\/p>\n<p>\u041c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u044f\u0437\u044b\u043a\u0430 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430. \u041d\u0443 \u0430 \u0447\u0442\u043e, \u0432 PHP \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0442\u0441\u044f \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430, \u0430 \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. <code>@public @static @class Math<\/code>. \u0411\u0435\u0437 \u0437\u043d\u0430\u0447\u043a\u043e\u0432 \u043a\u0430\u043a-\u0442\u043e \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u0435\u0435 \u0432\u0441\u0435-\u0442\u0430\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u0445 \u044d\u0442\u043e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0438 \u043d\u0435\u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e\u0441\u0442\u044c. \u041f\u0435\u0440\u0432\u0443\u044e \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0438\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440. \u0412\u0442\u043e\u0440\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0442\u0441\u043b\u0435\u0434\u0438\u0442\u044c, \u043d\u043e \u043f\u0430\u0440\u0441\u0438\u0442\u044c\u0441\u044f \u0432\u0441\u0435\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0432 \u0441\u043f\u0438\u0441\u043a\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043f\u043e\u043c\u0435\u0449\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430, \u043d\u0430\u0447\u0438\u043d\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0441 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a, \u0440\u0430\u043d\u044c\u0448\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u0430\u0440\u0438\u0430\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 <code>'return'<\/code>, \u0432\u044b\u0448\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 <code>ID<\/code>.<\/p>\n<p>  <\/p>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u2014 \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0443\u0441\u0442\u044b\u0435, \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0438x \u043d\u0430 <code>+<\/code> \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0435 \u0438 <code>?<\/code> \u0432 \u043c\u0435\u0441\u0442\u0435 \u0432\u044b\u0437\u043e\u0432\u0430, \u0438 \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u043b\u0435\u0432\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e, \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u0435\u0435 \u043d\u0430 \u043f\u043e\u0441\u0442\u0435\u043f\u0435\u043d\u043d\u044b\u0439 \u0441\u043f\u0443\u0441\u043a \u043f\u043e \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c. \u041f\u0443\u0441\u0442\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0430\u0440\u0441\u044f\u0442\u0441\u044f \u0443\u0441\u043f\u0435\u0448\u043d\u043e, \u043d\u043e \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u043f\u043e\u0442\u043e\u043a\u0430 \u043d\u0435 \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f, \u0438 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0442\u0438 \u0437\u0430\u0446\u0438\u043a\u043b\u0438\u0432\u0430\u043d\u0438\u0435. \u041f\u043e\u0442\u0435\u043d\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043f\u0443\u0441\u0442\u044b\u043c \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u0435\u043d \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0434\u0430\u043d\u043d\u044b\u0445 \u0434\u043b\u0438\u043d\u043e\u0439 0 \u0431\u0430\u0439\u0442.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">\/\/ \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e C: D A; A: B*;  \/\/ \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e C: D A?; A: B+;  \/\/ \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e Expression: Expression ('+' | '-') Expression;  \/\/ \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e Expression: MulExpression ('+' | '-') MulExpression; MulExpression: ...<\/code><\/pre>\n<p>  <\/p>\n<h3 id=\"rezultat\">\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h3>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0438\u0439\u0441\u044f \u043a\u043b\u0430\u0441\u0441 GdlParser \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 367 \u0441\u0442\u0440\u043e\u043a, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e, \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0430\u0440\u0441\u0438\u0442\u044c \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0432\u0435\u0449\u0438.<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f <a href=\"https:\/\/github.com\/michael-vostrikov\/gdl\" rel=\"nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>  <\/p>\n<p>\u041a\u043e\u0434 \u043f\u043e\u0434 \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0435\u0439 MIT, \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u0438\u0435 \u044f\u0437\u044b\u043a\u0438, \u0434\u043e\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u043d\u0430 \u0441\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0440\u0438\u0441\u043a.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/506188\/\"> https:\/\/habr.com\/ru\/post\/506188\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\" data-io-article-url=\"https:\/\/habr.com\/ru\/post\/506188\/\">\n<p>\u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0444\u0430\u0439\u043b\u043e\u0432 \u043f\u043e \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <a href=\"https:\/\/www.antlr.org\/\" rel=\"nofollow\">ANTLR<\/a> \u0438\u043b\u0438 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Yacc\" rel=\"nofollow\">Yacc<\/a>. \u041e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u044b \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0441 \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u043c \u043a\u043e\u0434\u043e\u043c \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430. \u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043b\u0438 \u044d\u0442\u043e \u0442\u0430\u043a \u0441\u043b\u043e\u0436\u043d\u043e? \u041f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0441\u043f\u0443\u0441\u043a\u0430. \u0414\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u044f \u0431\u0443\u0434\u0443 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u043e\u0431 ANTLR, \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u044e\u0442\u0441\u044f. \u041f\u043e\u0434 \u043a\u0430\u0442\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u043e\u0434\u0430, \u0431\u0435\u0437 \u044d\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u043f\u043e\u0447\u0435\u043c\u0443 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a, \u0430 \u043d\u0435 \u0438\u043d\u0430\u0447\u0435.<\/p>\n<p>  <\/p>\n<p>\u0411\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0432 ANTLR-like \u0432\u0438\u0434\u0435. \u0412\u043e\u0442 \u0432 \u0442\u0430\u043a\u043e\u043c:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">C:     | A1? A2* A3     | B1? B2+ B3 ;<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u0435\u043b\u0430\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 PHP. \u0410 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u043f\u0435\u0440\u0435\u043f\u0438\u0448\u0435\u043c \u043d\u0430 C++.<\/p>\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-305167","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/305167","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=305167"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/305167\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=305167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=305167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=305167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}