{"id":378024,"date":"2024-06-04T15:01:46","date_gmt":"2024-06-04T15:01:46","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=378024"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=378024","title":{"rendered":"<span>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043d\u0430 Kotlin<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <strong>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430<\/strong>, \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 <strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b<\/strong>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c, \u043e\u043d \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u043b \u043d\u0430 \u043c\u0435\u043d\u044f \u0441\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0432 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435. <strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b<\/strong> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432<\/strong> \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Kotlin. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u0438\u0434\u0430 <code>printf(\"%s = %f\", \"2 + 2\", 5)<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442\u0430. \u041a\u043e\u0434, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435, \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/zewalldev\/habr_combinators.git\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<h4>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043d\u044f\u0442\u0438\u0439 \u0438\u0437 \u0442\u0435\u043e\u0440\u0438\u0438 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432<\/h4>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA\" rel=\"noopener noreferrer nofollow\"><strong>\u0424\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a<\/strong><\/a> &#8212; \u044d\u0442\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0432 \u043d\u0430\u0434 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 &#8212; \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u043e\u043c. \u0427\u0442\u043e\u0431\u044b \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0441\u043b\u043e\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0435\u0433\u043e \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%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=\"noopener noreferrer nofollow\"><strong>\u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/strong><\/a>. \u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b \u0432\u0438\u0434\u0430: <code>L -> R<\/code>, \u0433\u0434\u0435 <code>L<\/code> &#8212; \u043d\u0435\u043f\u0443\u0441\u0442\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u0430 <code>R<\/code> &#8212; \u043b\u044e\u0431\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432. \u0422\u0435\u0440\u043c\u0438\u043d\u0430\u043b &#8212; \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430, \u0430 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0430\u043a\u0443\u044e-\u043b\u0438\u0431\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>S -> (S)S S -> \u03b5 <\/code><\/pre>\n<p>\u0433\u0434\u0435 <code>(<\/code>, <code>)<\/code> &#8212; \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b, <code>S<\/code> &#8212; \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b, \u03b5 &#8212; \u043f\u0443\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430.<\/p>\n<p>\u0414\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%98%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%8F_%D0%A5%D0%BE%D0%BC%D1%81%D0%BA%D0%BE%D0%B3%D0%BE\" rel=\"noopener noreferrer nofollow\">\u041d\u043e\u0430\u043c\u043e\u043c \u0425\u043e\u043c\u0441\u043a\u0438\u043c<\/a>.<\/p>\n<p>\u041f\u043e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0425\u043e\u043c\u0441\u043a\u043e\u0433\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 4 \u0442\u0438\u043f\u0430, \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0438 \u043b\u0435\u0433\u0447\u0435 \u043f\u043e\u0434\u0434\u0430\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0443:<\/p>\n<ul>\n<li>\n<p>\u0442\u0438\u043f 0. \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043b\u044e\u0431\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f 1. \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 \u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u00ab\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c\u00bb &#8212; \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0432 \u0442\u043e\u043c \u0436\u0435 \u0432\u0438\u0434\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0432 \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f 2. \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 \u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f 3. \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c (\u041a\u0421) \u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c (\u041a\u0417) \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u043c. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u044f\u0437\u044b\u043a\u0438, \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0435 \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u043c\u0438 \u044d\u0442\u043e &#8212; \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (\u043f\u0440\u0438\u043c\u0435\u0440 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0431\u044b\u043b \u0432\u044b\u0448\u0435) \u0438\u043b\u0438 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432, \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0445 \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0430\u043c\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 IDE, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043c\u0435\u044e\u0442 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c:<\/p>\n<pre><code class=\"kotlin\">printf(\"%s = %f\", \"2 + 2\", 5) <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u0441 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u044c\u044e (\u041c\u041f-\u0430\u0432\u0442\u043e\u043c\u0430\u0442), \u0430 \u0432\u043e\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u043e-\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442, \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043c \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u041c\u041f-\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c.<\/p>\n<h4>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430<\/h4>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u043e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b, \u0442\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u044e\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 DSL \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432.<\/p>\n<p>\u042f \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0435\u0439 \u0432 <a href=\"https:\/\/ru.wikibooks.org\/wiki\/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%BF%D0%B0%D1%80%D1%81%D0%B5%D1%80%D1%8B\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435 \u0415\u0440\u0443\u043d\u0430 \u0424\u043e\u043a\u0435\u0440\u0430<\/a>. \u0412\u043f\u0435\u0440\u0432\u044b\u0435 \u043e \u043f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0430\u0445 \u043d\u0430\u0447\u0430\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0432 1980 \u0433\u043e\u0434\u0430\u0445, \u0430 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 &#8212; \u044d\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0434\u043d\u0438\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435, \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b <code>Alt(p1, p2)<\/code> \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442 \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0430\u0440\u0441\u0435\u0440 <code>p1<\/code> \u0438 \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442 <code>p2<\/code>. \u0418\u043b\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f <code>Seq(p1, p2)<\/code>, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e <code>p1<\/code> \u0438 <code>p2<\/code>, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<h3>T\u0438\u043f Parser \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b.<\/h3>\n<h4>Parser \u0438 ParseResult<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>Parser<\/code> \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 <code>ParseResult<\/code>.<\/p>\n<p>\u0417\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>ParseResult&lt;out A><\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0438\u043b\u0438 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0437\u0431\u043e\u0440\u0430.<\/p>\n<pre><code class=\"kotlin\">sealed interface ParseResult&lt;out A> {     data class Fail(val msg: String) : ParseResult&lt;Nothing>     data class Success&lt;A>(val tail: String, val result: A) : ParseResult&lt;A> } <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>Nothing<\/code> \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <code>Fail<\/code> &#8212; \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>Nothing<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 Kotlin.<\/p>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Fail<\/code> \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442 <code>msg<\/code> &#8212; \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435, \u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Success<\/code> \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b:<\/p>\n<ul>\n<li>\n<p><code>tail<\/code> &#8212; \u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0441\u0442\u0440\u043e\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p><code>result<\/code> &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043c\u0432\u043e\u043b \u0442\u0438\u043f\u0430 <code>Char<\/code> \u0438\u043b\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"kotlin\">interface Parser&lt;A> {     fun parse(str: String): ParseResult&lt;A> } <\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0442\u0430\u043a\u043e\u0435, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b <code>Fail<\/code>, \u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u0430 \u0435\u0441\u043b\u0438 <code>Success<\/code>, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0432\u0435\u0434\u0435\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>map<\/code>:<\/p>\n<pre><code class=\"kotlin\">fun &lt;T, R> ParseResult&lt;T>.map(block: (ParseResult.Success&lt;T>) -> ParseResult&lt;R>) = when (this) {     is ParseResult.Fail -> this     is ParseResult.Success -> block(this) } <\/code><\/pre>\n<h4>\u041f\u0430\u0440\u0441\u0435\u0440 TakeIf<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 <code>TakeIf<\/code>. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c &#8212; \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u0443.<\/p>\n<pre><code class=\"kotlin\">class TakeIf(private val description: String, private val predicate: (Char) -> Boolean) : Parser&lt;Char> {     override fun parse(str: String) = when {         str.isEmpty() -> ParseResult.Fail(\"Input string is empty\")         !predicate(str.first()) -> ParseResult.Fail(\"Symbol '${str.first()}' does not satisfy predicate: $description\")         else -> ParseResult.Success(str.drop(1), str.first())     } } <\/code><\/pre>\n<p>\u0414\u0443\u043c\u0430\u044e, \u043a\u043e\u0434 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0432\u0435\u0434\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043d\u0430\u0431\u043e\u0440\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c:<\/p>\n<pre><code class=\"kotlin\">fun symbol(c: Char, vararg cs: Char) =     TakeIf(\"in [${(cs + c).joinToString { it.toString() }}]\") { it in cs + c } <\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"kotlin\">println(symbol('a').parse(\"abc\")) \/\/ output: Success(tail=bc, pos=1, result=a) println(symbol('b').parse(\"abc\")) \/\/ output: Fail(msg=Symbol 'a' does not satisfy predicate: in [b]) <\/code><\/pre>\n<h4>\u041f\u0430\u0440\u0441\u0435\u0440 Return<\/h4>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 <code>Return<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0438 \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c:<\/p>\n<pre><code class=\"kotlin\">class Return&lt;A>(private val a: A) : Parser&lt;A> {     override fun parse(str: String) = ParseResult.Success(str, 0, a) } <\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0438 \u0434\u0430\u043b\u044c\u0448\u0435, \u0432\u0432\u043e\u0434\u044f, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>number(n)<\/code>, <code>string(str)<\/code> \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0418\u043c\u0435\u044f \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b, \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043d\u043e, \u043a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438, \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u0445 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044b, \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u0445 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b.<\/p>\n<h3>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b<\/h3>\n<h4>Alt \u0438 Seq<\/h4>\n<p>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>S -> (S)S S -> \u03b5 <\/code><\/pre>\n<p>\u0413\u043b\u044f\u0434\u044f \u043d\u0430 \u044d\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u044f\u0441\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f <code>Seq<\/code> \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b <code>Alt<\/code>. <code>Seq<\/code> \u044d\u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0442\u0438\u043f\u0430 <code>Parser&lt;Pair&lt;A, B>><\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0434\u0432\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 <code>pa: Parser&lt;A><\/code>, <code>pb: Parser&lt;B><\/code> \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u0438\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f <code>Pair&lt;A, B><\/code>:<\/p>\n<pre><code class=\"kotlin\">class Seq&lt;A, B>(private val pa: Parser&lt;A>, private val pb: Parser&lt;B>) : Parser&lt;Pair&lt;A, B>> {     override fun parse(str: String) = pa.parse(str).map { it1 ->         pb.parse(it1.tail).map { it2 ->             ParseResult.Success(it2.tail, it1.result to it2.result)         }     } } <\/code><\/pre>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>Alt<\/code> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 <code>p1, p2: Parser&lt;A><\/code> \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f <code>p1<\/code>, \u0430 \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u0435\u0440\u043d\u0435\u0442 <code>Fail<\/code>, \u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f <code>p2<\/code>:<\/p>\n<pre><code class=\"kotlin\">class Alt&lt;A>(private val p1: Parser&lt;A>, private val p2: Parser&lt;A>) : Parser&lt;A> {     override fun parse(str: String) = when (val r = p1.parse(str)) {         is ParseResult.Fail -> p2.parse(str)         is ParseResult.Success -> r     } } <\/code><\/pre>\n<h4>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 Mapper \u0438 &#171;\u043b\u0435\u043d\u0438\u0432\u043e\u0441\u0442\u044c&#187;<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0435\u0448\u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0431\u044b \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"kotlin\">val `(` = symbol('(') val `)` = symbol(')')  fun parens() : Parser&lt;\/* \u041a\u0430\u043a \u0442\u0438\u043f \u0443\u043a\u0430\u0437\u0430\u0442\u044c?*\/> = Alt(     Seq(`(`, Seq(parens(), Seq(`)`, parens()))),     Return(Unit) )  fun main() {     parens().parse(\"(()())\") } <\/code><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043a\u043e\u0434, \u0432 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041f\u0435\u0440\u0432\u0430\u044f &#8212; \u044d\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0442\u0438\u043f \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>parens()<\/code>, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f &#8212; \u044d\u0442\u043e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0441\u0430\u043c\u043e\u0439 \u0441\u0435\u0431\u044f. \u0421\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u043b\u0435\u0433\u043a\u043e \u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 &#171;\u043b\u0435\u043d\u0438\u0432\u043e\u0441\u0442\u0438&#187; \u043d\u0430\u0448\u0438\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c:<\/p>\n<pre><code class=\"kotlin\">fun &lt;A> ref(lazy: () -> Parser&lt;A>) = object : Parser&lt;A> {     override fun parse(str: String) = lazy().parse(str) } <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u043d\u0443\u0436\u043d\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0442\u0438\u043f\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437 <code>Parser&lt;A><\/code> \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>Parser&lt;B><\/code>:<\/p>\n<pre><code class=\"kotlin\">class Mapper&lt;A, B>(private val p: Parser&lt;A>, private val f: (A) -> B) : Parser&lt;B> {     override fun parse(str: String) = p.parse(str).map { ParseResult.Success(it.tail, f(it.result)) } } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430:<\/p>\n<pre><code class=\"kotlin\">val `(` = symbol('(') val `)` = symbol(')')  fun parens(): Parser&lt;Tree> = Alt(     Mapper(         Seq(             `(`,             Seq(                 ref { parens() },                 Seq(                     `)`,                     ref { parens() }                 )             )         )     ) { (_, a) -> Tree.Node(a.first, a.second.second) },     Return(Tree.Leaf) )  fun main() {     println(parens().parse(\"(()())\")) \/\/output: Success(tail=, pos=6, result=Node(left=Node(left=Leaf, right=Node(left=Leaf, right=Leaf)), right=Leaf)) } <\/code><\/pre>\n<p>\u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0438\u0442\u043e\u0433.<\/p>\n<p>\u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0430\u0440\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 <code>TakeIf<\/code> \u0438 <code>Return&lt;A><\/code>, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c <code>Mapper&lt;A, B><\/code> \u0438 \u043f\u0430\u0440\u0443 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 <code>Alt&lt;A><\/code>, <code>Seq&lt;A, B><\/code>. \u0421 \u0442\u0430\u043a\u0438\u043c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0434 \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0435 \u0443\u0434\u043e\u0431\u043d\u043e.<\/p>\n<p>\u0412\u0432\u0435\u0434\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<h4>\u0412\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 alt, seq, optional, manyOf \u0438 someOf<\/h4>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>alt(p: Parser&lt;A>, vararg ps: Parser&lt;A>)<\/code> \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0430\u0431\u043e\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u044d\u0442\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u043f\u043e\u043a\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 <code>Success<\/code>. \u0420\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0435\u0435 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u0435\u0440\u0442\u043a\u0438(<code>fold<\/code>)<\/p>\n<pre><code class=\"kotlin\">fun &lt;A> alt(p: Parser&lt;A>, vararg ps: Parser&lt;A>): Parser&lt;A> = ps.fold(p) { x, xs -> Alt(x, xs) } <\/code><\/pre>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>seq<\/code> \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a \u0436\u0435, \u043a\u0430\u043a \u0438 <code>alt<\/code>, \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043d\u0430 \u0432\u0445\u043e\u0434 \u043d\u0430\u0431\u043e\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f \u0442\u0440\u0435\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0435\u0435 \u0441\u0438\u0433\u043d\u0430\u0442\u0443\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u0438\u0434:<\/p>\n<pre><code class=\"kotlin\">fun &lt;X1, X2, X3, Y> seq(p1: Parser&lt;X1>, p2: Parser&lt;X2>, p3: Parser&lt;X3>, f: (X1, X2, X3) -> Y): Parser&lt;Y> <\/code><\/pre>\n<p>\u0414\u043b\u044f <code>seq<\/code> \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u044f, \u0442\u0430\u043a \u043a\u0430\u043a \u0442\u0438\u043f <code>f<\/code> \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0442\u0438\u043f\u043e\u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u041d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u044e\u0442 \u0442\u0438\u043f \u0432\u0438\u0434\u0430 <code>(X1, X2, X3, X4) -> Y<\/code> \u0432 \u0442\u0438\u043f <code>(Pair&lt;X1, Pair&lt;X2, Pair&lt;X3, X4>>>) -> Y<\/code>. \u041f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0442\u0440\u0435\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u0430 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0441 \u043a\u043e\u0434\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u0442\u044c\u0441\u044f \u0432 <a href=\"https:\/\/github.com\/zewalldev\/habr_combinators\/blob\/main\/src\/parsers\/helpers.kt\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>:<\/p>\n<pre><code class=\"kotlin\">fun &lt;X1, X2, X3, X4, Y> args2tuple(f: (X1, X2, X3, X4) -> Y): (Pair&lt;X1, Pair&lt;X2, Pair&lt;X3, X4>>>) -> Y =     args2tuple { x1, x2, (x3, x4) -> f(x1, x2, x3, x4) }  fun &lt;X1, X2, X3, Y> seq(p1: Parser&lt;X1>, p2: Parser&lt;X2>, p3: Parser&lt;X3>, f: (X1, X2, X3) -> Y) =     Mapper(Seq(p1, Seq(p2, p3)), args2tuple(f)) <\/code><\/pre>\n<p>\u041d\u0430\u043c \u0431\u0443\u0434\u0443\u0442 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u0435\u0437\u043d\u044b \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b:<\/p>\n<ul>\n<li>\n<p><code>optional(p: Parser&lt;A>, a: A): Parser&lt;A><\/code> &#8212; \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440 <code>p<\/code> \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0443\u0434\u0430\u0447\u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>a<\/code>;<\/p>\n<\/li>\n<li>\n<p><code>someOf(p: Parser&lt;A>): Parser&lt;List&lt;A>><\/code> &#8212; \u043e\u0436\u0438\u0434\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u0438 \u0440\u0430\u0437\u0431\u043e\u0440\u0435 \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438, <code>p<\/code> \u0432\u0435\u0440\u043d\u0435\u0442 <code>Success<\/code> \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u0440\u0430\u0437;<\/p>\n<\/li>\n<li>\n<p><code>manyOf(p: Parser&lt;A>): Parser&lt;List&lt;A>><\/code> &#8212; \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 <code>p<\/code> \u043a \u0432\u0445\u043e\u0434\u044f\u0449\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043d\u0438 \u0440\u0430\u0437\u0443, \u0442\u043e \u0432\u0435\u0440\u043d\u0435\u0442 \u043f\u0443\u0441\u0442\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f:<\/p>\n<pre><code class=\"kotlin\">fun &lt;A> optional(p: Parser&lt;A>, a: A) = alt(p, Return(a))  fun &lt;A> someOf(p: Parser&lt;A>): Parser&lt;List&lt;A>> = seq(p, ref { manyOf(p) }) { x, xs -> listOf(x) + xs }  fun &lt;A> manyOf(p: Parser&lt;A>): Parser&lt;List&lt;A>> = optional(someOf(p), emptyList()) <\/code><\/pre>\n<p>\u041d\u0443\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u0430\u044f \u0432\u044b\u0448\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0439 <code>someOf<\/code> \u0438 <code>manyOf<\/code> \u043d\u0435\u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0438\u0437-\u0437\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0445 \u0432\u044b\u0437\u043e\u0432\u043e\u0432, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u0432 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043d\u0443\u0436\u043d\u043e \u0441 \u043e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u0432\u044b\u0448\u0435, \u043f\u0430\u0440\u0441\u0435\u0440 <code>parens()<\/code> \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u043c \u0432\u0438\u0434\u0435:<\/p>\n<pre><code class=\"kotlin\">fun parens2(): Parser&lt;Tree> = optional(     seq(`(`, ref { parens2() }, `)`, ref { parens2() }) { _, left, _, right -> Tree.Node(left, right) },     Tree.Leaf )  fun main() {     println(parens2().parse(\"(()())\")) \/\/ output: Success(tail=, result=Node(left=Node(left=Leaf, right=Node(left=Leaf, right=Leaf)), right=Leaf)) } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439.<\/p>\n<h4>\u0420\u0430\u0437\u0431\u043e\u0440 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439<\/h4>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u043e\u043f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"kotlin\">fun exp(): Parser&lt;Double> = ...  println(exp().parse(\"3+4*(1\/(2*3*4)-1\/(4*5*6)+1\/(6*7*8)-1\/(8*9*10)+1\/(10*11*12))\")) \/\/ output: Success(tail=, result=3.1427128427128426) <\/code><\/pre>\n<p>\u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0437\u0430\u0434\u0430\u0435\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code>op1 -> '+' | '-' op2 -> '*' | '\/' exp -> exp op1 term | term term -> term op2 factor | factor factor -> number | '(' exp ')' | -factor <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u043d\u0443\u0436\u043d\u043e \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043f\u0430\u0440\u0441\u0435\u0440. \u0415\u0441\u043b\u0438 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u043f\u0440\u0430\u0432\u0438\u043b, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"kotlin\">fun exp() = seq(ref { exp() }, op1(), term()) {...} <\/code><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 <code>exp<\/code> \u043a \u0441\u0442\u0440\u043e\u043a\u0435, \u0442\u043e \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0430\u043c \u0441\u0435\u0431\u044f \u043f\u043e\u043a\u0430 \u043d\u0435 \u043a\u043e\u043d\u0447\u0438\u0442\u0441\u044f \u043f\u0430\u043c\u044f\u0442\u044c. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043b\u0435\u0432\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e. \u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043b\u0435\u0432\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e, \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0432\u0438\u0434\u0430 <code>A -> A a | b<\/code> \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c \u0432\u0438\u0434\u0430:<\/p>\n<pre><code>A -> b A' | b A' -> a A | a <\/code><\/pre>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0435 \u0443\u0441\u0442\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043b\u0435\u0432\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432 <a href=\"https:\/\/neerc.ifmo.ru\/wiki\/index.php?title=%D0%A3%D1%81%D1%82%D1%80%D0%B0%D0%BD%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BB%D0%B5%D0%B2%D0%BE%D0%B9_%D1%80%D0%B5%D0%BA%D1%83%D1%80%D1%81%D0%B8%D0%B8\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u044d\u0442\u0438\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u043e\u043c:<\/p>\n<pre><code>op1 -> '+' | '-' op2 -> '*' | '\/' exp -> term exp1 | term exp1 -> op1 term exp1 | op1 term term -> factor term1 | factor term1 -> op2 factor term1 | op2 factor factor -> number | '(' exp ')' | -factor <\/code><\/pre>\n<p>\u041d\u0435 \u0431\u0443\u0434\u0443 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439, \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/zewalldev\/habr_combinators\/blob\/main\/src\/examples\/3_expression.kt\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>, \u043d\u043e \u0445\u043e\u0447\u0443 \u043e\u0431\u0441\u0443\u0434\u0438\u0442\u044c \u0442\u0438\u043f\u044b \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 <code>exp1(), term1()<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u043c\u0438. \u042f\u0441\u043d\u043e, \u0447\u0442\u043e \u0442\u0438\u043f <code>fun factor(): Parser&lt;Double><\/code>, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e <code>op2<\/code> &#8212; \u044d\u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u0431\u0438\u043d\u0430\u0440\u043d\u043e\u0433\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430, \u0438\u043c\u0435\u044e\u0449\u0438\u0439 \u0442\u0438\u043f <code>fun op2(): Parser&lt;(Double, Double) -> Double> <\/code>, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c, \u0447\u0442\u043e \u0442\u0438\u043f <code>fun term1(): Parser&lt;(Double) -> Double><\/code>. \u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"kotlin\">\/\/ term1 -> op2 factor term1 | op2 factor fun term1(): Parser&lt;(Double) -> Double> = alt(     seq(op2(), factor(), ref { term1() }) { op, b, t -> { a -> t(op(a, b)) } },     seq(op2(), factor()) { op, b -> { a -> op(a, b) } } ) <\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u0435 \u0436\u0435 \u0440\u0430\u0441\u0441\u0443\u0436\u0434\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0441\u0442\u0438 \u0438 \u0434\u043b\u044f <code>exp1()<\/code>.<\/p>\n<h4>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 Seq \u0438 Alt<\/h4>\n<p>\u0412\u0441\u043f\u043e\u043c\u0438\u043d\u0430\u044f, \u0447\u0442\u043e \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438, \u043b\u0435\u0432\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430, \u0442\u043e \u0438\u043d\u0442\u0443\u0438\u0442\u0438\u0432\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u0447\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 <code>seq<\/code> \u0438 <code>alt<\/code> \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u043b\u044e\u0431\u043e\u0439 \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438. \u0414\u043b\u044f \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u0438\u0434 <code>a A b -> a w b<\/code>, \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u041a\u0417-\u044f\u0437\u044b\u043a:<\/p>\n<pre><code>{anbncn: n \u2265 0} <\/code><\/pre>\n<p>\u0421\u043b\u043e\u0432\u0430 \u044d\u0442\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430 \u0441\u043e\u0441\u0442\u043e\u044f\u0442 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0433\u0440\u0443\u043f\u043f \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0439 \u0434\u043b\u0438\u043d\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>aabbcc<\/code>. \u0414\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u0441\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0441 \u043e\u0434\u043d\u0438\u043c \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u043c \u0441\u043b\u0435\u0432\u0430, \u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0431\u044b \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u043f\u0440\u0430\u0432\u0438\u043b. \u0415\u0441\u043b\u0438 \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u0443\u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430 \u044d\u0442\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 <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=\"noopener noreferrer nofollow\">\u0432\u0438\u043a\u0438\u043f\u0435\u0434\u0438\u0438<\/a>.<\/p>\n<p>\u041d\u043e \u0432\u043e\u0442 \u0435\u0441\u043b\u0438 \u0431\u044b \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b \u0441\u043f\u043e\u0441\u043e\u0431 \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430, \u0442\u043e \u043c\u044b \u0441\u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440 \u044d\u0442\u043e\u0433\u043e \u044f\u0437\u044b\u043a\u0430.<\/p>\n<h3>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f \u0438 \u0430\u043d\u0430\u043b\u0438\u0437 \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/h3>\n<p>\u041c\u043d\u043e\u0433\u0438\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0438 IDE \u0443\u043c\u0435\u044e\u0442 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u0435\u0434\u0443\u043f\u0440\u0435\u0436\u0434\u0435\u043d\u0438\u044f, \u0435\u0441\u043b\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0444\u043e\u0440\u043c\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0432\u043e\u0434\u0430, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>printf(\"%s = %f\", \"2 + 2\", 5)<\/code>, \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u0442\u0438\u043f\u043e\u0432 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u043e\u0440\u044f\u0434\u043a\u0443 \u0442\u0438\u043f\u043e\u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432. \u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0449\u0430\u044f \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430, \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u043f\u0430\u0440\u0441\u0435\u0440\u044b, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0449\u0438\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u0437\u0430\u0432\u0438\u0441\u044f\u0442 \u043e\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0441\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0435\u0439 \u0444\u043e\u0440\u043c\u0430\u0442\u0430 \u0432\u044b\u0432\u043e\u0434\u0430. \u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0443\u0447\u0438\u0442\u044c \u043d\u0430\u0448\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u0430.<\/p>\n<h4>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f \u0438 \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/h4>\n<p>\u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>Binder<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0430\u0440\u0441\u0435\u0440 <code>p: Parser&lt;A><\/code> \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>bind: (A) -> Parser&lt;B><\/code>, \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c \u0432\u044b\u0431\u043e\u0440 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a\u043e\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043b\u0435\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430 <code>p<\/code>:<\/p>\n<pre><code class=\"kotlin\">class Binder&lt;A, B>(private val pa: Parser&lt;A>, private val bind: (A) -> Parser&lt;B>) : Parser&lt;B> {     override fun parse(str: String) = pa.parse(str).map {         bind(it.result).parse(it.tail)     } }  fun &lt;A, B> Parser&lt;A>.then(bind: (A) -> Parser&lt;B>): Parser&lt;B> = Binder(this, bind) <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c <code>Binder<\/code> \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f <code>printf(\"%s = %f\", \"2 + 2\", 5)<\/code>. \u042f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>Success&lt;Unit><\/code> \u0435\u0441\u043b\u0438 \u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c \u0444\u043e\u0440\u043c\u0430\u0442\u0430, \u0432 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, <code>Fail<\/code> \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438, \u043e \u0442\u043e\u043c, \u0433\u0434\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u0448\u0438\u0431\u043a\u0430.<br \/> \u041c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0434\u0432\u0430 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430:<\/p>\n<ul>\n<li>\n<p><code>%f<\/code> &#8212; \u0447\u0438\u0441\u043b\u043e<\/p>\n<\/li>\n<li>\n<p><code>%s<\/code> &#8212; \u0441\u0442\u0440\u043e\u043a\u0430<\/p>\n<\/li>\n<\/ul>\n<p>\u041a\u043e\u0434 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"kotlin\">fun printf(): Parser&lt;Unit> = seq(     string(\"printf\"),     `(`,     quotedFrmStr().then {         it.map { spec ->             when (spec) {                 Spec.STR -> seq(comma(), strType()) { _, _ -> }                 Spec.INT -> seq(comma(), numType()) { _, _ -> }             }         }.fold(Return(Unit) as Parser&lt;Unit>) { types, type ->             seq(types, type) { _, _ -> }         }     },     `)` ) { _, _, _, _ -> } <\/code><\/pre>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 <code>quotedFrmStr(): Parser&lt;List&lt;Spec>><\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f, \u0437\u0430\u0442\u0435\u043c \u044d\u0442\u043e\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b, \u0434\u0430\u043b\u0435\u0435 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0432\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0430 <code>seq<\/code>.<\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b:<\/p>\n<pre><code class=\"kotlin\">println(printf().parse(\"printf(\\\"%s = %f\\\",\\\"2 + 2\\\",2+2)\")) \/\/ output: Success(tail=, result=kotlin.Unit) println(printf().parse(\"printf(\\\"%f = %s\\\",\\\"2 + 2\\\",5)\")) \/\/ output:  Fail(...) <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u043f\u0435\u0440\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0435\u0449\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c. \u041d\u043e \u0438\u0437-\u0437\u0430 \u043e\u0434\u043d\u043e\u043e\u0431\u0440\u0430\u0437\u0438\u044f \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u0432 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430\u0448\u0438\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u043c\u044b \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0438\u0437 \u0440\u0430\u0437\u0434\u0435\u043b\u0430 &#171;\u0410\u043d\u0430\u043b\u0438\u0437 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439&#187;:<\/p>\n<pre><code class=\"kotlin\">fun numType() = seq(exp()) { _ -> } <\/code><\/pre>\n<p>\u041c\u044b \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0438 \u0441 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0430\u043c\u0438 \u0438 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u0438\u0442\u043e\u0433.<\/p>\n<h3>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0443\u0432\u0438\u0434\u0435\u043b\u0438, \u043a\u0430\u043a \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b. \u0421 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 <code>seq<\/code> \u0438 <code>alt<\/code> \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0449\u0438\u0435 \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438. \u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435 \u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u044d\u0442\u0438\u0445 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u0439 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u0430\u0432\u0438\u043b \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438. \u0415\u0441\u043b\u0438 \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0441\u0432\u044f\u0437\u044b\u0432\u0430\u043d\u0438\u044f <code>Binder<\/code> \u0438\u043b\u0438 <code>then<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043a\u043b\u0430\u0441\u0441 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u043c\u044b\u0445 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442\u0441\u044f, \u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u043e\u0432\u043a\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0432\u0430\u043b\u0438\u0434\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<pre><code class=\"kotlin\"> val item: Map&lt;String, Any>  sealed interface PromoAction {     data class PromoCode(...): PromoAction     data class Sale(...): PromoAction }   fun extractPromo() = alt(     seq(extractId(), extractPromoCode()) {id, code -> PromoCode(id, code)},      seq(extractId(), extractSale()) {id, saleValue -> Sale(id, saleValue)} )  extractPromo().run(item) \/\/ output: Success(PromoCode) or Success(Sale) <\/code><\/pre>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u0434\u0430 \u0432\u044b\u0448\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445 \u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 data-\u043a\u043b\u0430\u0441\u0441\u044b. \u041f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0432 \u0435\u0433\u043e \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043f\u043e <code>extractPromo()<\/code> \u043c\u043e\u0436\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u044f \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u0438 \u0436\u0435\u043b\u0430\u044e \u0432\u0441\u0435\u043c \u043a\u043e\u0434\u0430 \u0431\u0435\u0437 \u043e\u0448\u0438\u0431\u043e\u043a! \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/819459\/\"> https:\/\/habr.com\/ru\/articles\/819459\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h3>\n<p>\u0421\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0440\u0430\u0437\u043d\u044b\u0435 \u0441\u043f\u043e\u0441\u043e\u0431\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u0434\u043b\u044f \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0439 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0439 <strong>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430<\/strong>, \u0442\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 <strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b<\/strong>.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u0432\u043f\u0435\u0440\u0432\u044b\u0435 \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u043c, \u043e\u043d \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u043b \u043d\u0430 \u043c\u0435\u043d\u044f \u0441\u0438\u043b\u044c\u043d\u043e\u0435 \u0432\u043f\u0435\u0447\u0430\u0442\u043b\u0435\u043d\u0438\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0431\u0435\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0438 \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u044b \u0432 \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u0442\u0438\u043b\u0435. <strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b<\/strong> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0442\u043e\u0442\u0438\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043b\u0435\u0433\u043a\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u043e\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u0430. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u043c\u044b \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 <strong>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432<\/strong> \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Kotlin. \u041d\u0430\u043f\u0438\u0448\u0435\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0434\u043b\u044f \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0432\u0438\u0434\u0430 <code>printf(\"%s = %f\", \"2 + 2\", 5)<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0444\u043e\u0440\u043c\u0430\u0442\u0430. \u041a\u043e\u0434, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435, \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432 <a href=\"https:\/\/github.com\/zewalldev\/habr_combinators.git\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<h4>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043d\u044f\u0442\u0438\u0439 \u0438\u0437 \u0442\u0435\u043e\u0440\u0438\u0438 \u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432<\/h4>\n<p><a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA\" rel=\"noopener noreferrer nofollow\"><strong>\u0424\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a<\/strong><\/a> &#8212; \u044d\u0442\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e \u0441\u043b\u043e\u0432 \u043d\u0430\u0434 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u043c \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 &#8212; \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u043e\u043c. \u0427\u0442\u043e\u0431\u044b \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0438\u0437 \u0432\u0441\u0435\u0433\u043e \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u0430 \u0441\u043b\u043e\u0432 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0435\u0433\u043e \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A4%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%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=\"noopener noreferrer nofollow\"><strong>\u0444\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438<\/strong><\/a>. \u0413\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043d\u0430\u0431\u043e\u0440\u043e\u043c \u043f\u0440\u0430\u0432\u0438\u043b \u0432\u0438\u0434\u0430: <code>L -> R<\/code>, \u0433\u0434\u0435 <code>L<\/code> &#8212; \u043d\u0435\u043f\u0443\u0441\u0442\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0430\u044f \u0445\u043e\u0442\u044f \u0431\u044b \u043e\u0434\u0438\u043d \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u0430 <code>R<\/code> &#8212; \u043b\u044e\u0431\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432. \u0422\u0435\u0440\u043c\u0438\u043d\u0430\u043b &#8212; \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u0441\u043e\u0441\u0442\u043e\u044f\u0449\u0438\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0430\u043b\u0444\u0430\u0432\u0438\u0442\u0430, \u0430 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b &#8212; \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u0430\u043a\u0443\u044e-\u043b\u0438\u0431\u043e \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c \u044f\u0437\u044b\u043a\u0430.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u0440 \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>S -> (S)S S -> \u03b5 <\/code><\/pre>\n<p>\u0433\u0434\u0435 <code>(<\/code>, <code>)<\/code> &#8212; \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0438\u043c\u0432\u043e\u043b\u044b, <code>S<\/code> &#8212; \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b, \u03b5 &#8212; \u043f\u0443\u0441\u0442\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430.<\/p>\n<p>\u0414\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u044e, \u043f\u0440\u0435\u0434\u043b\u043e\u0436\u0435\u043d\u043d\u0443\u044e <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%98%D0%B5%D1%80%D0%B0%D1%80%D1%85%D0%B8%D1%8F_%D0%A5%D0%BE%D0%BC%D1%81%D0%BA%D0%BE%D0%B3%D0%BE\" rel=\"noopener noreferrer nofollow\">\u041d\u043e\u0430\u043c\u043e\u043c \u0425\u043e\u043c\u0441\u043a\u0438\u043c<\/a>.<\/p>\n<p>\u041f\u043e \u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0425\u043e\u043c\u0441\u043a\u043e\u0433\u043e \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 4 \u0442\u0438\u043f\u0430, \u043a\u0430\u0436\u0434\u044b\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u0435\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u043c \u043f\u043e\u0434\u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0438 \u043b\u0435\u0433\u0447\u0435 \u043f\u043e\u0434\u0434\u0430\u0435\u0442\u0441\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0443:<\/p>\n<ul>\n<li>\n<p>\u0442\u0438\u043f 0. \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043b\u044e\u0431\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f 1. \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 \u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b, \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0439 \u00ab\u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043e\u043c\u00bb &#8212; \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u0432 \u0442\u043e\u043c \u0436\u0435 \u0432\u0438\u0434\u0435 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0430\u044f \u0432 \u043f\u0440\u0430\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f 2. \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u2014 \u043b\u0435\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430;<\/p>\n<\/li>\n<li>\n<p>\u0442\u0438\u043f 3. \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043d\u044b\u0435 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b, \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c (\u041a\u0421) \u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u043d\u043e-\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c (\u041a\u0417) \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u043c. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u044f\u0437\u044b\u043a\u0438, \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0435 \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u043c\u0438 \u044d\u0442\u043e &#8212; \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u044b\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 (\u043f\u0440\u0438\u043c\u0435\u0440 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u0431\u044b\u043b \u0432\u044b\u0448\u0435) \u0438\u043b\u0438 \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432, \u043f\u043e\u0440\u043e\u0436\u0434\u0430\u0435\u043c\u044b\u0445 \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0430\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0433\u043e \u0434\u043b\u0438\u043d\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0430\u043c\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0432 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 IDE, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u043c\u0435\u044e\u0442 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u043a\u043e\u0433\u0434\u0430 \u0442\u0438\u043f\u044b \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430\u043c:<\/p>\n<pre><code class=\"kotlin\">printf(\"%s = %f\", \"2 + 2\", 5) <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u041a\u0421-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0443, \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u0441 \u043c\u0430\u0433\u0430\u0437\u0438\u043d\u043d\u043e\u0439 \u043f\u0430\u043c\u044f\u0442\u044c\u044e (\u041c\u041f-\u0430\u0432\u0442\u043e\u043c\u0430\u0442), \u0430 \u0432\u043e\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u041a\u0417-\u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u043b\u0438\u043d\u0435\u0439\u043d\u043e-\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442, \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043c \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u043c\u043e\u0441\u0442\u0438 \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u041c\u041f-\u0430\u0432\u0442\u043e\u043c\u0430\u0442\u043e\u043c.<\/p>\n<h4>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430<\/h4>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u043e\u043d\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b, \u0442\u043e \u0435\u0441\u0442\u044c \u0437\u0430\u0434\u0430\u044e\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 DSL \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432.<\/p>\n<p>\u042f \u043f\u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0441\u044f \u0441 \u044d\u0442\u043e\u0439 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u0435\u0439 \u0432 <a href=\"https:\/\/ru.wikibooks.org\/wiki\/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D1%8B%D0%B5_%D0%BF%D0%B0%D1%80%D1%81%D0%B5%D1%80%D1%8B\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0430\u0442\u044c\u0435 \u0415\u0440\u0443\u043d\u0430 \u0424\u043e\u043a\u0435\u0440\u0430<\/a>. \u0412\u043f\u0435\u0440\u0432\u044b\u0435 \u043e \u043f\u0430\u0440\u0441\u0435\u0440 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0430\u0445 \u043d\u0430\u0447\u0430\u043b\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u0442\u044c \u0432 1980 \u0433\u043e\u0434\u0430\u0445, \u0430 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c\u0438.<\/p>\n<p>\u0418\u0442\u0430\u043a, \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 &#8212; \u044d\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043e\u0434\u043d\u0438\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u044e\u0442 \u0434\u0440\u0443\u0433\u0438\u0435, \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b <code>Alt(p1, p2)<\/code> \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442 \u043a \u0441\u0442\u0440\u043e\u043a\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0430\u0440\u0441\u0435\u0440 <code>p1<\/code> \u0438 \u0435\u0441\u043b\u0438 \u0440\u0430\u0437\u0431\u043e\u0440 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u0441\u044f \u0441 \u043e\u0448\u0438\u0431\u043a\u043e\u0439, \u0442\u043e \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442 <code>p2<\/code>. \u0418\u043b\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f <code>Seq(p1, p2)<\/code>, \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e <code>p1<\/code> \u0438 <code>p2<\/code>, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0441\u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<h3>T\u0438\u043f Parser \u0438 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b.<\/h3>\n<h4>Parser \u0438 ParseResult<\/h4>\n<p>\u041d\u0430\u0447\u043d\u0435\u043c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 <code>Parser<\/code> \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 <code>ParseResult<\/code>.<\/p>\n<p>\u0417\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 <code>ParseResult&lt;out A><\/code> \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0438\u043b\u0438 \u043d\u0435\u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0437\u0431\u043e\u0440\u0430.<\/p>\n<pre><code class=\"kotlin\">sealed interface ParseResult&lt;out A> {     data class Fail(val msg: String) : ParseResult&lt;Nothing>     data class Success&lt;A>(val tail: String, val result: A) : ParseResult&lt;A> } <\/code><\/pre>\n<p>\u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043a\u0430\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>Nothing<\/code> \u0434\u043b\u044f \u043a\u043b\u0430\u0441\u0441\u0430 <code>Fail<\/code> &#8212; \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>Nothing<\/code> \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a\u043e\u043c \u043b\u044e\u0431\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 Kotlin.<\/p>\n<p>\u0412 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Fail<\/code> \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442 <code>msg<\/code> &#8212; \u044d\u0442\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0431 \u043e\u0448\u0438\u0431\u043a\u0435, \u0430 \u0432 \u043a\u043b\u0430\u0441\u0441\u0435 <code>Success<\/code> \u0430\u0442\u0442\u0440\u0438\u0431\u0443\u0442\u044b:<\/p>\n<ul>\n<li>\n<p><code>tail<\/code> &#8212; \u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0441\u0442\u0440\u043e\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0435\u0449\u0435 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c;<\/p>\n<\/li>\n<li>\n<p><code>result<\/code> &#8212; \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u044d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0438\u043c\u0432\u043e\u043b \u0442\u0438\u043f\u0430 <code>Char<\/code> \u0438\u043b\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430.<\/p>\n<\/li>\n<\/ul>\n<p>\u0418\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"kotlin\">interface Parser&lt;A> {     fun parse(str: String): ParseResult&lt;A> } <\/code><\/pre>\n<p>\u041f\u0440\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 \u0447\u0430\u0441\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u043e\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u0442\u0430\u043a\u043e\u0435, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b <code>Fail<\/code>, \u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0434\u0435\u043b\u0430\u0442\u044c, \u0430 \u0435\u0441\u043b\u0438 <code>Success<\/code>, \u0442\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0432\u0435\u0434\u0435\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>map<\/code>:<\/p>\n<pre><code class=\"kotlin\">fun &lt;T, R> ParseResult&lt;T>.map(block: (ParseResult.Success&lt;T>) -> ParseResult&lt;R>) = when (this) {     is ParseResult.Fail -> this     is ParseResult.Success -> block(this) } <\/code><\/pre>\n<h4>\u041f\u0430\u0440\u0441\u0435\u0440 TakeIf<\/h4>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u0433\u043e\u0442\u043e\u0432\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430\u0448 \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u0430\u0440\u0441\u0435\u0440 <code>TakeIf<\/code>. \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c &#8212; \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0441\u0442\u0440\u043e\u043a\u0438 \u043f\u0440\u0435\u0434\u0438\u043a\u0430\u0442\u0443.<\/p>\n<pre><code class=\"kotlin\">class TakeIf(private val description: String, private val predicate: (Char) -> Boolean) : Parser&lt;Char> {     override fun parse(str: String) = when {         str.isEmpty() -> ParseResult.Fail(\"Input string is empty\")         !predicate(str.first()) -> ParseResult.Fail(\"Symbol '${str.first()}' does not satisfy predicate: $description\")         else -> ParseResult.Success(str.drop(1), str.first())     } } <\/code><\/pre>\n<p>\u0414\u0443\u043c\u0430\u044e, \u043a\u043e\u0434 \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0439.<\/p>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u0432\u0435\u0434\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0449\u0438\u0439 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0438 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043d\u0430\u0431\u043e\u0440\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043e\u043d\u0430 \u043d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c:<\/p>\n<pre><code class=\"kotlin\">fun symbol(c: Char, vararg cs: Char) =     TakeIf(\"in [${(cs + c).joinToString { it.toString() }}]\") { it in cs + c } <\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430:<\/p>\n<pre><code class=\"kotlin\">println(symbol('a').parse(\"abc\")) \/\/ output: Success(tail=bc, pos=1, result=a) println(symbol('b').parse(\"abc\")) \/\/ output: Fail(msg=Symbol 'a' does not satisfy predicate: in [b]) <\/code><\/pre>\n<h4>\u041f\u0430\u0440\u0441\u0435\u0440 Return<\/h4>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 <code>Return<\/code> \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0438 \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430\u043c \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c:<\/p>\n<pre><code class=\"kotlin\">class Return&lt;A>(private val a: A) : Parser&lt;A> {     override fun parse(str: String) = ParseResult.Success(str, 0, a) } <\/code><\/pre>\n<p>\u041c\u043e\u0436\u043d\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043d\u0430\u0431\u043e\u0440 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 \u0438 \u0434\u0430\u043b\u044c\u0448\u0435, \u0432\u0432\u043e\u0434\u044f, \u043a \u043f\u0440\u0438\u043c\u0435\u0440\u0443, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a <code>number(n)<\/code>, <code>string(str)<\/code> \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0418\u043c\u0435\u044f \u0442\u0430\u043a\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u044b, \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u044b \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432, \u043d\u043e, \u043a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0435\u043b\u0438, \u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u0445 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438 \u043f\u0440\u0438\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044b, \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u0438 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432 \u0438 \u043d\u0435\u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u043e\u0432. \u0414\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u0435\u0435 \u043c\u043e\u0449\u043d\u044b\u0445 \u0430\u043d\u0430\u043b\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u0432 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b.<\/p>\n<h3>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b<\/h3>\n<h4>Alt \u0438 Seq<\/h4>\n<p>\u0412\u0441\u043f\u043e\u043c\u043d\u0438\u043c, \u043a\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0433\u0440\u0430\u043c\u043c\u0430\u0442\u0438\u043a\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>S -> (S)S S -> \u03b5 <\/code><\/pre>\n<p>\u0413\u043b\u044f\u0434\u044f \u043d\u0430 \u044d\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u044f\u0441\u043d\u043e, \u0447\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f <code>Seq<\/code> \u0438 \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u044b <code>Alt<\/code>. <code>Seq<\/code> \u044d\u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 \u0442\u0438\u043f\u0430 <code>Parser&lt;Pair&lt;A, B>><\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0434\u0432\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 <code>pa: Parser&lt;A><\/code>, <code>pb: Parser&lt;B><\/code> \u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442 \u0438\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f <code>Pair&lt;A, B><\/code>:<\/p>\n<pre><code class=\"kotlin\">class Seq&lt;A, B>(private val pa: Parser&lt;A>, private val pb: Parser&lt;B>) : Parser&lt;Pair&lt;A, B>> {     override fun parse(str: String) = pa.parse(str).map { it1 ->         pb.parse(it1.tail).map { it2 ->             ParseResult.Success(it2.tail, it1.result to it2.result)         }     } } <\/code><\/pre>\n<p>\u041a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440 <code>Alt<\/code> \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 <code>p1, p2: Parser&lt;A><\/code> \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u0438\u0440\u0443\u0435\u0442 \u043f\u0430\u0440\u0441\u0435\u0440, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f <code>p1<\/code>, \u0430 \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u0435\u0440\u043d\u0435\u0442 <code>Fail<\/code>, \u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f <code>p2<\/code>:<\/p>\n<pre><code class=\"kotlin\">class Alt&lt;A>(private val p1: Parser&lt;A>, private val p2: Parser&lt;A>) : Parser&lt;A> {     override fun parse(str: String) = when (val r = p1.parse(str)) {         is ParseResult.Fail -> p2.parse(str)         is ParseResult.Success -> r     } } <\/code><\/pre>\n<h4>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 Mapper \u0438 &#171;\u043b\u0435\u043d\u0438\u0432\u043e\u0441\u0442\u044c&#187;<\/h4>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0435\u0448\u0438\u043b\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0441\u0435\u0440 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0439 \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438, \u0442\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 \u0431\u044b \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"kotlin\">val `(` = symbol('(') val `)` = symbol(')')  fun parens() : Parser&lt;\/* \u041a\u0430\u043a \u0442\u0438\u043f \u0443\u043a\u0430\u0437\u0430\u0442\u044c?*\/> = Alt(     Seq(`(`, Seq(parens(), Seq(`)`, parens()))),     Return(Unit) )  fun main() {     parens().parse(\"(()())\") } <\/code><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043a\u043e\u0434, \u0432 \u043d\u0435\u043c \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041f\u0435\u0440\u0432\u0430\u044f &#8212; \u044d\u0442\u043e \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0442\u0438\u043f \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 <code>parens()<\/code>, \u0430 \u0432\u0442\u043e\u0440\u0430\u044f &#8212; \u044d\u0442\u043e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0432\u044b\u0437\u043e\u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0441\u0430\u043c\u043e\u0439 \u0441\u0435\u0431\u044f. \u0421\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043e\u0439 \u043b\u0435\u0433\u043a\u043e \u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 &#171;\u043b\u0435\u043d\u0438\u0432\u043e\u0441\u0442\u0438&#187; \u043d\u0430\u0448\u0438\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c:<\/p>\n<pre><code class=\"kotlin\">fun &lt;A> ref(lazy: () -> Parser&lt;A>) = object : Parser&lt;A> {     override fun parse(str: String) = lazy().parse(str) } <\/code><\/pre>\n<p>\u0414\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0440\u0435\u0448\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u0443\u044e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443, \u043d\u0443\u0436\u043d\u043e \u0432\u0432\u0435\u0441\u0442\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0442\u0438\u043f\u0430 \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u0438\u0437 <code>Parser&lt;A><\/code> \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c <code>Parser&lt;B><\/code>:<\/p>\n<pre><code class=\"kotlin\">class Mapper&lt;A, B>(private val p: Parser&lt;A>, private val f: (A) -> B) : Parser&lt;B> {     override fun parse(str: String) = p.parse(str).map { ParseResult.Success(it.tail, f(it.result)) } } <\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0447\u0438\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u0443\u044e \u0441\u043a\u043e\u0431\u043e\u0447\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u0440\u0430\u0437\u0431\u043e\u0440\u0430:<\/p>\n<pre><code class=\"kotlin\">val `(` = symbol('(') val `)` = symbol(')')  fun parens(): Parser&lt;Tree> = Alt(     Mapper(         Seq(             `(`,             Seq(                 ref { parens() },                 Seq(                     `)`,                     ref { parens() }                 )             )         )     ) { (_, a) -> Tree.Node(a.first, a.second.second) },     Return(Tree.Leaf) )  fun main() {     println(parens().parse(\"(()())\")) \/\/output: Success(tail=, pos=6, result=Node(left=Node(left=Leaf, right=Node(left=Leaf, right=Leaf)), right=Leaf)) } <\/code><\/pre>\n<p>\u041f\u043e\u0434\u0432\u0435\u0434\u0435\u043c \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0438\u0442\u043e\u0433.<\/p>\n<p>\u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b\u0438 \u043f\u0430\u0440\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430\u0440\u043d\u044b\u0445 \u043f\u0430\u0440\u0441\u0435\u0440\u043e\u0432 <code>TakeIf<\/code> \u0438 <code>Return&lt;A><\/code>, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c <code>Mapper&lt;A, B><\/code> \u0438 \u043f\u0430\u0440\u0443 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u043e\u0432 <code>Alt&lt;A><\/code>, <code>Seq&lt;A, B><\/code>. \u0421 \u0442\u0430\u043a\u0438\u043c<\/p>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-378024","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378024","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=378024"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/378024\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=378024"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=378024"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=378024"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}