What different between inside and outside @tokens?

Parse content:

(test),(test

Fisrt grammer:

@top { statement+ }

statement { Test | Content }

Test { "(" Content ")" }

@tokens {
    Content { ![\n()]+ }
}

Parsed result:
Screenshot from 2020-04-14 17-59-09

Second grammar:

@top { statement+ }

statement { Test | Content }

@tokens {
    Test { "(" Content ")" }

    Content { ![\n()]+ }
}

Parsed result:
Screenshot from 2020-04-14 18-03-29

Why first grammar parse “(test” as Test node?

Tokens are always ‘atomic’, even if they use capitalized sub-rules. So in the second grammar, Content doesn’t even show up as a term in the generated parser, it’s conceptually inlined into Test.

Ok. But I still don’t understand why it parse "(test" as Test node in first grammar, "(test" is clearly missing ")" .

That’s why there is an error node after the Content node—the error correction broke off the Test rule early because it couldn’t produce a valid parse. Pass {strict: true} if you want the parser to throw an error in cases like that.

I get it now. Thank you.