-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LexAndYaccCalculator example #161
Open
brenoafb
wants to merge
1
commit into
fsprojects:master
Choose a base branch
from
brenoafb:add-lex-yacc-calculator-example
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
{ | ||
|
||
open FSharp.Text.Lexing | ||
open Parser | ||
|
||
type Lexbuf = LexBuffer<char> | ||
|
||
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 } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 ) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
%{ | ||
open Syntax | ||
%} | ||
|
||
%start start | ||
%token <string> ID | ||
%token <int> 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) } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
open System.IO | ||
open FSharp.Text.Lexing | ||
open Syntax | ||
|
||
let testLexerAndParserFromString text expected = | ||
let lexbuf = LexBuffer<char>.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)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you remove
start
and useExpr
as the starting symbol?