Go to the first, previous, next, last section, table of contents.


Syntactic Symbols

The complete list of recognized syntactic symbols is described in the c-offsets-alist variable. This chapter will provide some examples to help clarify these symbols.

Most syntactic symbol names follow a general naming convention. When a line begins with an open or close brace, the syntactic symbol will contain the suffix -open or -close respectively.

Usually, a distinction is made between the first line that introduces a construct and lines that continue a construct, and the syntactic symbols that represent these lines will contain the suffix -intro or -cont respectively. As a sub-classification of this scheme, a line which is the first of a particular brace block construct will contain the suffix -block-intro.

Let's look at some examples to understand how this works. Remember that you can check the syntax of any line by using C-c C-s.


  1: void
  2: swap( int& a, int& b )
  3: {
  4:     int tmp = a;
  5:     a = b;
  6:     b = tmp;
  7:     int ignored =
  8:         a + b;
  9: }

Line 1 shows a topmost-intro since it is the first line that introduces a top-level construct. Line 2 is a continuation of the top-level construct introduction so it has the syntax topmost-intro-cont. Line 3 shows a defun-open since it is the brace that opens a top-level function definition. Line 9 is a defun-close since it contains the brace that closes the top-level function definition. Line 4 is a defun-block-intro, i.e. it is the first line of a brace-block, which happens to be enclosed in a top-level function definition.

Lines 5, 6, and 7 are all given statement syntax since there isn't much special about them. Note however that line 8 is given statement-cont syntax since it continues the statement begun on the previous line.

Here's another example, which illustrates some C++ class syntactic symbols:


   1: class Bass
   2:     : public Guitar,
   3:       public Amplifiable
   4: {
   5: public:
   6:     Bass()
   7:         : eString( new BassString( 0.105 )),
   8:           aString( new BassString( 0.085 )),
   9:           dString( new BassString( 0.065 )),
  10:           gString( new BassString( 0.045 ))
  11:     {
  12:         eString.tune( 'E' );
  13:         aString.tune( 'A' );
  14:         dString.tune( 'D' );
  15:         gString.tune( 'G' );
  16:     }
  17: }

As in the previous example, line 1 has the topmost-intro syntax. Here however, the brace that opens a C++ class definition on line 4 is assigned the class-open syntax. Note that in C++, structs and unions are essentially equivalent syntactically (and are very similar semantically), so replacing the class keyword in the example above with struct or union would still result in a syntax of class-open for line 4 (13). Similarly, line 17 is assigned class-close syntax.

Line 2 introduces the inheritance list for the class so it is assigned the inher-intro syntax, and line 3, which continues the inheritance list is given inher-cont syntax.

Things get interesting at line 5. The primary syntactic symbol for this line is access-label since this a label keyword that specifies access protection in C++. However, this line actually shows two syntactic symbols when you hit C-c C-s. This is because it is also a top-level construct inside a class definition. Thus the other syntactic symbol assigned to this line is inclass. Similarly, line 6 is given both inclass and topmost-intro syntax.

Line 7 introduces a C++ member initialization list and as such is given member-init-intro syntax. Note that in this case it is not assigned inclass since this is not considered a top-level construct. Lines 8 through 10 are all assigned member-init-cont since they continue the member initialization list started on line 7.

Line 11 is assigned inline-open because it opens an in-class C++ inline method definition. This is distinct from, but related to, the C++ notion of an inline function in that its definition occurs inside an enclosing class definition, which in C++ implies that the function should be inlined. For example, if the definition of the Bass constructor appeared outside the class definition, line 11 would be given the defun-open syntax, even if the keyword inline appeared before the method name, as in:


class Bass
    : public Guitar,
      public Amplifiable
{
public:
    Bass();
}

inline
Bass::Bass()
    : eString( new BassString( 0.105 )),
      aString( new BassString( 0.085 )),
      dString( new BassString( 0.065 )),
      gString( new BassString( 0.045 ))
{
    eString.tune( 'E' );
    aString.tune( 'A' );
    dString.tune( 'D' );
    gString.tune( 'G' );
}

Similarly, line 16 is given inline-close syntax.

As in the first example above, line 12 is given defun-block-open syntax and lines 13 through 15 are all given statement syntax.

Here is another (totally contrived) example which illustrates how syntax is assigned to various conditional constructs:


   1: void spam( int index )
   2: {
   3:     for( int i=0; i<index; i++ )
   4:     {
   5:         if( i == 10 )
   6:         {
   7:             do_something_special();
   8:         }
   9:         else
  10:             do_something( i );
  11:     }
  12:     do {
  13:         another_thing( i-- );
  14:     }
  15:     while( i > 0 );
  16: }

Only the lines that illustrate new syntactic symbols will be discussed.

Line 4 has a brace which opens a conditional's substatement block. It is thus assigned substatement-open syntax, and since line 5 is the first line in the substatement block, it is assigned substatement-block-intro syntax. Lines 6 and 7 are assigned similar syntax. Line 8 contains the brace that closes the inner substatement block. It is given the generic syntax block-close, as are lines 11 and 14.

Line 9 is a little different -- since it contains the keyword else matching the if statement introduced on line 5; it is given the else-clause syntax. Note also that line 10 is slightly different too. Because else is considered a conditional introducing keyword (14), and because the following substatement is not a brace block, line 10 is assigned the substatement syntax.

One other difference is seen on line 15. The while construct that closes a do conditional is given the special syntax do-while-closure if it appears on a line by itself. Note that if the while appeared on the same line as the preceding close brace, that line would have been assigned block-close syntax instead.

Switch statements have their own set of syntactic symbols. Here's an example:


   1: void spam( enum Ingredient i )
   2: {
   3:     switch( i ) {
   4:     case Ham:
   5:         be_a_pig();
   6:         break;
   7:     case Salt:
   8:         drink_some_water();
   9:         break;
  10:     default:
  11:         {
  12:             what_is_it();
  13:             break;
  14:         }
  15:     }
  14: }

Here, lines 4, 7, and 10 are all assigned case-label syntax, while lines 5 and 8 are assigned statement-case-intro. Line 11 is treated slightly differently since it contains a brace that opens a block -- it is given statement-case-open syntax.

There are a set of syntactic symbols that are used to recognize constructs inside of brace lists. A brace list is defined as an enum or aggregate initializer list, such as might statically initialize an array of structs. For example:


  1: static char* ingredients[] =
  2: {
  3:     "Ham",
  4:     "Salt",
  5:     NULL
  6: }

Following convention, line 2 in this example is assigned brace-list-open syntax, and line 3 is assigned brace-list-intro syntax. Likewise, line 6 is assigned brace-list-close syntax. Lines 4 and 5 however, are assigned brace-list-entry syntax, as would all subsequent lines in this initializer list.

A number of syntactic symbols are associated with parenthesis lists, a.k.a argument lists, as found in function declarations and function calls. This example illustrates these:


   1: void a_function( int line1,
   2:                  int line2 );
   3: 
   4: void a_longer_function(
   5:     int line1,
   6:     int line2
   7:     );
   8: 
   9: void call_them( int line1, int line2 )
  10: {
  11:     a_function(
  12:         line1,
  13:         line2
  14:         );
  15: 
  16:     a_longer_function( line1,
  17:                        line2 );
  18: }

Lines 5 and 12 are assigned arglist-intro syntax since they are the first line following the open parenthesis, and lines 7 and 14 are assigned arglist-close syntax since they contain the parenthesis that closes the argument list.

The other lines with relevant syntactic symbols include lines 2 and 17 which are assigned arglist-cont-nonempty syntax. What this means is that they continue an argument list, but that the line containing the parenthesis that opens the list is non-empty following the open parenthesis. Contrast this against lines 6 and 13 which are assigned arglist-cont syntax. This is because the parenthesis that opens their argument lists is the last character on that line (15).

Note that there is no arglist-open syntax. This is because any parenthesis that opens an argument list, appearing on a separate line, is assigned the statement-cont syntax instead.

A few miscellaneous syntactic symbols that haven't been previously covered are illustrated by this example:


   1: void Bass::play( int volume )
   2: const
   3: {
   4:     /* this line starts a multi-line
   5:      * comment.  This line should get `c' syntax */
   6: 
   7:     char* a_long_multiline_string = "This line starts a multi-line \
   8: string.  This line should get `string' syntax.";
   9: 
  10:   note:
  11:     {
  12: #ifdef LOCK
  13:         Lock acquire();
  14: #endif // LOCK
  15:         slap_pop();
  16:         cout << "I played "
  17:              << "a note\n";
  18:     }
  19: }

The lines to note in this example include:

In Objective-C buffers, there are three additional syntactic symbols assigned to various message calling constructs. Here's an example illustrating these:


  1: - (void)setDelegate:anObject
  2:           withStuff:stuff
  3: {
  4:     [delegate masterWillRebind:self
  5:               toDelegate:anObject
  6:               withExtraStuff:stuff];
  7: }

Here, line 1 is assigned objc-method-intro syntax, and line 2 is assigned objc-method-args-cont syntax. Lines 5 and 6 are both assigned objc-method-call-cont syntax.

Other syntactic symbols may be recognized by cc-mode, but these are more obscure and so I haven't included examples of them. These include: knr-argdecl-intro, knr-argdecl, and the friend modifier.


Go to the first, previous, next, last section, table of contents.