Skip to content

Instantly share code, notes, and snippets.

@rflechner
Last active November 18, 2016 08:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rflechner/0fd750481defc5fa14cb4ca18b452e78 to your computer and use it in GitHub Desktop.
Save rflechner/0fd750481defc5fa14cb4ca18b452e78 to your computer and use it in GitHub Desktop.
CSS selector parsing exercice
open System
module Domain =
type ClassName = string
type TagName = string
type HtmlId = string
type Token =
| TagSelector of TagName
| ClassSelector of ClassName
| WhiteSpace
| IdSelector of HtmlId
module Parsing =
open Domain
let (|ExtractClassName|_|) (chars:char list) =
match chars with
| '.' :: t ->
let name = t |> List.takeWhile Char.IsLetterOrDigit
if name.Length <> 0
then Some (String(name |> Seq.toArray),(t |> List.skip name.Length))
else None
| _ -> None
let parseSelector (selector:string) =
let rec loop (chars:char list) (acc:Token list) : Token list =
match chars with
| ExtractClassName (name,t) ->
loop t ((TagSelector name) :: acc)
// TODO: handle other tokens
| [] -> acc
| _ :: t -> loop t acc // TODO: fail with invalid tokens
loop (selector |> Seq.toList) []
open Domain
// Tests
let selector1 = "div.toolbox span a#toto"
let parsedTokens = Parsing.parseSelector selector1
let expectedTokens =
[ TagSelector "div"
ClassSelector "toolbox"
WhiteSpace
TagSelector "span"
TagSelector "a" ]
// TODO: assert expectedTokens equals parsedTokens
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment