4. Grammar vocabulary
Associativity
1+2+3 = 1+(2+3) = (1+2)+3 Addition is both left or right associative
1*2*3 = 1*(2*3) = (1*2)*3 Multiplication too
1-2-3 ≠ 1–(2-3) = (1-2)-3 Subtraction is left associative
1/2/3 ≠ 1/(2/3) = (1/2)/3 Division is left associative
6. Grammar vocabulary
Backus-Naur form (BNF)
Named after John Backus and Peter Naur
::= : definition
| : choice operator
<abc>: non-terminal symbol
ABC: terminal symbol
Related and useful:
Kleene star – e* - zero or many
7. Grammar vocabulary
Shift/reduce conflicts
Reduce/reduce conflicts
"Dangling else" problem
Exists when "else" is optional
if e1 then if e2 then e3 else e4 ->
if e1 then (if e2 then e3) else e4 or
if e1 then (if e2 then e3 else e4)
8. Grammar vocabulary
Internal vs External
Internal
via Workflows/Computation expressions
via custom operators/combinators
via augmentations
Excellent resource: dungpa's DSL cheatsheet
https://github.com/dungpa/dsls-in-action-
fsharp/blob/master/DSLCheatsheet.md
10. Abstract syntax trees
type var = string
type Expr =
| Num of float
| Add of Expr * Expr
| Sub of Expr * Expr
| Mul of Expr * Expr
| Div of Expr * Expr
| Var of var
| Call of var * Expr list
12. Parsing with active patterns
let matchToken patt s =
Regex.Match(s, sprintf "A(%s)((?s).*)" patt, RegexOptions.Multiline)
|> fun m ->
if m.Success then
Some (m.Groups.[1].Value, m.Groups.[2].Value)
else
None
// val matchToken: string -> string -> (string * string) option
13. Parsing with active patterns
let (|WS|_|) = matchToken "[ |t|n|rn]+"
let (|COMMENT|_|) = matchToken "#.*[n|rn]"
let (|WHITESPACE|_|) s =
match s with
| WS rest -> Some rest
| COMMENT rest -> Some rest
| _ -> None
14. Parsing with active patterns
let rec (|Star|_|) f acc s =
match f s with
| Some (res, rest) ->
(|Star|_|) f (res :: acc) rest
| None ->
Some (List.rev acc, s)
16. Parsing with active patterns - limitations
• Right associative by default
• Left associativity is tricky
• Need to refactor grammar rules -> gets pretty complicated
• A ::= A B | A C | D | E
• A ::= (D | E) (B | C)*
• Otherwise end up with 1/2/3/4/5 -> 1/(2/(3/(4/5)))
23. Where are the instructions?
https://aka.ms/ms-docs
Docs.microsoft.com
https://aka.ms/intldocs
Do you like Open Source?
https://aka.ms/msossloc
in your language,
today!
VS Code
SQL on Linux
SQL Ops Studio
Team Explorer Everywhere
… and more!