From c951ce7fa7aafc01997599e8ebd694c5a1178a09 Mon Sep 17 00:00:00 2001 From: Katharina Fey Date: Tue, 23 Jul 2019 15:34:06 +0200 Subject: Initial draft of the file format parser --- parser.rb | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100755 parser.rb diff --git a/parser.rb b/parser.rb new file mode 100755 index 0000000..4e261ba --- /dev/null +++ b/parser.rb @@ -0,0 +1,87 @@ +#!/usr/bin/env ruby + +require "pp" + +require "parslet" +include Parslet + +class EntryParser < Parslet::Parser + root :doc + + ### Type segments + rule(:hour) { hour_.as(:hour) } + rule(:minute) { minute_.as(:minute) } + rule(:second) { second_.as(:second) } + + rule(:year) { year_.as(:year) } + rule(:month) { month_.as(:month) } + rule(:day) { day_.as(:day) } + + rule(:time) { time_.as(:time) } + rule(:local) { local_.as(:local) } + rule(:offset) { offset_.as(:offset) } + + rule(:date) { date_.as(:date) } + rule(:datetime) { date >> str(" ") >> time } + rule(:daterange) { start >> str(" -") >> stop } + + rule(:start) { datetime.as(:start) } + rule(:stop) { (str(" ") >> datetime).maybe.as(:stop) } + + rule(:title) { title_.as(:title) } + rule(:doc) { line_.repeat } + + ### Combinatory segments + rule(:hour_) { digit.repeat(2, 2) } + rule(:minute_) { digit.repeat(2, 2) } + rule(:second_) { digit.repeat(2, 2) } + + rule(:time_) { local >> offset } + rule(:date_) { year >> str("-") >> month >> str("-") >> day } + + rule(:year_) { digit.repeat(4, 4) } + rule(:month_) { digit.repeat(2, 2) } + rule(:day_) { digit.repeat(2, 2) } + + rule(:local_) { hour >> str(":") >> minute >> str(":") >> second } + rule(:offset_) { match("[zZ]") | tnoffset_ } + rule(:poffset_) { str(" ") >> match("[+\-]") } + rule(:tnoffset_) { poffset_ >> hour >> str(":").maybe >> minute } + + rule(:title_) { text >> str(":") } + + rule(:entry_) { title >> spaces >> daterange } + rule(:comment) { str("#") >> text } + rule(:line_) { comment | entry_ | newline } + + ### Primitive modes + rule(:digit) { match("[0-9]") } + rule(:text) { match("[a-zA-Z0-9 ]").repeat } + rule(:spaces) { match("[ \t]").repeat } + rule(:newline) { spaces.maybe >> str("\n") } +end + +PP.pp EntryParser.new.parse(" +# This is a comment +Bobs Burger: 2019-07-21 21:00:00 +0200 - +") + +__END__ + +# Following is an example of what the `timebox` file format looks like +# Comment lines start with `#`, description lines start with ` `. Every +# other line is an entry, with the account first, followed by `:`, then +# time slice information in YYYY-MM-DD hh:mm:ss +TZ - ... +# An ongoing shift is allowed to have no "end" time information + +Bobs Burger: 2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200 + Learning how to not burn down the kitchen + +Bobs Burger: 2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200 + Serving some food + +ACME Inc: 2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200 +ACME Inc: 2019-07-21 21:00:00 +0200 - 2019-07-21 22:00:00 +0200 + +Bobs Burger: 2019-07-22 09:00:00 +0200 - 2019-07-22 15:00:00 +0200 +Bobs Burger: 2019-07-22 21:00:00 +0200 - -- cgit v1.2.3