上传文件至 ''

This commit is contained in:
Sanchime 2022-06-25 16:49:05 +08:00
parent 7cff98a396
commit b49e695a6c
4 changed files with 123 additions and 0 deletions

72
Parser.fs Normal file
View File

@ -0,0 +1,72 @@
namespace Sanchime.Json
module Parser =
let (|Match|_|) pattern input =
let result = System.Text.RegularExpressions.Regex.Match(input, pattern)
if result.Success then Some result.Value else None
// Ststem.Boolean
let bool (value: string) = System.Boolean.Parse(value)
//
let unquote (str: string) = str.Substring(1, str.Length - 2)
// Token
let token = function
| Match @"^\s+" str -> str, Whitespace
| Match @"^""[^""\\]*(?:\\.[^""\\]*)*""" str -> str, str |> unquote |> StringLiteral
| Match @"^\{|^\}|^\[|^\]|^:|^," str -> str, str[0] |> Symbol
| Match @"^\d+(\.\d+)?|\.\d+" str -> str, str |> float |> NumberLiteral
| Match @"^true|false" str -> str, str |> bool |> BooleanLiteral
| _ -> failwith ""
// Token
let tokenize str =
let rec loop index (str: string) =
if index = str.Length then []
else
let next = str.Substring index
let text, token = next |> token
token :: loop (index + text.Length) str
loop 0 str
|> List.choose (function Whitespace -> None | value -> Some value)
let rec (|Value|_|) = function
//
| NumberLiteral number :: tokens -> Some (Number number, tokens)
//
| BooleanLiteral bool :: tokens -> Some (Boolean bool, tokens)
//
| StringLiteral string :: tokens -> Some (String string, tokens)
// 数组由标识符 + 左中括号 + 值列表 +
| Symbol '[' :: Values(jsons, Symbol ']' :: tokens) -> Some (Array jsons, tokens)
// 对象由标识符 + 左大括号 + 对象列表 +
| Symbol '{' :: Brackets (ps, Symbol '}' :: tokens) -> Some (Object ps, tokens)
| [] -> Some (Null, [])
| _ -> None
//
and (|Values|_|) = function
| Value(p, token) ->
let rec aux p' = function
| Symbol ',' :: Value (p, token) -> aux (p :: p') token
| token -> p' |> List.rev, token
Some (aux [p] token)
| _ -> None
// 对象由文本常量字面量 + 冒号 +
and (|Bracket|_|) = function
| StringLiteral key :: Symbol ':' :: Value (value, token) -> Some ((key, value), token)
| _ -> None
// 对象数组由对象 +
and (|Brackets|_|) = function
| Bracket (p, tokens) ->
let rec aux p' = function
| Symbol ',' :: Bracket(p, tokens) -> aux (p :: p') tokens
| tokens -> p' |> List.rev, tokens
Some (aux [p] tokens)
| _ -> None
let parse str =
str |> tokenize |> function
| Value (value, []) -> value
| _ -> failwith "Json"

24
Program.fs Normal file
View File

@ -0,0 +1,24 @@
open Sanchime.Json.Parser
let json = """
{
"Name": "Bob",
"Email": "bob@example.com",
"IsActive": true,
"Info": {
"Age": 18,
"Gender": "",
"Address": "西",
"City": "",
"Record": [
"",
"",
""
]
}
}
"""
let user = json |> parse
user |> printfn "%A"

View File

@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Include="Syntax.fs" />
<Compile Include="Parser.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
</Project>

16
Syntax.fs Normal file
View File

@ -0,0 +1,16 @@
namespace Sanchime.Json
type Token =
| Whitespace
| Symbol of char
| StringLiteral of string
| NumberLiteral of float
| BooleanLiteral of bool
type Json =
| String of string
| Array of Json list
| Boolean of bool
| Number of float
| Object of (string * Json) list
| Null