QScintilla:レクサーの作成

こんにちは、Habr!



UPD :サイクルの3番目の部分。



これは、QScintillaシリーズの2番目の記事です。 最初のものはここです。 そもそも、カルモヤマから私を連れ出してくれた皆さんに感謝します! これで開始できます。 今日は何をしますか? アセンブラー用のレクサーを作成します! 「箱の中」ではありません-それは重要ではありません、自分で書いてください! このプロセスは非常に時間がかかるため、少し書いてコメントします。 さらに、アセンブリ言語がわからないため、レクサーは非常に原始的で、コマンドとコメントのみをペイントします。



ガガーリンが言ったように-「行こう!」



この段階では、最初の記事(上記を参照)を既に読んでおり、エディターの作成とカスタマイズの方法を知っていると思います。 前回編集したのと同じプロジェクトを続け、同じツールセットを使用します(ここでは、最初の記事を読んでいない人が捕まりました)。



タスクとアイデア



アセンブラーの構文カラーリングを作成します。 ただし、QScintillaにはデフォルトでレクサー(配色)は存在しません。 何も書かない。 これにはQsciLexerCustomクラスがあります(秘密:仮想メソッドがあります)。



ビレット



レキサーで生地を準備しましょう。 空白は次のようになります。



class QsciLexerASM : public QsciLexerCustom { Q_OBJECT public: explicit QsciLexerASM(QObject *parent = 0); ~QsciLexerASM(); //!     (  ) void styleText(int start, int end); //!    (  styleText()) void paintKeywords(const QString &source, int start); void paintComments(const QString &source, int start); //!   (   ASM const char * language() const; //!    QColor defaultColor(int style) const; //!   QString description(int style) const; //!   enum { Default = 0, Comment = 1, Keyword = 2 }; private: QsciLexerASM(const QsciLexerASM &); QsciLexerASM &operator=(const QsciLexerASM &); QStringList keywordsList; };
      
      







ここにリストされている機能のいくつかは、私たちではなく、QScintillaに必要です。 しかし、誰かがそれらを必要とする場合、mainwindow.hでそれらを実装します。



 QString QsciLexerASM::description(int style) const { switch(style) { case Default: return "Default"; case Comment: return "Comment"; case Keyword: return "Keyword"; } return QString(style); } const char * QsciLexerASM::language() { return "ASM"; }
      
      







ここではすべてが明確だと思います。 さらに進みましょう。 次に、すべてのスタイルにデフォルトの色を実装する必要があります。



 QColor QsciLexerASM::defaultColor(int style) const { switch(style) { case Comment: return Qt::darkGreen; case Keyword: return Qt::blue; } return Qt::black; }
      
      







そして今だけ、コードを色付けします。 これを行うには、アセンブラーに含まれるキーワードを知る必要があります。 ウィキペディアではあまり見つけませんでした。 これを行うには、コンストラクタでkeywordListを設定します。



 QsciLexerASM::QsciLexerASM(QObject *parent) : QsciLexerCustom(parent) { keywordsList << "mov" << "add" << "sub" << "imul" << "or" << "and" << "xor" << "shr" << "jmp" << "loop" << "ret" << "int"; }
      
      







続けましょう。 今、私たちは非常に注意する必要があります-構文を色付けする場所に来ました! styleText()関数のコードリストを提供し、簡単にコメントします。



 void QsciLexerASM::styleText(int start, int end) { if(!editor()) return; //        char * data = new char[end - start + 1]; //   Scintilla editor()->SendScintilla(QsciScintilla::SCI_GETTEXTRANGE, start, end, data); QString source(data); delete [] data; if(source.isEmpty()) return; //  ! paintKeywords(source, start); paintComments(source, start); }
      
      







一瞬。 メソッドの最後の2行。 paintKeyword()およびpaintComments()関数は、それぞれキーワードとコメントに色を付けるために使用されます。 チームのカラーリングを呼び出してからコメントします。 なんで? ゲス。



今ではすべてが順調です。 ほとんどすべてのメソッドが実装されています。 paintKeyword()およびpaintComments()を実装するためにのみ残ります:



 void QsciLexerASM::paintKeywords(const QString &source, int start) { foreach(QString word, keywordsList) { //    if(source.contains(word)) { int p = source.count(word); //   int index = 0; //    c 0 while(p != 0) { int begin = source.indexOf(word, index); //    index = begin+1; //       startStyling(start + begin); //      setStyling(word.length(), Keyword); //   word.length   Keyword startStyling(start + begin); //   p--; } } } } void QsciLexerASM::paintComments(const QString &source, int start) { int p = source.count(";"); //     if(p == 0) return; int index = 0; //    ";"  0 while(p != 0) { int begin = source.indexOf(";", index); //    int length=0; //   index = begin+1; //       for(int k = begin; source[k] != '\n'; k++) //  source    length++; startStyling(start + begin); //      setStyling(length, Comment); //   length   Comment startStyling(start + begin); //   p--; } }
      
      







できた 今、レクサーは何かをする方法を知っています。 コンパイルできます。 はい、できます。 はい、間違いなくコンパイルできます。



結果



アセンブラーでは動作しませんでした。 とても申し訳ありません。 彼と仕事をするための基本的な原則すら知らない。 しかし、この記事の例としては完全に適合すると思いました。



取得したものは次のとおりです。









いくつかのバグが表示されます。たとえば、「dword」という単語は、キーとして「または」の出現を強調表示します。 同志TheHorseが示唆したように、テキスト内のキーワードの出現が区切り文字で区切られていることを確認する必要があります。 しかし、この記事の終わりまでに、私はとても疲れていたので、このバグを修正しないことにしましたが、読者には修正したままにしておきます:)



そして、これが私たちの作成です: qscintilla-demo-2



ありがとう、そしてまた言語を選んだことをおIび申し上げます。



All Articles