diff --git a/tests/LexAndYaccCalculator/LexAndYaccCalculator.fsproj b/tests/LexAndYaccCalculator/LexAndYaccCalculator.fsproj
new file mode 100644
index 0000000..e5d9a0e
--- /dev/null
+++ b/tests/LexAndYaccCalculator/LexAndYaccCalculator.fsproj
@@ -0,0 +1,27 @@
+
+
+
+ Exe
+ net6.0
+ lexandyacccalculator_example
+
+
+
+
+
+ --module Parser
+
+
+ --module Lexer --unicode
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/LexAndYaccCalculator/Lexer.fsl b/tests/LexAndYaccCalculator/Lexer.fsl
new file mode 100644
index 0000000..545237a
--- /dev/null
+++ b/tests/LexAndYaccCalculator/Lexer.fsl
@@ -0,0 +1,48 @@
+{
+
+open FSharp.Text.Lexing
+open Parser
+
+type Lexbuf = LexBuffer
+
+let lexeme (lexbuf : Lexbuf) = Lexbuf.LexemeString lexbuf
+
+let newline (lexbuf: LexBuffer<_>) =
+ lexbuf.StartPos <- lexbuf.StartPos.NextLine
+
+}
+
+// Regular expressions
+let whitespace = [' ' '\t' ]
+let newline = ('\n' | '\r' '\n')
+let separator = '_'
+let letter = '\Lu' | '\Ll' | '\Lt' | '\Lm' | '\Lo' | '\Nl'
+let digit = '\Nd'
+let anystring = anychar*
+let integer = digit ((digit | separator)* digit)?
+let char = '\'' ( [^'\\''\n''\r''\t''\b'] | escape_char) '\''
+
+let ident_char =
+ letter
+ | digit
+ | '_'
+let ident = letter ident_char*
+
+let anychar = [^'\n''\r']
+
+let comment = "/*" anystring "*/"
+
+rule tokenstream = parse
+| whitespace { tokenstream lexbuf }
+| newline { newline lexbuf; tokenstream lexbuf }
+// Identifiers
+| ident { ID(lexeme lexbuf) }
+| integer { INT(int (lexeme lexbuf)) }
+// Operators
+| "+" { OP_PLUS }
+| "-" { OP_MINUS }
+| "*" { OP_TIMES }
+| "/" { OP_DIVIDE }
+// --------------------------
+| _ { failwith ("ParseError" + LexBuffer<_>.LexemeString lexbuf) }
+| eof { Parser.EOF }
diff --git a/tests/LexAndYaccCalculator/Parser.fsi b/tests/LexAndYaccCalculator/Parser.fsi
new file mode 100644
index 0000000..5b22e20
--- /dev/null
+++ b/tests/LexAndYaccCalculator/Parser.fsi
@@ -0,0 +1,40 @@
+// Signature file for parser generated by fsyacc
+module Parser
+type token =
+ | OP_PLUS
+ | OP_MINUS
+ | OP_TIMES
+ | OP_DIVIDE
+ | LPAREN
+ | RPAREN
+ | EOF
+ | INT of (int)
+ | ID of (string)
+type tokenId =
+ | TOKEN_OP_PLUS
+ | TOKEN_OP_MINUS
+ | TOKEN_OP_TIMES
+ | TOKEN_OP_DIVIDE
+ | TOKEN_LPAREN
+ | TOKEN_RPAREN
+ | TOKEN_EOF
+ | TOKEN_INT
+ | TOKEN_ID
+ | TOKEN_end_of_input
+ | TOKEN_error
+type nonTerminalId =
+ | NONTERM__startstart
+ | NONTERM_start
+ | NONTERM_Expr
+/// This function maps tokens to integer indexes
+val tagOfToken: token -> int
+
+/// This function maps integer indexes to symbolic token ids
+val tokenTagToTokenId: int -> tokenId
+
+/// This function maps production indexes returned in syntax errors to strings representing the non terminal that would be produced by that production
+val prodIdxToNonTerminal: int -> nonTerminalId
+
+/// This function gets the name of a token as a string
+val token_to_string: token -> string
+val start : (FSharp.Text.Lexing.LexBuffer<'cty> -> token) -> FSharp.Text.Lexing.LexBuffer<'cty> -> ( Syntax.Expr )
diff --git a/tests/LexAndYaccCalculator/Parser.fsy b/tests/LexAndYaccCalculator/Parser.fsy
new file mode 100644
index 0000000..7d7b9ea
--- /dev/null
+++ b/tests/LexAndYaccCalculator/Parser.fsy
@@ -0,0 +1,27 @@
+%{
+open Syntax
+%}
+
+%start start
+%token ID
+%token INT
+
+%token LPAREN RPAREN EOF
+
+%token OP_PLUS OP_MINUS OP_TIMES OP_DIVIDE
+
+%left OP_PLUS OP_MINUS
+%left OP_TIMES OP_DIVIDE
+%type < Syntax.Expr > start
+
+
+%%
+
+start: Expr { $1 }
+
+Expr: ID { Var($1) }
+ | INT { Int($1) }
+ | Expr OP_PLUS Expr { Add($1,$3) }
+ | Expr OP_MINUS Expr { Sub($1,$3) }
+ | Expr OP_TIMES Expr { Mul($1,$3) }
+ | Expr OP_DIVIDE Expr { Div($1,$3) }
diff --git a/tests/LexAndYaccCalculator/Program.fs b/tests/LexAndYaccCalculator/Program.fs
new file mode 100644
index 0000000..8d11699
--- /dev/null
+++ b/tests/LexAndYaccCalculator/Program.fs
@@ -0,0 +1,20 @@
+open System.IO
+open FSharp.Text.Lexing
+open Syntax
+
+let testLexerAndParserFromString text expected =
+ let lexbuf = LexBuffer.FromString text
+
+ let parse = Parser.start Lexer.tokenstream lexbuf
+
+ printfn "parse: result = %A, expected %A" parse expected
+
+testLexerAndParserFromString "1" (Int 1)
+testLexerAndParserFromString "hello" (Var "hello")
+testLexerAndParserFromString "1 + 1" (Add((Int 1),(Int 1)))
+testLexerAndParserFromString "1 - 1" (Sub((Int 1),(Int 1)))
+testLexerAndParserFromString "1 * 1" (Mul((Int 1),(Int 1)))
+testLexerAndParserFromString "1 / 1" (Div((Int 1),(Int 1)))
+testLexerAndParserFromString "1 + 2 + 3" (Add(Add(Int 1, Int 2), Int 3))
+testLexerAndParserFromString "1 + 2 * 3" (Add(Int 1, Mul(Int 2, Int 3)))
+testLexerAndParserFromString "1 * 2 + 3" (Add(Mul(Int 1, Int 2), Int 3))
diff --git a/tests/LexAndYaccCalculator/Syntax.fs b/tests/LexAndYaccCalculator/Syntax.fs
new file mode 100644
index 0000000..a89e860
--- /dev/null
+++ b/tests/LexAndYaccCalculator/Syntax.fs
@@ -0,0 +1,11 @@
+module Syntax
+
+type Id = Id of string
+
+type Expr =
+ | Var of string
+ | Int of int
+ | Add of Expr * Expr
+ | Sub of Expr * Expr
+ | Mul of Expr * Expr
+ | Div of Expr * Expr