QML のパーサーの作り方

はじめに

大規模な Qt Quick のアプリケーションの開発時などに、QML ファイルの何かをチェックしたり、一括で処理をするようなツールが欲しくなることがあります。

その作業を正確に行うには、QML のパースが必要となりますが、ゼロから書く気にはなりませんよね。

当然ですが、QtQml モジュールには QML のパーサーが実装されているため、これを使ってパースをしてみましょう。

.pro

TEAMPLATE = app
QT = qml-private
CONFIG += cmdline
SOURCES = main.cpp

シンプルですね。

QtQml モジュールの内部クラスを利用するため、 QT に qml-private を指定しています。

CONFIG += cmdline は、Qt 5.12.2 あたりで追加された cmdline.prf を有効にするせっていです。

main.cpp

QML のパースは、qtdeclarative/src/qml/parser/ 以下で実装されている機能を使います。

これらを実装したものを https://github.com/task-jp/qmlanalyzer に置いておきましたので、興味のある方はご覧ください。

実行

デフォルトでは、ソースコード内に含まれている以下の QML のコードを解析します。

QString source("import QtQuick 2.0\nItem { id: root }");

$ ./qmlanalyzer

+ UiProgram
  + UiHeaderItemList
    + UiImport
      "import"
      + UiQualifiedId
        "QtQuick"
      - UiQualifiedId
      "2.0"
    - UiImport
  - UiHeaderItemList
  + UiObjectMemberList
    + UiObjectDefinition
      + UiQualifiedId
        "Item"
      - UiQualifiedId
      + UiObjectInitializer
        "{"
        + UiObjectMemberList
          + UiScriptBinding
            + UiQualifiedId
              "id"
            - UiQualifiedId
            ":"
            + ExpressionStatement
              + IdentifierExpression
                "root"
              - IdentifierExpression
            - ExpressionStatement
          - UiScriptBinding
        - UiObjectMemberList
        "}"
      - UiObjectInitializer
    - UiObjectDefinition
  - UiObjectMemberList
- UiProgram

引数に qml ファイルを渡すことで、その qml を解析できるようになっていますので、色々試して挙動を確認していただければと思います。

終わりに

QtQml 内部の機能を利用し、QML のパースと走査をしてみました。

これを発展させることで、import 文のチェックや、高度な置換、QML の分析などが可能になります。

QML をパースする必要がある際には、今回作成したサンプルコードを元に色々改造していただければと思います。