F#的简单Demo——简单的整型加减

Calc Demo

Demo下载地址:

https://github.com/TOHKAaaaa/Calc-Demo

找到calcfs文件夹,解压

可以看到demo所需的fsi以及fsy文件

如果成功下载,可以直接跳到最后,若无法下载或下载很慢,下面会给出具体的代码段

Demo代码

scanner.fsl

{ 
open Parser
open FSharp.Text.Lexing
let lexeme = LexBuffer<_>.LexemeString
}

rule token =
    parse [' ' '\t' '\r' '\n'] { token lexbuf }
        | '+' { PLUS }
        | '-' { MINUS }
        | '*' { TIMES }
        | '/' { DIVIDE }
        | ['0'-'9']+  { LITERAL(int (lexeme lexbuf)) }
        | eof { EOF }

 

parser.fsl

%{ 
open Ast
%}

%token PLUS MINUS TIMES DIVIDE EOF
%token <int> LITERAL
%left PLUS MINUS
%left TIMES DIVIDE
%start expr
%type <Ast.expr> expr

%%

expr:
    expr PLUS expr { Binop($1, Add, $3) }
    | expr MINUS expr { Binop($1, Sub, $3) }
    | expr TIMES expr { Binop($1, Mul, $3) }
    | expr DIVIDE expr { Binop($1, Div, $3) }
    | LITERAL { Lit($1) } 

 

Ast.fs

module Ast

type operator = Add | Sub | Mul | Div
type expr =
    | Binop of expr * operator * expr
    | Lit of int

 

Calc.fs

open System
open FSharp.Text.Lexing
open Ast

let rec eval = function
    Lit(x) -> x
    | Binop(e1, op, e2) ->
        let v1 = eval e1 
        let v2 = eval e2 in
            match op with
                | Add -> v1 + v2
                | Sub -> v1 - v2
                | Mul -> v1 * v2
                | Div -> v1 / v2
[<EntryPoint>]
let main argv =
    let rec loop () = 
        printf "user>"
        let input =  Console.ReadLine()
        let lexbuf = LexBuffer<char>.FromString input 
        try 
            let expr = Parser.expr Scanner.token lexbuf in

                let result = eval expr in
                    //printfn "%A" expr;
                    printfn "%s"  (string result)
        with e ->
            printfn "Errors"       
        loop ()
    loop ()   

 

calcfs.fsproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
  <!-- 
  fslex fsyacc 工具依赖
  dotnet run 会自动调用工具fslex fsyacc,并生成 Scanner.fs Parser.fs
   -->
    <FsLex Include="Scanner.fsl">
      <OtherFlags>--module Scanner --unicode</OtherFlags>
    </FsLex>
   <FsYacc Include="Parser.fsy">
      <OtherFlags>--module Parser</OtherFlags>
    </FsYacc>
<!-- 
  编译文件列表,注意有前后次序,被依赖的文件放前面,主文件 Calc.fs放在最后
 -->
    <Compile Include="Ast.fs" />
    <Compile Include="Parser.fs" />
    <Compile Include="Scanner.fs" />
    <Compile Include="Calc.fs" />

<!-- 
  fslexyacc外部包依赖 
  在项目目录,运行 `dotnet add package  fslexyacc`  添加
-->
    <PackageReference Include="fslexyacc" Version="10.2.0" />

  </ItemGroup>

</Project>

 

Demo的编译与运行

首先先到达calcfs的目录下,使用dotnet run即生成可执行程序calcfs.exe

运行完成后,在bin目录底下找到calcfs.exe也可以运行。

运行结果如下:

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值