⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexvhdl.cxx.svn-base

📁 Notepad++ is a generic source code editor (it tries to be anyway) and Notepad replacement written in
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
// Scintilla source code edit control
/** @file LexVHDL.cxx
 ** Lexer for VHDL
 ** Written by Phil Reid, 
 ** Based on:
 **  - The Verilog Lexer by Avi Yegudin 
 **  - The Fortran Lexer by Chuan-jian Shen
 **  - The C++ lexer by Neil Hodgson
 **/
// Copyright 1998-2002 by Neil Hodgson <neilh@scintilla.org>
// The License.txt file describes the conditions under which this software may be distributed.

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>

#include "Platform.h"

#include "PropSet.h"
#include "Accessor.h"
#include "StyleContext.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "SciLexer.h"

static void ColouriseVHDLDoc(
  unsigned int startPos,
  int length,
  int initStyle,
  WordList *keywordlists[],
  Accessor &styler);


/***************************************/
static inline bool IsAWordChar(const int ch) {
  return (ch < 0x80) && (isalnum(ch) || ch == '.' || ch == '_' );
}

/***************************************/
static inline bool IsAWordStart(const int ch) {
  return (ch < 0x80) && (isalnum(ch) || ch == '_');
}

/***************************************/
inline bool IsABlank(unsigned int ch) {
    return (ch == ' ') || (ch == 0x09) || (ch == 0x0b) ;
}

/***************************************/
static void ColouriseVHDLDoc(
  unsigned int startPos,
  int length,
  int initStyle,
  WordList *keywordlists[],
  Accessor &styler)
{
  WordList &Keywords   = *keywordlists[0];
  WordList &Operators  = *keywordlists[1];
  WordList &Attributes = *keywordlists[2];
  WordList &Functions  = *keywordlists[3];
  WordList &Packages   = *keywordlists[4];
  WordList &Types      = *keywordlists[5];
  WordList &User       = *keywordlists[6];

  StyleContext sc(startPos, length, initStyle, styler);

  for (; sc.More(); sc.Forward())
  {

    // Determine if the current state should terminate.
    if (sc.state == SCE_VHDL_OPERATOR) {
      sc.SetState(SCE_VHDL_DEFAULT);
    } else if (sc.state == SCE_VHDL_NUMBER) {
      if (!IsAWordChar(sc.ch) && (sc.ch != '#')) {
        sc.SetState(SCE_VHDL_DEFAULT);
      }
    } else if (sc.state == SCE_VHDL_IDENTIFIER) {
      if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
        char s[100];
        sc.GetCurrentLowered(s, sizeof(s));
        if (Keywords.InList(s)) {
          sc.ChangeState(SCE_VHDL_KEYWORD);
        } else if (Operators.InList(s)) {
          sc.ChangeState(SCE_VHDL_STDOPERATOR);
        } else if (Attributes.InList(s)) {
          sc.ChangeState(SCE_VHDL_ATTRIBUTE);
        } else if (Functions.InList(s)) {
          sc.ChangeState(SCE_VHDL_STDFUNCTION);
        } else if (Packages.InList(s)) {
          sc.ChangeState(SCE_VHDL_STDPACKAGE);
        } else if (Types.InList(s)) {
          sc.ChangeState(SCE_VHDL_STDTYPE);
        } else if (User.InList(s)) {
          sc.ChangeState(SCE_VHDL_USERWORD);
        }
        sc.SetState(SCE_VHDL_DEFAULT);
      }
    } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_V_COMMENTLINEBANG) {
      if (sc.atLineEnd) {
        sc.SetState(SCE_VHDL_DEFAULT);
      }
    } else if (sc.state == SCE_VHDL_STRING) {
      if (sc.ch == '\\') {
        if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
          sc.Forward();
        }
      } else if (sc.ch == '\"') {
        sc.ForwardSetState(SCE_VHDL_DEFAULT);
      } else if (sc.atLineEnd) {
        sc.ChangeState(SCE_V_STRINGEOL);
        sc.ForwardSetState(SCE_VHDL_DEFAULT);
      }
    }

    // Determine if a new state should be entered.
    if (sc.state == SCE_VHDL_DEFAULT) {
      if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
        sc.SetState(SCE_VHDL_NUMBER);
      } else if (IsAWordStart(sc.ch)) {
        sc.SetState(SCE_VHDL_IDENTIFIER);
      } else if (sc.Match('-', '-')) {
        sc.SetState(SCE_VHDL_COMMENT);
        sc.Forward(); 
      } else if (sc.Match('-', '-')) {
        if (sc.Match("--!"))  // Nice to have a different comment style
          sc.SetState(SCE_VHDL_COMMENTLINEBANG);
        else
          sc.SetState(SCE_VHDL_COMMENT);
      } else if (sc.ch == '\"') {
        sc.SetState(SCE_VHDL_STRING);
      } else if (isoperator(static_cast<char>(sc.ch))) {
        sc.SetState(SCE_VHDL_OPERATOR);
      }
    }
  }
  sc.Complete();
}
//=============================================================================
static bool IsCommentLine(int line, Accessor &styler) {
	int pos = styler.LineStart(line);
	int eol_pos = styler.LineStart(line + 1) - 1;
	for (int i = pos; i < eol_pos; i++) {
		char ch = styler[i];
		char chNext = styler[i+1];
		if ((ch == '-') && (chNext == '-'))
			return true;
		else if (ch != ' ' && ch != '\t')
			return false;
	}
	return false;
}

//=============================================================================
// Folding the code
static void FoldNoBoxVHDLDoc(
  unsigned int startPos,
  int length,
  int initStyle,
  Accessor &styler)
{
  // Decided it would be smarter to have the lexer have all keywords included. Therefore I
  // don't check if the style for the keywords that I use to adjust the levels.
  char words[] =
    "architecture begin case component else elsif end entity generate loop package process record then "
    "procedure function when";
  WordList keywords;
  keywords.Set(words);

  bool foldComment      = styler.GetPropertyInt("fold.comment", 1) != 0;
  bool foldCompact      = styler.GetPropertyInt("fold.compact", 1) != 0;
  bool foldAtElse       = styler.GetPropertyInt("fold.at.else", 1) != 0;
  bool foldAtBegin      = styler.GetPropertyInt("fold.at.Begin", 1) != 0;
  bool foldAtParenthese = styler.GetPropertyInt("fold.at.Parenthese", 1) != 0;
  //bool foldAtWhen       = styler.GetPropertyInt("fold.at.When", 1) != 0;  //< fold at when in case statements

  int  visibleChars     = 0;
  unsigned int endPos   = startPos + length;

  int lineCurrent       = styler.GetLine(startPos);
  int levelCurrent      = SC_FOLDLEVELBASE;
  if(lineCurrent > 0)
    levelCurrent        = styler.LevelAt(lineCurrent-1) >> 16;
  //int levelMinCurrent   = levelCurrent;
  int levelMinCurrentElse = levelCurrent;   //< Used for folding at 'else'
  int levelMinCurrentBegin = levelCurrent;  //< Used for folding at 'begin'
  int levelNext         = levelCurrent;

  /***************************************/
  int lastStart         = 0;
  char prevWord[32]     = "";

  /***************************************/
  // Find prev word
  // The logic for going up or down a level depends on a the previous keyword
  // This code could be cleaned up.
  int end = 0;
  unsigned int j;
  for(j = startPos; j>0; j--)
  {
    char ch       = styler.SafeGetCharAt(j);
    char chPrev   = styler.SafeGetCharAt(j-1);
    int style     = styler.StyleAt(j);
    int stylePrev = styler.StyleAt(j-1);
    if ((stylePrev != SCE_VHDL_COMMENT) && (stylePrev != SCE_VHDL_STRING))
    {
      if(IsAWordChar(chPrev) && !IsAWordChar(ch))
      {
        end = j-1;
      }
    }
    if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
    {
      if(!IsAWordChar(chPrev) && IsAWordStart(ch) && (end != 0))
      {
        char s[32];
        unsigned int k;
        for(k=0; (k<31 ) && (k<end-j+1 ); k++) {
          s[k] = static_cast<char>(tolower(styler[j+k]));
        }
        s[k] = '\0';

        if(keywords.InList(s)) {
          strcpy(prevWord, s);
          break;
        }
      }
    }
  }
  for(j=j+strlen(prevWord); j<endPos; j++)
  {
    char ch       = styler.SafeGetCharAt(j);
    int style     = styler.StyleAt(j);
    if ((style != SCE_VHDL_COMMENT) && (style != SCE_VHDL_STRING))
    {
      if((ch == ';') && (strcmp(prevWord, "end") == 0))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -