Check syntax (string and character comparison)
I suggest making the code more expressive by encapsulating the conditions as lambdas before the loop.

You should avoid magic numbers and for the mode create constants or an enum.

In the following example the {} stand for a block and [] for an attribute.

private static bool CheckIfSyntaxIsValid(string input)
{
    var mode = 1;
    var last = ' ';

    var isEndOfEmptyBlock = new Func&lt;char, bool&gt;(c =&gt; last == '{' &amp;&amp; c == '}');
    var isBeginOfNestedBlock = new Func&lt;char, bool&gt;(c =&gt; last == '{' &amp;&amp; c == '{');
    var isEndOfEmptyAttribute = new Func&lt;char, bool&gt;(c =&gt; last == '[' &amp;&amp; c == ']');
    var isNotDigitInsideAttribute = new Func&lt;char, bool&gt;(c =&gt; last == '[' &amp;&amp; !Char.IsDigit(c));
    var isAttributeBegin = new Func&lt;char, bool&gt;(c =&gt; c == '[');
    var isAttributeEnd = new Func&lt;char, bool&gt;(c =&gt; c == ']');
    var isBlockBegin = new Func&lt;char, bool&gt;(c =&gt; c == '{');
    var isBlockEnd = new Func&lt;char, bool&gt;(c =&gt; c == '}');

    foreach (char c in input)
    {
        if (isEndOfEmptyBlock(c))
        {
            last = ' ';
            mode = 1;
            continue;
        }

        if (isBeginOfNestedBlock(c))
        {
            return false;
        }

        if (isEndOfEmptyAttribute(c))
        {
            last = ' ';
            mode = 2;
            continue;
        }

        if (isNotDigitInsideAttribute(c))
        {
            return false;
        }

        if (isAttributeBegin(c))
        {
            if (mode == 2)
            {
                return false;
            }
            last = c;
            mode = 1;
        }

        if (isBlockBegin(c))
        {
            if (mode == 1)
            {
                return false;
            }

            last = c;
            mode = 2;
        }

        if (isAttributeEnd(c) || isBlockEnd(c))
        {
            return false;
        }
    }

    if (last != ' ')
    {
        return false;
    }

    return true;
}