-
Notifications
You must be signed in to change notification settings - Fork 1
example date
This example presents a parser for dates in the format dd-Mmm-yyyy
,
for instance 24-Jun-2014
. It demonstrates how verification of
semantic constraints can be included in the parser code – in this case
it is the number of days in each month including the leap day.
First, import the Comparse library and define an array with the abbreviations of months.
P = require('../lib/comparse')
months = [ "Jan", "Feb", "Mar", "Apr", "May", "Jun"
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" ]
This is the parser for the separator character (hyphen):
sep = P.char '-'
The parser for day reads a natural number and fails if it is not between 1 and 31.
day = P.nat0.bind (num) ->
if 1 <= num <= 31 then P.unit num else P.failure
The parser for month reads one uppercase and two lowercase letters
(the default number of repetitions of the repeat
combinator is
2). If the result is found in the months
array, it is returned,
otherwise the parser fails.
month = P.upper.bind (fst) ->
P.lower.repeat().bind (rest) ->
res = months.indexOf fst + rest.join('')
if res >= 0 then P.unit res else P.failure
And here is the complete parser for dates that checks whether the given day is possible in the given month and year.
date = day.bind (d) -> sep.bind -> month.bind (m) ->
if d > 30 and m in [1, 3, 5, 8, 10] or d > 29 and m is 1
P.failure
else
sep.bind -> P.nat0.bind (y) ->
# check leap day
if m is 1 and d is 29 and (y % 4 != 0 or
y % 100 == 0 and y % 400 != 0)
P.failure
else
P.unit new Date(y,m,d)
Now we can test the parser:
try
console.log date.parse '24-Jun-2014'
catch e
console.log e.name, 'at offset', e.offset
The result should be Tue Jun 24 2014 00:00:00 GMT+0200 (CEST)
,
possibly with another timezone.