{"id":481994,"date":"2026-06-02T03:15:14","date_gmt":"2026-06-02T03:15:14","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=481994"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=481994","title":{"rendered":"\u0421\u043e\u0437\u0434\u0430\u0451\u043c DSL \u043d\u0430 C#: \u041f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0414\u0430\u0432\u043d\u043e \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0435\u043b \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0442\u044c 1 \u0441\u0442\u0430\u0442\u044c\u044e \u0432 \u0440\u0430\u0437 \u043d\u0435\u0434\u0435\u043b\u044e, \u043d\u043e \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0430\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u0431\u0440\u043e\u0441\u0438\u043b \u0438 \u043d\u0430\u0447\u0430\u043b \u043f\u043e\u0438\u0441\u043a \u0440\u0430\u0431\u043e\u0442\u044b. \u041d\u0435 \u0434\u0430\u0432\u043d\u043e \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u0438 \u043a\u0430\u043a\u043e\u0433\u043e \u0431\u044b\u043b\u043e \u043c\u043e\u0435 \u0443\u0434\u0438\u0432\u043b\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430 3 \u0434\u043d\u044f. \u0427\u0442\u043e\u0436 \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0435\u0440\u0438\u044e \u044f \u0432\u044b\u043f\u0438\u0448\u0443 \u0431\u044b\u0441\u0442\u0440\u0435\u0435.<\/p>\n<ol>\n<li>\n<p><a href=\"https:\/\/habr.com\/ru\/articles\/970332\/\" rel=\"noopener noreferrer nofollow\">\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441<\/a><\/p>\n<\/li>\n<li>\n<p><strong>\u041f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440<\/strong><\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c blender<\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430<\/p>\n<\/li>\n<li>\n<p>\u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c Language Server Protocol \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 Visual Studio<\/p>\n<\/li>\n<li>\n<p>\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434<\/p>\n<\/li>\n<\/ol>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 SourceText<\/h2>\n<p>\u041c\u044b, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 <a href=\"https:\/\/learn.microsoft.com\/ru-ru\/dotnet\/api\/microsoft.codeanalysis.text.sourcetextcontainer.currenttext?view=roslyn-dotnet-4.13.0\" rel=\"noopener noreferrer nofollow\">SourceText<\/a>, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u043e\u0442\u043a\u0440\u043e\u0432\u0435\u043d\u043d\u043e \u043c\u0430\u043b\u043e \u0441\u043c\u044b\u0441\u043b\u0430. \u0412 Roslyn \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u0438 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u0443 \u043d\u0435\u0451 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c: \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443, \u0434\u043b\u0438\u043d\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a, \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 checksum \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438, \u043f\u043e\u0442\u043e\u043a\u0430 \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442\u043e\u0432.<\/p>\n<p>\u0427\u0435\u043c \u0436\u0435 \u043e\u043d \u0442\u0430\u043a \u043f\u043e\u043b\u0435\u0437\u0435\u043d? \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430\u043c\u0438. <code>SourceText<\/code> \u0443\u043c\u0435\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0430 \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0441 \u0431\u0430\u0439\u0442\u0430\u043c\u0438, \u0430 \u0441 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0434\u043e\u0442\u043d\u0435\u0442\u0430 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0438 <code>char<\/code>. \u042d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043a\u043e\u0434 \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, <code>SourceText<\/code> \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439. \u0412\u043d\u0443\u0442\u0440\u0438 Roslyn \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432: \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0442\u0435\u043a\u0441\u0442, \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0438\u0437 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432. \u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0440\u0435\u0448\u0430\u0442\u044c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Roslyn.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u0438\u0437\u0443\u0447\u0430\u0432 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u044e <code>SourceText<\/code>, \u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u043d\u0435 \u044d\u0442\u043e \u0430\u0443\u043a\u043d\u0435\u0442\u0441\u044f \u043a\u0441\u0442\u0430\u0442\u0438, \u043d\u043e \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0447\u0442\u043e \u043d\u0435\u0442.<\/p>\n<h2>TextWindow<\/h2>\n<p>\u041d\u043e \u043a\u0430\u043a \u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0440\u0430\u043d\u0435\u0435 SourceText \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u0430, \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0443 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0438\u0437-\u0437\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0430<\/p>\n<pre><code class=\"cs\">using Microsoft.CodeAnalysis.Text;namespace Akbura.Language;internal struct SlidingTextWindow{    public const char InvalidCharacter = char.MaxValue;    public const int DefaultWindowLength = 1024;    private static readonly ObjectPool&lt;char[]&gt; s_windowPool =        new(() =&gt; new char[DefaultWindowLength]);    public SourceText Text { get; }    private readonly int _textEnd;    private int _positionInText;    private ArraySegment&lt;char&gt; _characterWindow;    private int _characterWindowStartPositionInText;    public SlidingTextWindow(SourceText text)    {        Text = text;        _textEnd = text.Length;        _characterWindow = new ArraySegment&lt;char&gt;(s_windowPool.Allocate());        ReadChunkAt(0);    }    private void ReadChunkAt(int position)    {        position = Math.Min(position, _textEnd);        var amountToRead = Math.Min(_textEnd - position, DefaultWindowLength);        Text.CopyTo(            position,            _characterWindow.Array!,            0,            amountToRead);        _characterWindowStartPositionInText = position;        _characterWindow = new(_characterWindow.Array!, 0, amountToRead);    }    public readonly int Position =&gt; _positionInText;    public readonly ReadOnlySpan&lt;char&gt; CurrentWindowSpan    {        get        {            var start = _positionInText - _characterWindowStartPositionInText;            return start &lt; 0 || start &gt;= _characterWindow.Count                ? default                : _characterWindow.AsSpan(start);        }    }    private readonly int CharacterWindowEndPositionInText =&gt;        _characterWindowStartPositionInText + _characterWindow.Count;    private readonly bool PositionIsWithinWindow(int position)    {        return position &gt;= _characterWindowStartPositionInText &amp;&amp;               position &lt; CharacterWindowEndPositionInText;    }    public void Reset(int position)    {        _positionInText = Math.Min(position, _textEnd);        if (PositionIsWithinWindow(_positionInText))        {            return;        }        ReadChunkAt(_positionInText);    }    public readonly bool IsReallyAtEnd()    {        return Position &gt;= _textEnd;    }    public void AdvanceChar(int count)    {        _positionInText += count;    }    public char PeekChar()    {        if (IsReallyAtEnd())        {            return InvalidCharacter;        }        var position = _positionInText;        if (!PositionIsWithinWindow(position))        {            ReadChunkAt(position);        }        return _characterWindow.Array![position - _characterWindowStartPositionInText];    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/github.com\/Asaicraft\/Akbura\/blob\/master\/Akbura.Generator\/Language\/SlidingTextWindow.cs\" rel=\"noopener noreferrer nofollow\">TextWindow<\/a>, \u043d\u043e \u044d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u044b\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043f\u043e \u0441\u0443\u0442\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0434\u0438 \u044d\u0442\u043e\u0433\u043e, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 API \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u043b\u044e\u0448\u043a\u0438.<\/p>\n<h2>\u0418\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a<\/h2>\n<p>\u0412 C# \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0430\u0437\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"cs\">var a = \"Hello\";var b = \"Hello\";Console.WriteLine($\"Is same object? {object.ReferenceEquals(a, b)}\");<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 true, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 intern pool. CLR \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a \u0438 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.<\/p>\n<p>\u041d\u043e \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0430\u0440\u0441\u0438\u043c, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0443\u0436\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0442\u043e \u043f\u0440\u0438 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 string \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c.<\/p>\n<pre><code class=\"css\">button {    color: red;}button {    background: red;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c button \u0438 red \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u0415\u0441\u043b\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043b\u0438\u0448\u043d\u044e\u044e \u043f\u0430\u043c\u044f\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 <a href=\"https:\/\/github.com\/Asaicraft\/Akbura\/blob\/master\/Akbura.Generator\/Language\/SlidingTextWindow.cs\" rel=\"noopener noreferrer nofollow\">SlidingTextWindow<\/a>(\u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u043f\u0440\u0438\u044f\u0442\u043d\u0430\u044f \u043f\u043b\u044e\u0448\u043a\u0430) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0442\u0440\u043e\u043a. \u041e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u044d\u0448: \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0430\u0441\u044c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439.<\/p>\n<pre><code class=\"cs\">internal struct SlidingTextWindow{    private readonly StringTable _strings;    public SlidingTextWindow(SourceText text)    {        this.Text = text;        _textEnd = text.Length;        _strings = StringTable.GetInstance();        _characterWindow = new ArraySegment&lt;char&gt;(s_windowPool.Allocate());        \/\/ Read the first chunk of the file into the character window.        this.ReadChunkAt(0);    }    public readonly string Intern(StringBuilder text)    {        return _strings.Add(text);    }    public readonly string Intern(char[] array, int start, int length)        =&gt; Intern(array.AsSpan(start, length));    public readonly string Intern(ReadOnlySpan&lt;char&gt; chars)        =&gt; _strings.Add(chars);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 <a href=\"https:\/\/learn.microsoft.com\/en-us\/dotnet\/api\/system.string.intern?view=net-10.0#system-string-intern(system-string)\" rel=\"noopener noreferrer nofollow\">string.Intern<\/a>, \u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 StringTable. \u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430: \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0436\u0438\u0432\u0451\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0443\u0436\u0435\u043d SlidingTextWindow, \u0438 \u043d\u0435 \u0437\u0430\u0433\u0440\u044f\u0437\u043d\u044f\u0435\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 intern pool \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b, \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b. \u0422\u0430\u043a \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0443\u0436\u0435 \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0438 \u043f\u0443\u043d\u043a\u0442\u0443\u0430\u0446\u0438\u044f \u043a\u0441\u0442\u0430\u0442\u0438 \u0442\u043e\u0436\u0435.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 <a href=\"https:\/\/github.com\/Asaicraft\/Akbura\/blob\/master\/Akbura.Generator\/StringTable.cs\" rel=\"noopener noreferrer nofollow\">StringTable<\/a><\/p>\n<p><a href=\"https:\/\/github.com\/Asaicraft\/Akbura\/blob\/master\/Akbura.Generator\/StringTable.cs\" rel=\"noopener noreferrer nofollow\">StringTable<\/a> \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u043c\u0435\u043d\u0430 <code>string.Intern<\/code>, \u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 lossy cache \u0441\u0442\u0440\u043e\u043a. \u041e\u043d \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0435\u0447\u043d\u043e \u0438 \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a. \u0415\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435: \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.<\/p>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 <code>StringTable<\/code> \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0443\u0440\u043e\u0432\u043d\u044f \u043a\u044d\u0448\u0430: \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 L1-\u043a\u044d\u0448 \u0438 \u043e\u0431\u0449\u0438\u0439 shared L2-\u043a\u044d\u0448.<\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u0449\u0435\u0442\u0441\u044f \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435. \u042d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c: \u0438\u043d\u0434\u0435\u043a\u0441 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u0445\u0435\u0448\u0430, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c.<\/p>\n<pre><code class=\"cs\">private static int LocalIdxFromHash(int hash){    return hash &amp; LocalSizeMask;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>\u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c hash =&gt; \u0432\u0437\u044f\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043d\u0434\u0435\u043a\u0441 =&gt; \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u0437\u0430\u043f\u0438\u0441\u044c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0432\u043f\u0430\u043b\u0430 \u043f\u043e \u0445\u0435\u0448\u0443 \u0438 \u0442\u0435\u043a\u0441\u0442\u0443, <code>StringTable<\/code> \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>string<\/code>.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432 L1-\u043a\u044d\u0448\u0435 \u043f\u0440\u043e\u043c\u0430\u0445, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0438\u0439 shared L2-\u043a\u044d\u0448:<\/p>\n<pre><code class=\"cs\">private static readonly SegmentedArray&lt;Entry&gt; s_sharedTable = new(SharedSize);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>L2-\u043a\u044d\u0448 \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 <code>StringTable<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0441\u0442\u0440\u043e\u043a\u0443 <code>button<\/code>, \u0434\u0440\u0443\u0433\u043e\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 shared-\u043a\u044d\u0448.<\/p>\n<p>\u041f\u043e\u0438\u0441\u043a \u0432 L2 \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0422\u0430\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 bucket, \u0430 \u043e\u0431\u0445\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>quadratic probing<\/code>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 quadratic probing?<\/summary>\n<div class=\"spoiler__content\">\n<p> Quadratic probing \u2014 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0431\u0445\u043e\u0434\u0430 bucket \u0432 hash table \u043f\u0440\u0438 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044f\u0445. \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0432\u0430\u044f \u044f\u0447\u0435\u0439\u043a\u0430 \u0437\u0430\u043d\u044f\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043f\u043e \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438: 0, 1, 3, 6, 10 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0422\u0430\u043a\u043e\u0439 \u043e\u0431\u0445\u043e\u0434 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0437\u0430\u043c\u0435\u043d\u044b \u043f\u043e bucket. <\/p>\n<\/div>\n<\/details>\n<pre><code class=\"cs\">for (var i = 1; i &lt; SharedBucketSize + 1; i++){    e = arr[idx].Text;    var hash = arr[idx].HashCode;    if (e != null)    {        if (hash == hashCode &amp;&amp; TextEquals(e, chars))        {            break;        }        e = null;    }    else    {        break;    }    idx = (idx + i) &amp; SharedSizeMask;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e L2-\u043a\u044d\u0448 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u044f\u0436\u0435\u043b\u0435\u0435, \u0447\u0435\u043c L1:<\/p>\n<ol>\n<li>\n<p>\u043e\u043d \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 <code>StringTable<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u043e\u043d \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f bucket;<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>Volatile.Write<\/code>;<\/p>\n<\/li>\n<li>\n<p>\u0434\u043b\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>Interlocked.Increment<\/code>.<\/p>\n<\/li>\n<\/ol>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0430\u0448\u043b\u0430\u0441\u044c \u0432 shared-\u043a\u044d\u0448\u0435, \u043e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 L1-\u043a\u044d\u0448. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0440\u043e\u043a\u0435 \u0443\u0436\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u043f\u0443\u0442\u0438.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u043d\u0438 \u0432 L1, \u043d\u0438 \u0432 L2, \u043e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 <code>ToString()<\/code> \u0438\u043b\u0438 <code>Substring()<\/code>, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u0430 \u043a\u044d\u0448\u0430.<\/p>\n<h3>\u0417\u0430\u043c\u0435\u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 shared-\u043a\u044d\u0448\u0435<\/h3>\n<p>Shared-\u043a\u044d\u0448 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443. \u041f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043a\u043e\u0434 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0432 bucket:<\/p>\n<pre><code class=\"cs\">for (var i = 1; i &lt; SharedBucketSize + 1; i++){    if (arr[curIdx].Text == null)    {        idx = curIdx;        goto foundIdx;    }    curIdx = (curIdx + i) &amp; SharedSizeMask;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u043d\u0435\u0442, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 bucket \u0438 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439.<\/p>\n<p>\u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0435\u0448\u0451\u0432\u044b\u0439 \u043f\u0441\u0435\u0432\u0434\u043e\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c. \u0421\u0447\u0451\u0442\u0447\u0438\u043a \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <code>Guid.NewGuid().GetHashCode()<\/code>:<\/p>\n<pre><code class=\"cs\">private int _localRandom = Guid.NewGuid().GetHashCode();private static int s_sharedRandom = Guid.NewGuid().GetHashCode();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0422\u0430\u043a\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043d\u0435 \u043f\u043e\u0445\u043e\u0436 \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 <code>Random.Next()<\/code>, \u043d\u043e \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432 bucket \u044d\u0442\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<pre><code class=\"cs\">var i1 = LocalNextRandom() &amp; SharedBucketSizeMask;idx = (idx + ((i1 * i1 + i1) \/ 2)) &amp; SharedSizeMask;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>LocalNextRandom()<\/code> \u0434\u0430\u0451\u0442 \u043c\u0435\u043d\u044f\u044e\u0449\u0435\u0435\u0441\u044f \u0447\u0438\u0441\u043b\u043e, \u0430 <code>&amp; SharedBucketSizeMask<\/code> \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u0435\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u043c bucket. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u0430 \u0436\u0435 \u0444\u043e\u0440\u043c\u0443\u043b\u0430, \u0447\u0442\u043e \u0438 \u0432 quadratic probing:<\/p>\n<pre><code>(n\u00b2 + n) \/ 2<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a \u0437\u0430\u043c\u0435\u043d\u044b \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u043e \u0440\u0430\u0437\u043d\u044b\u043c \u043f\u043e\u0437\u0438\u0446\u0438\u044f\u043c bucket, \u0430 \u043a\u044d\u0448 \u043d\u0435 \u0432\u044b\u0442\u0435\u0441\u043d\u044f\u0435\u0442 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u044f\u0447\u0435\u0439\u043a\u0443.<\/p>\n<h3>\u041a\u043e\u0440\u043e\u0442\u043a\u0438\u0439 \u0438\u0442\u043e\u0433<\/h3>\n<p>L1-\u043a\u044d\u0448 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430 <code>StringTable<\/code>.<\/p>\n<p>L2-\u043a\u044d\u0448 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u0430\u043c\u0438 <code>StringTable<\/code>.<\/p>\n<p>\u041e\u0431\u0430 \u0443\u0440\u043e\u0432\u043d\u044f \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f lossy cache. \u0421\u0442\u0440\u043e\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0442\u0435\u0441\u043d\u0435\u043d\u0430, \u0438 \u044d\u0442\u043e \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e. \u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043e\u0431\u044b\u0447\u043d\u043e \u0435\u0441\u0442\u044c \u0432\u044b\u0441\u043e\u043a\u0430\u044f \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445: \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b, \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0438 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0436\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u044b\u0439 \u043a\u044d\u0448 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u044b\u0445 \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0439.<\/p>\n<h2>\u0414\u0435\u043b\u0430\u0435\u043c Lexer<\/h2>\n<p>\u0412\u043e \u043c\u043d\u043e\u0433\u0438\u0445 \u0441\u0442\u0430\u0442\u044c\u044f\u0445 \u043f\u0440\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u044b \u0446\u0435\u043f\u043e\u0447\u043a\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>Tokenizer =&gt; Parser<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u0435\u0449\u0451 \u043f\u0438\u0448\u0443\u0442:<\/p>\n<pre><code>Tokenizer =&gt; Lexer =&gt; Parser<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0432 Roslyn-\u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0435 \u0442\u0430\u043a\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0435. \u0422\u0443\u0442 \u0432\u0430\u0436\u043d\u043e \u0443\u0442\u043e\u0447\u043d\u0438\u0442\u044c: \u0441\u043b\u043e\u0432\u0430 <code>tokenizer<\/code> \u0438 <code>lexer<\/code> \u0447\u0430\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043f\u043e\u0447\u0442\u0438 \u043a\u0430\u043a \u0441\u0438\u043d\u043e\u043d\u0438\u043c\u044b. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u043d\u0435 \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0430. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0438\u0434\u0435\u0435 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0441\u043b\u043e\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0436\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430 \u043a\u0443\u0441\u043a\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u043a\u0442\u043e-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u0442\u0438 \u043a\u0443\u0441\u043a\u0438 \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b.<\/p>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u044b\u0439 \u0441\u043b\u043e\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0431\u044b \u043b\u0438\u0448\u043d\u044e\u044e \u0440\u0430\u0431\u043e\u0442\u0443. \u041c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0435\u0434\u0438\u043d\u0438\u0446\u0430 green tree \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u00ab\u0442\u0438\u043f \u0442\u043e\u043a\u0435\u043d\u0430 \u0438 \u0442\u0435\u043a\u0441\u0442\u00bb, \u0430 <code>GreenSyntaxToken<\/code>. \u041e\u043d \u0443\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c <code>leading trivia<\/code>, <code>trailing trivia<\/code>, \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432, \u0435\u0449\u0451 \u0438 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0435\u0441\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 tokenizer, \u0442\u043e \u043e\u043d, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e, \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435:<\/p>\n<pre><code>TokenKind + text + position<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u044d\u0442\u043e \u0432:<\/p>\n<pre><code>GreenSyntaxToken    leading trivia    kind    value    trailing trivia    diagnostics<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043b\u0438\u0448\u043d\u0438\u0439 \u044d\u0442\u0430\u043f:<\/p>\n<pre><code>SourceText    \u2193Tokenizer    \u2193Intermediate token    \u2193GreenSyntaxToken    \u2193Parser<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u0440\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u044b \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0442. \u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u0438 \u0432 Roslyn, lexer \u0441\u0440\u0430\u0437\u0443 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u044b, \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0438\u044f \u0434\u0435\u0440\u0435\u0432\u0430.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 lexer \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0436\u0435\u0442 \u0442\u0435\u043a\u0441\u0442<\/h3>\n<p>\u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0441\u0438\u043c\u0432\u043e\u043b \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0439 \u0441\u043c\u044b\u0441\u043b \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u043c\u0435\u0441\u0442\u0430, \u0433\u0434\u0435 \u043e\u043d \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0441\u044f. \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"cs\">+ \/\/ \u044d\u0442\u043e PlusToken\"asdas + sadas d\"\/\/ \u044d\u0442\u043e \u043e\u0434\u0438\u043d StringLiteralToken;\/\/ \u0437\u043d\u0430\u043a + \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u043e\u043a\u0438 \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0438\u043c\u0432\u043e\u043b <code>&lt;<\/code> \u0442\u043e\u0436\u0435 \u0445\u043e\u0440\u043e\u0448\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"cs\">&lt;      \/\/ LessThanToken&lt;=     \/\/ LessEqualsToken&lt;\/div&gt; \/\/ LessSlashToken, IdentifierToken, GreaterThanToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 Akbura \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u044f \u0435\u0449\u0451 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u044f\u0437\u044b\u043a\u0430 \u043c\u043e\u0433\u0443\u0442 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0442\u044c\u0441\u044f \u0443\u0447\u0430\u0441\u0442\u043a\u0438 C#-\u043a\u043e\u0434\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 lexer \u0434\u043e\u043b\u0436\u0435\u043d \u0443\u043c\u0435\u0442\u044c \u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<h3>LexerMode<\/h3>\n<p>\u0412 \u043c\u043e\u0451\u043c lexer \u0435\u0441\u0442\u044c <code>LexerMode<\/code>:<\/p>\n<pre><code class=\"cs\">internal enum LexerMode{    TopLevel = 0,    InInlineExpression = 1 &lt;&lt; 0,    InExpressionUntilSemicolon = 1 &lt;&lt; 1,    InExpressionUntilComma = 1 &lt;&lt; 2,    InArgumentExpression = 1 &lt;&lt; 3,    InMarkup = 1 &lt;&lt; 4,    InTypeName = 1 &lt;&lt; 5,    InAkcss = 1 &lt;&lt; 6,    InCSharpParameterList = 1 &lt;&lt; 7,    InCSharpArgumentList = 1 &lt;&lt; 8,}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0434\u0435\u044f \u0442\u0430\u043a\u0430\u044f: parser \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u0442\u044c lexer \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0443\u0447\u0430\u0441\u0442\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0435 \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435, \u0430 \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>TopLevel    \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c \u044f\u0437\u044b\u043a\u0430 AkburaInAkcss    \u0440\u0435\u0436\u0438\u043c \u0432\u043d\u0443\u0442\u0440\u0438 akcss-\u0431\u043b\u043e\u043a\u0430InInlineExpression    C#-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043e }InExpressionUntilSemicolon    C#-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043e ;InExpressionUntilComma    C#-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0434\u043e ,InArgumentExpression    C#-\u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0434\u043e , \u0438\u043b\u0438 )InTypeName    C#-\u0442\u0438\u043fInCSharpParameterList    C#-\u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432InCSharpArgumentList    C#-\u0441\u043f\u0438\u0441\u043e\u043a \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0443\u0436\u0435 \u043d\u0435 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 tokenizer. Lexer \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0434\u0451\u0442 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u0438 \u043e\u0442\u0434\u0430\u0451\u0442 \u043e\u0447\u0435\u0440\u0435\u0434\u043d\u043e\u0439 \u043a\u0443\u0441\u043e\u043a. \u041e\u043d \u0437\u043d\u0430\u0435\u0442, \u0432 \u043a\u0430\u043a\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f, \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0442\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">public GreenSyntaxToken Lex(LexerMode mode){    _mode = mode;    if (mode != LexerMode.TopLevel &amp;&amp; mode != LexerMode.InAkcss)    {        var tokenInfo = mode switch        {            LexerMode.InInlineExpression =&gt; ParseInlineExpression(),            LexerMode.InExpressionUntilSemicolon =&gt; ParseExpressionUntilSemicolon(),            LexerMode.InExpressionUntilComma =&gt; ParseExpressionUntilComma(),            LexerMode.InArgumentExpression =&gt; ParseArgumentExpression(),            LexerMode.InTypeName =&gt; ParseTypeName(),            LexerMode.InCSharpParameterList =&gt; ParseCSharpParameterList(),            LexerMode.InCSharpArgumentList =&gt; ParseCSharpArgumentList(),            _ =&gt; default        };        return CreateToken(in tokenInfo, null, null, null);    }    if (TryQuickScanToken(mode, out var quickToken))    {        return quickToken;    }    return ParseNextToken();}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u043e \u043e\u0431\u0449\u0443\u044e \u0441\u0445\u0435\u043c\u0443:<\/p>\n<pre><code>\u0435\u0441\u043b\u0438 \u0440\u0435\u0436\u0438\u043c C#-\u0432\u0441\u0442\u0430\u0432\u043a\u0438    \u0447\u0438\u0442\u0430\u0435\u043c \u043a\u0443\u0441\u043e\u043a \u043a\u0430\u043a C# \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c CSharpRawToken\u0438\u043d\u0430\u0447\u0435    \u043f\u0440\u043e\u0431\u0443\u0435\u043c quick scanner\u0435\u0441\u043b\u0438 quick scanner \u043d\u0435 \u0441\u043f\u0440\u0430\u0432\u0438\u043b\u0441\u044f    \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u043e\u043b\u043d\u044b\u0439 lexer<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u0443\u0442\u044c: ParseNextToken<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 lexer \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u0432 <code>TopLevel<\/code> \u0438\u043b\u0438 <code>InAkcss<\/code>, \u043e\u043d \u0447\u0438\u0442\u0430\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d Akbura. \u0414\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0447\u0435\u0440\u0435\u0437 <code>ParseNextToken<\/code>:<\/p>\n<pre><code class=\"cs\">private GreenSyntaxToken ParseNextToken(){    var tokenInfo = ParseNextTokenInfo(        out var leading,        out var trailing,        out var errors);    return CreateToken(in tokenInfo, leading, trailing, errors);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0432\u043d\u0443\u0442\u0440\u0438 <code>ParseNextTokenInfo<\/code> \u0442\u043e\u043a\u0435\u043d \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0442\u0440\u0451\u0445 \u0447\u0430\u0441\u0442\u0435\u0439:<\/p>\n<pre><code class=\"cs\">private TokenInfo ParseNextTokenInfo(    out GreenSyntaxListBuilder leading,    out GreenSyntaxListBuilder trailing,    out ImmutableArray&lt;AkburaDiagnostic&gt; errors){    _leadingTriviaCache.Clear();    LexSyntaxTrivia(isTrailing: false, triviaList: ref _leadingTriviaCache);    leading = _leadingTriviaCache;    TokenInfo tokenInfo = default;    Start();    ParseSyntaxToken(ref tokenInfo);    errors = GetErrors();    _trailingTriviaCache.Clear();    LexSyntaxTrivia(isTrailing: true, triviaList: ref _trailingTriviaCache);    trailing = _trailingTriviaCache;    return tokenInfo;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 lexer \u0447\u0438\u0442\u0430\u0435\u0442 <code>leading trivia<\/code>, \u043f\u043e\u0442\u043e\u043c \u0441\u0430\u043c \u0442\u043e\u043a\u0435\u043d, \u043f\u043e\u0442\u043e\u043c <code>trailing trivia<\/code>.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"css\">\/* comment *\/ button<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u043f\u0435\u0440\u0435\u0434 <code>button<\/code> \u043d\u0435 \u0438\u0441\u0447\u0435\u0437\u0430\u0435\u0442. \u041e\u043d \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e <code>leading trivia<\/code> \u0442\u043e\u043a\u0435\u043d\u0430 <code>button<\/code>. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u043e \u0434\u043b\u044f Roslyn-\u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0434\u0435\u0440\u0435\u0432\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u0447\u043d\u043e: \u043f\u0440\u043e\u0431\u0435\u043b\u044b, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0441\u0442\u0440\u043e\u043a \u0438 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442\u044c.<\/p>\n<h3>Trivia<\/h3>\n<p>Trivia \u2014 \u044d\u0442\u043e \u0442\u043e, \u0447\u0442\u043e \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u043e\u043c, \u043d\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u0438\u0442 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c\u0443 \u0442\u0435\u043a\u0441\u0442\u0443:<\/p>\n<pre><code>\u043f\u0440\u043e\u0431\u0435\u043b\u044b\u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0441\u0442\u0440\u043e\u043a\u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438\u043c\u043d\u043e\u0433\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 lexer \u044d\u0442\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e:<\/p>\n<pre><code class=\"cs\">private void LexSyntaxTrivia(bool isTrailing, ref GreenSyntaxListBuilder triviaList){    while (true)    {        Start();        var character = TextWindow.PeekChar();        if (character == SlidingTextWindow.InvalidCharacter)        {            return;        }        if (character &gt; 127)        {            if (SyntaxFacts.IsWhitespace(character))            {                character = ' ';            }            else if (SyntaxFacts.IsNewLine(character))            {                character = '\\n';            }        }        switch (character)        {            case ' ':            case '\\t':            case '\\v':            case '\\f':            case '\\u001A':                AddTrivia(ScanWhitespace(), ref triviaList);                break;            case '\\r':            case '\\n':                var eol = ScanEndOfLine();                AddTrivia(eol, ref triviaList);                if (isTrailing)                {                    return;                }                break;            case '\/':            {                var next = TextWindow.PeekChar(1);                if (next == '\/')                {                    LexSingleLineComment(ref triviaList);                    break;                }                if (next == '*')                {                    LexMultiLineComment(ref triviaList);                    break;                }                return;            }            default:                return;        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e: <code>trailing trivia<\/code> \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438. \u0422\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u0435\u043b \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u043a\u0435\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c trailing trivia, \u043d\u043e \u0435\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b\u0441\u044f \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0443\u0436\u0435 \u043d\u0430\u0447\u043d\u0451\u0442 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443.<\/p>\n<p>\u041f\u0440\u043e\u0431\u0435\u043b\u044b \u0442\u043e\u0436\u0435 \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b. \u041e\u0434\u0438\u043d \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u0440\u043e\u0431\u0435\u043b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0433\u043e\u0442\u043e\u0432\u0430\u044f trivia:<\/p>\n<pre><code class=\"cs\">if (this.CurrentLexemeWidth == 1 &amp;&amp; onlySpaces){    return GreenSyntaxFactory.Space;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u043c\u043e\u0433\u0443\u0442 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u044d\u0448:<\/p>\n<pre><code class=\"cs\">if (width &lt; MaxCachedTokenSize){    return _cache.LookupWhitespaceTrivia(        TextWindow,        this.LexemeStartPosition,        hashCode);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043c\u0435\u043b\u043e\u0447\u044c, \u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u043c\u0435\u043b\u043e\u0447\u0438 \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b. \u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u043e\u0432 \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u043e\u0432 \u0441\u0442\u0440\u043e\u043a \u043c\u043d\u043e\u0433\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0436\u0435 trivia \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e.<\/p>\n<h3>ParseSyntaxToken<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 leading trivia lexer \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>ParseSyntaxToken<\/code>. \u042d\u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u0435\u0442\u043e\u0434 \u0434\u043b\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 Akbura. \u041e\u043d \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<p>\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">private void ParseSyntaxToken(ref TokenInfo info){    var character = TextWindow.PeekChar();    switch (character)    {        case '+':            TextWindow.AdvanceChar();            info.Kind = SyntaxKind.PlusToken;            return;        case '&lt;':            TextWindow.AdvanceChar();            if (TextWindow.TryAdvance('\/'))            {                info.Kind = SyntaxKind.LessSlashToken;                return;            }            if (TextWindow.TryAdvance('='))            {                info.Kind = SyntaxKind.LessEqualsToken;                return;            }            info.Kind = SyntaxKind.LessThanToken;            return;        case &gt;= '0' and &lt;= '9':            ScanNumericLiteral(ref info);            return;        case '_':        case &gt;= 'a' and &lt;= 'z':        case &gt;= 'A' and &lt;= 'Z':            ScanIdentifierOrKeyword(ref info);            return;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u043f\u043e\u0447\u0435\u043c\u0443 lexer \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u0441\u0435\u043c \u00ab\u0442\u0443\u043f\u044b\u043c\u00bb. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0438\u043c\u0432\u043e\u043b <code>&lt;<\/code> \u043c\u043e\u0436\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0435\u0449\u0435\u0439:<\/p>\n<pre><code>&lt;  =&gt; LessThanToken&lt;= =&gt; LessEqualsToken&lt;\/ =&gt; LessSlashToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0441 <code>=<\/code>:<\/p>\n<pre><code>=  =&gt; EqualsToken== =&gt; EqualsEqualsToken=&gt; =&gt; ArrowToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0441 \u0442\u043e\u0447\u043a\u043e\u0439:<\/p>\n<pre><code>.  =&gt; DotToken.. =&gt; DoubleDotToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Lexer \u043e\u0431\u044f\u0437\u0430\u043d \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0432\u043f\u0435\u0440\u0451\u0434, \u0438\u043d\u0430\u0447\u0435 \u043e\u043d \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u043d\u0438\u0446\u0443 \u0442\u043e\u043a\u0435\u043d\u0430.<\/p>\n<h3>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430<\/h3>\n<p>\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0435\u0449\u044c\u044e, \u043d\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0435\u0433\u043e \u043b\u0443\u0447\u0448\u0435 \u0447\u0438\u0442\u0430\u0442\u044c \u0432 \u0434\u0432\u0430 \u044d\u0442\u0430\u043f\u0430: \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0447\u0430\u0441\u0442\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u0438 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432.<\/p>\n<pre><code class=\"cs\">private bool TryParseIdentifier(ref TokenInfo token){    if (TryParseIdentifier_Fast(ref token))    {        return true;    }    return TryParseIdentifier_Slow(ref token);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 ASCII-\u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432:<\/p>\n<pre><code>[_a-zA-Z][_a-zA-Z0-9]*<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043d \u0447\u0438\u0442\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 <code>CurrentWindowSpan<\/code>, \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0438 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u0435\u043b\u044f\u0445. \u0415\u0441\u043b\u0438 \u0432\u0441\u0451 \u0445\u043e\u0440\u043e\u0448\u043e, \u0442\u0435\u043a\u0441\u0442 \u0438\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f:<\/p>\n<pre><code class=\"cs\">var text = TextWindow.Intern(span[..length]);token.Text = text;token.Kind = SyntaxKind.IdentifierToken;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0435, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 Unicode-\u0441\u0438\u043c\u0432\u043e\u043b, escape sequence \u0438\u043b\u0438 surrogate pair, \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>false<\/code>, \u0438 lexer \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442 \u043a \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438.<\/p>\n<p>\u041c\u0435\u0434\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u0442 \u0431\u043e\u043b\u044c\u0448\u0435:<\/p>\n<pre><code>Unicode lettersUnicode escape sequences: \\uXXXX, \\UXXXXXXXXsurrogate pairsformatting charactersescaped identifier sequences<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u0442\u0443\u0442 \u0441\u043d\u043e\u0432\u0430 \u0432\u0438\u0434\u043d\u0430 \u0442\u0430 \u0436\u0435 \u0444\u0438\u043b\u043e\u0441\u043e\u0444\u0438\u044f:<\/p>\n<pre><code>\u0447\u0430\u0441\u0442\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u2014 \u0431\u044b\u0441\u0442\u0440\u043e\u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u2014 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u043d\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0442\u0435\u043d\u0438\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 lexer \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043b\u0438 \u043e\u043d \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c:<\/p>\n<pre><code class=\"cs\">if (_cache.TryGetKeywordKind(info.Text, out var keywordKind)){    if (SyntaxFacts.IsContextualKeyword(keywordKind))    {        info.Kind = SyntaxKind.IdentifierToken;        info.ContextualKind = keywordKind;    }    else    {        info.Kind = keywordKind;        info.ContextualKind = keywordKind;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u0432\u0430\u0436\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 hard keyword \u043e\u0442 contextual keyword.<\/p>\n<p>Hard keyword \u0441\u0440\u0430\u0437\u0443 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c. \u0410 contextual keyword \u043b\u0435\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f <code>IdentifierToken<\/code>, \u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0441\u0451\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 <code>ContextualKind<\/code>. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043b\u043e\u0432\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u043c\u0435\u0441\u0442\u0430 \u0432 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0435. Parser \u043f\u043e\u0442\u043e\u043c \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0448\u0438\u0442\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a \u043a\u043b\u044e\u0447\u0435\u0432\u043e\u0435 \u0441\u043b\u043e\u0432\u043e \u0438\u043b\u0438 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440.<\/p>\n<h3>\u0427\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b<\/h3>\n<p>\u0427\u0438\u0441\u043b\u0430 \u2014 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c lexer. \u041d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0432\u0437\u0433\u043b\u044f\u0434 \u0447\u0438\u0441\u043b\u043e \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0446\u0438\u0444\u0440 \u043f\u043e\u0434\u0440\u044f\u0434. \u041d\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432:<\/p>\n<pre><code>1231_000_0000xFF0b1010123u123L123UL1.51e101.5f1.5d1.5m<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u0435\u0442\u043e\u0434 <code>ScanNumericLiteral<\/code> \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442, \u043a\u0430\u043a\u043e\u0439 \u044d\u0442\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b:<\/p>\n<pre><code>decimalhexadecimalbinaryreal numberinteger with suffixfloating-point with suffix<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 <code>0x<\/code> \u0438\u043b\u0438 <code>0X<\/code>, \u043e\u043d\u043e \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a hex:<\/p>\n<pre><code class=\"cs\">if (character == '0'){    character = TextWindow.PeekChar(1);    if (character == 'x' || character == 'X')    {        TextWindow.AdvanceChar(2);        isHex = true;    }    else if (character == 'b' || character == 'B')    {        TextWindow.AdvanceChar(2);        isBinary = true;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0434\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u044b\u0445 \u0447\u0438\u0441\u0435\u043b lexer \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0434\u0440\u043e\u0431\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c:<\/p>\n<pre><code class=\"cs\">if ((character = TextWindow.PeekChar()) == '.'){    var ch2 = TextWindow.PeekChar(1);    if (ch2 &gt;= '0' &amp;&amp; ch2 &lt;= '9')    {        hasDecimal = true;        _builder.Append(character);        TextWindow.AdvanceChar();        ScanNumericLiteralSingleInteger(            ref underscoreInWrongPlace,            ref usedUnderscore,            ref firstCharWasUnderscore,            isHex: false,            isBinary: false);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c <code>123.332<\/code> \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c <code>NumericLiteralToken<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u043e\u0447\u043a\u0430 \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0446\u0438\u0444\u0440\u0430\u043c\u0438 \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0447\u0430\u0441\u0442\u044c\u044e \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0433\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u0430.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 lexer \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 exponent:<\/p>\n<pre><code>1e101E-101.5e+3<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u044b:<\/p>\n<pre><code>f \/ F =&gt; floatD \/ d =&gt; doublem \/ M =&gt; decimalu \/ U =&gt; uint \u0438\u043b\u0438 ulongL \/ l =&gt; long \u0438\u043b\u0438 ulong<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e lexer \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u0447\u0438\u0441\u043b\u0430, \u0430 \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0435\u0433\u043e \u0442\u0438\u043f \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cs\">info.Kind = SyntaxKind.NumericLiteralToken;info.Text = this.GetInternedLexemeText();var valueText = TextWindow.Intern(_builder);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0446\u0435\u043b\u044b\u0445 \u0447\u0438\u0441\u0435\u043b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>UInt64.TryParse<\/code> \u0438\u043b\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 binary-\u0447\u0438\u0441\u0435\u043b, \u0430 \u043f\u043e\u0442\u043e\u043c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u0442\u0438\u043f:<\/p>\n<pre><code>intuintlongulong<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u0431\u0435\u0437 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u0430 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f \u0432 <code>int<\/code>, \u043e\u043d\u043e \u0441\u0442\u0430\u043d\u0435\u0442 <code>System_Int32<\/code>. \u0415\u0441\u043b\u0438 \u043d\u0435 \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u0442\u0441\u044f, lexer \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u0442 <code>uint<\/code>, \u043f\u043e\u0442\u043e\u043c <code>long<\/code>, \u043f\u043e\u0442\u043e\u043c <code>ulong<\/code>.<\/p>\n<p>\u0414\u043b\u044f <code>float<\/code> \u0438 <code>double<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>RealParser<\/code> (\u044d\u0445\u0445 \u0432\u0441\u043f\u043e\u043c\u043d\u0438\u043b \u0448\u043a\u043e\u043b\u044c\u043d\u044b\u0435 \u0433\u043e\u0434\u0430 \u043a\u0430\u043a \u043f\u0438\u0441\u0430\u043b \u043d\u0430 Pascal Abc.Net):<\/p>\n<pre><code class=\"cs\">private float GetValueSingle(string text){    if (!RealParser.TryParseFloat(text, out var result))    {        this.AddError(ErrorCodes.ERR_FloatOverflow, [\"float\"]);    }    return result;}private double GetValueDouble(string text){    if (!RealParser.TryParseDouble(text, out var result))    {        this.AddError(ErrorCodes.ERR_FloatOverflow, [\"double\"]);    }    return result;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>RealParser<\/code> \u043d\u0443\u0436\u0435\u043d \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u0432\u044b\u0437\u043e\u0432\u0430 <code>float.Parse<\/code> \u0438\u043b\u0438 <code>double.Parse<\/code>. \u041e\u043d \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u0434\u0435\u0441\u044f\u0442\u0438\u0447\u043d\u044b\u0439 floating-point literal \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c\u043e\u0435 IEEE-\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043e\u043a\u0440\u0443\u0433\u043b\u0435\u043d\u0438\u0435 <code>round-to-nearest, ties-to-even<\/code>. \u0422\u0430\u043a\u0436\u0435 \u043e\u043d \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0432\u0435\u0434\u0443\u0449\u0438\u0439 \u0437\u043d\u0430\u043a, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 C# \u0438 \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u044f\u0437\u044b\u043a\u0430\u0445 <code>-1.0<\/code> \u2014 \u044d\u0442\u043e \u043d\u0435 \u043e\u0434\u0438\u043d \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u0442\u043e\u043a\u0435\u043d, \u0430 \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440 unary minus \u043f\u043b\u044e\u0441 \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043b\u0438\u0442\u0435\u0440\u0430\u043b <code>1.0<\/code>.<\/p>\n<p>\u0418 \u044d\u0442\u043e \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: lexer \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u043c\u0435\u043d\u043d\u043e \u043b\u0438\u0442\u0435\u0440\u0430\u043b. \u0417\u043d\u0430\u043a <code>-<\/code> \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u0442\u043e\u043a\u0435\u043d\u043e\u043c, \u0430 \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u0447\u0438\u0441\u043b\u043e \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430 \u0438\u043b\u0438 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438.<\/p>\n<p>\u0414\u043b\u044f <code>decimal<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>decimal.TryParse<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e decimal \u0432 .NET \u2014 \u044d\u0442\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0442\u0438\u043f \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u044f:<\/p>\n<pre><code class=\"cs\">private decimal GetValueDecimal(string text, int start, int end){    if (!decimal.TryParse(        text,        NumberStyles.AllowDecimalPoint | NumberStyles.AllowExponent,        CultureInfo.InvariantCulture,        out var result))    {        this.AddError(start, end - start, ErrorCodes.ERR_FloatOverflow, [\"decimal\"]);    }    return result;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 <code>NumericLiteralToken<\/code> \u0445\u0440\u0430\u043d\u0438\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u043d\u043e \u0438 \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430. \u042d\u0442\u043e \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u043f\u0440\u0438\u0447\u0438\u043d\u0430, \u043f\u043e\u0447\u0435\u043c\u0443 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 tokenizer \u0431\u044b\u043b \u0431\u044b \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u0430\u0431\u044b\u043c \u0441\u043b\u043e\u0435\u043c \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b.<\/p>\n<h3>C#-\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b \u0432\u043d\u0443\u0442\u0440\u0438 Akbura<\/h3>\n<p>\u041e\u0434\u043d\u0430 \u0438\u0437 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 Akbura \u2014 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c C#-\u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u0442\u0438\u043f\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0432\u043e\u0435\u0433\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u0430. \u0412 \u0442\u0430\u043a\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 lexer \u043d\u0435 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0432\u0435\u0441\u044c C# \u0437\u0430\u043d\u043e\u0432\u043e. \u0412\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442 \u0435\u0433\u043e Roslyn.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, inline expression \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0434\u043e <code>}<\/code>:<\/p>\n<pre><code class=\"cs\">private TokenInfo ParseInlineExpression(){    return ParseExpressionUntil('}');}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0434\u043e \u043f\u0435\u0440\u0432\u043e\u0439 <code>}<\/code> \u043d\u0435\u043b\u044c\u0437\u044f. \u0412\u043d\u0443\u0442\u0440\u0438 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0441\u043a\u043e\u0431\u043a\u0438:<\/p>\n<pre><code class=\"cs\">SomeMethod(new { Value = 10 })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 lexer \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u0433\u043b\u0443\u0431\u0438\u043d\u043e\u0439 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code class=\"cs\">var paren = 0;var brace = 0;var bracket = 0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b terminator \u043d\u0430 \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u0433\u043b\u0443\u0431\u0438\u043d\u0435:<\/p>\n<pre><code class=\"cs\">if (character == terminator &amp;&amp; paren == 0 &amp;&amp; brace == 0 &amp;&amp; bracket == 0){    break;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 Roslyn:<\/p>\n<pre><code class=\"cs\">var parsed = CSharpSyntaxFactory.ParseExpression(    expressionText,    0,    options: null,    consumeFullText: true); tokenInfo.CSharpNode = parsed; tokenInfo.CSharpSyntaxKind = parsed.Kind();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0442\u0438\u043f\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>ParseTypeName<\/code>:<\/p>\n<pre><code class=\"cs\">var parsed = CSharpSyntaxFactory.ParseTypeName(    sourceText,    startParse,    options: null,    consumeFullText: false);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432:<\/p>\n<pre><code class=\"cs\">var parsed = CSharpSyntaxFactory.ParseParameterList(    sourceText,    startParse,    options: null,    consumeFullText: false);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432:<\/p>\n<pre><code class=\"cs\">var parsed = CSharpSyntaxFactory.ParseArgumentList(    sourceText,    startParse,    options: null,    consumeFullText: false);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u0440\u0443\u0436\u0443 \u0432\u0441\u0451 \u044d\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d:<\/p>\n<pre><code class=\"cs\">Kind = SyntaxKind.CSharpRawToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0432 <code>CreateToken<\/code> \u0434\u043b\u044f \u0442\u0430\u043a\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u0435\u0441\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0430\u044f \u0432\u0435\u0442\u043a\u0430:<\/p>\n<pre><code class=\"cs\">if (tokenInfo.Kind == SyntaxKind.CSharpRawToken){    AkburaDebug.AssertNotNull(tokenInfo.CSharpNode);    return GreenSyntaxToken.CreateCSharpRawToken(tokenInfo.CSharpNode);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0434\u043b\u044f Akbura \u044d\u0442\u043e \u043e\u0434\u0438\u043d raw-\u0442\u043e\u043a\u0435\u043d, \u043d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u0443\u0436\u0435 \u043b\u0435\u0436\u0438\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 Roslyn C# syntax node. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0438\u0437\u043e\u0431\u0440\u0435\u0442\u0430\u0442\u044c \u0441\u0432\u043e\u0439 C# parser \u0438 \u043d\u0435 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0440\u0443\u043a\u0430\u043c\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c \u0432\u0435\u0441\u044c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441 C#.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 GreenSyntaxToken<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e \u043a\u0430\u043a lexer \u0441\u043e\u0431\u0440\u0430\u043b <code>TokenInfo<\/code>, leading trivia, trailing trivia \u0438 diagnostics, \u043e\u043d \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>CreateToken<\/code>.<\/p>\n<pre><code class=\"cs\">private static GreenSyntaxToken CreateToken(    in TokenInfo tokenInfo,    GreenSyntaxListBuilder? leading,    GreenSyntaxListBuilder? trailing,    ImmutableArray&lt;AkburaDiagnostic&gt;? diagnostics){    var leadingNode = leading?.ToListNode();    var trailingNode = trailing?.ToListNode();    GreenSyntaxToken? token = null;    if (tokenInfo.Kind == SyntaxKind.IdentifierToken)    {        token = GreenSyntaxToken.Identifier(            leadingNode,            tokenInfo.Text!,            trailingNode);    }    else if (tokenInfo.Kind == SyntaxKind.NumericLiteralToken)    {        \/\/ Create typed numeric literal token.    }    else    {        token = GreenSyntaxFactory.Token(            leadingNode,            tokenInfo.Kind,            trailingNode);    }    if (diagnostics?.IsDefaultOrEmpty == false)    {        token = Unsafe.As&lt;GreenSyntaxToken&gt;(token.WithDiagnostics(diagnostics));    }    return token;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u043f\u0443\u043d\u043a\u0442\u0443\u0430\u0446\u0438\u0438 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e <code>SyntaxKind<\/code>. \u0414\u043b\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432 \u043d\u0443\u0436\u0435\u043d \u0442\u0435\u043a\u0441\u0442. \u0414\u043b\u044f \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0445 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432 \u043d\u0443\u0436\u0435\u043d \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435\u043a\u0441\u0442, \u043d\u043e \u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 <code>NumericLiteralToken<\/code> \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u043e-\u0440\u0430\u0437\u043d\u043e\u043c\u0443 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 <code>ValueKind<\/code>:<\/p>\n<pre><code>System_Int32    =&gt; int literalSystem_UInt32   =&gt; uint literalSystem_Int64    =&gt; long literalSystem_UInt64   =&gt; ulong literalSystem_Single   =&gt; float literalSystem_Double   =&gt; double literalSystem_Decimal  =&gt; decimal literal<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0447\u0442\u0435\u043d\u0438\u044f \u0442\u043e\u043a\u0435\u043d\u0430 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u043e\u0448\u0438\u0431\u043a\u0438, \u043e\u043d\u0438 \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u044e\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u043a green token:<\/p>\n<pre><code class=\"cs\">if (diagnostics?.IsDefaultOrEmpty == false){    token = Unsafe.As&lt;GreenSyntaxToken&gt;(token.WithDiagnostics(diagnostics));}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, lexer \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u0438\u043f \u0442\u043e\u043a\u0435\u043d\u0430. \u041e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0434\u0435\u0440\u0435\u0432\u0430.<\/p>\n<h3>\u041e\u0448\u0438\u0431\u043a\u0438 \u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435<\/h3>\n<p>Lexer \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0430\u0434\u0430\u0442\u044c \u043d\u0430 \u043f\u0435\u0440\u0432\u043e\u043c \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u043c \u0441\u0438\u043c\u0432\u043e\u043b\u0435. \u0415\u0441\u043b\u0438 \u043e\u043d \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u0443\u044e \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c, \u043e\u043d \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0438 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<pre><code class=\"cs\">private void ConsumeUnexpected(    ref TokenInfo info,    int startingPosition,    bool isEscaped){    var ch = TextWindow.PeekChar();    if (ch != SlidingTextWindow.InvalidCharacter)    {        TextWindow.AdvanceChar();        if (char.IsHighSurrogate(ch) &amp;&amp; char.IsLowSurrogate(TextWindow.PeekChar()))        {            TextWindow.AdvanceChar();        }    }    info.Text = GetInternedLexemeText();    info.Kind = SyntaxKind.IdentifierToken;    AddError(ErrorCodes.ERR_UnexpectedCharacter, [messageText]);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u0434\u0435\u0442\u0430\u043b\u0435\u0439.<\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, lexer \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b, \u0438\u043d\u0430\u0447\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0446\u0438\u043a\u043b.<\/p>\n<p>\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, \u0435\u0441\u043b\u0438 \u0441\u0438\u043c\u0432\u043e\u043b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u0447\u0430\u043b\u043e\u043c surrogate pair, \u043e\u043d \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u0435\u0442 \u043e\u0431\u0430 <code>char<\/code>, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u0440\u0430\u0437\u043e\u0440\u0432\u0430\u0442\u044c Unicode-\u0441\u0438\u043c\u0432\u043e\u043b \u043f\u043e\u043f\u043e\u043b\u0430\u043c.<\/p>\n<p>\u0412-\u0442\u0440\u0435\u0442\u044c\u0438\u0445, \u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043a diagnostic \u0438 \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442\u0441\u044f \u043a \u0442\u043e\u043a\u0435\u043d\u0443.<\/p>\n<p>\u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u044b \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0430 \u0438 language server. \u0414\u0430\u0436\u0435 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u0439 \u043a\u043e\u0434, parser \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0445\u043e\u0442\u044f \u0431\u044b \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e, \u0447\u0442\u043e\u0431\u044b IDE \u043c\u043e\u0433\u043b\u0430 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0443, \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438 \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443.<\/p>\n<h3>\u0418\u0442\u043e\u0433<\/h3>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 lexer \u0432 Akbura \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0437\u0430\u0434\u0430\u0447:<\/p>\n<pre><code>\u0447\u0438\u0442\u0430\u0435\u0442 leading \u0438 trailing trivia\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0451\u0442 punctuation tokens\u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0438 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 contextual keywords\u0447\u0438\u0442\u0430\u0435\u0442 \u0447\u0438\u0441\u043b\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u0438 \u0441\u0440\u0430\u0437\u0443 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0438\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f\u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 Unicode identifiers \u0438 escape sequences\u0443\u043c\u0435\u0435\u0442 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043c\u0435\u0436\u0434\u0443 LexerMode\u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 C#-\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b Roslyn parser\u0441\u043e\u0437\u0434\u0430\u0451\u0442 GreenSyntaxToken\u043f\u0440\u0438\u043a\u0440\u0435\u043f\u043b\u044f\u0435\u0442 diagnostics\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 quick scanner \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0443\u0442\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043b\u043e\u0439 \u043f\u0440\u043e\u0441\u0442\u044b\u043c tokenizer \u0431\u044b\u043b\u043e \u0431\u044b \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e. Tokenizer \u043e\u0431\u044b\u0447\u043d\u043e \u0430\u0441\u0441\u043e\u0446\u0438\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441 \u043c\u0435\u0445\u0430\u043d\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0440\u0430\u0437\u0431\u0438\u0435\u043d\u0438\u0435\u043c \u0442\u0435\u043a\u0441\u0442\u0430 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b. \u0417\u0434\u0435\u0441\u044c \u0436\u0435 lexer \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u044c\u044e Roslyn-\u043f\u043e\u0434\u043e\u0431\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b: \u043e\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442 trivia, \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442 \u0440\u0435\u0436\u0438\u043c \u0440\u0430\u0437\u0431\u043e\u0440\u0430, \u0441\u043e\u0437\u0434\u0430\u0451\u0442 typed literals, \u0443\u043c\u0435\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 C#-\u0432\u0441\u0442\u0430\u0432\u043a\u0430\u043c\u0438 \u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 green tokens \u0434\u043b\u044f parser.<\/p>\n<p>\u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u0434\u0430\u0447\u0430 lexer \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c <code>SourceText<\/code> \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u043f\u043e\u0442\u043e\u043a \u043a\u0443\u0441\u043e\u0447\u043a\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u0430, \u0430 \u0432 \u043f\u043e\u0442\u043e\u043a \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0445 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 parser \u0443\u0436\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c green tree.<\/p>\n<h2>QuickScanner<\/h2>\n<p>\u041e\u0442\u043b\u0438\u0447\u043d\u043e, \u0432 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u043c \u0440\u043e\u0441\u043b\u0438\u043d\u0435 \u0435\u0441\u0442\u044c \u0435\u0449\u0435 <a href=\"https:\/\/github.com\/dotnet\/roslyn\/blob\/main\/src\/Compilers\/CSharp\/Portable\/Parser\/QuickScanner.cs\" rel=\"noopener noreferrer nofollow\">fast path \u0434\u043b\u044f \u043b\u0435\u043a\u0441\u0435\u0440\u0430<\/a>, \u0440\u043e\u0432\u043d\u043e \u043a\u0430\u043a \u0438 \u0434\u043b\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u0434\u0435\u043b\u0430\u0435\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u044b:<\/p>\n<pre><code>\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c leading trivia\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0430\u043c \u0442\u043e\u043a\u0435\u043d\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c trailing trivia\u0441\u043e\u0437\u0434\u0430\u0442\u044c GreenSyntaxToken\u043f\u0440\u0438\u043a\u0440\u0435\u043f\u0438\u0442\u044c diagnostics, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0435\u0441\u0442\u044c<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0439 \u0438 \u043f\u043e\u043b\u043d\u044b\u0439 \u043f\u0443\u0442\u044c, \u043d\u043e \u043e\u043d \u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0434\u0435\u0448\u0451\u0432\u044b\u0439. \u0412 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u043a\u043e\u0434\u0435 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432: \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b, \u043f\u0440\u043e\u0431\u0435\u043b\u044b, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0441\u0442\u0440\u043e\u043a \u0438 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0443\u043d\u043a\u0442\u0443\u0430\u0446\u0438\u044f.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code class=\"css\">button {    color: red;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u0414\u043b\u044f \u0442\u0430\u043a\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u2014 <code>QuickScanner<\/code>.<\/p>\n<p>\u0412\u0430\u0436\u043d\u043e: <code>QuickScanner<\/code> \u043d\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer. \u041e\u0431\u044b\u0447\u043d\u044b\u0439 lexer \u0432\u0441\u0451 \u0435\u0449\u0451 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u043e\u043c \u0438\u0441\u0442\u0438\u043d\u044b. Quick scanner \u0438\u043c\u0435\u0435\u0442 \u043f\u0440\u0430\u0432\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0438 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438. \u0415\u0441\u043b\u0438 \u043e\u043d \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442 \u0447\u0442\u043e-\u0442\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0435 \u0438\u043b\u0438 \u0441\u043e\u043c\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435, \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>false<\/code>, \u0430 \u0434\u0430\u043b\u044c\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e quick scanner-\u0430 \u0442\u0430\u043a\u043e\u0435:<\/p>\n<pre><code>\u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u2014 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0442\u043e\u043a\u0435\u043d\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0441\u043e\u043c\u043d\u0435\u043d\u0438\u0435 \u2014 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0442\u0440\u043e\u0433\u0430\u0435\u043c \u0438 \u043e\u0442\u0434\u0430\u0451\u043c \u0440\u0430\u0431\u043e\u0442\u0443 \u043e\u0431\u044b\u0447\u043d\u043e\u043c\u0443 lexer<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0432\u0438\u0434\u043d\u043e \u0437\u0434\u0435\u0441\u044c:<\/p>\n<pre><code class=\"cs\">private bool TryQuickScanToken(LexerMode mode, out GreenSyntaxToken token){    var position = TextWindow.Position;    if (TryQuickScanTokenCore(mode, out token))    {        return true;    }    Debug.Assert(        TextWindow.Position == position,        \"Quick scanner fallback must not consume text.\");    token = null!;    return false;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u043d\u0435 \u0441\u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432 \u0442\u0435\u043a\u0441\u0442\u0435 \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0441\u0442\u0430\u0442\u044c\u0441\u044f \u0442\u043e\u0439 \u0436\u0435 \u0441\u0430\u043c\u043e\u0439. \u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e. Quick scanner \u043c\u043e\u0436\u0435\u0442 \u043e\u0442\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0440\u0430\u0431\u043e\u0442\u044b, \u043d\u043e \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 lexer-\u0430.<\/p>\n<h2>\u0421\u0442\u0430\u0440\u044b\u0439 QuickScanner<\/h2>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0441\u0442\u0430\u0440\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 quick scanner-\u0430. \u0415\u0433\u043e \u0438\u0434\u0435\u044f \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f: \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c leading trivia, \u0441\u0430\u043c \u0442\u043e\u043a\u0435\u043d \u0438 trailing trivia, \u0430 \u043f\u043e\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 <code>GreenSyntaxToken<\/code>.<\/p>\n<p>\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u0430\u044f \u0441\u0445\u0435\u043c\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u0430 \u0442\u0430\u043a:<\/p>\n<pre><code>CurrentWindowSpan    \u2193\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c leading trivia    \u2193\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0442\u043e\u043a\u0435\u043d    \u2193\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c trailing trivia    \u2193\u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c hash \u0432\u0441\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430    \u2193\u043d\u0430\u0439\u0442\u0438 \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u044d\u0448\u0435 \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439    \u2193\u0441\u0434\u0432\u0438\u043d\u0443\u0442\u044c TextWindow<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 quick scanner \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451 \u0441\u0430\u043c.<\/p>\n<h3>\u0427\u0442\u043e \u043e\u043d \u0443\u043c\u0435\u043b \u0431\u044b\u0441\u0442\u0440\u043e \u0447\u0438\u0442\u0430\u0442\u044c<\/h3>\n<p>\u0421\u0442\u0430\u0440\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0431\u044b\u043b \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438:<\/p>\n<pre><code>whitespacenewlineidentifier\u043f\u0440\u043e\u0441\u0442\u043e\u0435 int32-\u0447\u0438\u0441\u043b\u043e\u043f\u0440\u043e\u0441\u0442\u0430\u044f punctuation<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0441\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, scanner \u0441\u0440\u0430\u0437\u0443 \u0434\u0435\u043b\u0430\u043b fallback.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u043d\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438\u0441\u044c \u043a\u0430\u043a \u043f\u0440\u043e\u0441\u0442\u043e\u0439 whitespace, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>\/<\/code> \u043c\u043e\u0436\u0435\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439:<\/p>\n<pre><code>\/       \u043e\u0431\u044b\u0447\u043d\u044b\u0439 slash token\/\/      \u043e\u0434\u043d\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439\/*      \u043c\u043d\u043e\u0433\u043e\u0441\u0442\u0440\u043e\u0447\u043d\u044b\u0439 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439\/&gt;      slash-greater token<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435 \u043e\u0442\u0434\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u043e\u0431\u044b\u0447\u043d\u043e\u043c\u0443 lexer.<\/p>\n<h3>Leading \u0438 trailing trivia<\/h3>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0442\u0430\u0440\u044b\u0439 quick scanner \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c trivia \u043f\u0435\u0440\u0435\u0434 \u0442\u043e\u043a\u0435\u043d\u043e\u043c.<\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u044b\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0441\u0442\u0440\u043e\u043a \u043e\u043d \u043c\u043e\u0433 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0431\u044b\u0441\u0442\u0440\u043e:<\/p>\n<pre><code>' '      whitespace'\\t'     whitespace'\\r'     newline \u0438\u043b\u0438 \u0447\u0430\u0441\u0442\u044c CRLF'\\n'     newline<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0435\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0441\u044f <code>\/<\/code>, scanner \u043d\u0435 \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0441\u0430\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439 \u0438 \u0443\u0445\u043e\u0434\u0438\u043b \u0432 fallback.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430 \u043e\u043d \u0434\u0435\u043b\u0430\u043b \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0434\u043b\u044f trailing trivia. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c trailing trivia \u0434\u043e\u043b\u0436\u043d\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0435 \u0441\u0442\u0440\u043e\u043a\u0438, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438 \u043e\u0431\u044b\u0447\u043d\u043e \u0443\u0436\u0435 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a \u0433\u0440\u0430\u043d\u0438\u0446\u0435 \u043c\u0435\u0436\u0434\u0443 \u0442\u043e\u043a\u0435\u043d\u0430\u043c\u0438.<\/p>\n<h3>\u0421\u0430\u043c \u0442\u043e\u043a\u0435\u043d<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 leading trivia scanner \u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430 \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0442\u043e\u043a\u0435\u043d\u0430 \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u043b \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c.<\/p>\n<p>\u041f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">state = ch switch{    '_' or (&gt;= 'a' and &lt;= 'z') or (&gt;= 'A' and &lt;= 'Z') =&gt; QuickScanState.Identifier,    &gt;= '0' and &lt;= '9' =&gt; QuickScanState.Number,    '+' or '-' or '*' or '%' or '^' or '|' or '&amp;' or '?' or ':' or ';' or ',' =&gt; QuickScanState.Punctuation,    '.' or '=' or '!' or '&lt;' or '&gt;' or '{' or '}' or '[' or ']' or '(' or ')' or '\/' =&gt; QuickScanState.Punctuation,    _ =&gt; QuickScanState.Bad};<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0442\u043e\u043a\u0435\u043d\u0430 \u0431\u044b\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434:<\/p>\n<pre><code>TryQuickScanIdentifierTryQuickScanDecimalInt32TryQuickScanPunctuation<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u2014 scanner \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u043b identifier. \u0415\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u043e \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0447\u0438\u0441\u043b\u043e. \u0415\u0441\u043b\u0438 punctuation \u2014 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u043b punctuation.<\/p>\n<h3>Identifier<\/h3>\n<p>\u0414\u043b\u044f identifier \u0441\u0442\u0430\u0440\u044b\u0439 quick scanner \u0447\u0438\u0442\u0430\u043b \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 ASCII-\u0432\u0430\u0440\u0438\u0430\u043d\u0442:<\/p>\n<pre><code>[_a-zA-Z][_a-zA-Z0-9]*<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0441\u044f Unicode, escape sequence \u0438\u043b\u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b, scanner \u043d\u0435 \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0431\u044b\u0442\u044c \u0443\u043c\u043d\u0435\u0435 \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b <code>false<\/code>.<\/p>\n<p>\u042d\u0442\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435. Quick scanner \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043a\u0440\u044b\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u0430 \u043d\u0435 \u0432\u0435\u0441\u044c \u044f\u0437\u044b\u043a.<\/p>\n<h3>Number<\/h3>\n<p>\u0421 \u0447\u0438\u0441\u043b\u0430\u043c\u0438 \u0438\u0441\u0442\u043e\u0440\u0438\u044f \u043f\u043e\u0445\u043e\u0436\u0430\u044f. \u0421\u0442\u0430\u0440\u044b\u0439 quick scanner \u043c\u043e\u0433 \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 decimal int32:<\/p>\n<pre><code>123421000<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0442\u0430\u043a\u0438\u0435 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b \u0443\u0436\u0435 \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0434\u043b\u044f \u0431\u044b\u0441\u0442\u0440\u043e\u0433\u043e \u043f\u0443\u0442\u0438:<\/p>\n<pre><code>123.451e100xFF0b10101_000123u123L<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043d\u0438 \u0443\u0445\u043e\u0434\u0438\u043b\u0438 \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer, \u0433\u0434\u0435 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 <code>ScanNumericLiteral<\/code> \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <code>RealParser<\/code> \u0434\u043b\u044f floating-point \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u043e\u0432.<\/p>\n<h3>Punctuation<\/h3>\n<p>\u0414\u043b\u044f punctuation \u0431\u044b\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 <code>switch<\/code>. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0438\u043c\u0432\u043e\u043b <code>&lt;<\/code> \u043c\u043e\u0433 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c\u0441\u044f \u0432 \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b:<\/p>\n<pre><code class=\"cs\">case '&lt;':    if (next == '\/')    {        kind = SyntaxKind.LessSlashToken;        width = 2;        return true;    }    if (next == '=')    {        kind = SyntaxKind.LessEqualsToken;        width = 2;        return true;    }    kind = SyntaxKind.LessThanToken;    width = 1;    return true;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u043e, \u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer. \u0415\u0441\u043b\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0439 punctuation token \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 lexer, \u043d\u0443\u0436\u043d\u043e \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c quick scanner.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u043e\u043a\u0435\u043d\u0430<\/h3>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u043e\u043d \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b \u0442\u043e\u043a\u0435\u043d.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0433\u043e \u0447\u0442\u0435\u043d\u0438\u044f \u043e\u043d \u0441\u043e\u0431\u0438\u0440\u0430\u043b \u0434\u0430\u043d\u043d\u044b\u0435:<\/p>\n<pre><code>kindleading triviatrailing triviatextint value, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0447\u0438\u0441\u043b\u043e<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u043f\u043e\u0442\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u043b <code>GreenSyntaxToken<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e:<\/p>\n<pre><code class=\"cs\">private static GreenSyntaxToken CreateQuickToken(QuickTokenData data){    return data.Kind switch    {        SyntaxKind.IdentifierToken =&gt;            GreenSyntaxFactory.Identifier(data.Leading, data.Text!, data.Trailing),        SyntaxKind.NumericLiteralToken =&gt;            GreenSyntaxFactory.Literal(data.Leading, data.Text!, data.IntValue, data.Trailing),        _ =&gt;            GreenSyntaxFactory.Token(data.Leading, data.Kind, data.Trailing)    };}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0432\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0433\u043b\u0430\u0432\u043d\u044b\u0439 \u043c\u0438\u043d\u0443\u0441 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u043f\u043e\u0434\u0445\u043e\u0434\u0430. Quick scanner \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u043c, \u0430 \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0439 \u0432\u0442\u043e\u0440\u043e\u0439 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 lexer-\u0430.<\/p>\n<p>\u041e\u043d \u0441\u0430\u043c:<\/p>\n<pre><code>\u0447\u0438\u0442\u0430\u0435\u0442 trivia\u0447\u0438\u0442\u0430\u0435\u0442 identifier\u0447\u0438\u0442\u0430\u0435\u0442 number\u0447\u0438\u0442\u0430\u0435\u0442 punctuation\u0441\u043e\u0437\u0434\u0430\u0451\u0442 GreenSyntaxToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0434\u0430\u0451\u0442 \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u0435, \u043d\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043b\u043e\u0433\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c lexer.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u0441\u0442\u0430\u0440\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0431\u044b\u043b \u043f\u043e\u043b\u0435\u0437\u0435\u043d<\/h3>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043c\u0438\u043d\u0443\u0441\u044b, \u0441\u0442\u0430\u0440\u044b\u0439 quick scanner \u0431\u044b\u043b \u043f\u043e\u043b\u0435\u0437\u0435\u043d. \u041e\u043d \u0443\u0431\u0438\u0440\u0430\u043b \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u0434\u043b\u044f \u0441\u0430\u043c\u044b\u0445 \u0447\u0430\u0441\u0442\u044b\u0445 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u043b \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0439 \u0437\u0430 \u0441\u0447\u0451\u0442 \u043a\u044d\u0448\u0430.<\/p>\n<p>\u041d\u043e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043d\u043e \u0443 \u043d\u0435\u0433\u043e \u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430: \u043e\u043d \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043b \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0442\u043e\u043a\u0435\u043d\u0430. \u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u043e\u043d \u043d\u0430\u0447\u0438\u043d\u0430\u043b \u043a\u043e\u043d\u043a\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c lexer, \u0445\u043e\u0442\u044f quick scanner \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u043f\u0443\u0442\u0451\u043c \u043f\u0435\u0440\u0435\u0434 \u043d\u0438\u043c.<\/p>\n<p>\u041a\u043e\u0440\u043e\u0442\u043a\u043e:<\/p>\n<pre><code>\u0441\u0442\u0430\u0440\u044b\u0439 QuickScanner = \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 lexer \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u043b, \u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c hot path \u0435\u0449\u0451 \u043f\u0440\u043e\u0449\u0435.<\/p>\n<h2>\u041d\u043e\u0432\u044b\u0439 QuickScanner<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u043c \u043a \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 quick scanner-\u0430.<\/p>\n<p>\u0413\u043b\u0430\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e quick scanner \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435\u043c \u0433\u0440\u0430\u043d\u0438\u0446 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430. \u041e\u043d \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u043e \u0443\u0447\u0430\u0441\u0442\u043a\u0443 \u0442\u0435\u043a\u0441\u0442\u0430, \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442 <code>full width<\/code>, \u0441\u0447\u0438\u0442\u0430\u0435\u0442 hash \u0438 \u043f\u0440\u043e\u0431\u0443\u0435\u0442 \u043d\u0430\u0439\u0442\u0438 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u044d\u0448\u0435. \u0415\u0441\u043b\u0438 \u0442\u043e\u043a\u0435\u043d\u0430 \u0432 \u043a\u044d\u0448\u0435 \u043d\u0435\u0442, \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0433\u043e <code>GreenSyntaxToken<\/code> \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer.<\/p>\n<p>\u0421\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>quick scanner \u043d\u0430\u0445\u043e\u0434\u0438\u0442 full width + hash    \u2193\u0438\u0449\u0435\u043c \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u044d\u0448\u0435    \u2193\u0435\u0441\u043b\u0438 cache miss, \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer \u0441\u043e\u0437\u0434\u0430\u0451\u0442 GreenSyntaxToken<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a quick scanner \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0431\u044b\u0441\u0442\u0440\u044b\u043c \u0441\u043b\u043e\u0435\u043c \u043f\u0435\u0440\u0435\u0434 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c lexer-\u043e\u043c \u0438 \u043d\u0435 \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u044e \u0435\u0433\u043e \u043b\u043e\u0433\u0438\u043a\u0443.<\/p>\n<h3>\u0414\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b<\/h3>\n<p>\u041d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0434\u0432\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<p><a href=\"https:\/\/github.com\/Asaicraft\/Akbura\/blob\/4060f9c6bd0cb0ba5629a6be3f0864d159ae04a1\/Akbura.Generator\/Language\/Lexer_QuickScanner.cs#L496\" rel=\"noopener noreferrer nofollow\">\u041f\u0435\u0440\u0432\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430<\/a> \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u0435\u0442 \u0441\u0438\u043c\u0432\u043e\u043b\u044b. \u0412\u043c\u0435\u0441\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 \u0431\u043e\u043b\u044c\u0448\u043e\u0439 <code>switch<\/code>, scanner \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0441\u0438\u043c\u0432\u043e\u043b \u0432 \u043e\u0434\u043d\u0443 \u0438\u0437 \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0439:<\/p>\n<pre><code class=\"cs\">private enum CharFlags : byte{    White,    CR,    LF,    Letter,    Digit,    Punct,    Dot,    Slash,    Asterisk,    Bang,    Colon,    Less,    Equals,    Greater,    Complex,    EndOfFile}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>'a' =&gt; Letter'7' =&gt; Digit' ' =&gt; White'.' =&gt; Dot'\/' =&gt; Slash'&lt;' =&gt; Less'=' =&gt; EqualsUnicode \u0438\u043b\u0438 \u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0435 =&gt; Complex<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043a\u043e\u0434\u0435 \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">var flags = (uint)uc &lt; (uint)charPropertiesLength    ? (CharFlags)charProperties[uc]    : CharFlags.Complex;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 lookup \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d ASCII-\u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u043e\u043c:<\/p>\n<pre><code class=\"cs\">var charPropertiesLength = Math.Min(128, charProperties.Length);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u0432\u044b\u0448\u0435 <code>127<\/code> \u0441\u0447\u0438\u0442\u0430\u044e\u0442\u0441\u044f <code>Complex<\/code> \u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u043c lexer-\u043e\u043c. Unicode identifiers \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u043e\u0441\u0442\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043f\u043e\u043b\u043d\u043e\u043c \u043f\u0443\u0442\u0438 \u0440\u0430\u0437\u0431\u043e\u0440\u0430.<\/p>\n<p><a href=\"https:\/\/github.com\/Asaicraft\/Akbura\/blob\/4060f9c6bd0cb0ba5629a6be3f0864d159ae04a1\/Akbura.Generator\/Language\/Lexer_QuickScanner.cs#L61\" rel=\"noopener noreferrer nofollow\">\u0412\u0442\u043e\u0440\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430<\/a> \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439:<\/p>\n<pre><code class=\"cs\">private static ReadOnlySpan&lt;byte&gt; StateTransitions =&gt; [...]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0437\u0434\u0435\u0441\u044c quick scanner \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0430\u0432\u0442\u043e\u043c\u0430\u0442.<\/p>\n<h3>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/h3>\n<p>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0445\u0440\u0430\u043d\u0438\u0442, \u0447\u0442\u043e scanner \u0443\u0436\u0435 \u0443\u0441\u043f\u0435\u043b \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cs\">private enum QuickScanState : byte{    Initial,    FollowingWhite,    FollowingCR,    Ident,    Number,    Punctuation,    Dot,    Slash,    Bang,    Colon,    Less,    Equals,    Greater,    DoneAfterNext,    Done,    Bad = Done + 1}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043c\u044b\u0441\u043b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code>Initial          \u0435\u0449\u0451 \u043d\u0435 \u043d\u0430\u0447\u0430\u043b\u0438 \u0442\u043e\u043a\u0435\u043dIdent            \u0447\u0438\u0442\u0430\u0435\u043c identifierNumber           \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0447\u0438\u0441\u043b\u043ePunctuation      \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u0443\u044e punctuationDot              \u0443\u0432\u0438\u0434\u0435\u043b\u0438 .Slash            \u0443\u0432\u0438\u0434\u0435\u043b\u0438 \/Bang             \u0443\u0432\u0438\u0434\u0435\u043b\u0438 !Colon            \u0443\u0432\u0438\u0434\u0435\u043b\u0438 :Less             \u0443\u0432\u0438\u0434\u0435\u043b\u0438 &lt;Equals           \u0443\u0432\u0438\u0434\u0435\u043b\u0438 =Greater          \u0443\u0432\u0438\u0434\u0435\u043b\u0438 &gt;FollowingWhite   \u0447\u0438\u0442\u0430\u0435\u043c trailing whitespaceFollowingCR      \u0443\u0432\u0438\u0434\u0435\u043b\u0438 \\r \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0439 \\nDone             \u0442\u043e\u043a\u0435\u043d \u0443\u0441\u043f\u0435\u0448\u043d\u043e \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043dBad              \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043d\u0443\u0436\u0435\u043d fallback<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0434\u043b\u044f <code>Dot<\/code>, <code>Slash<\/code>, <code>Bang<\/code>, <code>Colon<\/code>, <code>Less<\/code>, <code>Equals<\/code>, <code>Greater<\/code> \u043d\u0443\u0436\u043d\u044b \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u044d\u0442\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0434\u0432\u0443\u0445\u0441\u0438\u043c\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u0442\u043e\u043a\u0435\u043d\u044b:<\/p>\n<pre><code>.  \u0438\u043b\u0438 ..\/  \u0438\u043b\u0438 \/&gt;!  \u0438\u043b\u0438 !=:  \u0438\u043b\u0438 ::&lt;  \u0438\u043b\u0438 &lt;= \u0438\u043b\u0438 &lt;\/=  \u0438\u043b\u0438 == \u0438\u043b\u0438 =&gt;&gt;  \u0438\u043b\u0438 &gt;=<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 scanner \u0443\u0432\u0438\u0434\u0435\u043b <code>&lt;<\/code>, \u043e\u043d \u0435\u0449\u0451 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u0442\u043e\u043a\u0435\u043d. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b \u0440\u0435\u0448\u0438\u0442, \u0431\u0443\u0434\u0435\u0442 \u044d\u0442\u043e <code>&lt;<\/code>, <code>&lt;=<\/code> \u0438\u043b\u0438 <code>&lt;\/<\/code>.<\/p>\n<h3>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432<\/h3>\n<p>\u0412 \u043a\u043e\u0434\u0435 <code>StateTransitions<\/code> \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u0430\u043a \u043f\u043b\u043e\u0441\u043a\u0438\u0439 \u043c\u0430\u0441\u0441\u0438\u0432, \u043d\u043e \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0430:<\/p>\n<pre><code>\u0441\u0442\u0440\u043e\u043a\u0430   = \u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043a\u043e\u043b\u043e\u043d\u043a\u0430  = \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 = \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0440\u0438\u0441\u0443\u043d\u043a\u0435 \u043d\u0438\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0430 \u044d\u0442\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0432 \u0431\u043e\u043b\u0435\u0435 \u0447\u0438\u0442\u0430\u0435\u043c\u043e\u043c \u0432\u0438\u0434\u0435.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/0c\/eb\/3e\/0ceb3ed875ef556303f312cceca5ec01.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/0c\/eb\/3e\/0ceb3ed875ef556303f312cceca5ec01.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/0c\/eb\/3e\/0ceb3ed875ef556303f312cceca5ec01.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>Scanner \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 <code>CharFlags<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u043e\u0434\u043d\u0438\u043c \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c \u043a \u043c\u0430\u0441\u0441\u0438\u0432\u0443 \u0431\u0435\u0440\u0451\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435:<\/p>\n<pre><code class=\"cs\">state = (QuickScanState)stateTransitions[    ((int)state &lt;&lt; CharFlagsShift) + (int)flags];<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>CharFlagsShift<\/code> \u0440\u0430\u0432\u0435\u043d <code>4<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 16 \u043a\u043e\u043b\u043e\u043d\u043e\u043a. \u0421\u0434\u0432\u0438\u0433 <code>state &lt;&lt; 4<\/code> \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 <code>state * 16<\/code>, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u043d\u0443\u0436\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u0430\u043c \u0431\u044b \u0437\u0430\u043c\u0435\u043d\u0438\u043b \u044d\u0442\u043e \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u0441\u0434\u0432\u0438\u0433, \u043d\u043e \u044f \u0431\u044b\u043b \u0432 \u044d\u0442\u043e\u043c \u043d\u0435 \u0443\u0432\u0435\u0440\u0435\u043d, \u0442\u0430\u043a \u043a\u0430\u043a <code>ILSPY<\/code> \u043f\u043e\u043a\u0430\u0437\u0430\u043b \u0447\u0442\u043e \u043d\u0435\u0442.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>Initial + Letter =&gt; IdentIdent + Letter   =&gt; IdentIdent + Digit    =&gt; IdentIdent + White    =&gt; FollowingWhite<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0411\u0443\u043a\u0432\u044b \u0438 \u0446\u0438\u0444\u0440\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u044e\u0442 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440. \u041f\u0440\u043e\u0431\u0435\u043b \u043f\u043e\u0441\u043b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u0430 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 scanner \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 trailing whitespace.<\/p>\n<h3>\u041f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0431\u043e\u0442\u044b DFA<\/h3>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0434\u0432\u0430 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u043f\u0440\u0438\u043c\u0435\u0440\u0430.<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/8a\/3b\/8a\/8a3b8a12500bf1affc8a7d0921798d5b.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/8a\/3b\/8a\/8a3b8a12500bf1affc8a7d0921798d5b.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/8a\/3b\/8a\/8a3b8a12500bf1affc8a7d0921798d5b.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 scanner \u0447\u0438\u0442\u0430\u0435\u0442:<\/p>\n<pre><code>button {<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0438\u043c\u0432\u043e\u043b <code>b<\/code> \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u0438\u0437 <code>Initial<\/code> \u0432 <code>Ident<\/code>. \u0414\u0430\u043b\u044c\u0448\u0435 <code>u<\/code>, <code>t<\/code>, <code>t<\/code>, <code>o<\/code>, <code>n<\/code> \u0442\u043e\u0436\u0435 \u043a\u043b\u0430\u0441\u0441\u0438\u0444\u0438\u0446\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u043a\u0430\u043a <code>Letter<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f <code>Ident<\/code>.<\/p>\n<p>\u041f\u0440\u043e\u0431\u0435\u043b \u043f\u043e\u0441\u043b\u0435 <code>button<\/code> \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 scanner \u0432 <code>FollowingWhite<\/code>. \u0421\u0430\u043c \u043f\u0440\u043e\u0431\u0435\u043b \u043c\u043e\u0436\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432 cached token \u043a\u0430\u043a trailing trivia. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0441\u0438\u043c\u0432\u043e\u043b <code>{<\/code> \u0443\u0436\u0435 \u043d\u0435 \u0432\u0445\u043e\u0434\u0438\u0442 \u0432 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 token span, \u043d\u043e \u043e\u043d \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0442\u0435\u043a\u0443\u0449\u0438\u0439 cached token \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u043b\u0441\u044f:<\/p>\n<pre><code>FollowingWhite + Punct =&gt; Done<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 quick scanner \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u043e\u043a:<\/p>\n<pre><code>button\u2420<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 <code>{<\/code> \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0442\u043e\u043a\u0435\u043d\u0430.<\/p>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 scanner \u0447\u0438\u0442\u0430\u0435\u0442:<\/p>\n<pre><code>&gt;= value<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>&gt;<\/code> \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0430\u0432\u0442\u043e\u043c\u0430\u0442 \u0432 <code>Greater<\/code>, <code>=<\/code> \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0432 <code>Punctuation<\/code>, \u043f\u0440\u043e\u0431\u0435\u043b \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0438\u0442 \u0435\u0433\u043e \u0432 <code>FollowingWhite<\/code>, \u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0431\u0443\u043a\u0432\u0430 <code>v<\/code> \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 cached token:<\/p>\n<pre><code>Initial + Greater       =&gt; GreaterGreater + Equals        =&gt; PunctuationPunctuation + White     =&gt; FollowingWhiteFollowingWhite + Letter =&gt; Done<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 cached token span \u0431\u0443\u0434\u0435\u0442:<\/p>\n<pre><code>&gt;=\u2420<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 <code>value<\/code> \u043d\u0430\u0447\u043d\u0451\u0442\u0441\u044f \u0443\u0436\u0435 \u043a\u0430\u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d.<\/p>\n<h3>\u041a\u0430\u043a \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 if\/switch<\/h3>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0432\u0440\u0443\u0447\u043d\u0443\u044e, \u043a\u043e\u0434 \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0432\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 <code>switch<\/code>:<\/p>\n<pre><code class=\"cs\">private static QuickScanState MoveSlow(QuickScanState state, CharFlags flags){    switch (state)    {        case QuickScanState.Initial:            switch (flags)            {                case CharFlags.Letter:                    return QuickScanState.Ident;                case CharFlags.Digit:                    return QuickScanState.Number;                case CharFlags.Dot:                    return QuickScanState.Dot;                case CharFlags.Slash:                    return QuickScanState.Slash;                case CharFlags.Complex:                    return QuickScanState.Bad;            }            break;        case QuickScanState.Ident:            switch (flags)            {                case CharFlags.Letter:                case CharFlags.Digit:                    return QuickScanState.Ident;                case CharFlags.White:                    return QuickScanState.FollowingWhite;                case CharFlags.Slash:                case CharFlags.Complex:                    return QuickScanState.Bad;                default:                    return QuickScanState.Done;            }    }    return QuickScanState.Bad;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/c4\/57\/32\/c45732c1ac54b18342edea8f3de84188.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/webt\/c4\/57\/32\/c45732c1ac54b18342edea8f3de84188.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/webt\/c4\/57\/32\/c45732c1ac54b18342edea8f3de84188.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442 \u044d\u0442\u0443 \u043b\u043e\u0433\u0438\u043a\u0443 \u043e\u0434\u043d\u043e\u0439 \u0444\u043e\u0440\u043c\u0443\u043b\u043e\u0439:<\/p>\n<pre><code class=\"cs\">state = (QuickScanState)stateTransitions[    ((int)state &lt;&lt; CharFlagsShift) + (int)flags];<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043d\u0434\u0435\u043a\u0441 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a:<\/p>\n<pre><code>\u043d\u043e\u043c\u0435\u0440 \u0441\u0442\u0440\u043e\u043a\u0438 * 16 + \u043d\u043e\u043c\u0435\u0440 \u043a\u043e\u043b\u043e\u043d\u043a\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c:<\/p>\n<pre><code>\u0442\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 + \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430 = \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u043e\u0433\u043e \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0435 \u043a \u043c\u0430\u0441\u0441\u0438\u0432\u0443.<\/p>\n<h3>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u0446\u0438\u043a\u043b<\/h3>\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0446\u0438\u043a\u043b quick scanner-\u0430 \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u043e:<\/p>\n<pre><code class=\"cs\">var state = QuickScanState.Initial;var hashCode = HashCode.FnvOffsetBias;var currentIndex = 0;for (; currentIndex &lt; textWindowCharSpan.Length; currentIndex++){    var c = textWindowCharSpan[currentIndex];    var uc = unchecked((int)c);    var flags = (uint)uc &lt; (uint)charPropertiesLength        ? (CharFlags)charProperties[uc]        : CharFlags.Complex;    state = (QuickScanState)stateTransitions[        ((int)state &lt;&lt; CharFlagsShift) + (int)flags];    if (state &gt;= QuickScanState.Done)    {        goto exitLoop;    }    hashCode = HashCode.CombineFNVHash(hashCode, c);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b scanner \u0434\u0435\u043b\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:<\/p>\n<pre><code>\u0431\u0435\u0440\u0451\u0442 char\u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 CharFlags\u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043f\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 Done\/Bad\u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 FNV hash<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u043d \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 trivia, \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 identifier string, \u043d\u0435 \u043f\u0430\u0440\u0441\u0438\u0442 int \u0438 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 <code>GreenSyntaxFactory<\/code>. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 hot path \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u043f\u0440\u043e\u0449\u0435.<\/p>\n<h3>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u0438 Done \u0438 Bad<\/h3>\n<p>\u0412 <code>QuickScanState<\/code> \u0435\u0441\u0442\u044c \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0430\u044f \u0434\u0435\u0442\u0430\u043b\u044c:<\/p>\n<pre><code class=\"cs\">Done,Bad = Done + 1<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>Bad<\/code> \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0438\u0434\u0451\u0442 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u0441\u043b\u0435 <code>Done<\/code>, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432\u044b\u0439\u0442\u0438 \u0438\u0437 \u0446\u0438\u043a\u043b\u0430 \u043e\u0434\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439:<\/p>\n<pre><code class=\"cs\">if (state &gt;= QuickScanState.Done){    goto exitLoop;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0430\u0432\u043d\u043e <code>Done<\/code>, quick scanner \u0443\u0432\u0435\u0440\u0435\u043d \u0432 \u0433\u0440\u0430\u043d\u0438\u0446\u0435 \u0442\u043e\u043a\u0435\u043d\u0430. \u041e\u043d \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442 \u0434\u043b\u0438\u043d\u0443, \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442 <code>TextWindow<\/code> \u0438 \u0438\u0449\u0435\u0442 \u0442\u043e\u043a\u0435\u043d \u0432 \u043a\u044d\u0448\u0435:<\/p>\n<pre><code class=\"cs\">token = _cache.LookupToken(    textWindowCharSpan[..tokenLength],    hashCode,    static lexer =&gt; CreateQuickTokenFromRegularLexer(lexer),    this);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0439 \u0442\u043e\u043a\u0435\u043d \u0443\u0436\u0435 \u0431\u044b\u043b, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0441\u0440\u0430\u0437\u0443. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer:<\/p>\n<pre><code class=\"cs\">private static GreenSyntaxToken CreateQuickTokenFromRegularLexer(Lexer lexer){    var fullTokenStart = lexer.LexemeStartPosition;    lexer.TextWindow.Reset(fullTokenStart);    var token = lexer.ParseNextToken();    return token;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0441\u0442\u0430\u0440\u043e\u0433\u043e \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430: \u043d\u043e\u0432\u044b\u0439 quick scanner \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 <code>GreenSyntaxToken<\/code> \u0441\u0430\u043c, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0439\u0442\u0438 \u0433\u0440\u0430\u043d\u0438\u0446\u044b \u0438 hash.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0438\u0442\u043e\u0433\u043e\u0432\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0440\u0430\u0432\u043d\u043e <code>Bad<\/code>, \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c \u043d\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442. \u042d\u0442\u043e \u043d\u0435 \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 scanner \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 <code>false<\/code>, \u0430 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 \u0442\u043e\u0439 \u0436\u0435 \u043f\u043e\u0437\u0438\u0446\u0438\u0438.<\/p>\n<p>\u0412 <code>Bad<\/code> \u0443\u0445\u043e\u0434\u044f\u0442, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0430\u043a\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0438:<\/p>\n<pre><code>Unicode identifier\u0447\u0438\u0441\u043b\u043e \u0441 \u0442\u043e\u0447\u043a\u043e\u0439: 123.45hex\/binary number: 0xFF, 0b1010\u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0439: \/\/ ... \u0438\u043b\u0438 \/* ... *\/\u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u043b\u0438\u043d\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d\u0433\u0440\u0430\u043d\u0438\u0446\u0430 SlidingTextWindow\u043d\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u0438\u043c\u0432\u043e\u043b<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043e\u0441\u0442\u0430\u0451\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c: quick scanner \u0431\u044b\u0441\u0442\u0440\u043e \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0438 \u0447\u0430\u0441\u0442\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439, \u0430 \u0432\u0441\u0451 \u0441\u043e\u043c\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0432 fallback.<\/p>\n<h2>\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u043e\u0432<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u0441\u0440\u0430\u0432\u043d\u0438\u0442\u044c \u0441\u0442\u0430\u0440\u044b\u0439 \u0438 \u043d\u043e\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u044b.<\/p>\n<p>\u0421\u0442\u0430\u0440\u044b\u0439 quick scanner:<\/p>\n<pre><code>+ \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u0439+ \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u043e\u043a\u0435\u043d+ \u0443\u043c\u0435\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 trivia, identifier, int32, punctuation- \u043c\u043d\u043e\u0433\u043e if\/switch- \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer- \u0441\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u0451\u0442 GreenSyntaxToken- \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e\u0435 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c lexer<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e\u0432\u044b\u0439 quick scanner:<\/p>\n<pre><code>+ \u043e\u0434\u0438\u043d \u043a\u043e\u043c\u043f\u0430\u043a\u0442\u043d\u044b\u0439 \u0446\u0438\u043a\u043b \u043f\u043e \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c+ \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u0447\u0435\u0440\u0435\u0437 \u0442\u0430\u0431\u043b\u0438\u0446\u0443+ \u0431\u044b\u0441\u0442\u0440\u043e \u0441\u0447\u0438\u0442\u0430\u0435\u0442 full width \u0438 FNV hash+ \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u0442\u043e\u043a\u0435\u043d \u0441\u0430\u043c+ cache miss \u0434\u0435\u043b\u0435\u0433\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u044b\u0447\u043d\u043e\u043c\u0443 lexer+ \u043c\u0435\u043d\u044c\u0448\u0435 \u0440\u0438\u0441\u043a \u0440\u0430\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u044f \u0441 \u043e\u0431\u044b\u0447\u043d\u044b\u043c lexer- \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432 \u0441\u043b\u043e\u0436\u043d\u0435\u0435 \u0447\u0438\u0442\u0430\u0442\u044c- \u043d\u0443\u0436\u043d\u043e \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0442\u044c StateTransitions- \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u0441\u0440\u0430\u0437\u0443 \u0443\u0445\u043e\u0434\u044f\u0442 \u0432 fallback<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0413\u043b\u0430\u0432\u043d\u043e\u0435 \u0440\u0430\u0437\u043b\u0438\u0447\u0438\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u0444\u043e\u0440\u043c\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>\u0441\u0442\u0430\u0440\u044b\u0439 QuickScanner = \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0439 \u0432\u0442\u043e\u0440\u043e\u0439 lexer \u0434\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432\u043d\u043e\u0432\u044b\u0439 QuickScanner = \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u0444\u0438\u043b\u044c\u0442\u0440 \u043f\u0435\u0440\u0435\u0434 \u043e\u0431\u044b\u0447\u043d\u044b\u043c lexer<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>\u0411\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0446\u0438\u0444\u0440\u044b. \u0417\u0434\u0435\u0441\u044c \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e: \u0441\u0442\u0430\u0440\u044b\u0439 quick scanner \u0431\u0435\u0437 \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u043e\u0433\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0430 \u0438 \u043d\u043e\u0432\u044b\u0439 quick scanner \u0441 \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u044b\u043c\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430\u043c\u0438.<\/p>\n<h3>\u0421\u0442\u0430\u0440\u044b\u0439 quick scanner<\/h3>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Repetitions<\/p>\n<\/th>\n<th>\n<p align=\"left\">QuickScanner disabled<\/p>\n<\/th>\n<th>\n<p align=\"left\">QuickScanner enabled<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u0440\u043e\u0441\u0442<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">80<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.838 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.754 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.57%<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">800<\/p>\n<\/td>\n<td>\n<p align=\"left\">16.806 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.512 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">7.70%<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">8000<\/p>\n<\/td>\n<td>\n<p align=\"left\">161.227 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">154.494 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">4.18%<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0421\u0442\u0430\u0440\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u0441\u043a\u043e\u0440\u044f\u043b lexer, \u043d\u043e \u043f\u0440\u0438\u0440\u043e\u0441\u0442 \u0431\u044b\u043b \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439: \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043e\u0442 4% \u0434\u043e 8%.<\/p>\n<h3>\u041d\u043e\u0432\u044b\u0439 quick scanner<\/h3>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Repetitions<\/p>\n<\/th>\n<th>\n<p align=\"left\">QuickScanner disabled<\/p>\n<\/th>\n<th>\n<p align=\"left\">QuickScanner enabled<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u0440\u0438\u0440\u043e\u0441\u0442<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">80<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.988 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.673 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">15.85%<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">800<\/p>\n<\/td>\n<td>\n<p align=\"left\">24.923 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">18.952 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">23.96%<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">8000<\/p>\n<\/td>\n<td>\n<p align=\"left\">268.511 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">218.486 ms<\/p>\n<\/td>\n<td>\n<p align=\"left\">18.63%<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041d\u043e\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0434\u0430\u0451\u0442 \u0431\u043e\u043b\u0435\u0435 \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u0439 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u0438\u0440\u043e\u0441\u0442: \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043e\u0442 16% \u0434\u043e 24%.<\/p>\n<h3>\u0410\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0438<\/h3>\n<p>\u041f\u043e \u043f\u0430\u043c\u044f\u0442\u0438 \u043e\u0431\u0430 \u043f\u043e\u0434\u0445\u043e\u0434\u0430 \u0434\u0430\u044e\u0442 \u043f\u043e\u0445\u043e\u0436\u0438\u0439 \u044d\u0444\u0444\u0435\u043a\u0442.<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">Repetitions<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0421\u0442\u0430\u0440\u044b\u0439 scanner<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041d\u043e\u0432\u044b\u0439 scanner<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">80<\/p>\n<\/td>\n<td>\n<p align=\"left\">984.64 KB \u2192 907.46 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">989.36 KB \u2192 910.31 KB<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">800<\/p>\n<\/td>\n<td>\n<p align=\"left\">9701.21 KB \u2192 8914.44 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">9701.50 KB \u2192 8934.56 KB<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">8000<\/p>\n<\/td>\n<td>\n<p align=\"left\">94487.90 KB \u2192 86458.79 KB<\/p>\n<\/td>\n<td>\n<p align=\"left\">94167.93 KB \u2192 86209.39 KB<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0412 \u043e\u0431\u043e\u0438\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u0441\u043d\u0438\u0436\u0435\u043d\u0438\u0435 \u0430\u043b\u043b\u043e\u043a\u0430\u0446\u0438\u0439 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u043e\u043a\u043e\u043b\u043e 8%. \u042d\u0442\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e: \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u044d\u043a\u043e\u043d\u043e\u043c\u0438\u044e \u0434\u0430\u0451\u0442 \u043d\u0435 \u0441\u0430\u043c\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u0432, \u0430 \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432 \u0438 trivia.<\/p>\n<details class=\"spoiler\">\n<summary>\u0412\u0430\u0436\u043d\u0430\u044f \u043e\u0433\u043e\u0432\u043e\u0440\u043a\u0430<\/summary>\n<div class=\"spoiler__content\">\n<p>\u042d\u0442\u0438 \u0431\u0435\u043d\u0447\u043c\u0430\u0440\u043a\u0438 \u043d\u0435 \u0441\u0442\u043e\u0438\u0442 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0441\u0442\u0435\u0440\u0438\u043b\u044c\u043d\u043e\u0435 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435 \u0434\u0432\u0443\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0439. Quick scanner \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0441\u0431\u043e\u0440\u043a\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u043a\u043b\u044e\u0447\u0451\u043d, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u043e\u0432 \u043c\u043d\u0435 \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0444\u043b\u0430\u0433\u0438, \u0447\u0442\u043e\u0431\u044b \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u0443\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0442\u044c. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u0434\u043b\u044f unit-\u0442\u0435\u0441\u0442\u043e\u0432 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u043b\u0441\u044f \u0441\u0431\u043e\u0440 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 quick scanner-\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0432 \u043e\u0431\u044b\u0447\u043d\u0443\u044e \u0438\u0442\u043e\u0433\u043e\u0432\u0443\u044e \u0441\u0431\u043e\u0440\u043a\u0443.<\/p>\n<p>\u0418\u0437-\u0437\u0430 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 Visual Studio \u0441\u0442\u0430\u0440\u044b\u0435 benchmark\/unit-test \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0438 \u0441 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u043c\u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c\u0438: \u0447\u0435\u0440\u0435\u0437 <code>dotnet test<\/code> \u0438 <code>dotnet run<\/code> \u0432\u0441\u0451 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e, \u043d\u043e \u0441\u0430\u043c\u0430 Visual Studio \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b\u0430 \u043f\u0441\u0435\u0432\u0434\u043e\u043e\u0448\u0438\u0431\u043a\u0438. \u0427\u0442\u043e\u0431\u044b \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0432 IDE, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 <code>DebugStats<\/code> \u0438 <code>ReleaseStats<\/code>.<\/p>\n<p>\u041f\u043e\u0431\u043e\u0447\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 quick scanner \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0443 \u043d\u0430\u0447\u0430\u043b\u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0447\u0430\u0441\u0442\u0438 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b: \u043e\u0431\u044b\u0447\u043d\u044b\u0439 lexer, <code>SyntaxFactory<\/code>, <code>GreenNodeCache<\/code> \u0438 \u0442.\u0434. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 baseline \u0432 \u044d\u0442\u0438\u0445 \u0437\u0430\u043c\u0435\u0440\u0430\u0445 \u0438\u0437\u043c\u0435\u043d\u0438\u043b\u0441\u044f, \u0438 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u0442\u044c raw time \u0441\u0442\u0430\u0440\u043e\u0439 \u0438 \u043d\u043e\u0432\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043d\u0435 \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e.<\/p>\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0432\u044b\u0432\u043e\u0434 \u0437\u0434\u0435\u0441\u044c \u0434\u0440\u0443\u0433\u043e\u0439: \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0432\u043e\u0435\u0439 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043d\u043e\u0432\u044b\u0439 quick scanner \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0434\u0430\u0451\u0442 \u0437\u0430\u043c\u0435\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u0440\u043e\u0441\u0442 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 &#8212; \u043e\u043a\u043e\u043b\u043e 16\u201324%. \u0414\u0430\u0436\u0435 \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u043f\u043e\u0440\u044f\u0434\u043e\u043a \u043f\u0440\u0438\u0440\u043e\u0441\u0442\u0430 \u043d\u0430 <a href=\"https:\/\/benchmarkdotnet.org\/api\/BenchmarkDotNet.Jobs.Job.html#BenchmarkDotNet_Jobs_Job_LongRun\" rel=\"noopener noreferrer nofollow\">Job.LongRun<\/a> \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0441\u0442\u0430\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u0438\u043c \u0436\u0435. \u041d\u043e \u0434\u043b\u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0447\u0435\u0441\u0442\u043d\u043e\u0433\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f raw time \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0447\u0438\u0441\u0442\u044b\u0439 benchmark \u0431\u0435\u0437 \u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043a\u0438 \u0438 \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f\u043c\u0438 \u0441\u0431\u043e\u0440\u043a\u0438.<\/p>\n<\/div>\n<\/details>\n<p>\u0415\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u044f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0445\u043e\u0442\u0435\u043b \u0434\u0435\u043b\u0430\u0442\u044c DFA, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u043b \u0432\u044b\u0438\u0433\u0440\u044b\u0448 \u043e\u0442 \u043d\u0435\u0433\u043e \u043d\u0435\u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c. \u0418\u0437-\u0437\u0430 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u0441\u043e\u0432\u043c\u0435\u0449\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0430 \u044f\u0437\u044b\u043a\u0430 \u0438 \u0447\u0430\u0441\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u044b \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043e\u0442\u0434\u0430\u0451\u0442\u0441\u044f C#, \u044d\u0442\u043e \u043c\u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c. \u041d\u043e \u0442\u0430\u043a \u043a\u0430\u043a \u044f \u043e\u0431\u0435\u0449\u0430\u043b \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043e\u0431\u0435\u0449\u0430\u043d\u0438\u0435. \u0418, \u0435\u0441\u043b\u0438 \u0447\u0435\u0441\u0442\u043d\u043e, \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u044f \u043e\u0447\u0435\u043d\u044c \u0434\u043e\u0432\u043e\u043b\u0435\u043d. \u041f\u0440\u0438\u0440\u043e\u0441\u0442 \u0432 20% \u2014 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0438 \u043f\u043b\u043e\u0445\u043e.<\/p>\n<h2>\u041f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a Parser<\/h2>\n<p>\u0421 lexer-\u043e\u043c \u043c\u044b \u043d\u0430\u043a\u043e\u043d\u0435\u0446-\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432. \u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0451 \u043f\u0440\u043e\u0441\u0442\u043e: \u0431\u0435\u0440\u0451\u043c \u0442\u043e\u043a\u0435\u043d\u044b \u043e\u0434\u0438\u043d \u0437\u0430 \u0434\u0440\u0443\u0433\u0438\u043c \u0438 \u0441\u0442\u0440\u043e\u0438\u043c \u0434\u0435\u0440\u0435\u0432\u043e. \u041d\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 parser \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e <code>while<\/code> \u043f\u043e \u0442\u043e\u043a\u0435\u043d\u0430\u043c. \u0415\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u0447\u0443\u0442\u044c \u043d\u0435\u043f\u0440\u0438\u044f\u0442\u043d\u0435\u0435: \u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043d\u044f\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u044f\u0437\u044b\u043a\u0430, \u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u0443\u043c\u0435\u0442\u044c \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0441\u043b\u0435 \u043e\u0448\u0438\u0431\u043e\u043a \u0438 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043d\u0435 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u043e\u0439.<\/p>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: parser \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0440\u0435\u0448\u0430\u0442\u044c, \u0438\u043c\u0435\u0435\u0442 \u043b\u0438 \u043a\u043e\u0434 \u0441\u043c\u044b\u0441\u043b. \u041e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439 \u0432\u043e\u043f\u0440\u043e\u0441: <strong>\u043a\u0430\u043a\u0443\u044e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0443\u044e \u0444\u043e\u0440\u043c\u0443 \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c?<\/strong><\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043b:<\/p>\n<pre><code>state count = ;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u044d\u0442\u043e \u043f\u043b\u043e\u0445\u043e\u0439 \u043a\u043e\u0434, \u043d\u043e \u044d\u0442\u043e \u0432\u0441\u0451 \u0435\u0449\u0451 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 <code>state<\/code>-\u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435. Parser \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u043f\u0430\u0441\u0442\u044c \u0438\u043b\u0438 \u0441\u043a\u0430\u0437\u0430\u0442\u044c: \u00ab\u044f \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u043b\u00bb. \u041e\u043d \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c <code>StateDeclarationSyntax<\/code>, \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u0442\u0443\u0434\u0430 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 initializer \u043a\u0430\u043a missing token \/ missing node \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c diagnostic. \u0422\u043e\u0433\u0434\u0430 IDE \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u0438\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443, \u043d\u043e \u0434\u0435\u0440\u0435\u0432\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u043c \u0434\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430, \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 parser \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u0430\u043a \u043e\u0447\u0435\u043d\u044c \u0442\u0435\u0440\u043f\u0435\u043b\u0438\u0432\u044b\u0439 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044c. \u041e\u043d \u0432\u0438\u0434\u0438\u0442 \u043c\u0443\u0441\u043e\u0440, \u043d\u043e \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0443\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b.<\/p>\n<h3>\u041f\u043e\u0442\u043e\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432<\/h3>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 parser-\u0430 \u043e\u0431\u044b\u0447\u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0439:<\/p>\n<pre><code class=\"cs\">private GreenSyntaxToken CurrentToken =&gt; PeekToken(0);private GreenSyntaxToken PeekToken(int offset){    \/\/ \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0442\u043e\u043a\u0435\u043d \u0432\u043f\u0435\u0440\u0451\u0434, \u043d\u0435 \u0441\u044a\u0435\u0434\u0430\u044f \u0435\u0433\u043e}private GreenSyntaxToken EatToken(){    \/\/ \u0432\u0437\u044f\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0438 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043a \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443}private GreenSyntaxToken EatToken(SyntaxKind expected){    \/\/ \u0432\u0437\u044f\u0442\u044c \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u0442\u044c missing token}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>CurrentToken<\/code> \u043d\u0443\u0436\u0435\u043d \u043f\u043e\u0447\u0442\u0438 \u0432\u0435\u0437\u0434\u0435. <code>PeekToken<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u0442\u043b\u0438\u0447\u0430\u0442\u044c \u043f\u043e\u0445\u043e\u0436\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f inline Akcss \u0431\u043b\u043e\u043a\u0430 \u043d\u0430\u043c \u0432\u0430\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e <code>@<\/code>, \u0430 \u043f\u0430\u0440\u0443 \u0442\u043e\u043a\u0435\u043d\u043e\u0432:<\/p>\n<pre><code class=\"cs\">SyntaxKind.AtToken when PeekToken(1).Kind == SyntaxKind.AkcssKeyword<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e <code>@akcss { ... }<\/code> \u2014 \u044d\u0442\u043e inline-\u0431\u043b\u043e\u043a \u0441\u0442\u0438\u043b\u0435\u0439, \u0430 <code>@akcss = 1;<\/code> \u2014 \u044d\u0442\u043e \u0443\u0436\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 C# verbatim identifier, \u0438 \u043f\u0430\u0440\u0441\u0435\u0440 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u0445 \u043f\u0443\u0442\u0430\u0442\u044c.<\/p>\n<p><code>EatToken<\/code> \u2014 \u044d\u0442\u043e \u043c\u0435\u0441\u0442\u043e, \u0433\u0434\u0435 parser \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0434\u0432\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u0432\u043f\u0435\u0440\u0451\u0434. \u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442, \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f. \u0415\u0441\u043b\u0438 \u043d\u0435\u0442, parser \u0441\u043e\u0437\u0434\u0430\u0451\u0442 missing token \u043d\u0443\u0436\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0430, \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 diagnostic \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443. \u042d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0431\u0430\u0437\u043e\u0432\u044b\u0445 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u043e\u0432 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"cs\">private GreenSyntaxToken EatToken(SyntaxKind expected){    if (CurrentToken.Kind == expected)    {        return EatToken();    }    AddError(CurrentToken, $\"Expected {expected}\");    return GreenSyntaxFactory.MissingToken(expected);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c \u043a\u043e\u0434\u0435, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u0431\u043e\u043b\u044c\u0448\u0435 \u0434\u0435\u0442\u0430\u043b\u0435\u0439: trivia, \u043f\u043e\u0437\u0438\u0446\u0438\u044f, \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0438, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f. \u041d\u043e \u0438\u0434\u0435\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a\u0430\u044f.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 parser \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u043e\u043a\u0435\u043d\u044b \u0441 trivia<\/h3>\n<p>\u041c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e parser-\u0443 \u043d\u0443\u0436\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e meaningful-\u0442\u043e\u043a\u0435\u043d\u044b: <code>state<\/code>, <code>count<\/code>, <code>=<\/code>, <code>0<\/code>, <code>;<\/code>. \u041f\u0440\u043e\u0431\u0435\u043b\u044b \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u044b \u0441\u0442\u0440\u043e\u043a \u0432\u0440\u043e\u0434\u0435 \u0431\u044b \u043d\u0435 \u0432\u0430\u0436\u043d\u044b. \u041d\u043e \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439 tooling, \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a.<\/p>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0443\u043c\u0435\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c:<\/p>\n<pre><code class=\"cs\">syntax.ToFullString()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0440\u043e\u0432\u043d\u043e \u0442\u043e\u0442 \u0442\u0435\u043a\u0441\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c. \u0421 \u0442\u0435\u043c\u0438 \u0436\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u0430\u043c\u0438, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0430\u043c\u0438 \u0441\u0442\u0440\u043e\u043a, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u043c\u0438 \u0438 \u0434\u0430\u0436\u0435 \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u043c\u0438 \u043a\u0443\u0441\u043a\u0430\u043c\u0438. \u042d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0445\u043e\u0447\u0435\u0442 \u0436\u0438\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 IDE.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 trivia \u043d\u0435 \u0432\u044b\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f. Lexer \u043f\u0440\u0438\u043a\u043b\u0435\u0438\u0432\u0430\u0435\u0442 leading \u0438 trailing trivia \u043a \u0442\u043e\u043a\u0435\u043d\u0430\u043c, \u0430 parser \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u044d\u0442\u0438 \u0442\u043e\u043a\u0435\u043d\u044b \u0432 \u0434\u0435\u0440\u0435\u0432\u043e. \u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0434\u0435\u0440\u0435\u0432\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f lossless: \u043e\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043c\u044b\u0441\u043b\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443, \u043d\u043e \u0438 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>state   count   =   0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0438<\/p>\n<pre><code>state count = 0;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0441\u0435\u043c\u0430\u043d\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043e\u0434\u043d\u043e \u0438 \u0442\u043e \u0436\u0435, \u043d\u043e \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0442\u0435\u043a\u0441\u0442\u044b. Parser \u043e\u0431\u044f\u0437\u0430\u043d \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043e\u0431\u0430 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430 \u0431\u0435\u0437 \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h3>\u0412\u0435\u0440\u0445\u043d\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430<\/h3>\n<p>\u0414\u043b\u044f Akbura \u0432\u0435\u0440\u0445\u043d\u0438\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u043a\u0430\u043a \u0441\u043f\u0438\u0441\u043e\u043a <code>AkTopLevelMember<\/code>:<\/p>\n<pre><code>using System;namespace Demo.App;state count = 0;&lt;Button&gt;    {count}&lt;\/Button&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u044d\u0442\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0442\u044c\u0441\u044f <code>using<\/code>, <code>namespace<\/code>, <code>inject<\/code>, <code>param<\/code>, <code>state<\/code>, <code>useEffect<\/code>, <code>command<\/code>, \u043e\u0431\u044b\u0447\u043d\u044b\u0435 C# statements, inline <code>@akcss<\/code> \u0438 markup root. Parser \u0441\u043c\u043e\u0442\u0440\u0438\u0442 \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043c\u0435\u0442\u043e\u0434 \u0440\u0430\u0437\u0431\u043e\u0440\u0430:<\/p>\n<pre><code class=\"cs\">internal GreenAkTopLevelMemberSyntax ParseCompilationUnitMember(){    return CurrentToken.Kind switch    {        SyntaxKind.AtToken when PeekToken(1).Kind == SyntaxKind.AkcssKeyword            =&gt; ParseInlineAkcssBlockSyntax(),        SyntaxKind.UsingKeyword            =&gt; ParseUsingDirectiveSyntax(),        SyntaxKind.GlobalKeyword when PeekToken(1).Kind == SyntaxKind.UsingKeyword            =&gt; ParseUsingDirectiveSyntax(),        SyntaxKind.NamespaceKeyword            =&gt; ParseNamespaceDeclarationSyntax(),        _ =&gt; ParseTopLevelMember()    };}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u0443\u0436\u0435 \u0432\u0438\u0434\u043d\u043e, \u043f\u043e\u0447\u0435\u043c\u0443 lexer mode \u0438 lookahead \u0442\u0430\u043a \u0432\u0430\u0436\u043d\u044b. \u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0441\u0438\u043c\u0432\u043e\u043b <code>&lt;<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u043e\u043c markup-\u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0447\u0430\u0441\u0442\u044c\u044e C# \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 <code>@<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0447\u0430\u043b\u043e\u043c inline Akcss, Akcss-\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u043e\u0439 \u0438\u043b\u0438 verbatim identifier. Parser \u0434\u043e\u043b\u0436\u0435\u043d \u0430\u043a\u043a\u0443\u0440\u0430\u0442\u043d\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043e\u0434\u0438\u043d \u0441\u0438\u043c\u0432\u043e\u043b.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e parser \u0441\u0442\u0440\u043e\u0438\u0442 \u0442\u0430\u043a\u0438\u0435 top-level members, \u043a\u0430\u043a \u043e\u043d \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0440\u0435\u0436\u0438\u043c\u044b lexer-\u0430 \u0438 \u043a\u0430\u043a \u0434\u0435\u043b\u0430\u0435\u0442 recovery, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u043f\u043e\u0447\u0442\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439, \u043d\u043e \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434.<\/p>\n<h3>ParseTopLevelMember<\/h3>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0445 file-level \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 parser \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0440\u0430\u0437\u0431\u043e\u0440 top-level member. \u0417\u0434\u0435\u0441\u044c \u043b\u043e\u0433\u0438\u043a\u0430 \u0435\u0449\u0451 \u043f\u0440\u043e\u0449\u0435: \u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u043e\u043a\u0435\u043d \u0438 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434.<\/p>\n<pre><code class=\"cs\">internal GreenAkTopLevelMemberSyntax ParseTopLevelMember(){    return CurrentToken.Kind switch    {        SyntaxKind.StateKeyword =&gt; ParseStateDeclaration(),        SyntaxKind.ParamKeyword =&gt; ParseParamDeclarationSyntax(),        SyntaxKind.InjectKeyword =&gt; ParseInjectDeclarationSyntax(),        SyntaxKind.CommandKeyword =&gt; ParseCommandDeclarationSyntax(),        SyntaxKind.UseEffectKeyword =&gt; ParseUseEffectDeclarationSyntax(),        SyntaxKind.LessThanToken =&gt; ParseMarkupRootSyntax(),        _ =&gt; ParseCSharpStatementSyntax()    };}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437 \u0442\u0435\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432, \u0433\u0434\u0435 \u0445\u043e\u0440\u043e\u0448\u043e \u0432\u0438\u0434\u043d\u043e, \u0447\u0442\u043e Akbura \u2014 \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u044f\u0437\u044b\u043a, \u0430 \u043d\u0430\u0434\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043d\u0430\u0434 C#. \u0412\u0441\u0451, \u0447\u0442\u043e parser \u043d\u0435 \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043b \u043a\u0430\u043a \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e Akbura, \u043e\u043d \u043e\u0442\u0434\u0430\u0451\u0442 \u0432 <code>ParseCSharpStatementSyntax<\/code>.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>state count = 0;if(count &gt; 10){    Console.WriteLine(count);}&lt;Button&gt;{count}&lt;\/Button&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0435\u0440\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443 parser \u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u0435\u0442 \u043a\u0430\u043a <code>StateDeclarationSyntax<\/code>, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u043a\u0430\u043a <code>MarkupRootSyntax<\/code>, \u0430 <code>if<\/code> \u0443\u0439\u0434\u0451\u0442 \u0432 C# statement. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u0437\u0430\u043d\u043e\u0432\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0432\u0435\u0441\u044c C# parser. \u042d\u0442\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0431\u0435\u0437\u0443\u043c\u0438\u0435\u043c \u0432 \u043f\u043b\u043e\u0445\u043e\u043c \u0441\u043c\u044b\u0441\u043b\u0435 \u0441\u043b\u043e\u0432\u0430.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0441\u0442\u0440\u0430\u0442\u0435\u0433\u0438\u044f \u0442\u0430\u043a\u0430\u044f:<\/p>\n<pre><code>Akbura-\u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f?  =&gt; \u043f\u0430\u0440\u0441\u0438\u043c \u0441\u0430\u043c\u0438markup?              =&gt; \u043f\u0430\u0440\u0441\u0438\u043c \u0441\u0430\u043c\u0438\u043e\u0431\u044b\u0447\u043d\u044b\u0439 C#?          =&gt; \u043e\u0442\u0434\u0430\u0451\u043c C# parser-\u0443<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0440\u0435\u0436\u0438\u043c\u043e\u0432 lexer-\u0430<\/h3>\n<p>\u0414\u043e \u044d\u0442\u043e\u0433\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 lexer \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c <code>TopLevel<\/code> \u0440\u0435\u0436\u0438\u043c\u0435. \u041d\u043e \u0432\u043d\u0443\u0442\u0440\u0438 Akbura \u0435\u0441\u0442\u044c \u0443\u0447\u0430\u0441\u0442\u043a\u0438, \u0433\u0434\u0435 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0442\u0435\u043a\u0441\u0442 \u043d\u0443\u0436\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443.<\/p>\n<p>\u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, inline Akcss:<\/p>\n<pre><code>@akcss {    .card {        Padding: 12;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0440\u0435\u0436\u0438\u043c\u0435 \u0442\u043e\u0447\u043a\u0430 <code>.<\/code> \u0438 <code>@<\/code> \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d \u0441\u043c\u044b\u0441\u043b, \u0430 \u0432\u043d\u0443\u0442\u0440\u0438 Akcss \u2014 \u0434\u0440\u0443\u0433\u043e\u0439. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0434 \u0440\u0430\u0437\u0431\u043e\u0440\u043e\u043c inline Akcss parser \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442 lexer mode:<\/p>\n<pre><code class=\"cs\">internal GreenInlineAkcssBlockSyntax ParseInlineAkcssBlockSyntax(){    var mode = _mode;    _mode = Lexer.LexerMode.InAkcss;    try    {        var atToken = EatToken(SyntaxKind.AtToken);        var akcssKeyword = EatToken(SyntaxKind.AkcssKeyword);        var openBrace = EatToken(SyntaxKind.OpenBraceToken);        var members = ParseAkcssTopLevelMemberList();        var closeBrace = EatToken(SyntaxKind.CloseBraceToken);        return GreenSyntaxFactory.InlineAkcssBlockSyntax(            atToken,            akcssKeyword,            openBrace,            members,            closeBrace);    }    finally    {        _mode = mode;    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>try\/finally<\/code> \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u0434\u0435\u043a\u043e\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439. Parser \u043c\u043e\u0436\u0435\u0442 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u0442\u044c \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u0439 \u043a\u043e\u0434, missing token, \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e, \u043d\u043e \u0440\u0435\u0436\u0438\u043c lexer-\u0430 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u0418\u043d\u0430\u0447\u0435 \u043e\u0434\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 <code>@akcss<\/code> \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0432\u0435\u0441\u044c \u043e\u0441\u0442\u0430\u0442\u043e\u043a \u0444\u0430\u0439\u043b\u0430.<\/p>\n<p>\u0422\u0430\u043a\u0430\u044f \u0436\u0435 \u0438\u0434\u0435\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0438 \u0434\u043b\u044f C# \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 <code>state<\/code>:<\/p>\n<pre><code>state count = 10 + GetDefaultCount();<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0430\u0432\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u044d\u0442\u043e C# expression. Akbura parser \u043d\u0435 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 \u0435\u0433\u043e \u043f\u043e \u043e\u043f\u0435\u0440\u0430\u0442\u043e\u0440\u0430\u043c. \u041e\u043d \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442 lexer \u0432 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0440\u0435\u0436\u0438\u043c, \u0437\u0430\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0434\u0438\u043d <code>CSharpRawToken<\/code>, \u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043d\u0435\u0433\u043e \u0443\u0436\u0435 \u043b\u0435\u0436\u0438\u0442 Roslyn-\u043e\u0432\u0441\u043a\u0430\u044f C# \u043d\u043e\u0434\u0430.<\/p>\n<pre><code class=\"cs\">private GreenCSharpExpressionSyntax ParseCSharpExpressionInMode(    Lexer.LexerMode expressionMode){    var mode = _mode;    _mode = expressionMode;    var token = EatToken();    _mode = mode;    return GreenSyntaxFactory.CSharpExpressionSyntax(token);}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044e C# \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 raw-\u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e Akbura parser-\u0443 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d <code>a + b * c<\/code>, lambda expression \u0438\u043b\u0438 generic method call. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443\u0436\u0435 \u0435\u0441\u0442\u044c Roslyn.<\/p>\n<h3>C# block \u043a\u0430\u043a \u0441\u043c\u0435\u0448\u0430\u043d\u043d\u044b\u0439 \u0431\u043b\u043e\u043a<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u2014 \u0431\u043b\u043e\u043a\u0438 C# control flow. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>if(isOpen){    Console.WriteLine(\"Opened\");    &lt;TextBlock Text=\"Opened!\"\/&gt;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043d\u0435 Razor-style <code>@if<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 markup. \u042d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 C# <code>if<\/code> \u043d\u0430 top-level, \u043d\u043e \u0435\u0433\u043e \u0442\u0435\u043b\u043e \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u0438 C# statements, \u0438 markup. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 <code>CSharpBlockSyntax<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 Akbura \u0445\u0440\u0430\u043d\u0438\u0442 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043f\u0438\u0441\u043e\u043a C# \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0430 \u0441\u043f\u0438\u0441\u043e\u043a <code>AkTopLevelMember<\/code>.<\/p>\n<pre><code class=\"cs\">private GreenCSharpBlockSyntax ParseCSharpBlock(){    var openBraceToken = EatToken(SyntaxKind.OpenBraceToken);    var members = _pool.Allocate&lt;GreenAkTopLevelMemberSyntax&gt;();    try    {        while (CurrentToken.Kind is not               (SyntaxKind.EndOfFileToken or SyntaxKind.CloseBraceToken))        {            var member = ParseTopLevelMember();            members.Add(member);        }        var closeBraceToken = EatToken(SyntaxKind.CloseBraceToken);        return GreenSyntaxFactory.CSharpBlockSyntax(            openBraceToken,            members.ToList(),            closeBraceToken);    }    finally    {        _pool.Free(members);    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u043d\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <code>ParseTopLevelMember<\/code>, \u0430 \u043d\u0435 <code>ParseCompilationUnitMember<\/code>. \u042d\u0442\u043e \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0435, \u043d\u043e \u0432\u0430\u0436\u043d\u043e\u0435 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435: \u0432\u043d\u0443\u0442\u0440\u0438 C# \u0431\u043b\u043e\u043a\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c <code>state<\/code>, markup \u0438\u043b\u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 C# statements, \u043d\u043e file-level <code>using<\/code>, <code>namespace<\/code> \u0438 <code>@akcss<\/code> \u0442\u0443\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u043a\u0430\u043a \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438.<\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c:<\/p>\n<pre><code>if(isOpen){    Console.WriteLine(\"Hello\");    &lt;TextBlock Text=\"Opened\" \/&gt;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441 markup-internal control flow \u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u043b:<\/p>\n<pre><code>&lt;Button&gt;    @if(isOpen)    {        &lt;TextBlock \/&gt;    }&lt;\/Button&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u0443\u0436\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u044f\u0437\u044b\u043a \u0438 \u0434\u0440\u0443\u0433\u0430\u044f \u043c\u043e\u0434\u0435\u043b\u044c \u0440\u0435\u043d\u0434\u0435\u0440\u0430. \u0421\u0435\u0439\u0447\u0430\u0441 \u0443\u0441\u043b\u043e\u0432\u043d\u044b\u0439 rendering \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 C# control flow \u043d\u0430 top-level \u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0441\u043a\u0440\u044b\u0442\u0438\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 <code>IsVisible={isOpen}<\/code>.<\/p>\n<h3>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e<\/h3>\n<p>\u041f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0435 \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438:<\/p>\n<pre><code>Lexer       =&gt; \u0440\u0435\u0436\u0435\u0442 \u0442\u0435\u043a\u0441\u0442 \u043d\u0430 \u0442\u043e\u043a\u0435\u043d\u044b \u0438 raw C# \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044bParser      =&gt; \u0441\u0442\u0440\u043e\u0438\u0442 lossless syntax treeRoslyn      =&gt; \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0435\u0442 C# expressions\/statements\/typesSemantics   =&gt; \u043f\u043e\u0437\u0436\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442 \u0441\u043c\u044b\u0441\u043bCodegen     =&gt; \u043f\u043e\u0437\u0436\u0435 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442 \u0434\u0435\u0440\u0435\u0432\u043e \u0432 C# \u043a\u043e\u0434<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Parser \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 <code>DashboardViewModel<\/code>, \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u043b\u0438 \u0442\u0438\u043f \u0443 <code>UserId<\/code>, \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c utility <code>.gap-(double value)<\/code> \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0443, \u0438 \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 <code>SelectedTask<\/code>. \u0412\u0441\u0451 \u044d\u0442\u043e \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043d\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u044d\u0442\u0430\u043f\u0430\u0445.<\/p>\n<p>\u041d\u0430 \u044d\u0442\u0430\u043f\u0435 parser-\u0430 \u0432\u0430\u0436\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0435:<\/p>\n<pre><code>\u043d\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u0442\u044c \u0442\u0435\u043a\u0441\u0442\u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u043f\u043e\u0445\u043e\u0436\u0443\u044e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443\u043d\u0435 \u0443\u043f\u0430\u0441\u0442\u044c \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0435\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0434\u043b\u044f semantic layer<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u0442\u0430\u043a\u043e\u0439 \u0431\u0430\u0437\u043e\u0439 \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c: <code>state<\/code>, <code>param<\/code>, <code>inject<\/code>, <code>useEffect<\/code>, <code>command<\/code>, markup \u0438 inline Akcss.<\/p>\n<h2>\u0420\u0430\u0437\u0431\u043e\u0440 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u043e \u043f\u0440\u043e\u0439\u0442\u0438\u0441\u044c \u043f\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 parser \u0443\u0436\u0435 \u0443\u043c\u0435\u0435\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c. \u041f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435 \u043e\u043d\u0438 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u0448\u0430\u0431\u043b\u043e\u043d\u0443: parser \u0441\u044a\u0435\u0434\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0445 \u0442\u043e\u043a\u0435\u043d\u043e\u0432, \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u0441\u043b\u043e\u0436\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u0438 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 green node \u0447\u0435\u0440\u0435\u0437 <code>GreenSyntaxFactory<\/code>.<\/p>\n<h3>State, param \u0438 inject<\/h3>\n<p>\u0421\u0430\u043c\u044b\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u0432\u044b\u0433\u043b\u044f\u0434\u044f\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>inject ILogger&lt;DashboardPage&gt; log;param int UserId = 1;param bind string Search = \"\";state bool isOpen = false;state ReactList tasks = bind viewModel.Tasks;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0423 <code>inject<\/code> \u0435\u0441\u0442\u044c keyword, \u0442\u0438\u043f, \u0438\u043c\u044f \u0438 <code>;<\/code>.<\/p>\n<p>\u0423 <code>param<\/code> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f binding keyword, optional type \u0438 optional default value.<\/p>\n<p>\u0423 <code>state<\/code> \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f initializer. \u041e\u043d \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044b\u0447\u043d\u044b\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c \u0438\u043b\u0438 bindable initializer:<\/p>\n<pre><code>state count = 0;state tasks = bind viewModel.Tasks;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Parser \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u043b\u0438 <code>viewModel.Tasks<\/code>, \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442 \u043b\u0438 \u0442\u0438\u043f \u0438 \u043c\u043e\u0436\u043d\u043e \u043b\u0438 \u0442\u0430\u043a\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u0442\u044c \u043a state. \u041e\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u0440\u043e\u0438\u0442 \u0444\u043e\u0440\u043c\u0443:<\/p>\n<pre><code>StateKeywordType?NameEqualsInitializerSemicolon<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0441\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0442\u0438\u043f\u043e\u0432 \u0438 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u0434\u043b\u044f semantic layer.<\/p>\n<h3>useEffect<\/h3>\n<p><code>useEffect<\/code> \u0447\u0443\u0442\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0443 \u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 block \u0438 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 <code>cancel<\/code> \/ <code>finally<\/code> blocks:<\/p>\n<pre><code>useEffect(UserId, Search) {    log.LogInformation(\"Loading user\");}cancel {    log.LogInformation(\"Cancelled\");}finally {    log.LogInformation(\"Done\");}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Parser \u0447\u0438\u0442\u0430\u0435\u0442 dependency list \u043a\u0430\u043a \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0451\u043d, \u0437\u0430\u0442\u0435\u043c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 C# block. \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u0433\u043e \u043e\u043d \u0441\u043c\u043e\u0442\u0440\u0438\u0442, \u0438\u0434\u0443\u0442 \u043b\u0438 <code>cancel<\/code> \u0438 <code>finally<\/code>.<\/p>\n<p>\u0421\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438 \u044d\u0442\u043e \u043e\u0434\u043d\u0430 top-level \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 <code>AkburaDocumentSyntax.Members<\/code> \u0432\u0435\u0441\u044c \u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u044b\u0448\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u044d\u043b\u0435\u043c\u0435\u043d\u0442: <code>UseEffectDeclarationSyntax<\/code>.<\/p>\n<p>\u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0438. Semantic layer \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 block, cancel block \u0438 finally block \u043a\u0430\u043a \u0447\u0430\u0441\u0442\u0438 \u043e\u0434\u043d\u043e\u0433\u043e \u044d\u0444\u0444\u0435\u043a\u0442\u0430.<\/p>\n<h3>command<\/h3>\n<p><code>command<\/code> \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u0430\u043a\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f:<\/p>\n<pre><code>command Task Refresh(int userId);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c parser \u0447\u0438\u0442\u0430\u0435\u0442 return type, \u0438\u043c\u044f, parameter list \u0438 semicolon. \u0422\u0435\u043b\u043e \u0443 <code>command<\/code> \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442. \u0421\u043c\u044b\u0441\u043b \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f \u043f\u043e\u0437\u0436\u0435, \u043a\u043e\u0433\u0434\u0430 codegen \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442 \u0435\u0451 \u0432 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u043c.<\/p>\n<p>\u041d\u0430 \u0443\u0440\u043e\u0432\u043d\u0435 parser-\u0430 \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0446\u0438\u044f:<\/p>\n<pre><code>CommandKeywordReturnTypeNameParameterListSemicolon<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>Markup<\/h3>\n<p>Markup &#8212; \u0441\u0430\u043c\u0430\u044f \u0437\u0430\u043c\u0435\u0442\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u044f\u0437\u044b\u043a\u0430:<\/p>\n<pre><code>&lt;StackPanel class=\"card\" gap-4 p-4 {isBusy}:opacity-50&gt;    &lt;TextBlock Text=\"Dashboard\" \/&gt;    &lt;Button OnClick={count++}&gt;Open&lt;\/Button&gt;&lt;\/StackPanel&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Parser \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0441 <code>&lt;<\/code>, \u0447\u0438\u0442\u0430\u0435\u0442 \u0438\u043c\u044f \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430, \u0437\u0430\u0442\u0435\u043c \u0441\u043f\u0438\u0441\u043e\u043a attributes \u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0438\u0439 token <code>&gt;<\/code> \u0438\u043b\u0438 <code>\/&gt;<\/code>.<\/p>\n<p>Attributes \u0434\u0435\u043b\u044f\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0434\u043e\u0432:<\/p>\n<pre><code>Title=\"Dashboard\"bind:Value={Search}out:Selected={SelectedTask}w-30gap-4{isBusy}:opacity-50<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0431\u044b\u0447\u043d\u044b\u0435 attributes \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f <code>MarkupPlainAttributeSyntax<\/code>.<\/p>\n<p><code>bind:<\/code> \u0438 <code>out:<\/code> \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f <code>MarkupPrefixedAttributeSyntax<\/code>.<\/p>\n<p>Tailwind-like attributes \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f <code>TailwindAttributeSyntax<\/code>. \u0423 \u043d\u0438\u0445 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c simple prefix, expression prefix, numeric segment \u0438\u043b\u0438 expression segment:<\/p>\n<pre><code>md:w-40{isMobile}:h-15p-{size}gap-{state * 2}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 body parser \u0447\u0438\u0442\u0430\u0435\u0442 \u0442\u0435\u043a\u0441\u0442, inline expressions \u0438 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b:<\/p>\n<pre><code>&lt;Button&gt;    Hello {name}    &lt;Icon Name=\"save\" \/&gt;&lt;\/Button&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>Inline expression \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043a\u0430\u043a <code>{ expr }<\/code>, \u0433\u0434\u0435 <code>expr<\/code> \u0441\u043d\u043e\u0432\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 \u0432 C# expression mode.<\/p>\n<h3>Inline Akcss<\/h3>\n<p>Inline Akcss \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0442\u0438\u043b\u0438 \u043f\u0440\u044f\u043c\u043e \u0432 <code>.akbura<\/code> \u0444\u0430\u0439\u043b\u0435:<\/p>\n<pre><code>@akcss {    .card {        Padding: 12;        @if(IsHovered) {            Background: \"AliceBlue\";        }    }    @utilities {        .gap-(double value) {            RowGap: value * Spacing;        }    }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438 \u0432\u0445\u043e\u0434\u0435 \u0432 \u0442\u0430\u043a\u043e\u0439 block parser \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442 lexer \u0432 <code>InAkcss<\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 Akcss selectors, style rules, utilities, assignments \u0438 <code>@if<\/code>.<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0439 <code>}<\/code> \u0440\u0435\u0436\u0438\u043c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u044b\u0439 \u0438\u043d\u0432\u0430\u0440\u0438\u0430\u043d\u0442: \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 block \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043c\u0435\u043d\u044f\u0442\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0442\u0435\u043d\u0438\u044f \u0432\u0441\u0435\u0433\u043e \u043e\u0441\u0442\u0430\u0432\u0448\u0435\u0433\u043e\u0441\u044f \u0444\u0430\u0439\u043b\u0430.<\/p>\n<h2>Recovery \u0438 \u0442\u0435\u0441\u0442\u044b<\/h2>\n<p>\u0414\u043b\u044f parser-\u0430 \u043c\u0430\u043b\u043e \u043f\u0440\u043e\u0439\u0442\u0438 happy path. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u043e\u043b\u044c\u0448\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0438\u0448\u0435\u0442 \u043a\u043e\u0434 \u0432 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u043e\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438: \u0433\u0434\u0435-\u0442\u043e \u043d\u0435\u0442 <code>;<\/code>, \u0433\u0434\u0435-\u0442\u043e \u043d\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0430 <code>}<\/code>, \u0433\u0434\u0435-\u0442\u043e attribute \u043d\u0430\u0447\u0430\u0442 \u0438 \u043d\u0435 \u0437\u0430\u043a\u043e\u043d\u0447\u0435\u043d.<\/p>\n<p>\u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0435\u0441\u0442\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442 \u0434\u0432\u0435 \u0432\u0435\u0449\u0438.<\/p>\n<p>\u041f\u0435\u0440\u0432\u0430\u044f: \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0441\u0442\u0440\u043e\u044f\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u044b\u0435 node types.<\/p>\n<pre><code class=\"cs\">Assert.IsType&lt;GreenStateDeclarationSyntax&gt;(syntax.Members[0]);Assert.IsType&lt;GreenMarkupRootSyntax&gt;(syntax.Members[1]);<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0442\u043e\u0440\u0430\u044f: \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e.<\/p>\n<pre><code class=\"cs\">Assert.Equal(code, syntax.ToFullString());<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043b\u043e\u0432\u0438\u0442 \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c. \u0415\u0441\u043b\u0438 parser \u043f\u043e\u0442\u0435\u0440\u044f\u043b \u043f\u0440\u043e\u0431\u0435\u043b, \u043f\u0435\u0440\u0435\u043d\u043e\u0441 \u0441\u0442\u0440\u043e\u043a\u0438, \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u0439 attribute \u0438\u043b\u0438 \u043d\u0435\u043e\u0436\u0438\u0434\u0430\u043d\u043d\u044b\u0439 token, \u0442\u0435\u0441\u0442 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043a\u0430\u0436\u0435\u0442 \u0440\u0430\u0441\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435.<\/p>\n<p>\u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0441\u043b\u043e\u043c\u0430\u043d\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438:<\/p>\n<pre><code>state count = ;&lt;Button @if(isOpen)&gt;@akcss<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0438\u0435 \u0441\u043b\u0443\u0447\u0430\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0434\u0430\u0432\u0430\u0442\u044c diagnostics \u0438 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e. IDE \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043e\u0448\u0438\u0431\u043a\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u043f\u043e\u0434\u0441\u0432\u0435\u0442\u043a\u0443 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<h2>\u0418\u0442\u043e\u0433<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u044b\u0439 lexer \u0438 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0431\u043e\u0447\u0438\u0439 parser \u0434\u043b\u044f Akbura.<\/p>\n<p>\u041c\u044b \u0432\u0437\u044f\u043b\u0438 <code>SourceText<\/code>, \u0441\u0434\u0435\u043b\u0430\u043b\u0438 <code>SlidingTextWindow<\/code>, \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a, \u043d\u0430\u0443\u0447\u0438\u043b\u0438 lexer \u0447\u0438\u0442\u0430\u0442\u044c \u0442\u043e\u043a\u0435\u043d\u044b, trivia \u0438 C# raw fragments. \u0417\u0430\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 quick scanner, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u0440\u043e\u0441\u0442\u043e\u0439, \u043f\u043e\u0442\u043e\u043c \u0442\u0430\u0431\u043b\u0438\u0447\u043d\u044b\u0439 DFA. \u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e parser \u043d\u0430\u0447\u0430\u043b \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c lossless syntax tree: top-level declarations, C# blocks, markup, Tailwind-like attributes \u0438 inline Akcss.<\/p>\n<p>\u0413\u043b\u0430\u0432\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438: <code>.akbura<\/code> \u0444\u0430\u0439\u043b \u0443\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c \u0432 \u0434\u0435\u0440\u0435\u0432\u043e, \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442 \u0447\u0435\u0440\u0435\u0437 <code>ToFullString()<\/code> \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0434\u043b\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u044d\u0442\u0430\u043f\u043e\u0432.<\/p>\n<p>\u0414\u0430\u043b\u044c\u0448\u0435 \u043f\u0443\u0442\u044c \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0435. \u0418\u0438\u0438\u0438 \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u2014 \u044d\u0442\u043e blender. \u041b\u0430\u0434\u043d\u043e \u0431\u044b \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 Akbura, \u0441 \u043d\u0438\u043c\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u0435\u0433\u043a\u043e, \u043d\u043e \u043a\u0430\u043a \u0431\u044b\u0442\u044c \u0441 C#? \u041e\u0434\u0438\u043d \u0442\u043e\u043a\u0435\u043d \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0435\u0441\u043b\u043e\u0436\u043d\u043e, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/learn.microsoft.com\/lb-lu\/dotnet\/api\/microsoft.codeanalysis.csharp.syntaxtokenparser?view=roslyn-dotnet-5.0.0\" rel=\"noopener noreferrer nofollow\">SyntaxTokenParser<\/a>. \u041d\u043e \u043a\u0430\u043a \u0431\u044b\u0442\u044c \u0441 \u0446\u0435\u043b\u044b\u043c\u0438 \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u043c\u0438? \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0441\u0442\u0443\u0447\u0430\u0442\u044c\u0441\u044f \u0432 \u0441\u0430\u043c Roslyn \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043c pull request, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043c\u0435\u0442\u043e\u0434 \u0432\u0440\u043e\u0434\u0435 <code>SyntaxFactory.Reparse&lt;T&gt;(T, TextChangeEventArgs) where T : SyntaxNode<\/code>. \u041d\u043e \u043d\u0435 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u044d\u0442\u043e\u0433\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0434\u0430 \u0438 \u0432\u0440\u044f\u0434 \u043b\u0438 \u043e\u043d\u0438 \u0441\u043e\u0433\u043b\u0430\u0441\u044f\u0442\u0441\u044f \u0442\u0430\u043a\u043e\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u0430\u0436\u0435 \u0441 \u043f\u043e\u043c\u0435\u0442\u043a\u043e\u0439 <code>RSEXPERIMENTAL<\/code>.<\/p>\n<p>\u0418 \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u0434\u043b\u044f \u043c\u0435\u043d\u044f \u043b\u0438\u0447\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043b, \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u043b \u0438 \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043b Roslyn \u043f\u043e\u0434 \u0441\u0435\u0431\u044f, \u0430 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c \u0433\u043e\u043b\u043e\u0432\u043e\u0439.<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1042432\/\">https:\/\/habr.com\/ru\/articles\/1042432\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0414\u0430\u0432\u043d\u043e \u043d\u0435 \u0431\u044b\u043b\u043e \u0441\u0442\u0430\u0442\u044c\u0435\u0439, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0435\u043b \u0432\u044b\u043f\u0443\u0441\u043a\u0430\u0442\u044c 1 \u0441\u0442\u0430\u0442\u044c\u044e \u0432 \u0440\u0430\u0437 \u043d\u0435\u0434\u0435\u043b\u044e, \u043d\u043e \u043d\u0435 \u0443\u0441\u043f\u0435\u0432\u0430\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0430\u0431\u0440\u043e\u0441\u0438\u043b \u0438 \u043d\u0430\u0447\u0430\u043b \u043f\u043e\u0438\u0441\u043a \u0440\u0430\u0431\u043e\u0442\u044b. \u041d\u0435 \u0434\u0430\u0432\u043d\u043e \u0440\u0435\u0448\u0438\u043b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u0438 \u043a\u0430\u043a\u043e\u0433\u043e \u0431\u044b\u043b\u043e \u043c\u043e\u0435 \u0443\u0434\u0438\u0432\u043b\u0435\u043d\u0438\u0435 \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u044b \u043e\u0441\u0442\u0430\u0432\u0430\u043b\u043e\u0441\u044c \u043d\u0430 3 \u0434\u043d\u044f. \u0427\u0442\u043e\u0436 \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0441\u0435\u0440\u0438\u044e \u044f \u0432\u044b\u043f\u0438\u0448\u0443 \u0431\u044b\u0441\u0442\u0440\u0435\u0435.\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0438\u043d\u0442\u0430\u043a\u0441\u0438\u0441\u041f\u0438\u0448\u0435\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0421\u043e\u0431\u0438\u0440\u0430\u0435\u043c blender\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430\u0418\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u0443\u0435\u043c Language Server Protocol \u0438 \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0443 \u0432 Visual Studio\u0413\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u0434\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 SourceText\u041c\u044b, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 SourceText, \u043d\u043e \u0432 \u044d\u0442\u043e\u043c \u043e\u0442\u043a\u0440\u043e\u0432\u0435\u043d\u043d\u043e \u043c\u0430\u043b\u043e \u0441\u043c\u044b\u0441\u043b\u0430. \u0412 Roslyn \u0443\u0436\u0435 \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u0430\u044f \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0435\u043a\u0441\u0442\u0430, \u0438 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0451, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430, \u0443 \u043d\u0435\u0451 \u0443\u0436\u0435 \u0435\u0441\u0442\u044c: \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0438\u043c\u0432\u043e\u043b\u0430\u043c \u043f\u043e \u0438\u043d\u0434\u0435\u043a\u0441\u0443, \u0434\u043b\u0438\u043d\u0430 \u0442\u0435\u043a\u0441\u0442\u0430, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441\u043e \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u0434\u0441\u0442\u0440\u043e\u043a, \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 checksum \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0442\u0435\u043a\u0441\u0442\u0430 \u0438\u0437 \u0441\u0442\u0440\u043e\u043a\u0438, \u043f\u043e\u0442\u043e\u043a\u0430 \u0438\u043b\u0438 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0431\u0430\u0439\u0442\u043e\u0432.\u0427\u0435\u043c \u0436\u0435 \u043e\u043d \u0442\u0430\u043a \u043f\u043e\u043b\u0435\u0437\u0435\u043d? \u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043c\u043e\u0436\u043d\u043e \u043c\u0435\u043d\u044c\u0448\u0435 \u0434\u0443\u043c\u0430\u0442\u044c \u043e \u043d\u0438\u0437\u043a\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0430\u043c\u0438. SourceText \u0443\u043c\u0435\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u043a\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0430 \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u0430\u0440\u0441\u0435\u0440\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0435 \u0441 \u0431\u0430\u0439\u0442\u0430\u043c\u0438, \u0430 \u0441 \u043f\u0440\u0438\u0432\u044b\u0447\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0434\u043e\u0442\u043d\u0435\u0442\u0430 \u0441\u0442\u0440\u043e\u043a\u0430\u043c\u0438 \u0438 char. \u042d\u0442\u043e \u0441\u0438\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u043a\u043e\u0434 \u043b\u0435\u043a\u0441\u0435\u0440\u0430 \u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430.\u0412\u043e-\u0432\u0442\u043e\u0440\u044b\u0445, SourceText \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439. \u0412\u043d\u0443\u0442\u0440\u0438 Roslyn \u0435\u0441\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432: \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442, \u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0442\u0435\u043a\u0441\u0442, \u0442\u0435\u043a\u0441\u0442 \u043f\u043e\u0441\u043b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0438 \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0438\u0437 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432. \u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0440\u0435\u0448\u0430\u0442\u044c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u0444\u0430\u0439\u043b \u0432 \u043f\u0430\u043c\u044f\u0442\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u043f\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0443\u0436\u0435 \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 Roslyn.\u041f\u043e\u044d\u0442\u043e\u043c\u0443, \u043f\u043e\u0438\u0437\u0443\u0447\u0430\u0432 \u044d\u0442\u043e\u0442 \u0432\u043e\u043f\u0440\u043e\u0441, \u044f \u0440\u0435\u0448\u0438\u043b \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u044e SourceText, \u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0443\u044e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0432 \u0431\u0443\u0434\u0443\u0449\u0435\u043c \u043c\u043d\u0435 \u044d\u0442\u043e \u0430\u0443\u043a\u043d\u0435\u0442\u0441\u044f \u043a\u0441\u0442\u0430\u0442\u0438, \u043d\u043e \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0447\u0442\u043e \u043d\u0435\u0442.TextWindow\u041d\u043e \u043a\u0430\u043a \u044f \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b \u0440\u0430\u043d\u0435\u0435 SourceText \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0438\u0437 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u043e\u0432 \u0442\u0435\u043a\u0441\u0442\u0430, \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0441\u0438\u043c\u0432\u043e\u043b\u0443 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435 \u0438\u0437-\u0437\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0431\u0430\u043d\u0430\u043b\u044c\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043a\u0443\u0441\u043e\u043a \u0442\u0435\u043a\u0441\u0442\u0430using Microsoft.CodeAnalysis.Text;namespace Akbura.Language;internal struct SlidingTextWindow{    public const char InvalidCharacter = char.MaxValue;    public const int DefaultWindowLength = 1024;    private static readonly ObjectPool&lt;char[]&gt; s_windowPool =        new(() =&gt; new char[DefaultWindowLength]);    public SourceText Text { get; }    private readonly int _textEnd;    private int _positionInText;    private ArraySegment&lt;char&gt; _characterWindow;    private int _characterWindowStartPositionInText;    public SlidingTextWindow(SourceText text)    {        Text = text;        _textEnd = text.Length;        _characterWindow = new ArraySegment&lt;char&gt;(s_windowPool.Allocate());        ReadChunkAt(0);    }    private void ReadChunkAt(int position)    {        position = Math.Min(position, _textEnd);        var amountToRead = Math.Min(_textEnd &#8212; position, DefaultWindowLength);        Text.CopyTo(            position,            _characterWindow.Array!,            0,            amountToRead);        _characterWindowStartPositionInText = position;        _characterWindow = new(_characterWindow.Array!, 0, amountToRead);    }    public readonly int Position =&gt; _positionInText;    public readonly ReadOnlySpan&lt;char&gt; CurrentWindowSpan    {        get        {            var start = _positionInText &#8212; _characterWindowStartPositionInText;            return start &lt; 0 || start &gt;= _characterWindow.Count                ? default                : _characterWindow.AsSpan(start);        }    }    private readonly int CharacterWindowEndPositionInText =&gt;        _characterWindowStartPositionInText + _characterWindow.Count;    private readonly bool PositionIsWithinWindow(int position)    {        return position &gt;= _characterWindowStartPositionInText &amp;&amp;               position &lt; CharacterWindowEndPositionInText;    }    public void Reset(int position)    {        _positionInText = Math.Min(position, _textEnd);        if (PositionIsWithinWindow(_positionInText))        {            return;        }        ReadChunkAt(_positionInText);    }    public readonly bool IsReallyAtEnd()    {        return Position &gt;= _textEnd;    }    public void AdvanceChar(int count)    {        _positionInText += count;    }    public char PeekChar()    {        if (IsReallyAtEnd())        {            return InvalidCharacter;        }        var position = _positionInText;        if (!PositionIsWithinWindow(position))        {            ReadChunkAt(position);        }        return _characterWindow.Array![position &#8212; _characterWindowStartPositionInText];    }}\u0421\u043f\u0440\u0430\u0432\u0435\u0434\u043b\u0438\u0432\u043e\u0441\u0442\u0438 \u0440\u0430\u0434\u0438 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u0442\u0438\u043c \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f TextWindow, \u043d\u043e \u044d\u0442\u0430 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u044b\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0430 \u043f\u043e \u0441\u0443\u0442\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0434\u0438 \u044d\u0442\u043e\u0433\u043e, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 API \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0435 \u0438 \u0443\u0434\u043e\u0431\u043d\u044b\u0435 \u043f\u043b\u044e\u0448\u043a\u0438.\u0418\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a\u0412 C# \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u043e\u0431\u044b\u0447\u043d\u043e \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u043a\u0430\u043a \u0440\u0430\u0437\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:var a = &#171;Hello&#187;;var b = &#171;Hello&#187;;Console.WriteLine($&#187;Is same object? {object.ReferenceEquals(a, b)}&#187;);\u0412 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u0435\u0432 \u044d\u0442\u043e\u0442 \u043a\u043e\u0434 \u0432\u044b\u0432\u0435\u0434\u0435\u0442 true, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432 intern pool. CLR \u0445\u0440\u0430\u043d\u0438\u0442 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0438\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a \u0438 \u043c\u043e\u0436\u0435\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u043e\u0434\u043d\u0443 \u0438 \u0442\u0443 \u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0443 \u0434\u043b\u044f \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0445 \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u0445 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439.\u041d\u043e \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0430\u0440\u0441\u0438\u043c, \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0443\u0436\u0435 \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u0432 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440, \u0442\u043e \u043f\u0440\u0438 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437\u043d\u044b\u0445 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 string \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c.button {    color: red;}button {    background: red;}\u0417\u0434\u0435\u0441\u044c button \u0438 red \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e. \u0415\u0441\u043b\u0438 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u043e\u043a\u0443, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0442\u0440\u0430\u0442\u0438\u0442\u044c \u043b\u0438\u0448\u043d\u044e\u044e \u043f\u0430\u043c\u044f\u0442\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 SlidingTextWindow(\u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u043f\u0440\u0438\u044f\u0442\u043d\u0430\u044f \u043f\u043b\u044e\u0448\u043a\u0430) \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0432\u043e\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0442\u0440\u043e\u043a. \u041e\u043d\u0430 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u044d\u0448: \u0435\u0441\u043b\u0438 \u0442\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u043b\u0430\u0441\u044c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439.internal struct SlidingTextWindow{    private readonly StringTable _strings;    public SlidingTextWindow(SourceText text)    {        this.Text = text;        _textEnd = text.Length;        _strings = StringTable.GetInstance();        _characterWindow = new ArraySegment&lt;char&gt;(s_windowPool.Allocate());        \/\/ Read the first chunk of the file into the character window.        this.ReadChunkAt(0);    }    public readonly string Intern(StringBuilder text)    {        return _strings.Add(text);    }    public readonly string Intern(char[] array, int start, int length)        =&gt; Intern(array.AsSpan(start, length));    public readonly string Intern(ReadOnlySpan&lt;char&gt; chars)        =&gt; _strings.Add(chars);}\u0412\u0430\u0436\u043d\u043e, \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043d\u0435 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 string.Intern, \u0430 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 StringTable. \u042d\u0442\u043e \u043f\u043e\u043b\u0435\u0437\u043d\u043e \u0434\u043b\u044f \u043f\u0430\u0440\u0441\u0435\u0440\u0430: \u0442\u0430\u0431\u043b\u0438\u0446\u0430 \u0436\u0438\u0432\u0451\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u043e\u043b\u044c\u043a\u043e, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0443\u0436\u0435\u043d SlidingTextWindow, \u0438 \u043d\u0435 \u0437\u0430\u0433\u0440\u044f\u0437\u043d\u044f\u0435\u0442 \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0439 intern pool \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.\u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0430\u0441\u0442\u043e \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u044e\u0449\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b, \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b, \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u043f\u0440\u043e\u0431\u0435\u043b\u044b. \u0422\u0430\u043a \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u0443\u0436\u0435 \u0437\u0430\u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0438 \u043f\u0443\u043d\u043a\u0442\u0443\u0430\u0446\u0438\u044f \u043a\u0441\u0442\u0430\u0442\u0438 \u0442\u043e\u0436\u0435.\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 StringTableStringTable \u044d\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0430\u044f \u0437\u0430\u043c\u0435\u043d\u0430 string.Intern, \u0430 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 lossy cache \u0441\u0442\u0440\u043e\u043a. \u041e\u043d \u043d\u0435 \u0445\u0440\u0430\u043d\u0438\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432\u0435\u0447\u043d\u043e \u0438 \u043d\u0435 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0434\u0435\u0434\u0443\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u0432\u0441\u0435\u0445 \u0441\u0442\u0440\u043e\u043a. \u0415\u0433\u043e \u0437\u0430\u0434\u0430\u0447\u0430 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u043f\u0440\u043e\u0449\u0435: \u0431\u044b\u0441\u0442\u0440\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0447\u0430\u0441\u0442\u043e \u0432\u0441\u0442\u0440\u0435\u0447\u0430\u044e\u0449\u0438\u0435\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u0430\u0440\u0441\u0438\u043d\u0433\u0430.\u0412\u043d\u0443\u0442\u0440\u0438 StringTable \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u0443\u0440\u043e\u0432\u043d\u044f \u043a\u044d\u0448\u0430: \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 L1-\u043a\u044d\u0448 \u0438 \u043e\u0431\u0449\u0438\u0439 shared L2-\u043a\u044d\u0448.\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u0442\u0440\u043e\u043a\u0430 \u0438\u0449\u0435\u0442\u0441\u044f \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435. \u042d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0431\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u0443\u0442\u044c: \u0438\u043d\u0434\u0435\u043a\u0441 \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0438\u0437 \u0445\u0435\u0448\u0430, \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c.private static int LocalIdxFromHash(int hash){    return hash &amp; LocalSizeMask;}\u0423\u043f\u0440\u043e\u0449\u0451\u043d\u043d\u043e \u044d\u0442\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:\u043f\u043e\u0441\u0447\u0438\u0442\u0430\u0442\u044c hash =&gt; \u0432\u0437\u044f\u0442\u044c \u043e\u0434\u0438\u043d \u0438\u043d\u0434\u0435\u043a\u0441 =&gt; \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u043e\u0434\u043d\u0443 \u0437\u0430\u043f\u0438\u0441\u044c\u0415\u0441\u043b\u0438 \u0437\u0430\u043f\u0438\u0441\u044c \u0441\u043e\u0432\u043f\u0430\u043b\u0430 \u043f\u043e \u0445\u0435\u0448\u0443 \u0438 \u0442\u0435\u043a\u0441\u0442\u0443, StringTable \u0441\u0440\u0430\u0437\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 string.\u0415\u0441\u043b\u0438 \u0432 L1-\u043a\u044d\u0448\u0435 \u043f\u0440\u043e\u043c\u0430\u0445, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u0449\u0438\u0439 shared L2-\u043a\u044d\u0448:private static readonly SegmentedArray&lt;Entry&gt; s_sharedTable = new(SharedSize);L2-\u043a\u044d\u0448 \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 StringTable, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043e\u043d \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0438 \u043c\u0435\u0436\u0434\u0443 \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0441\u0435\u0440\u0430\u043c\u0438. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0435\u0441\u043b\u0438 \u043e\u0434\u0438\u043d \u043f\u0430\u0440\u0441\u0435\u0440 \u0443\u0436\u0435 \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043b \u0441\u0442\u0440\u043e\u043a\u0443 button, \u0434\u0440\u0443\u0433\u043e\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043f\u0430\u0440\u0441\u0435\u0440\u0430 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u0442\u0440\u043e\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 shared-\u043a\u044d\u0448.\u041f\u043e\u0438\u0441\u043a \u0432 L2 \u0443\u0441\u0442\u0440\u043e\u0435\u043d \u0441\u043b\u043e\u0436\u043d\u0435\u0435. \u0422\u0430\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 bucket, \u0430 \u043e\u0431\u0445\u043e\u0434 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 quadratic probing.\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 quadratic probing? Quadratic probing \u2014 \u044d\u0442\u043e \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0431\u0445\u043e\u0434\u0430 bucket \u0432 hash table \u043f\u0440\u0438 \u043a\u043e\u043b\u043b\u0438\u0437\u0438\u044f\u0445. \u0415\u0441\u043b\u0438 \u043f\u0435\u0440\u0432\u0430\u044f \u044f\u0447\u0435\u0439\u043a\u0430 \u0437\u0430\u043d\u044f\u0442\u0430, \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u043f\u043e \u043a\u0432\u0430\u0434\u0440\u0430\u0442\u0438\u0447\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438: 0, 1, 3, 6, 10 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u0422\u0430\u043a\u043e\u0439 \u043e\u0431\u0445\u043e\u0434 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0438 \u0437\u0430\u043c\u0435\u043d\u044b \u043f\u043e bucket. for (var i = 1; i &lt; SharedBucketSize + 1; i++){    e = arr[idx].Text;    var hash = arr[idx].HashCode;    if (e != null)    {        if (hash == hashCode &amp;&amp; TextEquals(e, chars))        {            break;        }        e = null;    }    else    {        break;    }    idx = (idx + i) &amp; SharedSizeMask;}\u0418\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e L2-\u043a\u044d\u0448 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u044f\u0436\u0435\u043b\u0435\u0435, \u0447\u0435\u043c L1:\u043e\u043d \u043e\u0431\u0449\u0438\u0439 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440\u043e\u0432 StringTable;\u043e\u043d \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443;\u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442\u0441\u044f bucket;\u043f\u0440\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Volatile.Write;\u0434\u043b\u044f \u043e\u0431\u0449\u0435\u0433\u043e \u0441\u0447\u0451\u0442\u0447\u0438\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f Interlocked.Increment.\u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0430\u0448\u043b\u0430\u0441\u044c \u0432 shared-\u043a\u044d\u0448\u0435, \u043e\u043d\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u043b\u043e\u043a\u0430\u043b\u044c\u043d\u044b\u0439 L1-\u043a\u044d\u0448. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u044d\u0442\u043e\u0439 \u0436\u0435 \u0441\u0442\u0440\u043e\u043a\u0435 \u0443\u0436\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0439\u0442\u0438 \u043f\u043e \u0431\u044b\u0441\u0442\u0440\u043e\u043c\u0443 \u043f\u0443\u0442\u0438.\u0415\u0441\u043b\u0438 \u0441\u0442\u0440\u043e\u043a\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u043d\u0438 \u0432 L1, \u043d\u0438 \u0432 L2, \u043e\u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 ToString() \u0438\u043b\u0438 Substring(), \u043f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u043e\u0431\u0430 \u043a\u044d\u0448\u0430.\u0417\u0430\u043c\u0435\u043d\u0430 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 shared-\u043a\u044d\u0448\u0435Shared-\u043a\u044d\u0448 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d \u043f\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0443. \u041f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u0438 \u043a\u043e\u0434 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0439\u0442\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0432 bucket:for (var i = 1; i &lt; SharedBucketSize + 1; i++){    if (arr[curIdx].Text == null)    {        idx = curIdx;        goto foundIdx;    }    curIdx = (curIdx + i) &amp; SharedSizeMask;}\u0415\u0441\u043b\u0438 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430 \u043d\u0435\u0442, \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u044f \u0432\u043d\u0443\u0442\u0440\u0438 bucket \u0438 \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u043e\u043a\u043e\u0439.\u0414\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0435\u0448\u0451\u0432\u044b\u0439 \u043f\u0441\u0435\u0432\u0434\u043e\u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c. \u0421\u0447\u0451\u0442\u0447\u0438\u043a \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 Guid.NewGuid().GetHashCode():private int _localRandom = Guid.NewGuid().GetHashCode();private static int s_sharedRandom = Guid.NewGuid().GetHashCode();\u0414\u0430\u043b\u044c\u0448\u0435 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0432\u0435\u043b\u0438\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u0422\u0430\u043a\u043e\u0439 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043d\u0435 \u043f\u043e\u0445\u043e\u0436&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-481994","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481994","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=481994"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481994\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=481994"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=481994"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=481994"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}