Arithmetic evaluation: Difference between revisions

Content added Content deleted
(added F#)
Line 919: Line 919:


See [[Arithmetic Evaluator/Go]]
See [[Arithmetic Evaluator/Go]]


=={{header|F_Sharp|F#}}==
Using FsLex and FsYacc from the F# PowerPack, we implement this with multiple source files:

<code>AbstractSyntaxTree.fs</code>:
<lang fsharp>module AbstractSyntaxTree
type Expression =
| Int of int
| Plus of Expression * Expression
| Minus of Expression * Expression
| Times of Expression * Expression
| Divide of Expression * Expression</lang>

<code>Lexer.fsl</code>:
<lang fsharp>{
module Lexer

open Parser // we need the terminal tokens from the Parser

let lexeme = Lexing.LexBuffer<_>.LexemeString
}

let intNum = '-'? ['0'-'9']+
let whitespace = ' ' | '\t'
let newline = '\n' | '\r' '\n'

rule token = parse
| intNum { INT (lexeme lexbuf |> int) }
| '+' { PLUS }
| '-' { MINUS }
| '*' { TIMES }
| '/' { DIVIDE }
| '(' { LPAREN }
| ')' { RPAREN }
| whitespace { token lexbuf }
| newline { lexbuf.EndPos <- lexbuf.EndPos.NextLine; token lexbuf }
| eof { EOF }
| _ { failwithf "unrecognized input: '%s'" <| lexeme lexbuf }</lang>

<code>Parser.fsy</code>:
<lang fsharp>%{
open AbstractSyntaxTree
%}

%start Expr

// terminal tokens
%token <int> INT
%token PLUS MINUS TIMES DIVIDE LPAREN RPAREN
%token EOF

// associativity and precedences
%left PLUS MINUS
%left TIMES DIVIDE

// return type of Expr
%type <Expression> Expr
%%
Expr: INT { Int $1 }
| Expr PLUS Expr { Plus ($1, $3) }
| Expr MINUS Expr { Minus ($1, $3) }
| Expr TIMES Expr { Times ($1, $3) }
| Expr DIVIDE Expr { Divide ($1, $3) }
| LPAREN Expr RPAREN { $2 } </lang>

<code>Program.fs</code>:
<lang fsharp>open AbstractSyntaxTree
open Lexer
open Parser

let parse txt =
txt
|> Lexing.LexBuffer<_>.FromString
|> Parser.Expr Lexer.token

let rec eval = function
| Int i -> i
| Plus (a,b) -> eval a + eval b
| Minus (a,b) -> eval a - eval b
| Times (a,b) -> eval a * eval b
| Divide (a,b) -> eval a / eval b

do
"((11+15)*15)*2-(3)*4*1"
|> parse
|> eval
|> printfn "%d"</lang>


=={{header|Haskell}}==
=={{header|Haskell}}==