I am trying to define my grammar as a discriminated union. It has two possible types: int
and datetime
and mathemetical operators of Add
and Mul
.
Add
works on int
and datetime
(as add days in int)
Mul
works only on int
and not on datetime
Grammar can be recursive
My grammar looks like
type MyExpression =
|Integer of int
|Date of datetime
|Add of MyExpression * MyExpression
|Mul of MyExpression * MyExpression
I have written a parser (fparsec) that can parse text in my grammar, but I am not sure how to handle the condition that Mul
can be recursive but only on Integer
.
Is there an option to define this restriction on my MyExpression
type or do I have to handle this in my parsed input?
To reset your password if you're not logged in to Facebook: Click Forgot Password?. Type the email, mobile phone number, full name or username associated with your account, then click Search. Follow the on-screen instructions.
Email: You can log in with any email that's listed on your Facebook account. Phone number: If you have a mobile number confirmed on your account, you can enter it here (don't add any zeros before the country code, or any symbols). Username: You can also log in with your username, if you set one up.
You can use the popular fbdown.net website, which allows you to download Facebook videos using your web browser. OR install an app dedicated for the same function. If you're going to download Facebook videos on your Android device regularly, the dedicated Facebook Video Downloader app might be more appealing, though.
The design suggested by Asti would also be my first choice. Depending on your requirements, that may be all you need.
It does, however, also enable you to compile an expression like
Add(Val(System.Console.Out), Val(System.Console.Error))
which is probably not what you want.
Alternatively, you could model expressions like this:
open System
type IntExpression =
| Integer of int
| Mul of IntExpression * IntExpression
| Add of IntExpression * IntExpression
type DateTimeExpression =
| Date of DateTime
| Add of DateTimeExpression * DateTimeExpression
type MyExpression =
| IntExpression of IntExpression
| DateTimeExpression of DateTimeExpression
This is clearly a more verbose type definition, but it does embody the rule that an expression can contain leaf nodes of either integers or DateTime
values, and no other values - if that's the rule you want to enforce.
I'm not claiming that this is better; I'm only supplying an alternative.
Usage:
> IntExpression(Mul(IntExpression.Add(Integer(1), Integer(2)),Integer 3));;
val it : MyExpression =
IntExpression (Mul (Add (Integer 1,Integer 2),Integer 3))
> DateTimeExpression(Add(Date(DateTime.MinValue),Date(DateTime.MinValue)));;
val it : MyExpression =
DateTimeExpression
(Add
(Date 01.01.0001 00:00:00 {Date = 01.01.0001 00:00:00;
Day = 1;
DayOfWeek = Monday;
DayOfYear = 1;
Hour = 0;
Kind = Unspecified;
Millisecond = 0;
Minute = 0;
Month = 1;
Second = 0;
Ticks = 0L;
TimeOfDay = 00:00:00;
Year = 1;},
Date 01.01.0001 00:00:00 {Date = 01.01.0001 00:00:00;
Day = 1;
DayOfWeek = Monday;
DayOfYear = 1;
Hour = 0;
Kind = Unspecified;
Millisecond = 0;
Minute = 0;
Month = 1;
Second = 0;
Ticks = 0L;
TimeOfDay = 00:00:00;
Year = 1;}))
If you have type based constraints, it may be easier going for a generic approach:
type MyExpression<'t> =
|Val of 't
|Mul of MyExpression<int> * MyExpression<int>
|Add of MyExpression<'t> * MyExpression<'t>
let Integer (x:int) = Val(x)
let Date (x:DateTime) = Val(x)
Usage:
Mul(Integer(1), Integer(2)) //compiles
Mul(Date(DateTime.Now), Date(DateTime.Now)) //error
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With