開発
2015/1/8
D言語で、構文拡張
mima
D言語の構文を拡張するライブラリ、Tcenalを作り、D言語アドベントカレンダーに書きました。
Swap演算子を追加したい場合、
import parser_combinator.parsing_result : ParsingResult;
import parser_combinator.memo : Memo;
import parser_combinator.combinators;
import tcenal.dparsers : skip;
import tcenal.dsl.generate_parsers : generateParsers;
mixin (generateParsers(`
AssignExpression <- SwapExpression / super;
SwapExpression <- ConditionalExpression ":=:" ConditionalExpression;
`));
import tcenal.rule_selector : createRuleSelector;
import tcenal.dparsers : Module, skip;
alias parse = Module!(createRuleSelector!().RuleSelector);
import parser_combinator.parse_tree_node : ParseTreeNode;
string generateVisitor(ParseTreeNode node)
{
if (node.ruleName == "SwapExpression")
{
return "(){"
"static import std.algorithm;"
"std.algorithm.swap(" ~ node.children[0].children[0].generateVisitor() ~ ","
~ node.children[0].children[2].generateVisitor() ~ ");"
"}()";
}
else if (node.ruleName.length > 0)
{
string codeSegment;
foreach (child; node.children)
{
codeSegment ~= child.generateVisitor();
}
return codeSegment;
}
else
{
return node.value ~ " ";
}
}
string SWAP_OP(string src)
{
Memo memo;
return parse(src, 0, memo).node.generateVisitor();
}
のように記述し、
import swap_op;
mixin (SWAP_OP(
q{
void bubblesort(T)(T[] array)
{
foreach (base; 0 .. array.length - 1)
{
foreach_reverse (i; base .. array.length - 1)
{
if (array[i] > array[i + 1])
{
array[i] :=: array[i + 1];
}
}
}
}
void main()
{
import std.stdio : writeln;
int[] array = [3, 1, 4, 1, 5, 9, 2];
array.bubblesort();
writeln(array);
}
}));
のように使うことが出来ます。
詳しくは以下の記事を参照してください。
Qiita – D言語の構文を拡張する
担当:美馬(アドベントカレンダー用に作るライブラリとしては大きすぎた感じがします)
2024/09/13
2024/05/17
2024/05/10
2024/01/05
2023/08/18
2023/07/14
2023/05/12