{"id":325809,"date":"2021-07-01T15:00:17","date_gmt":"2021-07-01T15:00:17","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=325809"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=325809","title":{"rendered":"\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 DBML \u043d\u0430 PHP"},"content":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ac9\/b88\/5eb\/ac9b885ebeab0a42a5805927710695e0.png\" width=\"1211\" height=\"385\"><figcaption><\/figcaption><\/figure>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e DSL \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 PHP \u043a\u043e\u0434\u0430. \u0418 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438.<\/p>\n<hr>\n<p>\u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c <a href=\"https:\/\/dbdiagram.io\" rel=\"noopener noreferrer nofollow\">dbdiagram<\/a> \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0411\u0414 \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0438\u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u043d \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0442\u0430\u0431\u043b\u0438\u0446 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 DBML \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c51\/3d5\/e06\/c513d5e061385e60a0133d7075f0a3bc.png\" alt=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\" title=\"\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f\" width=\"1356\" height=\"661\"><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0440\u0430\u043d\u0435\u0435, \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 DBML \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0411\u0414, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043d\u0438 \u0436\u0435 \u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b\u0438 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/www.dbml.org\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e<\/a> \u043f\u043e \u043d\u0435\u043c\u0443.<\/p>\n<h2>\u0417\u0430\u0447\u0435\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u043b\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043d\u044b\u0445 \u0441\u0445\u0435\u043c \u0411\u0414, \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u0430 \u0438\u0434\u0435\u044f: <em>\u043a\u0430\u043a \u0431\u044b \u044d\u0442\u0443 \u0441\u0445\u0435\u043c\u0443 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 PHP \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f Laravel \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430<\/em>. <\/p>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/303\/de8\/210\/303de8210a47083050f10eb86fe5aef9.jpeg\" width=\"217\" height=\"233\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0435\u0440\u0432\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430<\/h2>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434, \u0430 \u0438\u0437\u0443\u0447\u0438\u0442\u044c <a href=\"https:\/\/github.com\/duythinht\/dbml-go\" rel=\"noopener noreferrer nofollow\">\u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 GO,<\/a> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430\u0445, \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0432\u0441\u0435 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u043d\u0430 PHP.<\/p>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0430 \u043f\u043e\u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0446\u0438\u044f (\u0440\u0430\u0437\u0431\u043e\u0440&nbsp;\u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438&nbsp;\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432&nbsp;\u043d\u0430 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u044b\u0435&nbsp;\u0433\u0440\u0443\u043f\u043f\u044b (\u043b\u0435\u043a\u0441\u0435\u043c\u044b) \u0441 \u0446\u0435\u043b\u044c\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u00ab\u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438\u00bb). \u041d\u0443 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u0442\u043e\u0433\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u044c (\u043c\u0430\u0441\u0441\u0438\u0432) \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<pre><code class=\"json\">\/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \/\/ full_name varchar [not null, unique, default: 1]  \/\/ \u041f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0432 JSON \u0444\u043e\u0440\u043c\u0430\u0442\u0435 [     {\"name\": \"IDENT\", \"string\": \"full_name\", \"pos\": [0, 9]},     {\"name\": \"IDENT\", \"string\": \"varchar\", \"pos\": [0, 17]},     {\"name\": \"LBRACK\", \"string\": \"[\", \"pos\": [0, 18]},     {\"name\": \"NOT\", \"string\": \"not\", \"pos\": [0, 22]},     {\"name\": \"NULL\", \"string\": \"null\", \"pos\": [0, 27]},     {\"name\": \"COMMA\", \"string\": \",\", \"pos\": [0, 27]},     {\"name\": \"UNIQUE\", \"string\": \"unique\", \"pos\": [0, 35]},     {\"name\": \"COMMA\", \"string\": \",\", \"pos\": [0, 35]},     {\"name\": \"DEFAULT\", \"string\": \"default\", \"pos\": [0, 44]},     {\"name\": \"COLON\", \"string\": \":\", \"pos\": [0, 44]},     {\"name\": \"INT\", \"string\": \"1\", \"pos\": [0, 46]},     {\"name\": \"RBRACK\", \"string\": \"]\", \"pos\": [0, 47]} ]<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0442\u043e\u043a\u0435\u043d\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0438\u0437 \u043d\u0438\u0445 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B5_%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\">\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e<\/a>.<\/p>\n<p><strong>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<pre><code class=\"dart\">\/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 DBML Project test {   database_type: 'PostgreSQL'   Note: 'Description of the project' }<\/code><\/pre>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u043d\u0435\u0433\u043e<\/p>\n<pre><code class=\"json\">[     {\"name\":\"PROJECT\",\"string\":\"Project\",\"pos\":[0,7]},     {\"name\":\"IDENT\",\"string\":\"test\",\"pos\":[0,12]},     {\"name\":\"LBRACE\",\"string\":\"{\",\"pos\":[0,13]},     {\"name\":\"IDENT\",\"string\":\"database_type\",\"pos\":[1,15]},     {\"name\":\"COLON\",\"string\":\":\",\"pos\":[1,15]},     {\"name\":\"DSTRING\",\"string\":\"PostgreSQL\",\"pos\":[1,18]},     {\"name\":\"NOTE\",\"string\":\"Note\",\"pos\":[2,6]},     {\"name\":\"COLON\",\"string\":\":\",\"pos\":[2,6]},     {\"name\":\"DSTRING\",\"string\":\"Description of the project\",\"pos\":[2,9]},     {\"name\":\"RBRACE\",\"string\":\"}\",\"pos\":[3,0]} ]<\/code><\/pre>\n<p>\u041f\u043e \u0442\u043e\u043a\u0435\u043d\u0443 <code>PROJECT<\/code> \u043c\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u0430\u043b\u0435\u0435 \u043d\u0430\u0441 \u0436\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php  \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u043e\u0432 $tokens = TokenCollection(...);  \/\/ \u0422\u043e\u043a\u0435\u043d \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 $token = $tokens-&gt;nextToken();  \/\/ \u0415\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0432 \u043a\u043e\u0432\u044b\u0447\u043a\u0430\u0445, \u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 if (!$token-&gt;is(Token::IDENT) &amp;&amp; !$token-&gt;is(Token::DSTRING)) {   throw new ParserException('Project does not have a name'); }  $name = $token-&gt;getString();  \/\/ \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443 LBRACE $token = $tokens-&gt;nextToken(); if (!$token-&gt;is('LBRACE')) {   throw new ParserException('Expects {'); }  $project = new Project($name);  \/\/ \u041f\u0440\u043e\u0431\u0435\u0433\u0430\u0435\u043c\u0441\u044f \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u0439\u0434\u0435\u043c \u0434\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u043a\u043e\u0431\u043a\u0438 do {   $token = $tokens-&gt;nextToken();    switch ($token-&gt;getName()) {     case Token::IDENT:       switch ($token-&gt;getString()) {         case 'database_type':           $project-&gt;setDbType(...);           break;         default:           throw new ParserException('Expects database_type');       }       break;     \/\/ \u0415\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u0441 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u043c, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439     case Token::NOTE:       $project-&gt;setNote(...);       break;     \/\/ \u0415\u0441\u043b\u0438 \u0437\u0430\u043a\u0440\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0446\u0438\u043a\u043b\u0430     case 'RBRACE':       return $project;     default:       throw new ParserException(sprintf('Invalid token %s', $token-&gt;getString()));   }    } while ($tokens-&gt;valid());<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 50% \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 DBML, \u043d\u0435\u0440\u0432\u044b \u043d\u0435 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u0438 \u0445\u043e\u0442\u044f  \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u0438 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u0432\u0441\u0435 \u043b\u0435\u0433\u043a\u043e, \u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438, \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439.<\/p>\n<h2>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 phplrt<\/h2>\n<p>\u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u0434\u043d\u044f\u0445 \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 PHP Russia 2021 <a class=\"mention\" href=\"\/users\/serafimarts\">@SerafimArts<\/a>\u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b \u0441 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u043e \u0441\u0432\u043e\u0435\u043c \u0438\u043d\u0441\u0442\u0443\u0440\u0435\u043c\u0435\u043d\u0442\u0435 <a href=\"https:\/\/github.com\/phplrt\/phplrt\" rel=\"noopener noreferrer nofollow\">phplrt<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0430\u0437\u0431\u043e\u0440\u043e\u043c \u044f\u0437\u044b\u043a\u0430 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435\u043c AST. \u0422.\u0435. \u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0440\u0435\u0448\u0430\u0435\u0442 \u043c\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u0433\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0442\u043e \u044d\u0442\u043e \u043f\u0430\u0440\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 DBML, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0\" rel=\"noopener noreferrer nofollow\">EBNF<\/a>.  \u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e EBNF phplrt \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0434\u043e\u0441\u0442\u0430\u0435\u0442 \u0438\u0437 \u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043f\u043e \u0441\u0432\u043e\u0438\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u043c \u0438 \u0441\u0442\u0440\u043e\u0438\u0442 AST. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c.<\/p>\n<blockquote>\n<p>phplrt \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 EBNF \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0430\u0446\u0438\u0438 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0438 \u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/butschster\/dbml-parser\/blob\/master\/src\/grammar.php\" rel=\"noopener noreferrer nofollow\">php \u0444\u0430\u0439\u043b\u0430<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/regex101.com\/r\/ZXNgVu\/1\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430<\/a> \u043d\u0435 \u0434\u043b\u044f \u0441\u043b\u0430\u0431\u043e\u043d\u0435\u0440\u0432\u043d\u044b\u0445 \u0434\u043b\u044f DBML :)))<\/p>\n<pre><code class=\"php\">\\G(?|(?:(?:\\s+)(*MARK:T_WHITESPACE))|(?:(?:\\\/\\\/[^\\n]*\\n)(*MARK:T_COMMENT))|(?:(?:(?&lt;=\\b)true\\b)(*MARK:T_BOOL_TRUE))|(?:(?:(?&lt;=\\b)false\\b)(*MARK:T_BOOL_FALSE))|(?:(?:(?&lt;=\\b)null\\b)(*MARK:T_NULL))|(?:(?:(?&lt;=\\b)Project\\b)(*MARK:T_PROJECT))|(?:(?:(?&lt;=\\b)Table\\b)(*MARK:T_TABLE))|(?:(?:(?&lt;=\\b)as\\b)(*MARK:T_TABLE_ALIAS))|(?:(?:(?&lt;=\\b)(Indexes|indexes)\\b)(*MARK:T_TABLE_INDEXES))|(?:(?:(Ref|ref))(*MARK:T_TABLE_REF))|(?:(?:(?&lt;=\\b)TableGroup\\b)(*MARK:T_TABLE_GROUP))|(?:(?:(?&lt;=\\b)(Enum|enum)\\b)(*MARK:T_ENUM))|(?:(?:(?&lt;=\\b)(primary\\ske|pk)\\b)(*MARK:T_TABLE_SETTING_PK))|(?:(?:(?&lt;=\\b)unique\\b)(*MARK:T_TABLE_SETTING_UNIQUE))|(?:(?:(?&lt;=\\b)increment\\b)(*MARK:T_TABLE_SETTING_INCREMENT))|(?:(?:(?&lt;=\\b)default\\b)(*MARK:T_TABLE_SETTING_DEFAULT))|(?:(?:(?&lt;=\\b)null\\b)(*MARK:T_TABLE_SETTING_NULL))|(?:(?:(?&lt;=\\b)not\\snull\\b)(*MARK:T_TABLE_SETTING_NOT_NULL))|(?:(?:(?&lt;=\\b)cascade\\b)(*MARK:T_REF_ACTION_CASCADE))|(?:(?:(?&lt;=\\b)restrict\\b)(*MARK:T_REF_ACTION_RESTRICT))|(?:(?:(?&lt;=\\b)set\\snull\\b)(*MARK:T_REF_ACTION_SET_NULL))|(?:(?:(?&lt;=\\b)set\\default\\b)(*MARK:T_REF_ACTION_SET_DEFAULT))|(?:(?:(?&lt;=\\b)no\\saction\\b)(*MARK:T_REF_ACTION_NO_ACTION))|(?:(?:(?&lt;=\\b)delete\\b)(*MARK:T_REF_ACTION_DELETE))|(?:(?:(?&lt;=\\b)update\\b)(*MARK:T_REF_ACTION_UPDATE))|(?:(?:note:)(*MARK:T_SETTING_NOTE))|(?:(?:(?&lt;=\\b)Note\\b)(*MARK:T_NOTE))|(?:(?:[0-9]+\\.[0-9]+)(*MARK:T_FLOAT))|(?:(?:[0-9]+)(*MARK:T_INT))|(?:(?:('{3}|[\"']{1})([^'\"][\\s\\S]*?)\\1)(*MARK:T_QUOTED_STRING))|(?:(?:(`{1})([\\s\\S]+?)\\1)(*MARK:T_EXPRESSION))|(?:(?:[a-zA-Z0-9_]+)(*MARK:T_WORD))|(?:(?:\\\\n)(*MARK:T_EOL))|(?:(?:\\()(*MARK:T_LPAREN))|(?:(?:\\))(*MARK:T_RPAREN))|(?:(?:{)(*MARK:T_LBRACE))|(?:(?:})(*MARK:T_RBRACE))|(?:(?:\\[)(*MARK:T_LBRACK))|(?:(?:\\])(*MARK:T_RBRACK))|(?:(?:\\&gt;)(*MARK:T_GT))|(?:(?:\\&lt;)(*MARK:T_LT))|(?:(?:,)(*MARK:T_COMMA))|(?:(?::)(*MARK:T_COLON))|(?:(?:\\-)(*MARK:T_MINUS))|(?:(?:\\.)(*MARK:T_DOT))|(?:(?:.+?)(*MARK:T_UNKNOWN)))<\/code><\/pre>\n<p><strong>\u041d\u0443 \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432<\/strong><\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/p>\n<pre><code class=\"bash\">\/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Project test {   database_type: 'PostgreSQL'   Note: 'Description of the project' }<\/code><\/pre>\n<p>\u0418 \u043e\u043f\u0438\u0448\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0442.\u0435. \u043e\u043f\u0438\u0448\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0432 \u043d\u0435\u0439.<\/p>\n<pre><code class=\"dart\">\/\/ \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 %token  T_PROJECT               (?&lt;=\\b)Project\\b \/\/ \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f %token  T_NOTE                  (?&lt;=\\b)Note\\b \/\/ \u0421\u0442\u0440\u043e\u043a\u0430, \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u0445 %token  T_QUOTED_STRING         ('{3}|[\"']{1})([^'\"][\\s\\S]*?)\\1 \/\/ \u041b\u044e\u0431\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 %token  T_WORD                  [a-zA-Z_]+ \/\/ \u0421\u0438\u043c\u0432\u043e\u043b\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f %token  T_LBRACE            { %token  T_RBRACE            } %token  T_COLON             : %token  T_EOL               \\\\n \/\/ \u0421\u0438\u043c\u0432\u043e\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u0438\u043c \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 %skip   T_WHITESPACE        \\s+<\/code><\/pre>\n<p>\u041d\u0443 \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0443 \u043e \u0441\u0442\u0440\u0443\u0442\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/p>\n<pre><code class=\"dart\">#Project :     ::T_PROJECT:: &lt;T_WORD&gt; ::T_LBRACE:: ::T_EOL::          \/\/ \u0417\u0434\u0435\u0441\u044c \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438          ::T_RBRACE:: ::EOL:: ;  \/\/ #Project - \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e (\u0442\u0438\u043f\u0430 \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432  \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430  \/\/ \u0422\u043e\u043a\u0435\u043d\u044b ::TOKEN_NAME:: \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0438\u0437 AST \/\/ \u0422\u043e\u043a\u0435\u043d\u044b &lt;TOKEN_NAME&gt; \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0438 \u0441 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/code><\/pre>\n<p>\u042f \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0435 \u0441\u0442\u0430\u043b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0447\u0430\u0441\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c. <\/p>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0438\u0448\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e \u0447\u0430\u0441\u0442\u044c<\/p>\n<pre><code class=\"dart\">\/\/ \u0421\u0442\u0440\u043e\u043a\u0430 database_type: 'PostgreSQL' #ProjectSetting :     &lt;T_WORD&gt; ::T_COLON:: (&lt;T_WORD&gt; | &lt;T_QUOTED_STRING&gt;) ;  \/\/ \u0421\u0442\u0440\u043e\u043a\u0430 Note: 'Description of the project' #Note :     ::T_NOTE:: ::T_COLON:: (&lt;T_WORD&gt; | &lt;T_QUOTED_STRING&gt;) ;  \/\/ ( &lt;T_WORD&gt; | &lt;T_QUOTED_STRING&gt; ) \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b \/\/ \u0431\u044b\u0442\u044c \u0438\u043b\u0438 \u0441\u043b\u043e\u0432\u043e \u0438\u043b\u0438 \u0441\u043b\u043e\u0432\u043e \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u0445<\/code><\/pre>\n<p>\u041d\u0443 \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u0432\u0441\u0435 \u0432\u043e\u0435\u0434\u0438\u043d\u043e<\/p>\n<pre><code class=\"dart\">#DBML :     \/\/ \u041d\u0430\u0448\u0430 DBML \u0441\u0445\u0435\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043f\u0440\u0430\u0432\u0438\u043b     \/\/ \u041e \u0447\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0441\u0438\u043c\u043e\u0432\u043b (...)* \t\t(       \tProject()         \/\/ Project() |         \/\/ Table() |         \/\/ TableGroup() |         \/\/ Enum() |         \/\/ Ref()           )* ;  #Project :     ::T_PROJECT:: &lt;T_WORD&gt; ::T_LBRACE:: ::T_EOL::          \/\/ \u041a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043f\u0440\u0430\u0432\u0438\u043b \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f 0 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437     (ProjectSetting() | Note() ::T_EOL::)*          ::T_RBRACE:: ::T_EOL:: ;<\/code><\/pre>\n<p>\u041e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u0430. \u042f \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b \u0441\u0445\u0435\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u0435\u0435 \u043b\u0435\u0433\u0447\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u044c. \u041f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/butschster\/dbml-parser\/blob\/master\/ebnf.pp2\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u041f\u043e \u0438\u0442\u043e\u0433\u0443 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c xml \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<pre><code class=\"xml\">&lt;DBML offset=\"0\"&gt;     &lt;Project offset=\"0\"&gt;         &lt;T_WORD offset=\"8\"&gt;project_name&lt;\/T_WORD&gt;         &lt;ProjectSetting offset=\"27\"&gt;             &lt;T_WORD offset=\"27\"&gt;database_type&lt;\/T_WORD&gt;             &lt;T_QUOTED_STRING offset=\"42\"&gt;'PostgreSQL'&lt;\/T_QUOTED_STRING&gt;         &lt;\/ProjectSetting&gt;         &lt;Note offset=\"59\"&gt;             &lt;T_QUOTED_STRING offset=\"65\"&gt;'Description of the project'&lt;\/T_QUOTED_STRING&gt;         &lt;\/Note&gt;     &lt;\/Project&gt; &lt;\/DBML&gt;<\/code><\/pre>\n<p>\u041e\u043a\u0435\u0439, \u0441\u0445\u0435\u043c\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b\u0438, XML \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438, \u0447\u0442\u043e \u0434\u0430\u043b\u044c\u0448\u0435? <\/p>\n<p>\u0410 \u0434\u0430\u043b\u044c\u0448\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u043e \u0432 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u0412 phplrt \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043f\u043e\u043d\u044f\u0442\u0438\u0435 \u043a\u0430\u043a <a href=\"https:\/\/phplrt.org\/docs\/compiler\/code\" rel=\"noopener noreferrer nofollow\">PHP \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u0438<\/a> <\/p>\n<blockquote>\n<p><em>!!!\u0412\u0430\u0436\u043d\u043e!!! \u0420\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u043e\u043b\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438. \u041f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 XML \u043d\u0430 \u043b\u0435\u0442\u0443, \u043e\u043d\u0438 \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u0443\u044e\u0442\u0441\u044f.<\/em><\/p>\n<\/blockquote>\n<p>\u0418\u043d\u044a\u0435\u043a\u0446\u0438\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0432 \u043d\u0430\u0448\u0435\u0439 \u0441\u0445\u0435\u043c\u0435 \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0432\u0441\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<pre><code class=\"dart\">#Project -&gt; {     return new ProjectNode(         \/\/ $children - \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a         \/\/ \u0432 \u0432\u0438\u0434\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \\Butschster\\Dbml\\Ast\\Project\\SettingNode          \/\/ \u0438\u043b\u0438 \\Butschster\\Dbml\\Ast\\NoteNode         $token-&gt;getOffset(), $children     ); }  #ProjectSetting -&gt; {     return new SettingNode(         \/\/ \\current($children) - \u043a\u043b\u044e\u0447         \/\/ \\end($children) - \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435         $token-&gt;getOffset(), \\current($children), \\end($children)     ); }  #Note -&gt; {     return new NoteNode(         \/\/ \\end($children) \u0442\u0435\u043a\u0441\u0442 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f         $token-&gt;getOffset(), \\end($children)     ); }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 PHP \u043a\u043b\u0430\u0441\u0441\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php  class ProjectNode {     private ?string $note = null;     \/** @var SettingNode[] *\/     private array $settings = [];     private string $name;      public function __construct(         private int $offset,         array $children     )     {         foreach ($children as $child) {             if ($child instanceof NoteNode) {                 $this-&gt;note = $child-&gt;getDescription();             } else if ($child instanceof SettingNode) {                 $this-&gt;settings[$child-&gt;getKey()] = $child;             } else if ($child instanceof NameNode) {                 $this-&gt;name = $child-&gt;getValue();             }         }     }      public function getName(): string     {         return $this-&gt;name;     }      public function getNote(): ?string     {         return $this-&gt;note;     }      public function getSettings(): array     {         return $this-&gt;settings;     } }  class NoteNode {     private string $description;      public function __construct(private int $offset, StringNode $string)     {         $this-&gt;description = $string-&gt;getValue();     }      public function getDescription(): string     {         return $this-&gt;description;     } }  class SettingNode {     private string $key;     private string $value;      public function __construct(         private int $offset, SettingKeyNode $key, StringNode $value     )     {         $this-&gt;key = $key-&gt;getValue();         $this-&gt;value = $value-&gt;getValue();     }      public function getKey(): string     {         return $this-&gt;key;     }      public function getValue(): string     {         return $this-&gt;value;     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041d\u0443 \u044f \u0434\u0443\u043c\u0430\u044e \u0438\u0434\u0435\u044f \u043f\u043e\u043d\u044f\u0442\u043d\u0430. \u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043f\u0430\u0440\u0441\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 DBML \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442, \u043e\u043d \u0435\u0433\u043e \u0440\u0430\u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u0442 \u043f\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u043c \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c. <\/p>\n<p>\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c phplrt \u0437\u0430\u043d\u044f\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0434\u043d\u0435\u0439 \u0438 \u0441\u0430\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f EBNF \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u0411\u0440\u0430\u043b \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u0437 DBML \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430<\/p>\n<\/li>\n<li>\n<p>\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u043b \u0435\u0451 \u0432 EBNF<\/p>\n<\/li>\n<li>\n<p>\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b XML \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0442\u0435\u0441\u0442\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ol>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0435\u0441\u0442\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php  class ProjectParserTest extends TestCase {     function test_project_with_single_line_note_should_be_parsed()     {         $this-&gt;assertAst(&lt;&lt;&lt;DBML Project project_name {     Note: 'Description of the project'     database_type: 'PostgreSQL' } DBML             , &lt;&lt;&lt;AST &lt;Schema offset=\"0\"&gt;     &lt;Project offset=\"0\"&gt;         &lt;ProjectName offset=\"8\"&gt;             &lt;String offset=\"8\"&gt;                 &lt;T_WORD offset=\"8\"&gt;project_name&lt;\/T_WORD&gt;             &lt;\/String&gt;         &lt;\/ProjectName&gt;         &lt;Note offset=\"27\"&gt;             &lt;String offset=\"33\"&gt;                 &lt;T_QUOTED_STRING offset=\"33\"&gt;'Description of the project'&lt;\/T_QUOTED_STRING&gt;             &lt;\/String&gt;         &lt;\/Note&gt;         &lt;ProjectSetting offset=\"66\"&gt;             &lt;ProjectSettingKey offset=\"66\"&gt;                 &lt;T_WORD offset=\"66\"&gt;database_type&lt;\/T_WORD&gt;             &lt;\/ProjectSettingKey&gt;             &lt;String offset=\"81\"&gt;                 &lt;T_QUOTED_STRING offset=\"81\"&gt;'PostgreSQL'&lt;\/T_QUOTED_STRING&gt;             &lt;\/String&gt;         &lt;\/ProjectSetting&gt;     &lt;\/Project&gt; &lt;\/Schema&gt; AST         );     }      function test_project_with_multi_line_note_should_be_parsed()     {         $this-&gt;assertAst(&lt;&lt;&lt;DBML Project project_name {     database_type: 'PostgreSQL'     Note: '''         # DBML - Database Markup Language         (database markup language) is a simple, readable DSL language designed to define database structures.          ## Benefits         * It is simple, flexible and highly human-readable         * It is database agnostic, focusing on the essential database structure definition without worrying about the detailed syntaxes of each database         * Comes with a free, simple database visualiser at [dbdiagram.io](http:\/\/dbdiagram.io)     ''' } DBML             , &lt;&lt;&lt;AST &lt;Schema offset=\"0\"&gt;     &lt;Project offset=\"0\"&gt;         &lt;ProjectName offset=\"8\"&gt;             &lt;String offset=\"8\"&gt;                 &lt;T_WORD offset=\"8\"&gt;project_name&lt;\/T_WORD&gt;             &lt;\/String&gt;         &lt;\/ProjectName&gt;         &lt;ProjectSetting offset=\"27\"&gt;             &lt;ProjectSettingKey offset=\"27\"&gt;                 &lt;T_WORD offset=\"27\"&gt;database_type&lt;\/T_WORD&gt;             &lt;\/ProjectSettingKey&gt;             &lt;String offset=\"42\"&gt;                 &lt;T_QUOTED_STRING offset=\"42\"&gt;'PostgreSQL'&lt;\/T_QUOTED_STRING&gt;             &lt;\/String&gt;         &lt;\/ProjectSetting&gt;         &lt;Note offset=\"59\"&gt;             &lt;String offset=\"65\"&gt;                 &lt;T_QUOTED_STRING offset=\"65\"&gt;'''     # DBML - Database Markup Language     (database markup language) is a simple, readable DSL language designed to define database structures.      ## Benefits     * It is simple, flexible and highly human-readable     * It is database agnostic, focusing on the essential database structure definition without worrying about the detailed syntaxes of each database     * Comes with a free, simple database visualiser at [dbdiagram.io](http:\/\/dbdiagram.io) '''&lt;\/T_QUOTED_STRING&gt;             &lt;\/String&gt;         &lt;\/Note&gt;     &lt;\/Project&gt; &lt;\/Schema&gt; AST         );     }      function test_project_with_block_note_should_be_parsed()     {         $this-&gt;assertAst(&lt;&lt;&lt;DBML Project project_name {     database_type: 'PostgreSQL'     Note {         'This is a note of this table'     } } DBML             , &lt;&lt;&lt;AST &lt;Schema offset=\"0\"&gt;     &lt;Project offset=\"0\"&gt;         &lt;ProjectName offset=\"8\"&gt;             &lt;String offset=\"8\"&gt;                 &lt;T_WORD offset=\"8\"&gt;project_name&lt;\/T_WORD&gt;             &lt;\/String&gt;         &lt;\/ProjectName&gt;         &lt;ProjectSetting offset=\"27\"&gt;             &lt;ProjectSettingKey offset=\"27\"&gt;                 &lt;T_WORD offset=\"27\"&gt;database_type&lt;\/T_WORD&gt;             &lt;\/ProjectSettingKey&gt;             &lt;String offset=\"42\"&gt;                 &lt;T_QUOTED_STRING offset=\"42\"&gt;'PostgreSQL'&lt;\/T_QUOTED_STRING&gt;             &lt;\/String&gt;         &lt;\/ProjectSetting&gt;         &lt;Note offset=\"59\"&gt;             &lt;String offset=\"74\"&gt;                 &lt;T_QUOTED_STRING offset=\"74\"&gt;'This is a note of this table'&lt;\/T_QUOTED_STRING&gt;             &lt;\/String&gt;         &lt;\/Note&gt;     &lt;\/Project&gt; &lt;\/Schema&gt; AST         );     } }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u044f \u043f\u043e\u043a\u0440\u044b\u043b \u0432\u0441\u0435 \u0432\u0430\u0440\u0438\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b DBML \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430 \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0439 EBNF, \u0442\u043e phplrt \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u0443\u0435\u0442 \u0435\u0451 \u0432 <a href=\"https:\/\/github.com\/butschster\/dbml-parser\/blob\/master\/src\/grammar.php\" rel=\"noopener noreferrer nofollow\">php \u043a\u043e\u0434<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u0430\u043b\u0435\u0435 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 (\u041a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430).<\/p>\n<p>\u0418 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u0441\u0435\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0441\u0442\u0430\u043b <strong>yet another DBML parser written on PHP8<\/strong> \u0441 \u043f\u043e\u043a\u0440\u044b\u0442\u0438\u0435\u043c \u0442\u0435\u0441\u0442\u0430\u043c\u0438 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 (\u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e\u0447\u043d\u043e) &#8212; <a href=\"https:\/\/github.com\/butschster\/dbml-parser\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/butschster\/dbml-parser<\/a><\/p>\n<p><strong>\u041f\u0435\u0440\u0432\u044b\u0439 \u044d\u0442\u0430\u043f \u0432 \u043c\u043e\u0435\u043c \u043f\u043b\u0430\u043d\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d. \u0422\u0435\u043f\u0435\u0440\u044c \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043c\u043e\u0434\u0435\u043b\u0435\u0439 \u0438 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0439.<\/strong><\/p>\n<p>\u041f\u043e \u0438\u0442\u043e\u0433\u0430\u043c \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0438\u043d\u0441\u0442\u0443\u0440\u043c\u0435\u043d\u0442\u043e\u043c phplrt \u0445\u043e\u0447\u0443 \u0432\u044b\u0440\u0430\u0437\u0438\u0442\u044c \u0440\u0435\u0441\u043f\u0435\u043a\u0442 \u0438 \u0443\u0432\u0430\u0436\u0435\u043d\u0438\u0435 <a class=\"mention\" href=\"\/users\/serafimarts\">@SerafimArts<\/a> \u0437\u0430 \u043d\u0435\u0433\u043e, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433 \u0432 \u043a\u043e\u0440\u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0443 \u044f\u0437\u044b\u043a\u0430 \u0438 \u0440\u0435\u0448\u0438\u0442\u044c \u043c\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0435 \u0441\u043f\u0430\u0441\u0438\u0431\u043e <a class=\"mention\" href=\"\/users\/greabock\">@greabock<\/a> \u0438 <a class=\"mention\" href=\"\/users\/serafimarts\">@SerafimArts<\/a> \u0437\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0435 \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u0438 \u043f\u043e\u043c\u043e\u0449\u0438 \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043f\u0430\u0440\u0441\u0435\u0440\u0430.<\/p>\n<h3>\u0421\u0441\u044b\u043b\u043a\u0438<\/h3>\n<ul>\n<li>\n<p>DBML \u043f\u0430\u0440\u0441\u0435\u0440 &#8212; <a href=\"https:\/\/github.com\/butschster\/dbml-parser\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/butschster\/dbml-parser<\/a><\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 phplrt &#8212; <a href=\"https:\/\/github.com\/phplrt\/phplrt\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/phplrt\/phplrt<\/a><\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e phlrt &#8212; <a href=\"https:\/\/phplrt.org\/\" rel=\"noopener noreferrer nofollow\">https:\/\/phplrt.org\/<\/a><\/p>\n<\/li>\n<\/ul>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/565694\/\"> https:\/\/habr.com\/ru\/post\/565694\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text_v2\" id=\"post-content-body\">\n<figure class=\"full-width\"><figcaption><\/figcaption><\/figure>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0437\u0430\u0434\u0430\u0447\u0430 \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0433\u043e DSL \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043d\u0438\u043c \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 PHP \u043a\u043e\u0434\u0430. \u0418 \u044f \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u043e\u043f\u044b\u0442\u043e\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438.<\/p>\n<hr>\n<p>\u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0434\u043e\u043b\u0433\u043e\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0441\u044c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c <a href=\"https:\/\/dbdiagram.io\" rel=\"noopener noreferrer nofollow\">dbdiagram<\/a> \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0411\u0414 \u0434\u043b\u044f \u0431\u0443\u0434\u0443\u0449\u0438\u0445 \u0438\u043b\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0414\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u044f \u0432\u044b\u0431\u0440\u0430\u043b \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u043d \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442 \u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438. \u041e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0442\u0430\u0431\u043b\u0438\u0446 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 DBML \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u0438\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<figure class=\"full-width\"><figcaption>\u041f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0438 \u0432\u0438\u0437\u0443\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f<\/figcaption><\/figure>\n<p>\u041a\u0430\u043a \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0440\u0430\u043d\u0435\u0435, \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 DBML \u0434\u043b\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0411\u0414, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u043d\u0438 \u0436\u0435 \u0438 \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u043b\u0438 \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 <a href=\"https:\/\/www.dbml.org\" rel=\"noopener noreferrer nofollow\">\u0441\u043f\u0435\u0446\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e<\/a> \u043f\u043e \u043d\u0435\u043c\u0443.<\/p>\n<h2>\u0417\u0430\u0447\u0435\u043c \u043f\u0430\u0440\u0441\u0438\u0442\u044c<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0434\u043e\u043b\u0433\u043e\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u0430\u0441\u0441\u0438\u0432\u043d\u044b\u0445 \u0441\u0445\u0435\u043c \u0411\u0414, \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u043b\u0430 \u0438\u0434\u0435\u044f: <em>\u043a\u0430\u043a \u0431\u044b \u044d\u0442\u0443 \u0441\u0445\u0435\u043c\u0443 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c \u0432 PHP \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u043e\u0434\u0435\u043b\u0438 \u0438 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f Laravel \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430<\/em>. <\/p>\n<figure class=\"\"><figcaption><\/figcaption><\/figure>\n<h2>\u041f\u0435\u0440\u0432\u0430\u044f \u043f\u043e\u043f\u044b\u0442\u043a\u0430<\/h2>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0432\u0435\u043b\u043e\u0441\u0438\u043f\u0435\u0434, \u0430 \u0438\u0437\u0443\u0447\u0438\u0442\u044c <a href=\"https:\/\/github.com\/duythinht\/dbml-go\" rel=\"noopener noreferrer nofollow\">\u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0430 GO,<\/a> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0445 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430\u0445, \u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c \u0432\u0441\u0435 \u0442\u043e, \u0447\u0442\u043e \u043e\u043d\u0430 \u0434\u0435\u043b\u0430\u0435\u0442 \u043d\u0430 PHP.<\/p>\n<p>\u041f\u0430\u0440\u0441\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c: \u0440\u0430\u0437\u0431\u0438\u0432\u043a\u0430 \u043f\u043e\u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u043e \u0432\u0441\u0435\u0433\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430, \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0446\u0438\u044f (\u0440\u0430\u0437\u0431\u043e\u0440&nbsp;\u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438&nbsp;\u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432&nbsp;\u043d\u0430 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0432\u0430\u0435\u043c\u044b\u0435&nbsp;\u0433\u0440\u0443\u043f\u043f\u044b (\u043b\u0435\u043a\u0441\u0435\u043c\u044b) \u0441 \u0446\u0435\u043b\u044c\u044e \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0435\u0439, \u043d\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0445 \u00ab\u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438\u00bb). \u041d\u0443 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0438\u0442\u043e\u0433\u043e\u043c \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u044c (\u043c\u0430\u0441\u0441\u0438\u0432) \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043c\u0438.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<pre><code class=\"json\">\/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \/\/ full_name varchar [not null, unique, default: 1]  \/\/ \u041f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0432 JSON \u0444\u043e\u0440\u043c\u0430\u0442\u0435 [     {\"name\": \"IDENT\", \"string\": \"full_name\", \"pos\": [0, 9]},     {\"name\": \"IDENT\", \"string\": \"varchar\", \"pos\": [0, 17]},     {\"name\": \"LBRACK\", \"string\": \"[\", \"pos\": [0, 18]},     {\"name\": \"NOT\", \"string\": \"not\", \"pos\": [0, 22]},     {\"name\": \"NULL\", \"string\": \"null\", \"pos\": [0, 27]},     {\"name\": \"COMMA\", \"string\": \",\", \"pos\": [0, 27]},     {\"name\": \"UNIQUE\", \"string\": \"unique\", \"pos\": [0, 35]},     {\"name\": \"COMMA\", \"string\": \",\", \"pos\": [0, 35]},     {\"name\": \"DEFAULT\", \"string\": \"default\", \"pos\": [0, 44]},     {\"name\": \"COLON\", \"string\": \":\", \"pos\": [0, 44]},     {\"name\": \"INT\", \"string\": \"1\", \"pos\": [0, 46]},     {\"name\": \"RBRACK\", \"string\": \"]\", \"pos\": [0, 47]} ]<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u0442\u043e\u043a\u0435\u043d\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u0438\u0437 \u043d\u0438\u0445 \u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%90%D0%B1%D1%81%D1%82%D1%80%D0%B0%D0%BA%D1%82%D0%BD%D0%BE%D0%B5_%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%87%D0%B5%D1%81%D0%BA%D0%BE%D0%B5_%D0%B4%D0%B5%D1%80%D0%B5%D0%B2%D0%BE\" rel=\"noopener noreferrer nofollow\">\u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e<\/a>.<\/p>\n<p><strong>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<pre><code class=\"dart\">\/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 DBML Project test {   database_type: 'PostgreSQL'   Note: 'Description of the project' }<\/code><\/pre>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0434\u043b\u044f \u043d\u0435\u0433\u043e<\/p>\n<pre><code class=\"json\">[     {\"name\":\"PROJECT\",\"string\":\"Project\",\"pos\":[0,7]},     {\"name\":\"IDENT\",\"string\":\"test\",\"pos\":[0,12]},     {\"name\":\"LBRACE\",\"string\":\"{\",\"pos\":[0,13]},     {\"name\":\"IDENT\",\"string\":\"database_type\",\"pos\":[1,15]},     {\"name\":\"COLON\",\"string\":\":\",\"pos\":[1,15]},     {\"name\":\"DSTRING\",\"string\":\"PostgreSQL\",\"pos\":[1,18]},     {\"name\":\"NOTE\",\"string\":\"Note\",\"pos\":[2,6]},     {\"name\":\"COLON\",\"string\":\":\",\"pos\":[2,6]},     {\"name\":\"DSTRING\",\"string\":\"Description of the project\",\"pos\":[2,9]},     {\"name\":\"RBRACE\",\"string\":\"}\",\"pos\":[3,0]} ]<\/code><\/pre>\n<p>\u041f\u043e \u0442\u043e\u043a\u0435\u043d\u0443 <code>PROJECT<\/code> \u043c\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u0430\u043b\u0435\u0435 \u043d\u0430\u0441 \u0436\u0434\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"php\">&lt;?php  \/\/ \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u043e\u0432 $tokens = TokenCollection(...);  \/\/ \u0422\u043e\u043a\u0435\u043d \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 $token = $tokens-&gt;nextToken();  \/\/ \u0415\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0438 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u0432 \u043a\u043e\u0432\u044b\u0447\u043a\u0430\u0445, \u0442\u043e \u044d\u0442\u043e \u043d\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 if (!$token-&gt;is(Token::IDENT) &amp;&amp; !$token-&gt;is(Token::DSTRING)) {   throw new ParserException('Project does not have a name'); }  $name = $token-&gt;getString();  \/\/ \u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u0442\u043e\u043a\u0435\u043d\u0443 LBRACE $token = $tokens-&gt;nextToken(); if (!$token-&gt;is('LBRACE')) {   throw new ParserException('Expects {'); }  $project = new Project($name);  \/\/ \u041f\u0440\u043e\u0431\u0435\u0433\u0430\u0435\u043c\u0441\u044f \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0430\u043c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0434\u043e\u0439\u0434\u0435\u043c \u0434\u043e \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 \u0441\u043a\u043e\u0431\u043a\u0438 do {   $token = $tokens-&gt;nextToken();    switch ($token-&gt;getName()) {     case Token::IDENT:       switch ($token-&gt;getString()) {         case 'database_type':           $project-&gt;setDbType(...);           break;         default:           throw new ParserException('Expects database_type');       }       break;     \/\/ \u0415\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d \u0441 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0435\u043c, \u0442\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043f\u0440\u043e\u0435\u043a\u0442 \u043a\u043e\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439     case Token::NOTE:       $project-&gt;setNote(...);       break;     \/\/ \u0415\u0441\u043b\u0438 \u0437\u0430\u043a\u0440\u0432\u0430\u044e\u0449\u0430\u044f \u0441\u043a\u043e\u0431\u043a\u0430, \u0442\u043e \u0432\u044b\u0445\u043e\u0434\u0438\u043c \u0438\u0437 \u0446\u0438\u043a\u043b\u0430     case 'RBRACE':       return $project;     default:       throw new ParserException(sprintf('Invalid token %s', $token-&gt;getString()));   }    } while ($tokens-&gt;valid());<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0430 50% \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430 \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440 DBML, \u043d\u0435\u0440\u0432\u044b \u043d\u0435 \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u043b\u0438 \u0438 \u0445\u043e\u0442\u044f  \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f, \u0438 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u0447\u0442\u043e \u0432\u0441\u0435 \u043b\u0435\u0433\u043a\u043e, \u043d\u043e \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e\u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438, \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u043e\u0436\u043d\u043e \u0438 \u044f \u0440\u0435\u0448\u0438\u043b \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0438 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432 \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u0434\u0440\u0443\u0433\u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439.<\/p>\n<h2>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 phplrt<\/h2>\n<p>\u0411\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043d\u0430 \u0434\u043d\u044f\u0445 \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 PHP Russia 2021 <a class=\"mention\" href=\"\/users\/serafimarts\">@SerafimArts<\/a>\u0432\u044b\u0441\u0442\u0443\u043f\u0430\u043b \u0441 \u0434\u043e\u043a\u043b\u0430\u0434\u043e\u043c \u043e \u0441\u0432\u043e\u0435\u043c \u0438\u043d\u0441\u0442\u0443\u0440\u0435\u043c\u0435\u043d\u0442\u0435 <a href=\"https:\/\/github.com\/phplrt\/phplrt\" rel=\"noopener noreferrer nofollow\">phplrt<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0430\u0437\u0431\u043e\u0440\u043e\u043c \u044f\u0437\u044b\u043a\u0430 \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u0435\u043c AST. \u0422.\u0435. \u0434\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0440\u0435\u0448\u0430\u0435\u0442 \u043c\u043e\u044e \u0437\u0430\u0434\u0430\u0447\u0443 \u0438 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u0434\u0440\u0443\u0433\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c. <\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u0432\u0441\u0435\u043c \u0433\u0440\u0443\u0431\u043e \u0433\u043e\u0432\u043e\u0440\u044f, \u0442\u043e \u044d\u0442\u043e \u043f\u0430\u0440\u0441\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u0432 \u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 DBML, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/%D0%A0%D0%B0%D1%81%D1%88%D0%B8%D1%80%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0_%D0%91%D1%8D%D0%BA%D1%83%D1%81%D0%B0_%E2%80%94_%D0%9D%D0%B0%D1%83%D1%80%D0%B0\" rel=\"noopener noreferrer nofollow\">EBNF<\/a>.  \u0421\u043e\u0433\u043b\u0430\u0441\u043d\u043e EBNF phplrt \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438 \u0434\u043e\u0441\u0442\u0430\u0435\u0442 \u0438\u0437 \u043d\u0435\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0442\u043e\u043a\u0435\u043d\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u043f\u043e \u0441\u0432\u043e\u0438\u043c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430\u043c \u0438 \u0441\u0442\u0440\u043e\u0438\u0442 AST. \u0414\u0430\u043b\u0435\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c \u0434\u0435\u0440\u0435\u0432\u043e\u043c.<\/p>\n<blockquote>\n<p>phplrt \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 EBNF \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0430\u0446\u0438\u0438 \u0440\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0438 \u0438\u043b\u0438 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 <a href=\"https:\/\/github.com\/butschster\/dbml-parser\/blob\/master\/src\/grammar.php\" rel=\"noopener noreferrer nofollow\">php \u0444\u0430\u0439\u043b\u0430<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u0431\u043e\u0440\u0430 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u044f\u0437\u044b\u043a\u0430.<\/p>\n<\/blockquote>\n<p><a href=\"https:\/\/regex101.com\/r\/ZXNgVu\/1\" rel=\"noopener noreferrer nofollow\">\u0420\u0435\u0433\u0443\u043b\u044f\u0440\u043a\u0430<\/a> \u043d\u0435 \u0434\u043b\u044f \u0441\u043b\u0430\u0431\u043e\u043d\u0435\u0440\u0432\u043d\u044b\u0445 \u0434\u043b\u044f DBML :)))<\/p>\n<pre><code class=\"php\">\\G(?|(?:(?:\\s+)(*MARK:T_WHITESPACE))|(?:(?:\\\/\\\/[^\\n]*\\n)(*MARK:T_COMMENT))|(?:(?:(?&lt;=\\b)true\\b)(*MARK:T_BOOL_TRUE))|(?:(?:(?&lt;=\\b)false\\b)(*MARK:T_BOOL_FALSE))|(?:(?:(?&lt;=\\b)null\\b)(*MARK:T_NULL))|(?:(?:(?&lt;=\\b)Project\\b)(*MARK:T_PROJECT))|(?:(?:(?&lt;=\\b)Table\\b)(*MARK:T_TABLE))|(?:(?:(?&lt;=\\b)as\\b)(*MARK:T_TABLE_ALIAS))|(?:(?:(?&lt;=\\b)(Indexes|indexes)\\b)(*MARK:T_TABLE_INDEXES))|(?:(?:(Ref|ref))(*MARK:T_TABLE_REF))|(?:(?:(?&lt;=\\b)TableGroup\\b)(*MARK:T_TABLE_GROUP))|(?:(?:(?&lt;=\\b)(Enum|enum)\\b)(*MARK:T_ENUM))|(?:(?:(?&lt;=\\b)(primary\\ske|pk)\\b)(*MARK:T_TABLE_SETTING_PK))|(?:(?:(?&lt;=\\b)unique\\b)(*MARK:T_TABLE_SETTING_UNIQUE))|(?:(?:(?&lt;=\\b)increment\\b)(*MARK:T_TABLE_SETTING_INCREMENT))|(?:(?:(?&lt;=\\b)default\\b)(*MARK:T_TABLE_SETTING_DEFAULT))|(?:(?:(?&lt;=\\b)null\\b)(*MARK:T_TABLE_SETTING_NULL))|(?:(?:(?&lt;=\\b)not\\snull\\b)(*MARK:T_TABLE_SETTING_NOT_NULL))|(?:(?:(?&lt;=\\b)cascade\\b)(*MARK:T_REF_ACTION_CASCADE))|(?:(?:(?&lt;=\\b)restrict\\b)(*MARK:T_REF_ACTION_RESTRICT))|(?:(?:(?&lt;=\\b)set\\snull\\b)(*MARK:T_REF_ACTION_SET_NULL))|(?:(?:(?&lt;=\\b)set\\default\\b)(*MARK:T_REF_ACTION_SET_DEFAULT))|(?:(?:(?&lt;=\\b)no\\saction\\b)(*MARK:T_REF_ACTION_NO_ACTION))|(?:(?:(?&lt;=\\b)delete\\b)(*MARK:T_REF_ACTION_DELETE))|(?:(?:(?&lt;=\\b)update\\b)(*MARK:T_REF_ACTION_UPDATE))|(?:(?:note:)(*MARK:T_SETTING_NOTE))|(?:(?:(?&lt;=\\b)Note\\b)(*MARK:T_NOTE))|(?:(?:[0-9]+\\.[0-9]+)(*MARK:T_FLOAT))|(?:(?:[0-9]+)(*MARK:T_INT))|(?:(?:('{3}|[\"']{1})([^'\"][\\s\\S]*?)\\1)(*MARK:T_QUOTED_STRING))|(?:(?:(`{1})([\\s\\S]+?)\\1)(*MARK:T_EXPRESSION))|(?:(?:[a-zA-Z0-9_]+)(*MARK:T_WORD))|(?:(?:\\\\n)(*MARK:T_EOL))|(?:(?:\\()(*MARK:T_LPAREN))|(?:(?:\\))(*MARK:T_RPAREN))|(?:(?:{)(*MARK:T_LBRACE))|(?:(?:})(*MARK:T_RBRACE))|(?:(?:\\[)(*MARK:T_LBRACK))|(?:(?:\\])(*MARK:T_RBRACK))|(?:(?:\\&gt;)(*MARK:T_GT))|(?:(?:\\&lt;)(*MARK:T_LT))|(?:(?:,)(*MARK:T_COMMA))|(?:(?::)(*MARK:T_COLON))|(?:(?:\\-)(*MARK:T_MINUS))|(?:(?:\\.)(*MARK:T_DOT))|(?:(?:.+?)(*MARK:T_UNKNOWN)))<\/code><\/pre>\n<p><strong>\u041d\u0443 \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043f\u0430\u0440\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432<\/strong><\/p>\n<p>\u0412\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u043a \u043d\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0441\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/p>\n<pre><code class=\"bash\">\/\/ \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Project test {   database_type: 'PostgreSQL'   Note: 'Description of the project' }<\/code><\/pre>\n<p>\u0418 \u043e\u043f\u0438\u0448\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b, \u0442.\u0435. \u043e\u043f\u0438\u0448\u0435\u043c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u0432 \u043d\u0435\u0439.<\/p>\n<pre><code class=\"dart\">\/\/ \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 %token  T_PROJECT               (?&lt;=\\b)Project\\b \/\/ \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0434\u043b\u044f \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0430 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f %token  T_NOTE                  (?&lt;=\\b)Note\\b \/\/ \u0421\u0442\u0440\u043e\u043a\u0430, \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u0445 %token  T_QUOTED_STRING         ('{3}|[\"']{1})([^'\"][\\s\\S]*?)\\1 \/\/ \u041b\u044e\u0431\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 %token  T_WORD                  [a-zA-Z_]+ \/\/ \u0421\u0438\u043c\u0432\u043e\u043b\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f %token  T_LBRACE            { %token  T_RBRACE            } %token  T_COLON             : %token  T_EOL               \\\\n \/\/ \u0421\u0438\u043c\u0432\u043e\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0445\u043e\u0442\u0438\u043c \u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0437\u0431\u043e\u0440\u0430 %skip   T_WHITESPACE        \\s+<\/code><\/pre>\n<p>\u041d\u0443 \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0443 \u043e \u0441\u0442\u0440\u0443\u0442\u043a\u0442\u0443\u0440\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/p>\n<pre><code class=\"dart\">#Project :     ::T_PROJECT:: &lt;T_WORD&gt; ::T_LBRACE:: ::T_EOL::          \/\/ \u0417\u0434\u0435\u0441\u044c \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u0441 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438          ::T_RBRACE:: ::EOL:: ;  \/\/ #Project - \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e (\u0442\u0438\u043f\u0430 \u043a\u0430\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f), \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432  \/\/ \u0434\u0440\u0443\u0433\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430  \/\/ \u0422\u043e\u043a\u0435\u043d\u044b ::TOKEN_NAME:: \u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044e\u0442\u0441\u044f \u0438\u0437 AST \/\/ \u0422\u043e\u043a\u0435\u043d\u044b &lt;TOKEN_NAME&gt; \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u0438 \u0441 \u043d\u0438\u043c\u0438 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c<\/code><\/pre>\n<p>\u042f \u043f\u043e\u043a\u0430 \u0447\u0442\u043e \u043d\u0435 \u0441\u0442\u0430\u043b \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u0447\u0430\u0441\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0437\u0430\u043f\u0443\u0442\u0430\u0442\u044c. <\/p>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u043f\u0438\u0448\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u044e \u0447\u0430\u0441\u0442\u044c<\/p>\n<pre><code class=\"dart\">\/\/ \u0421\u0442\u0440\u043e\u043a\u0430 database_type: 'PostgreSQL' #ProjectSetting :     &lt;T_WORD&gt; ::T_COLON:: (&lt;T_WORD&gt; | &lt;T_QUOTED_STRING&gt;) ;  \/\/ \u0421\u0442\u0440\u043e\u043a\u0430 Note: 'Description of the project' #Note :     ::T_NOTE:: ::T_COLON:: (&lt;T_WORD&gt; | &lt;T_QUOTED_STRING&gt;) ;  \/\/ ( &lt;T_WORD&gt; | &lt;T_QUOTED_STRING&gt; ) \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0432 \u044d\u0442\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b \/\/ \u0431\u044b\u0442\u044c \u0438\u043b\u0438 \u0441\u043b\u043e\u0432\u043e \u0438\u043b\u0438 \u0441\u043b\u043e\u0432\u043e \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0430\u0445<\/code><\/pre>\n<p>\u041d\u0443 \u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0431\u0435\u0440\u0435\u043c \u0432\u0441\u0435 \u0432\u043e\u0435\u0434\u0438\u043d\u043e<\/p>\n<pre><code class=\"dart\">#DBML :     \/\/ \u041d\u0430\u0448\u0430 DBML \u0441\u0445\u0435\u043c\u0430 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0438\u0437 \u043f\u0440\u0430\u0432\u0438\u043b     \/\/ \u041e \u0447\u0435\u043c \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0441\u0438\u043c\u043e\u0432\u043b (...)* \t\t(       \tProject()         \/\/ Project() |         \/\/ Table() |         \/\/ TableGroup() |         \/\/ Enum() |         \/\/ Ref()           )* ;  #Project :     ::T_PROJECT:: &lt;T_WORD&gt; ::T_LBRACE:: ::T_EOL::          \/\/ \u041a\u0430\u0436\u0434\u043e\u0435 \u0438\u0437 \u043f\u0440\u0430\u0432\u0438\u043b \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f 0 \u0438\u043b\u0438 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437     (ProjectSetting() | Note() ::T_EOL::)*          ::T_RBRACE:: ::T_EOL:: ;<\/code><\/pre>\n<p>\u041e\u0431\u0449\u0430\u044f \u0438\u0434\u0435\u044f \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u043f\u043e\u043d\u044f\u0442\u043d\u0430. \u042f \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043b \u0441\u0445\u0435\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u0435\u0435 \u043b\u0435\u0433\u0447\u0435 \u0431\u044b\u043b\u043e \u043f\u043e\u043d\u044f\u0442\u044c. \u041f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0447\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c <a href=\"https:\/\/github.com\/butschster\/dbml-parser\/blob\/master\/ebnf.pp2\" rel=\"noopener noreferrer nofollow\">\u0437\u0434\u0435\u0441\u044c<\/a>.<\/p>\n<p>\u041f\u043e \u0438\u0442\u043e\u0433\u0443 \u0432 \u0442\u0435\u0441\u0442\u0430\u0445 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c xml \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430.<\/p>\n<p><strong>\u041f\u0440\u0438\u043c\u0435\u0440<\/strong><\/p>\n<pre><code class=\"xml\">&lt;DBML offset=\"0\"&gt;     &lt;Project offset=\"0\"&gt;         &lt;T_WORD offset=\"8\"&gt;project_name&lt;\/T_WORD&gt;         &lt;Projec<\/code><\/pre>\n<\/hr>\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-325809","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/325809","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=325809"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/325809\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=325809"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=325809"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=325809"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}