Grammer Class/Production Rules of Programming Languages I'd read around on the interwebs, and a lot of the text indicated that many programming languages are generated by a context-free grammar, which leads me to 2 questions:

Doesn't variable scoping require a context-sensitive grammer?  Particularly, I'm thinking of the following valid C code:

int main(){
    int count=0;
    count++;
    return count;
}


As opposed to the following invalid C code:

int main(){
    count++;
    int count=0;
    return count;
}


There could also be some other stuff involving namespaces and classes for C++, or the '.' operator for C structs, for example.  I get the impression that, as a result, C (and various descendents) does (do) have context-sensitive aspects (though this may only be partial context-sensitivity).  Thus question 1:

Is it correct to say that C and some derivative languages, as well as some other languages, can only be generated by grammars with a minimum of context-sensitivity?

Secondly is there a relationship between language class and grammar class?

Particularly, I'm thinking of the language BrainF*** when I ask, since its syntax is clearly generated by a context-free grammar, yet its implementation is turing complete (assuming an implementation with an infinite tape).  Does this mean that there are languages that have regular grammars, yet are turing complete?
The issue is where you want to draw the line for what is considered "syntax". Sure, variable scoping typically requires context-sensitivity, but that doesn't need to be handled by the parser. The parser could just parse the syntax allowing out-of-scope variables, and a follow-on pass could check for out-of-scope errors. In practice, many real implementations of parser for real languages are context-sensitive, but this is handled in an ad-hoc manner by sharing state between productions and allowing "actions" to be attached to context-free productions. In particular, few (no?) languages use general-purpose context-sensitive parsing approaches. In fact, few uses general-purpose context-free parsing approaches. Instead, tooling for potentially limited classes of context-free grammars is used and, as mentioned, ad-hoc "semantic actions" lead to the parser actually being context-sensitive but this done in a way that is not captured by the context-free grammars that putatively describe the language.

In other words, a context-free grammar for a language often describes a larger language than what is actually accepted. But rejecting a program after parsing it for out-of-scope variables, say, is no different than rejecting it for having a type error. Type checking is almost never done while parsing. So what checks are done while parsing or later is usually done as a matter of convenience, and many aren't nicely described by a grammar.

The grammar complexity of the syntax has little to do with the computational complexity.  For example, every bit string is a syntactically (and semantically!) valid Jot program, and Jot is Turing-complete.