Sounds like you're very close.
IRecursiveDescentLexicalParser is an interface so you can write a bridge class yourself.
Alternatively, and probably the easier method is to use our existing implementations. The Simple language sample is your best resource for looking at what to do. Let's look at some things to do:
First, you need to tell the language to do semantic parsing in a separate thread when the semantic parser service runs. This is how you do that:
/// <summary>
/// Semantically parses the specified <see cref="TextRange"/> of the <see cref="Document"/>.
/// </summary>
/// <param name="document">The <see cref="Document"/> to examine.</param>
/// <param name="parseTextRange">A <see cref="TextRange"/> indicating the offset range to parse.</param>
/// <param name="flags">A <see cref="SemanticParseFlags"/> that indicates semantic parse flags.</param>
public override void PerformSemanticParse(Document document, TextRange parseTextRange, SemanticParseFlags flags) {
SemanticParserService.Parse(new SemanticParserServiceRequest(SemanticParserServiceRequest.MediumPriority,
document, parseTextRange, flags, this, document));
}
It makes a request to the semantic parser service and when the worker thread is ready to run the parse data (which may or may not be immediately), will callback to this interface implementation:
/// <summary>
/// Performs a semantic parsing operation using the data in the <see cref="SemanticParserServiceRequest"/>.
/// </summary>
/// <param name="request">A <see cref="SemanticParserServiceRequest"/> containing data about what to parse.</param>
void ISemanticParserServiceProcessor.Process(SemanticParserServiceRequest request) {
MergableLexicalParserManager manager = new MergableLexicalParserManager(request.TextBufferReader, this);
request.SemanticParseData = this.PerformSemanticParse(manager) as ISemanticParseData;
}
Note that that code creates the manager and calls another PerformSemanticParse method that is parse of the MergableSyntaxLanguage class (and can be called by the manager when in a merged language scenario).
/// <summary>
/// Semantically parses the text in the <see cref="MergableLexicalParserManager"/>.
/// </summary>
/// <param name="manager">The <see cref="MergableLexicalParserManager"/> that is managing the mergable language and the text to parse.</param>
/// <returns>An object that contains the results of the semantic parsing operation.</returns>
protected override object PerformSemanticParse(MergableLexicalParserManager manager) {
SimpleRecursiveDescentLexicalParser lexicalParser = new SimpleRecursiveDescentLexicalParser(this, manager);
lexicalParser.InitializeTokens();
SimpleSemanticParser semanticParser = new SimpleSemanticParser(lexicalParser);
semanticParser.Parse();
return semanticParser.CompilationUnit;
}
That code creates a "bridge" lexical parser between the real lexical parser and the semantic parser. It uses the manager that is passed in.
So to sum up, in the main PerformSemanticParse, you make a request to the semantic parser service. At some later time, the ISemanticParserServiceProcessor.Process method is called. That makes a manager and calls a third method that runs the actual semantic parser.