I'm trying to implement error recovery in this version of the project (make followed by ./parse e1.input to test).
Given (1 in e1.input, I would like the parser to act as if it parsed ) and build an AST Paren (Int 1). Thus, I tried
let (startp, endp) = positions in
let _ = feed (T T_RPAREN) startp () endp env in
However, it returned an error Invalid_argument("feed: outgoing transition does not exist")
hahahaha depth of env 2
hahahaha current_state_number 2
hahahaha startp 1:1
hahahaha endp 1:2
element number of state 2
element startp 1:1
element endp 1:2
element incoming_symbol an integer
element v toComplete
element item: an expression -> an integer.
element number of state 1
element startp 1:0
element endp 1:1
element incoming_symbol (
element v toComplete
element item: an expression -> ( .an expression )
Line 1, characters 2-2: Error (parsing)
Error while analyzing an expression.
Fatal error: exception Invalid_argument("feed: outgoing transition does not exist")
Does anyone know why this error was raised?
Before feeding ), we should first reduce, the following code works:
let env_new = force_reduction (find_production 1) env in
let env_new_new = feed (T T_RPAREN) startp () endp env_new in
(lex, input_needed env_new_new)
For (1+2 for instance, we should reduce twice before feeding ), the following code works:
let env_new = force_reduction (find_production 1) env in
let env_new_new = force_reduction (find_production 3) env_new in
let env_new_new_new = feed (T T_RPAREN) startp () endp env_new_new in
(lex, input_needed env_new_new_new)
Related
For a class I'm following, I have to do the following exercise:
Implement a function
let splitAt (i : int) (l : List<'a>) : List<'a> * List<'a> = ...
that splits the list into two lists, the rst one containing all the elements of l from position 0 to position i
included, and the second one containing all the remaining elements. The two resulting lists are returned
in a tuple. For example:
split 3 [3;5;4;-1;2;2] = ([3;5;4;-1],[2;2])
We have to do these problems only using functional programming, and thus I'm not allowed to use pre-existing functions.
I have the following code which seems to me to (logically) be correct:
let splitAt (i:int)(l: List<'a>): List<'a> * List<'a> =
let rec loop n startlist restlist =
if n = i then
restlist * startlist
else
match startlist with
| h :: t -> loop (n+1) [t] [(restlist :: h)]
| h :: [] -> None
loop 0 l []
and below my [<EntryPoint>]
printfn "%A" (splitAt stringlist 3)
However, this gives me a couple of errors, namely:
None of the types 'a list, 'a list support the operator *
This expression was expected to have type int but here has type char list
This expression was expected to have type List<'a> but here has type int
The * operator is used for declaring a tuple type, but when you're building a tuple you use , instead. So you want restlist, startlist.
Then you'll discover that there's another type error, because one branch of your match expression returns None. That's an option type, so the value you return should be a Some. So you want Some (restlist, startlist).
And now you'll discover one more type error, which is that you've declared that the function returns a tuple but in fact it returns a tuple option (that is, either None or Some tuple). So your type declaration needs to become (List<'a> * List<'a>) option.
For more on why * is used in declaring tuple types rather than ,, https://fsharpforfunandprofit.com/posts/tuples/ is a good read.
So I have this function that calculates the frequency percentage of each letter given a string. this function is called "frequency" and utilizes other helper functions that I've wrote ("count", "lowerCases", and "percent"). But when I try to return my result, I keep getting a mismatch error. Here is my code below:
let frequency(str:string) : float =
let myList = ['a'..'z']
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
System.Console.WriteLine(frequency"hello world")
I keep getting this error:
This expression was expected to have type float but here has type unit
How can I fix this type mismatch error? I've already tried setting my result to a different variable and calling that variable, but that didn't work.
You've declared the function as returning a float:
let frequency(str:string) : float =
However, your function doesn't return a float, it just prints one out:
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
The printf function returns unit, meaning that it effectively has no return value (it has a constant return value of the singleton type unit).
There are two things that I see you needing to fix here. You need to return a value from the function (by having it be the value of the last line), and I think you will want your return type to be a list or a map instead of a single value (else, how would you know two which letter the frequency applies)?
You can achieve this result by just calling your percent function from List.map, and then making Map of the list:
let frequency(str:string) : Map<char, float> =
['a'..'z']
|> List.map (fun letter -> letter, (percent ((count letter str) (lowerCases str))))
|> Map.ofList
An F# function binds a single value of the single expression in its body (the one which comes last after all let-bindings, simply speaking. In your case, this expression is
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
It has the type unit, meaning it does not return anything useful but a special value (), while the let frequency ... : float = binding says that it returns a float. Hence the error.
printf already prints to console. What you want is probably
let frequency(str:string) : unit =
let myList = ['a'..'z']
for i=0 to 25 do
printf "%f" (percent ((count myList.[i] str) (lowerCases str)))
do frequency "hello world"
It is idiomatic to omit the : unit annotation in such a function, and let the compiler infer the return type. This code does not shine the F# glory, naturally, but does the job.
As it appears you are learning the language, here's an exercise, maybe for the future. Your function lumps together computing the letter frequencies and printing them, and functional programming is all about composition. What if you want to display the result in a window instead of printing it to console, or format it differently? Try to write two functions, one returning a data structure with the letter frequencies, and another printing it.
I'm trying to parse a file, using FParsec, which consists of either float or int values. I'm facing two problems that I can't find a good solution for.
1
Both pint32 and pfloat will successfully parse the same string, but give different answers, e.g pint32 will return 3 when parsing the string "3.0" and pfloat will return 3.0 when parsing the same string. Is it possible to try parsing a floating point value using pint32 and have it fail if the string is "3.0"?
In other words, is there a way to make the following code work:
let parseFloatOrInt lines =
let rec loop intvalues floatvalues lines =
match lines with
| [] -> floatvalues, intvalues
| line::rest ->
match run floatWs line with
| Success (r, _, _) -> loop intvalues (r::floatvalues) rest
| Failure _ ->
match run intWs line with
| Success (r, _, _) -> loop (r::intvalues) floatvalues rest
| Failure _ -> loop intvalues floatvalues rest
loop [] [] lines
This piece of code will correctly place all floating point values in the floatvalues list, but because pfloat returns "3.0" when parsing the string "3", all integer values will also be placed in the floatvalues list.
2
The above code example seems a bit clumsy to me, so I'm guessing there must be a better way to do it. I considered combining them using choice, however both parsers must return the same type for that to work. I guess I could make a discriminated union with one option for float and one for int and convert the output from pint32 and pfloat using the |>> operator. However, I'm wondering if there is a better solution?
You're on the right path thinking about defining domain data and separating definition of parsers and their usage on source data. This seems to be a good approach, because as your real-life project grows further, you would probably need more data types.
Here's how I would write it:
/// The resulting type, or DSL
type MyData =
| IntValue of int
| FloatValue of float
| Error // special case for all parse failures
// Then, let's define individual parsers:
let pMyInt =
pint32
|>> IntValue
// this is an alternative version of float parser.
// it ensures that the value has non-zero fractional part.
// caveat: the naive approach would treat values like 42.0 as integer
let pMyFloat =
pfloat
>>= (fun x -> if x % 1 = 0 then fail "Not a float" else preturn (FloatValue x))
let pError =
// this parser must consume some input,
// otherwise combined with `many` it would hang in a dead loop
skipAnyChar
>>. preturn Error
// Now, the combined parser:
let pCombined =
[ pMyFloat; pMyInt; pError ] // note, future parsers will be added here;
// mind the order as float supersedes the int,
// and Error must be the last
|> List.map (fun p -> p .>> ws) // I'm too lazy to add whitespase skipping
// into each individual parser
|> List.map attempt // each parser is optional
|> choice // on each iteration, one of the parsers must succeed
|> many // a loop
Note, the code above is capable working with any sources: strings, streams, or whatever. Your real app may need to work with files, but unit testing can be simplified by using just string list.
// Now, applying the parser somewhere in the code:
let maybeParseResult =
match run pCombined myStringData with
| Success(result, _, _) -> Some result
| Failure(_, _, _) -> None // or anything that indicates general parse failure
UPD. I have edited the code according to comments. pMyFloat was updated to ensure that the parsed value has non-zero fractional part.
FParsec has the numberLiteral parser that can be used to solve the problem.
As a start you can use the example available at the link above:
open FParsec
open FParsec.Primitives
open FParsec.CharParsers
type Number = Int of int64
| Float of float
// -?[0-9]+(\.[0-9]*)?([eE][+-]?[0-9]+)?
let numberFormat = NumberLiteralOptions.AllowMinusSign
||| NumberLiteralOptions.AllowFraction
||| NumberLiteralOptions.AllowExponent
let pnumber : Parser<Number, unit> =
numberLiteral numberFormat "number"
|>> fun nl ->
if nl.IsInteger then Int (int64 nl.String)
else Float (float nl.String)```
Why doesn't this work?
type RetryBuilder(max) =
member x.Return(a) = a // Enable 'return'
member x.Delay(f) = f // Gets wrapped body and returns it (as it is)
// so that the body is passed to 'Run'
member x.Zero() = failwith "Zero" // Support if .. then
member x.Run(f) = // Gets function created by 'Delay'
let rec loop 0 (Some(ex)) = raise ex
let rec loop n maybeEx = try f() with ex -> loop (n-1) (Some(ex))
loop max None
let retry = RetryBuilder(4)
It says 'incomplete pattern matches on this expression. For example, the value '1' may indicate a case not covered by the pattern'.
But why wouldn't that match the one below? If I remember correctly, Haskell would match that, why doesn't F#?
You're writing F# code in Haskell syntax. The reason why your code compiles is F# compiler thought there are two loop functions where the former is shadowed by the latter. Obviously in the first loop function, pattern matching fails with any integer different from 0 for the first parameter and None for the second parameter.
A declaration close to Haskell syntax could be:
let rec loop = function
| 0, Some ex -> raise ex
| n, maybeEx -> try f() with ex -> loop (n-1, Some ex)
loop(max, None)
I have written two versions of code. The first one works as expected and print "Hi". the second one gives me error that "block following this let is unfinished"
1st version
#light
let samplefn() =
let z = 2
let z = z * 2
printfn "hi"
samplefn()
2nd version
#light
let samplefn() =
let z = 2
let z = z * 2
samplefn()
Only difference is the printfn is absent in the second version. I am using Visual Studio 2010 as my IDE. I am very new to F# but this error seems very strange to me. I guess I am missing some very important concept. Please explain.
Edit: Also if I do it outside the function I get error even with the first version of code.
#light
let z = 2
let z = z * 2
printfn "Error: Duplicate definition of value z"
let binds a value to a label but otherwise doesn't do much else. Your function contains two bindings but doesn't use them, and so you get an error.
To think of it another way, all functions in F# need a return value, which is the value of the last executed expression in your function. let doesn't have a return value so your function is invalid. To fix this you can add a return value, for example:
let samplefn() =
let z = 2
let z = z * 2
()
which defines a function that does absolutely nothing (returns unit). Perhaps a better example is this:
let samplefn() =
let z = 2
let z = z * 2
z
which will return 4 (the value of the binding for label z).
I think it is helpful to understand the non-light syntax here. Let's translate:
1st Version (let binding expressions)
let samplefn() =
let z = 2 in
let z = z * 2 in
printfn "hi";;
samplefn();;
The important thing to understand here is that all non-top-level let bindings are actually expressions of the form let <variable> = <expression1> in <expression2> where <variable> is bound to the result of <expression1> in a new scope <expression2>, and <expression2> is the return value of the entire expression. The light syntax makes you believe such let bindings are variable assignments / statements, when in fact it really is true that almost everything in F# is an expression.
Perhaps the following illustrates this more clearly:
let a = (let b = 3 in b + 2) //a is 5
2nd Version (top-level let bindings)
let z = 2;;
let z = z * 2;;
printfn "Error: Duplicate definition of value z";;
Top level let-bindings are terminated with ;;, indicating the completion of what may be thought of as a statement. The top-level is a single scope, and here we get an error for trying to bind z twice within the same scope. Whereas using the expression form of let bindings in Example 1, we bind z anew for each sub-scope in the expression chain. Note that we could do something like this at the top-level:
let z = (let z = 2 in z * 2);;
A let that is not at the top level (e.g. your indented ones) has to have a statement (actually an expression, as pst notes) called a "body" following the assignment. In the first example the body is printfn "hi", while the second example has no body. That's what the compiler is complaining about.
Note that in your function definitions the inner let expressions actually create nested scopes. That is, the let z = z * 2 actually creates a new value called z and binds to it the value of the outer z times 2, then uses it in the body of the let (which is the printfn in this case). A nested let will always have a body. It is the nesting which allows the seemingly duplicate definition.
Since an outermost let does not need a body, the compiler thinks you're trying to redefine z in the same scope, which is an error. You can use parentheses to tell the compiler how to properly interpret the last example:
let z = 2
(let z = z * 2
printfn "z = %d" z)
printfn "z = %d" z
The above will print z = 4
z = 2