Skip to content

origami(2019年1月18日)

KASE edited this page Jan 28, 2019 · 9 revisions

command

commandはorigamiです。
grammar fileのdefault値はkonoha6.tpegであり、別のgrammar fileを指定したい場合には-gを用います。
origami ruleのdefault値はcommon.origamiであり、別のorigami ruleを指定する場合は引数の指定は必要なく、fileの拡張子がorigamiのfileを入力すれば良いです。
参考:

origami_files = [f for f in opt['inputs'] if f.endswith('.origami')]
source_files = [f for f in opt['inputs'] if not f.endswith('.origami')]

commandの例:

python3 pegpy/main.py origami sample.k
python3 pegpy/main.py origami -g nico2.tpeg solidity.origami sample.nico

origamiの構造

origamiはtpegでparseすることで出力された木構造を入力に取り、ソースコードの文字列を出力するものです。
origamiは「構文木をS式へ変換」, 「S式の操作」, 「型付け」, 「出力」の4部分からなり、それぞれのコードはpegpy/origmai/expression.py, pegpy/origami/desugar.py, pegpy/origami/typesys.py, pegpy/origami/pprint.pyにあります。
これらの操作はファイル拡張子がorigamiのファイルに記載されているorigami ruleに基づいて行います。

origami rule

origami ruleの文法はorigami.tpeg内に記載されています。
詳しくは「origami ruleの書き方」のページを参照してください。

origamiの手順

pegpy/main.pyのorigmai()に記載されている通り、parseした後に出力される構文木をpegpy/origami/typesys.pyのtranspile()の引数に渡します。
transpile()の引数のenvにはtranspile_init()で読み込まれたorigami ruleが格納されています。

S式へ変換

transpile()内のExpression.treeConv()によって変換されています。
少し見ない間に大分変更されていました。

S式の操作

pegpy/origami.pyのenv.asType()よりdesugar()を呼び出して操作をします。
型付けを行う前はisUntyped()は必ずTrueになるため、transpile()には記述しなくても問題ありません。可読性よりも効率が重要です。
まずorigami ruleに記載されているcodeに対して、pythonの正規表現のライブラリを用いてマッチングします。
正規表現オブジェクトは下記のようになっています。

re.compile(r'\$\{@([a-z0-9.]*)\((-?\w\:?-?\d?)\)\}')

escape文字などはpythonの公式ライブラリを参照してください。
マッチングしなかった場合には何も操作はせず、型付けの手順に入ります。
desugar()の下記の部分

code = desugar_find(defined.code)
for func, args in code:

desugar_find()が正規表現のマッチングをする関数であり、その返り値の型はList<Tuple<str, str>>です。
マッチングしなかった場合にはlengthが0になります。
このfuncには正規表現の最初の()で囲われた[a-z0-9.]にマッチする文字列が入り、
argsには次の()で囲われた-?\w:?-?\d?にマッチする文字列が入ります。
現在errorを起こさずに正しく操作できる関数はnop, block, retです。
新しく関数を加える際にはこれらを参考にして下さい。

型付け

class Origamiによって型付けされています。
lookupMethod()にある通り、S式のTagに#が付いている場合には#を除去し、Exprが付いている場合にはさらにExprを除去した名前の関数をgestattrで取得し、その関数で各S式における型付けを行っています。
FuncExpr, ApplyExpr, MethodExpr, TrueExpr, FalseExprはExprを除去しません。

出力

出力します。 「origami ruleの書き方」で詳しく書いてあります。
新規に出力のformat変更を加える場合は、関数を作成し、その関数名をFMTFUNCに加えます。

余談

konoha6.tpegでは'で囲むとCharExpr、"で囲むとStringExprになります。文字数は関係ありません。
また'''で囲むとTemplateExprとなり、複数行入力が可能となりますが、その子nodeにStringExprが指定されているため、出力時の文字列は"で囲われています。