Adding syntax checking is done in the following three steps (see the procedures that follow for details):
Adding Grammar Rules
Setting Language Properties
Adding Error Productions
注意
You must provide your own lex/yacc-compatible tools; these tools are not included in the VS SDK and the language service project will not build without them. To build the language service using the sample grammar and parser for the sample My C Package, you must use version 1.24 or later of Bison and version 2.5.4a or later of Flex. Place the Bison and Flex executables in the Babel Tools folder, for example, <InstallPath>\VisualStudioIntegration\Babel\Tools. These version numbers are specific to the My C sample.
Adding Grammar Rules
The grammar rules are a very important component for enabling syntax checking.
To add grammar rules
- Open the parser.y file and add the grammar rules for the language.
Most languages already have a yacc-compatible grammar. You can simply copy these rules into parser.y. Unlike the lexer, there are no restrictions on the grammar rules as Babel uses them. However, for an example, here are simplified rules for My C expressions:
Example of grammar rules for My C
Expr: MulExpr AddOp Expr
| MulExpr
;
AddOp
: '+' | '-'
;
MulExpr
: PreExpr MulOp MulExpr
| PreExpr
;
MulOp
: '*' | '/'
;
Factor
: IDENTIFIER
| NUMBER
| '(' Expr ')'
;
Setting Language Properties
After adding the language grammar rules, you can set the following language properties:
Set the CodeSense language property to a value of one (1) to enable syntax checking.
Set the CodeSenseDelay property to specify the delay, in milliseconds, before errors are displayed. In practice, a value between 1,000 to 3,000 milliseconds works well; the default value is 1,500.
Set the CodeSenseFastOnChangeLine property to a value of one (1) if you want to display errors immediately when the user leaves a changed line. This property is enabled by default.
Set the MaxErrorMessages property to give the maximum number of displayed error messages (per source file). The default value is 5.
Adding Error Productions
Error productions are added to provide specific information about the error and allow parsing to recover. The global language service (g_service) can be used to send messages about errors that are detected during parsing, as is shown in the following example:
Example of Error Productions
void syntaxError( in const char* construct,
in const Location* loc = NULL );
void expectError( in const char* construct,
in const char* expecting,
in const Location* loc = NULL );
void errorMessage( in Severity severity,
in const char* message,
in const Location* loc = NULL );
Use the syntaxError method for general errors during parsing. For example, assuming that SourceFile is the <start> production, you might want to add this catch-all error production to your grammar:
SourceFile: Program
| error { g_service->syntaxError( "program" ); }
;
Use the expectError method whenever a certain closing token is expected. For example, in the My C binding, the following error production catches absent closing parentheses:
ParenExpr
: '(' Expr ')'
| '(' Expr error
{ g_service->expectError( "unmatched parenthesis", ")" ); }
;
Sometimes, the current point in the input does not determine the location of the error token. In this case, the location can be given using the $ notation of Bison, which specifies which token determines the position. Token numbers start at 1.
ImportStatement
: IMPORT QualifiedName SemiColons
| IMPORT QualifiedName '.' '*' SemiColons
| IMPORT error SemiColons
{ g_service->syntaxError( "import declaration", &$2 ); }
;
Frequently, error productions add conflicts to the grammar. Add error productions for common errors, as well as a few catch-all productions. For examples, see the My C Package sample.