Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 访问未被解析器规则引用的ANTLR令牌_C#_.net_Parsing_Antlr_Antlr4 - Fatal编程技术网

C# 访问未被解析器规则引用的ANTLR令牌

C# 访问未被解析器规则引用的ANTLR令牌,c#,.net,parsing,antlr,antlr4,C#,.net,Parsing,Antlr,Antlr4,我正试图基于Java语言,用C#编写一个Java语法高亮程序。为了做到这一点,我目前正试图跟踪访问者中的\u index字段,我每次通过一个节点时都会添加该字段。代码如下: private class Visitor : JavaBaseVisitor<object> { private readonly string _rawText; private readonly SpannableString _text; private readonly ISyn

我正试图基于Java语言,用C#编写一个Java语法高亮程序。为了做到这一点,我目前正试图跟踪访问者中的
\u index
字段,我每次通过一个节点时都会添加该字段。代码如下:

private class Visitor : JavaBaseVisitor<object>
{
    private readonly string _rawText;
    private readonly SpannableString _text;
    private readonly ISyntaxStyler _styler;

    private int _index;

    internal Visitor(string text, ISyntaxStyler styler)
    {
        _rawText = text;
        _text = new SpannableString(text);
        _styler = styler;
    }

    public override object VisitAnnotation([NotNull] JavaParser.AnnotationContext context)
    {
        Advance("@", SyntaxKind.Annotation);
        VisitAnnotationName(context.annotationName());
        this.VisitChildren(context, 2);
        return null;
    }

    public override object VisitPackageDeclaration([NotNull] JavaParser.PackageDeclarationContext context)
    {
        int index = 0;
        var child = context.GetChild(0);

        while (child is JavaParser.AnnotationContext)
        {
            Visit(child);
            child = context.GetChild(++index);
        }

        Advance("package", SyntaxKind.Keyword);
        this.VisitChildren(context, index + 1);
        return null;
    }

    public override object VisitTerminal(ITerminalNode node)
    {
        Advance(node.Symbol.Text, SyntaxKind.Identifier);
        return null;
    }

    internal SpannableString HighlightText()
    {
        Visit(CreateTree(_rawText));
        return _text;
    }

    private void Advance(int count, SyntaxKind kind)
    {
        var span = _styler.GetSpan(kind);
        _text.SetSpan(span, _index, _index + count, SpanTypes.InclusiveExclusive);
        _index += count;
    }

    private void Advance(string toSkip, SyntaxKind kind)
    {
        int count = toSkip.Length;
        Debug.Assert(string.Compare(_rawText, _index, toSkip, 0, count) == 0);
        Advance(count, kind);
    }

    private static JavaParser.CompilationUnitContext CreateTree(string text)
    {
        var inputStream = new AntlrInputStream(text);
        var lexer = new JavaLexer(inputStream);
        var tokenStream = new CommonTokenStream(lexer);
        var parser = new JavaParser(tokenStream);
        return parser.compilationUnit();
    }
}
直到处理
之后,当前标记的索引与原始文本中的索引相同。但是,当处理
a
时,
\u索引
的空格没有增加,因此它比应该的值落后1。当<代码>已处理,它将落后于它应该的2。然后
将获得
a
的着色,
a
将获得下一个
的着色,
d
将获得
的着色,等等


有没有一种方法可以在访问者中提取空白标记,这样索引就不会被弄乱?谢谢。

你说得对,语法吃空格。但是lexer没有。我处理语法突出显示,因此也处理显式标记处理,包括空格,如下所示。主要的事情是覆盖lexer的
Emit
方法。这是我在这里概述的过程的一部分

  • 一个小类,允许我在令牌源中记录类型、开始和停止长度

    public class TokenExtent
    {
        public string Name { get; set; }
        public int Start { get; set; }
        public int Length { get; set; }
        public TokenExtent(string name, int start, int stop)
        {
            Name = name;
            Start = start;
            Length = stop - start + 1;
        }
     }
    
  • 我用每次解析填充的标记扩展数据块列表

    public static List<TokenExtent> TokenExtents = new List<TokenExtent>();
    
  • 我应用样式的表单中的
    Higlight()
    方法:

    private void Highlight()
    {
        foreach (TokenExtent ext in BasicEnvironment.TokenExtents)
        {
            switch (ext.Name)
            {
                case "ID" :
                {
                    etCode2.Select(ext.Start, ext.Length);
                    etCode2.SelectionColor = Color.Blue;
                    break;
                }
                case "COMMENT" :
                {
                    etCode2.Select(ext.Start, ext.Length);
                    etCode2.SelectionColor = Color.DimGray;
                    break;
                }
                case "WS":
                {
                    etCode2.Select(ext.Start, ext.Length);
                    etCode2.SelectionBackColor = Color.BurlyWood;
                    break;
                }
            }
        }
    }
    
  • 我更改了空白的背景色以使其更加突出,因此它看起来是这样的:

    如您所见,如果您使用lexer进入其中,您可以将这些空白标记与lexer规则命名的任何其他标记一样对待

    public class BailLexer : LISBASICLexer
    {
        public BailLexer(ICharStream input) : base(input) { }
        public override IToken Emit()
        {
            IToken token = base.Emit();
            switch (token.Type)
            {
            case ID :
                {
                TokenExtent extent = new TokenExtent("ID", token.StartIndex, token.StopIndex);
                BasicEnvironment.TokenExtents.Add(extent);
                break;
                }
    
                case COMMENT :
                {
                TokenExtent extent = new TokenExtent("COMMENT", token.StartIndex, token.StopIndex);
                BasicEnvironment.TokenExtents.Add(extent);
                break;
                }
                case WS:
                {
                TokenExtent extent = new TokenExtent("WS", token.StartIndex, token.StopIndex);
                BasicEnvironment.TokenExtents.Add(extent);
                break;
                }
    
    private void Highlight()
    {
        foreach (TokenExtent ext in BasicEnvironment.TokenExtents)
        {
            switch (ext.Name)
            {
                case "ID" :
                {
                    etCode2.Select(ext.Start, ext.Length);
                    etCode2.SelectionColor = Color.Blue;
                    break;
                }
                case "COMMENT" :
                {
                    etCode2.Select(ext.Start, ext.Length);
                    etCode2.SelectionColor = Color.DimGray;
                    break;
                }
                case "WS":
                {
                    etCode2.Select(ext.Start, ext.Length);
                    etCode2.SelectionBackColor = Color.BurlyWood;
                    break;
                }
            }
        }
    }