ProgrammaticLexicalScope ending problem.

SyntaxEditor for Windows Forms Forum

Posted 12 years ago by Erik Pepping - RADVenture B.V
Version: 4.0.0259
Avatar
Hi,
I've taken your previous advice and started to work on a very simple extension of the CsharpLanguage (add-on).
In a nutshell, i am trying to add ASP directive state into c#.


1) The state change works (so i correctly switchs to "TplState")
2) The highlighting works too.
3) My problem is that IsTemplateScopeEnded NEVER gets called.

Probably i am doing something wrong but i can't see it.

Below is the Example derived language:


using System;
using System.Collections.Generic;
using System.Text;
using ActiproSoftware.SyntaxEditor.Addons.CSharp;
using ActiproSoftware.SyntaxEditor;
using ActiproSoftware.SyntaxEditor.Addons.Dynamic;
using System.Collections;
using System.Drawing;

namespace TestApplication
{
    public class MyCSharp : CSharpSyntaxLanguage
    {

        public ILexicalState GwTemplateState
        {
            get
            {
                return LexicalStates["TplState"];
            }
        }

        public MyCSharp()
        {
            IsUpdating = true;

            HighlightingStyles.Add(new HighlightingStyle("TplDirectiveDelimiterStyle", null, Color.Black, Color.Yellow));

            // Create a new lexical state
            int number = LexicalStates.Count + 1 ;

            DefaultLexicalState tplState = new DefaultLexicalState(number, "TplState");
            tplState.DefaultHighlightingStyle = HighlightingStyles["TplDirectiveDelimiterStyle"];
            tplState.LexicalScopes.Add(new ProgrammaticLexicalScope( IsTemplateScopeStarted , IsTemplateScopeEnded));
            LexicalStates.Add(tplState);

            DefaultLexicalState.ChildLexicalStates.Add(tplState);

            IsUpdating = false;
        }

        public MatchType IsTemplateScopeStarted(ITextBufferReader reader, ILexicalScope lexicalScope, ref ITokenLexicalParseData lexicalParseData)
        {
            // If the character is a letter or digit...
            if (reader.Peek() == '<')
            {
                reader.Read();
                if (reader.Peek() == '%')
                {
                    reader.Read();
                    //lexicalParseData = new GwTemplateStartToken(this, GwTemplateState);
                    lexicalParseData = new LexicalScopeAndIDTokenLexicalParseData(lexicalScope, 201);
                    return MatchType.ExactMatch;
                }
                reader.ReadReverse();
            }
            return MatchType.NoMatch;
        }

        public MatchType IsTemplateScopeEnded(ITextBufferReader reader, ILexicalScope lexicalScope, ref ITokenLexicalParseData lexicalParseData)
        {
            // If the character is a letter or digit...
            if (reader.Read() == '%')
            {
                if (reader.Read() == '>')
                {
                    //lexicalParseData = new LexicalStateAndIDTokenLexicalParseData(DefaultLexicalState, byte.Parse("0"));
                    lexicalParseData = new GwTemplateEndToken(this, DefaultLexicalState);
                    return MatchType.ExactMatch;
                }
                else
                {
                    reader.ReadReverse();
                    reader.ReadReverse();
                    return MatchType.NoMatch;
                }
            }
            else
            {
                reader.ReadReverse();
                return MatchType.NoMatch;
            }
        }

    }
}

Comments (4)

Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Erik,

Actually it does get called but end scopes are only searched if there is no token match in the current state. In the case of our lexical parser right now, it is treating unknown lexical states as the default state and is matching % as a modulus operator. Therefore it never needs to search the scopes. If you type a character that isn't recognized such as # in the middle of a word, then it will hit your end scope.

We will update the lexical parser for the next maintenance release so that the normal tokens are only matched in the default lexical state instead of putting that code in a "default:" switch block, which currently catches the default lexical state ID and any unknown ones. This may help with your scenario.


Actipro Software Support

Posted 12 years ago by Erik Pepping - RADVenture B.V
Avatar
OK, thanks. Will wait for that.

Once that's working as expected: Do you think it's possible to that kind of State Transition without affecting the c# semantic parser?

I still want to keep the c# code completion working correctly. I could not find details about this in the Docs, is the any "topic ID" that you would suggest reading for this next step?

Thanks in advance.
Posted 12 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
If you'd like, send over an email and maybe we can post a preview build for you to test it all out.

I would think that perhaps if you keep your child language's token ID's all 0 (zero) then you may find that some of the semantic stuff still works in the root language. I'd be interested if you try this and post the results. So if you are using a dynamic child language and aren't setting token ID's there, then you can try this out.


Actipro Software Support

Posted 12 years ago by Erik Pepping - RADVenture B.V
Avatar
Thanks, I can perfectly wait for the next release since this approach (using the add-on) is my most advance scenario. I now went back to the Dynamic Languages since I really need merging capabilities.
The latest build of this product (v2018.1 build 0341) was released 3 months ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.