今回はParserScript 3.0で使われたエスケープ文字の対応の仕方について書きます。
実は、ParserScriptの開発に使っているC#言語ではタイトルにもある通り一行だけで実装部分が書けます。
C#での実装方法
では、どうやって実装するのかというと文字列型を数値型に変換するTryParseメソッドとC#8.0で実装された機能をうまく使います。実装には変数が最低一つ要ります。それをTryParseメソッドで宣言して、それをC#8.0で実装された機能を使って吸収するという方法をとります。
これは実際のコードを書いた方がわかりやすいと思います。
using System;
using System.Linq;
using System.Text.RegularExpressions;
internal static class Converter
{
public static string Replace(this string s) => string.Join("", Regex.Replace(string.Join("", s[(int.TryParse("0", out int i))..]), @"(\\).", "$1").Aggregate(Array.Empty<string>(), (x, y) => [.. x.Append(s[i].ToString() == "\\" ? s[i++].ToString() + s[i++].ToString() : s[i++].ToString())]).Select(x => x == "\\n" ? "\n" : (x == "\\t" ? "\t" : (x == "\\\\" ? "\\" : (x == "\\\"" ? "\"" : x)))));
}
一行で書いたのでわかりずらいと思いますが、簡単に書きます。
まず、TryParseメソッド第二引数でout変数を宣言しパース結果の0をout変数iに代入します。その時にできるいらない真偽値を三項演算子で必ず0を返すようにします。ではこの0をどうするのかというと、C#8.0の機能を使ってReplaceメソッドに渡した引数sをchar配列にバラして、string.Joinメソッドでまた連結して0を吸収します。次に正規表現を使い
a\nb
を
a\b
にします。
それをLINQ to ObjectsのAggregateメソッドで
a, \n, b
に、なるようにします。
それをSelectメソッドで改行、水平タブ、バックスラッシュ、ダブルクォーテーションのエスケープ文字に置き換えます。そして、最後にそれらを連結して、値を返します。
a
b
これが一行でエスケープ文字に対応できるカラクリでした。
終わりに
C#言語ってなんかちょっとずるいですよね。C#言語で自作言語を作りたいと思う方は参考にしてください。