kubo39's blog

ただの雑記です。

Peggedを使ってみる話

最近このへん触ってないなと思い。 Peggedまったく触ったことないわけではなかったけどパーサ書く時はいつも手書きでやってしまいがちなのであんまり詳しくなかったり。 PeggedD言語でPEGを扱うライブラリです。

初回なので一番簡単な題材にしたいところだけどちょうどいい題材がなかったのでpest(RustのPEGライブラリ)の例をちょっとやってみる。

// Taken from https://pest.rs/book/examples/csv.html

import pegged.grammar;
import std.conv : to;
import std.file : readText;
import std.stdio;
import std.string : join;

mixin(grammar(`
CSVParser:
  File <- (Record :endOfLine)* eol?
  Record <- Field ("," Field)*
  Field <- ([0-9] / "." / "-")+
`));

void main()
{
    auto unparsedFile = readText("numbers.csv");
    auto file = CSVParser(unparsedFile);
    assert(file.successful);

    double fieldSum = 0.0;
    ulong recordCount = 0;

    foreach (record; file.children[0].children)
    {
        recordCount++;
        foreach (field; record.children)
        {
            fieldSum += field.matches.join.to!double;
        }
    }

    writefln("Sum of fileds: %f", fieldSum);
    writefln("Number of records: %d", recordCount);
}

こうParseTreeをいい感じに走査してごにょごにょするのがなんかいい(??)