I'm trying to implement a plugin for our internal IDE, which edits custom DSL code with the help of SyntaxEditor. Up to now the control very simply just loads the text and I have registered an ILexer implementation and a TokenTaggerProvider service. When I open even a small file containing text like this:
version 1.0;
[attribute=10,
attribute=(20, 30, 40)]
service S {}
I get quite a number of calls to the ILexer.Parse implementation with repeating snapshot ranges. The following debug output is generated from just setting the document text:
Parsing: {Line=1,Character=0} through {Line=2,Character=0}
Parsing: {Line=2,Character=0} through {Line=3,Character=0}
Parsing: {Line=3,Character=0} through {Line=4,Character=0}
Parsing: {Line=4,Character=0} through {Line=4,Character=12}
Parsing: {Line=2,Character=0} through {Line=3,Character=0}
Parsing: {Line=3,Character=0} through {Line=4,Character=0}
Parsing: {Line=4,Character=0} through {Line=4,Character=12}
Parsing: {Line=3,Character=0} through {Line=4,Character=0}
Parsing: {Line=4,Character=0} through {Line=4,Character=12}
Parsing: {Line=0,Character=0} through {Line=1,Character=0}
Parsing: {Line=1,Character=0} through {Line=2,Character=0}
Parsing: {Line=2,Character=0} through {Line=3,Character=0}
Parsing: {Line=3,Character=0} through {Line=4,Character=0}
Parsing: {Line=4,Character=0} through {Line=4,Character=12}
Similar things happen when I place the cursor within the document, which absolutely has no effect on the lexer results at all. It gets worse when the document text gets a little larger (say a hundred lines of source text). When I scroll through the document there are repeated calls to Parse which makes the overall process way too slow - the GUI blocks for a few seconds.
The lexer implementation internally uses another component where an ANTLR generated lexer is encapsulated with some additional lexer state and I can't get my mind around how to correctly add that state information to the ILexer implementation. In above example you see the part in square brackets, which are attributes for the service. These are recognized by my scanner and the left hand side tokens can never be keywords, which is why I need some kind of state at all.
So my questions are:
1.) Why do I get so many callbacks - is it related to the ILexicalScopeStateNode objects being passed to ILexerTarget.OnTokenParsed method?
2.) How do I use the lexical scopes/states correctly? In my case the scanner already provides all context information and has its own state stack associated with each produced token. Why do I need lexical scopes at all? I would just want to attach my scanner's state to the token - then I could pick up at basically any token boundary within the text.
I also tried a mergable lexer (which is not what I actually need), but with even less success - it starts over at the first token forever. So I quit that approach.