5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

RoslynでC#の構文を解析する

Last updated at Posted at 2020-01-14

exeに「.cs」を投げたら解析するような簡単なRoslynアプリケーションを作成する

なぜ

RoslynはVisualStudioに搭載されているコンパイラであるが、これのAPIが提供、公開されているので誰でも構文解析が楽しめます。
Roslynに私は無限の可能性を感じているのでこれを書きました。

準備

まず、「新しいプロジェクト」でコンソールアプリを作成する。

Nugetで「Microsoft.CodeAnalysis.CSharp」をインストールする。
これは、Roslyn APIを利用するためのパッケージである。

「using」で以下の物を追加する

  • Microsoft.CodeAnalysis;
  • Microsoft.CodeAnalysis.CSharp;
  • Microsoft.CodeAnalysis.CSharp.Syntax;

これで、Roslyn APIを利用できる状態になった。

中身

Roslynでの解析は、VS拡張機能のような修正機能か文字列を受け取って解析する機能の二つである。
今回は文字列で受け取りたいので


public void main(string[] args){
   using(FileStream fs = new FileStream(args[0],FileMode.Open)){
      StreamReader sr = new StreamReader(fs);
      string Text = sr.ReadToEnd();
      //解析するやつ
   }
}

みたいな感じで読みます。(StreamReaderってusingでやったほうがいいんですかね...)

stringのC#コード文字列を解析できる形に変換する。
まず、CSharpSyntaxTree.ParseTextメソッドでSyntaxTreeに変換が出来、さらにノードへの変換はSyntaxTree.GetRootメソッドで出来る。


SyntaxTree tr = CSharpSyntaxTree.ParseText(Text);
SyntaxNode node = tr.GetRoot();

これでNodeに変換できたので好きなように扱えるようになった。

今回は簡単に全ノードを巡回して情報を書き出す。
それには、SyntaxWalkerを利用する。
これを利用して以下のようなクラスを作成して巡回し書くノードの情報を書き出す。


public class AllNodeWriter : SyntaxWalker
{
   Public override void Visit(SyntaxNode node)
   {
      Console.WriteLine(node.Kind());
      base.Visit(node);
   }
}

そして、以下のように呼び出す。


AllNodeWriter writer = new AllNodeWriter();
writer.Visit(node);

終わりに

今回は、情報を書き出しただけでしたがここで変換したノードを書き換えて文字列に戻すことも出来ますし、なんなら解析結果を別言語に変換するなんてことも出来るって感じです。(労力は考えてない)

雰囲気だけでも伝わってくれているといいなって感じです。
やればやるほど楽しいですし、拡張機能を作れるようになると非常に助かります。
稚拙な文章でしたが最後まで読んでいただきありがとうございました。

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?