Copyright (C) 2000-2012 |
GNU Info (ccmode)Syntactic SymbolsSyntactic Symbols ***************** Here is a complete list of the recognized syntactic symbols as described in the `c-offsets-alist' style variable, along with a brief description. More detailed descriptions follow. `string' Inside a multi-line string. `c' Inside a multi-line C style block comment. `defun-open' Brace that opens a top-level function definition. `defun-close' Brace that closes a top-level function definition. `defun-block-intro' The first line in a top-level defun. `class-open' Brace that opens a class definition. `class-close' Brace that closes a class definition. `inline-open' Brace that opens an in-class inline method. `inline-close' Brace that closes an in-class inline method. `func-decl-cont' The region between a function definition's argument list and the function opening brace (excluding K&R argument declarations). In C, you cannot put anything but whitespace and comments in this region, however in C++ and Java, `throws' declarations and other things can appear here. `knr-argdecl-intro' First line of a K&R C argument declaration. `knr-argdecl' Subsequent lines in a K&R C argument declaration. `topmost-intro' The first line in a "topmost" definition. `topmost-intro-cont' Topmost definition continuation lines. `member-init-intro' First line in a member initialization list. `member-init-cont' Subsequent member initialization list lines. `inher-intro' First line of a multiple inheritance list. `inher-cont' Subsequent multiple inheritance lines. `block-open' Statement block open brace. `block-close' Statement block close brace. `brace-list-open' Open brace of an enum or static array list. `brace-list-close' Close brace of an enum or static array list. `brace-list-intro' First line in an enum or static array list. `brace-list-entry' Subsequent lines in an enum or static array list. `brace-entry-open' Subsequent lines in an enum or static array list where the line begins with an open brace. `statement' A statement. `statement-cont' A continuation of a statement. `statement-block-intro' The first line in a new statement block. `statement-case-intro' The first line in a case block. `statement-case-open' The first line in a case block that starts with a brace. `substatement' The first line after a conditional or loop construct. `substatement-open' The brace that opens a substatement block. `case-label' A `case' or `default' label. `access-label' C++ access control label. `label' Any non-special C label. `do-while-closure' The `while' line that ends a `do'-`while' construct. `else-clause' The `else' line of an `if'-`else' construct. `catch-clause' The `catch' or `finally' (in Java) line of a `try'-`catch' construct. `comment-intro' A line containing only a comment introduction. `arglist-intro' The first line in an argument list. `arglist-cont' Subsequent argument list lines when no arguments follow on the same line as the arglist opening paren. `arglist-cont-nonempty' Subsequent argument list lines when at least one argument follows on the same line as the arglist opening paren. `arglist-close' The solo close paren of an argument list. `stream-op' Lines continuing a stream operator (C++ only). `inclass' The line is nested inside a class definition. `cpp-macro' The start of a C preprocessor macro definition. `cpp-macro-cont' Subsequent lines of a multi-line C preprocessor macro definition. `friend' A C++ friend declaration. `objc-method-intro' The first line of an Objective-C method. definition. `objc-method-args-cont' Lines continuing an Objective-C method. definition `objc-method-call-cont' Lines continuing an Objective-C method call. `extern-lang-open' Brace that opens an external language block. `extern-lang-close' Brace that closes an external language block. `inextern-lang' Analogous to `inclass' syntactic symbol, but used inside external language blocks (e.g. `extern "C" {'). `namespace-open' Brace that opens a C++ namespace block. `namespace-close' Brace that closes a C++ namespace block. `innamespace' Analogous to `inextern-lang' syntactic symbol, but used inside C++ namespace blocks. `template-args-cont' C++ template argument list continuations. `inlambda' Analogous to `inclass' syntactic symbol, but used inside lambda (i.e. anonymous) functions. Only used in Pike mode. `lambda-intro-cont' Lines continuing the header of a lambda function, i.e. between the `lambda' keyword and the function body. Only used in Pike mode. `inexpr-statement' A statement block inside an expression. The gcc C extension of this is recognized. It's also used for the special functions that takes a statement block as an argument in Pike. `inexpr-class' A class definition inside an expression. This is used for anonymous classes in Java. It's also used for anonymous array initializers in Java. 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 the corresponding `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, 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: friend class Luthier; 18: } 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++, classes, 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 (1). Similarly, line 18 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. Hitting `C-c C-s' on line 5 shows the following analysis: `((inclass . 58) (access-label . 67))' The primary syntactic symbol for this line is `access-label' as this a label keyword that specifies access protection in C++. However, because this line is also a top-level construct inside a class definition, the analysis actually shows two syntactic symbols. The other syntactic symbol assigned to this line is `inclass'. Similarly, line 6 is given both `inclass' and `topmost-intro' syntax: `((inclass . 58) (topmost-intro . 60))' 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's analysis is a bit more complicated: `((inclass . 58) (inline-open))' This line is assigned a syntax of both `inline-open' and `inclass' 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. If though, the definition of the `Bass' constructor appeared outside the class definition, the construct 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' ); } Returning to the previous example, line 16 is given `inline-close' syntax, while line 12 is given `defun-block-open' syntax, and lines 13 through 15 are all given `statement' syntax. Line 17 is interesting in that its syntactic analysis list contains three elements: `((friend) (inclass . 58) (topmost-intro . 380))' The `friend' syntactic symbol is a modifier that typically does not have a relative buffer position. Template definitions introduce yet another syntactic symbol: 1: ThingManager <int, 2: Framework::Callback *, 3: Mutex> framework_callbacks; Here, line 1 is analyzed as a `topmost-intro', but lines 2 and 3 are both analyzed as `template-args-cont' lines. 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 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. The `try'-`catch' constructs in C++ and Java are treated this way too, with the only difference that the `catch', and in Java also `finally', is marked with `catch-clause'. Line 10 is also slightly different. Because `else' is considered a conditional introducing keyword (2), 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. The three special aggregate constructs in Pike, `({ })', `([ ])' and `(< >)', are treated as brace lists too. An 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. Your static initializer might be initializing nested structures, for example: 1: struct intpairs[] = 2: { 3: { 1, 2 }, 4: { 5: 3, 6: 4 7: } 8: { 1, 9: 2 }, 10: { 3, 4 } 11: } Here, you've already seen the analysis of lines 1, 2, 3, and 11. On line 4, things get interesting; this line is assigned `brace-entry-open' syntactic symbol because it's a bracelist entry line that starts with an open brace. Lines 5 and 6 (and line 9) are pretty standard, and line 7 is a `brace-list-close' as you'd expect. Once again, line 8 is assigned as `brace-entry-open' as is line 10. External language definition blocks also have their own syntactic symbols. In this example: 1: extern "C" 2: { 3: int thing_one( int ); 4: int thing_two( double ); 5: } line 2 is given the `extern-lang-open' syntax, while line 5 is given the `extern-lang-close' syntax. The analysis for line 3 yields: `((inextern-lang) (topmost-intro . 14))', where `inextern-lang' is a modifier similar in purpose to `inclass'. Similarly, C++ namespace constructs have their own associated syntactic symbols. In this example: 1: namespace foo 2: { 3: void xxx() {} 4: } line 2 is given the `namespace-open' syntax, while line 4 is given the `namespace-close' syntax. The analysis for line 3 yields: `((innamespace) (topmost-intro . 17))', where `innamespace' is a modifier similar in purpose to `inextern-lang' and `inclass'. 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. Lines that continue argument lists can be assigned one of two syntactic symbols. For example, Lines 2 and 17 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 _not 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. 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 C++ 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_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: * Line 2 is assigned the `func-decl-cont' syntax. * Line 4 is assigned both `defun-block-intro' _and_ `comment-intro' syntax. * Line 5 is assigned `c' syntax. * Line 6 which, even though it contains nothing but whitespace, is assigned `defun-block-intro'. Note that the appearance of the comment on lines 4 and 5 do not cause line 6 to be assigned `statement' syntax because comments are considered to be "syntactic whitespace", which are ignored when analyzing code. * Line 8 is assigned `string' syntax. * Line 10 is assigned `label' syntax. * Line 11 is assigned `block-open' syntax. * Lines 12 and 14 are assigned `cpp-macro' syntax in addition to the normal syntactic symbols (`statement-block-intro' and `statement', respectively). Normally `cpp-macro' is configured to cancel out the normal syntactic context to make all preprocessor directives stick to the first column, but that's easily changed if you want preprocessor directives to be indented like the rest of the code. * Line 17 is assigned `stream-op' syntax. Multi-line C preprocessor macros are now (somewhat) supported. At least CC Mode now recognizes the fact that it is inside a multi-line macro, and it properly skips such macros as syntactic whitespace. In this example: 1: #define LIST_LOOP(cons, listp) \ 2: for (cons = listp; !NILP (cons); cons = XCDR (cons)) \ 3: if (!CONSP (cons)) \ 4: signal_error ("Invalid list format", listp); \ 5: else line 1 is given the syntactic symbol `cpp-macro'. This first line of a macro is always given this symbol. The second and subsequent lines (e.g. lines 2 through 5) are given the `cpp-macro-cont' syntactic symbol, with a relative buffer position pointing to the `#' which starts the macro definition. 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. Java has a concept of anonymous classes, which may look something like this: 1: public void watch(Observable o) { 2: o.addObserver(new Observer() { 3: public void update(Observable o, Object arg) { 4: history.addElement(arg); 5: } 6: }); 7: } The brace following the `new' operator opens the anonymous class. Lines 3 and 6 are assigned the `inexpr-class' syntax, besides the `inclass' symbol used in normal classes. Thus, the class will be indented just like a normal class, with the added indentation given to `inexpr-class'. There are a few occasions where a statement block may be used inside an expression. One is in C code using the gcc extension for this, e.g: 1: int res = ({ 2: int y = foo (); int z; 3: if (y > 0) z = y; else z = - y; 4: z; 5: }); Lines 2 and 5 get the `inexpr-statement' syntax, besides the symbols they'd get in a normal block. Therefore, the indentation put on `inexpr-statement' is added to the normal statement block indentation. In Pike code, there are a few other situations where blocks occur inside statements, as illustrated here: 1: array itgob() 2: { 3: string s = map (backtrace()[-2][3..], 4: lambda 5: (mixed arg) 6: { 7: return sprintf ("%t", arg); 8: }) * ", " + "\n"; 9: return catch { 10: write (s + "\n"); 11: }; 12: } Lines 4 through 8 contain a lambda function, which CC Mode recognizes by the `lambda' keyword. If the function argument list is put on a line of its own, as in line 5, it gets the `lambda-intro-cont' syntax. The function body is handled as an inline method body, with the addition of the `inlambda' syntactic symbol. This means that line 6 gets `inlambda' and `inline-open', and line 8 gets `inline-close'(3). On line 9, `catch' is a special function taking a statement block as its argument. The block is handled as an in-expression statement with the `inexpr-statement' syntax, just like the gcc extended C example above. The other similar special function, `gauge', is handled like this too. Two other syntactic symbols can appear in old style, non-prototyped C code (4): 1: int add_three_integers(a, b, c) 2: int a; 3: int b; 4: int c; 5: { 6: return a + b + c; 7: } Here, line 2 is the first line in an argument declaration list and so is given the `knr-argdecl-intro' syntactic symbol. Subsequent lines (i.e. lines 3 and 4 in this example), are given `knr-argdecl' syntax. ---------- Footnotes ---------- (1) This is the case even for C and Objective-C. For consistency, structs in all supported languages are syntactically equivalent to classes. Note however that the keyword `class' is meaningless in C and Objective-C. (2) The list of conditional keywords are (in C, C++, Objective-C, Java, and Pike): `for', `if', `do', `else', `while', and `switch'. C++ and Java have two additional conditional keywords: `try' and `catch'. Java also has the `finally' and `synchronized' keywords. (3) You might wonder why it doesn't get `inlambda' too. It's because the closing brace is relative to the opening brace, which stands on its own line in this example. If the opening brace was hanging on the previous line, then the closing brace would get the `inlambda' syntax too to be indented correctly. (4) a.k.a. K&R C, or Kernighan & Ritchie C automatically generated by info2www version 1.2.2.9 |