zell
zell

Reputation: 10204

Under the command line, how to compile a F# lexer and then run it on a Mac OS?

I do not find documents on the command line for compiling a F# source and then run it on a Mac OS. Here is what I tried, which did not work.

First, I have a lexer specification file "ExprLex_hj.fsl". I generated the lexer using a strange command line which I took from a website:

 mono ~/.nuget/packages/fslexyacc/10.0.0/build/fslex/net46/fslex.exe --unicode ExprLex_hj.fsl

The line above produces a file named "ExprLex_hj.fs". Then I compiled that f# file with another strange command line I copied from another website

fsharpc -r ~/.nuget/packages/fslexyacc/10.0.0/build/fsyacc/net46/FsLexYacc.Runtime.dll ExprLex_hj.fs

This line above produces an EXE file on my Mac OS, ExprLex_hj.exe. Now I need to run this EXE file. I heard that we could do it with mono, an open source implementation of Microsoft's .NET Framework. So, I tried

mono ExprLex_hj.exe

Boom! I got an error:

Unhandled Exception: System.BadImageFormatException: Could not resolve field token 0x04000008, due to: Could not load type of field '<StartupCode$ExprLex_hj>.$ExprLex:_fslex_tables@24' (2) due to: Could not load file or assembly 'FsLexYacc.Runtime, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. assembly:/Users/zell/test_lexer_fsharp/ExprLex_hj.exe type:$ExprLex member:(null)

Can you tell me how to solve this issue? The thing is few documentation can be found on how to run an executable generated from a F# source file. Most tutorials suggest to use .FSX or run a f# file on REPL, which is not what I want -- I would like to execute the generated binary from the command line.

Besides, on my machine, I have Visual Studio installed but I still need to know the command line way to execute an EXE. Also, after installing Visual Studio, I got "fshapri", "fsharpc", "mono", and "dotnet" in my PATH. I am actually unsure whether I should use "mono" or "dotnet" to run an EXE in this situation.

Upvotes: 1

Views: 347

Answers (1)

Koenig Lear
Koenig Lear

Reputation: 2436

Mono is on the way to extinction. It's being replaced by .NET 5 (The successor of .NET core 3.x and .NET framework 4.7x) In the meantime and in your particular scenario you should use .NET core as this will lead to less issues. The tutorial or links you're following must be pretty old.

Using .NET core you build dlls not exes, even if it's an executable. To run them you do dotnet myFile.dll. This works wether you're in Windows, Linux or Mac.

To build .NET core apps use dotnet build. But since you have Visual Studio for Mac that does it for you; Just make sure to create a .NET core project with F#.

You will need to use the .net core 3.x version of fslexyacc rather than .Net framework 4.6. Anything targeting .Net framework 4.6 is designed for Windows. Mono might be able to run it but support is patchy. So why complicate matters if .NET core runs natively in Mac.

To get this dll you can either build it from https://github.com/fsprojects/FsLexYacc.git. Or use nuget. To use nuget create a blank new project in VS for Mac (.NET core console F#) in Nuget packages add Fslexyacc.

The binary for fslex (in a Mac) will be placed in ~/.nuget/packages/fslexyacc/10.0.0/build/fslex/netcoreapp3.0/.

From there you should be able to build your lexer:

dotnet fslex.dll --unicode ExprLex_hj.fsl

Add ExprLex_hj.fs to your project, build. FsLexYacc.Runtime.dll should have been added as a reference when you added the nuget package. That should work.

Upvotes: 3

Related Questions