What is a syntax grammar?

A syntax grammar is a kind of grammar. It describes the order of lexical tokens in the sentences.

English

Here are a few syntax grammar rules for the English language:

A sentence has a subject, a predicate, and a period.
A noun phrase is a kind of subject.
A noun phrase has zero or more adjectives and a noun.
A verb phrase is a kind of predicate.
A verb phrase has a verb and zero or more adverbs.

An adjective modifies a noun.
An adverb modifies a verb.
A noun names a person, place, or thing.
A verb denotes action.

You could use those rules to produce this sentence:

sentence
|
+-------------------------+--------------+
|                         |              |
subject                   predicate      |
|                         |              |
noun phrase               verb phrase    |
|                         |              |
+---------+---------+     +-----+        |
|         |         |     |     |        |
adjective adjective noun  verb  adverb   |
|         |         |     |     |        |
Colorless green     ideas sleep furiously.

from here.

Although that sentence is valid syntax, it is semantic nonsense.

Here are some of the reasons why that sentence is semantic nonsense:

A noun cannot be both "colorless" and "green".
An "idea" cannot be "green".
An "idea" cannot be "colorless".
An "idea" cannot "sleep".
A noun cannot "sleep" "furiously".

C++

The C++ Standard, in Appendix A, contains syntax grammar rules, some of which can be paraphrased in English as follows:

A simple-declaration has one or more decl-specifier's, zero or more init-declarator's, and a semicolon.
A function-specifier is a kind of decl-specifier.
A storage-class-specifier is a kind of decl-specifier.
A type-specifier is a kind of decl-specifier.
"constexpr" is a kind of decl-specifier.
"friend" is a kind of decl-specifier.
"inline" is a kind of decl-specifier.
"typedef" is a kind of decl-specifier.
"explicit" is a kind of function-specifier.
"virtual" is a kind of function-specifier.
"extern" is a kind of storage-class-specifier.
"mutable" is a kind of storage-class-specifier.
"static" is a kind of storage-class-specifier.
"thread_local" is a kind of storage-class-specifier.
A class-specifier is a kind of type-specifier.
A enum-specifier is a kind of type-specifier.

You could use those rules to produce this sentence:

simple-declaration
|
+--------------+--------------+--------------+------------------+-----------------------+--------------+--------------+-----------------------+-----------------------+-----------------------+--------------+------------------+---------------+
|              |              |              |                  |                       |              |              |                       |                       |                       |              |                  |               |
decl-specifier decl-specifier decl-specifier decl-specifier     decl-specifier          decl-specifier decl-specifier decl-specifier          decl-specifier          decl-specifier          decl-specifier decl-specifier     init-declarator ;
|              |              |              |                  |                       |              |              |                       |                       |                       |              |
type-specifier constexpr      type-specifier function-specifier storage-class-specifier friend         inline         storage-class-specifier storage-class-specifier storage-class-specifier typedef        function-specifier
|                             |              |                  |                                                     |                       |                       |                                      |
class-specifier               enum-specifier explicit           extern                                                mutable                 static                  thread_local                           virtual

Although that sentence is valid syntax, it is semantic nonsense.

Here are some of the reasons why that sentence is semantic nonsense:

A simple-declaration cannot contain the same decl-specifier more than once.
A simple-declaration cannot contain more than one type-specifier.
A simple-declaration for a function cannot be "mutable".
A simple-declaration for a function cannot be both "virtual" and "static".
A simple-declaration for a function cannot be "thread_local".
A simple-declaration for a variable cannot be "explicit".
A simple-declaration for a variable cannot be "virtual".
etc.

Syntax grammars are useful for parsers, but they are not useful:

How to generate semantically-valid sentences

If your goal is to produce valid semantics, then you probably don't want to do it this way:

  1. produce a large set of sentences which are valid syntax
  2. remove from that set all of the sentences which are semantic nonsense

There must be an easier way.

There is.

Use a semantic grammar rather than a syntax grammar.