Click here to Skip to main content
15,897,226 members
Articles / Programming Languages / C#

Writing Your First Visual Studio Language Service

Rate me:
Please Sign up or sign in to vote.
4.95/5 (61 votes)
11 Dec 2009CPOL8 min read 234.4K   4K   157  
A guide to writing a language service for Visual Studio using Irony.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Irony.Compiler {

  [Flags]
  public enum ProductionFlags {
    None = 0,
    IsInitial = 0x01,    //is initial production
    HasTerminals = 0x02, //contains terminal
    IsError = 0x04,      //contains Error terminal
    IsEmpty = 0x08,
  }

  public class LR0ItemList : List<LR0Item> { }
  public class ProductionList : List<Production> { }

  public class Production {
    public ProductionFlags Flags;
    public readonly NonTerminal LValue;                              // left-side element
    public readonly BnfTermList RValues = new BnfTermList();         //the right-side elements sequence
    public readonly GrammarHintList Hints = new GrammarHintList();
    public readonly LR0ItemList LR0Items = new LR0ItemList();        //LR0 items based on this production 
    public Production(NonTerminal lvalue) {
      LValue = lvalue;
    }//constructor

    public bool IsSet(ProductionFlags flag) {
      return (Flags & flag) != ProductionFlags.None;
    }

    public override string ToString() {
      return TextUtils.ProductionToString(this, -1); //no dot
    }

  }//Production class

  public partial class LR0Item {
    public readonly Production Production;
    public readonly int Position;

    public readonly StringSet TailFirsts = new StringSet(); //tail is a set of elements after the Current element
    public bool TailIsNullable = false;

    //automatically generated IDs - used for building keys for lists of kernel LR0Items
    // which in turn are used to quickly lookup parser states in hash
    internal readonly int ID;

    public LR0Item(Production production, int position, int id) {
      Production = production;
      Position = position;
      ID = id;
    }
    //The after-dot element
    public BnfTerm Current {
      get {
        if (Position < Production.RValues.Count)
          return Production.RValues[Position];
        else
          return null;
      }
    }
    public bool IsKernel {
      get { return Position > 0 || (Production.IsSet(ProductionFlags.IsInitial) && Position == 0); }
    }
    public override string ToString() {
      return TextUtils.ProductionToString(this.Production, Position);
    }
  }//LR0Item


}//namespace

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions