Skip to content
This repository has been archived by the owner on Aug 27, 2024. It is now read-only.

Create parser #3

Merged
merged 2 commits into from
Jun 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/crncc/AST.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module CRN.AST

type SpeciesS = string
type PNumberS = PNumber of float

type ConcS = Conc of SpeciesS * PNumberS

type ExprS = Expr of list<SpeciesS>

type ReactionS = Reaction of ExprS * ExprS * PNumberS

type ModuleS =
| Ld of SpeciesS * SpeciesS
| Add of SpeciesS * SpeciesS * SpeciesS
| Sub of SpeciesS * SpeciesS * SpeciesS
| Mul of SpeciesS * SpeciesS * SpeciesS
| Div of SpeciesS * SpeciesS * SpeciesS
| Sqrt of SpeciesS * SpeciesS
| Cmp of SpeciesS * SpeciesS

type ConditionS =
| Gt of CommandS list
| Ge of CommandS list
| Eq of CommandS list
| Lt of CommandS list
| Le of CommandS list

and CommandS =
| Reaction of ReactionS
| Module of ModuleS
| Condition of ConditionS

type StepS = Step of list<CommandS>

type RootS =
| Conc of ConcS
| Step of StepS

type CrnS = Crn of list<RootS>
113 changes: 113 additions & 0 deletions src/crncc/Parser.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
module CRN.Parser

open CRN.AST
open FParsec

// Doesn't work right now
let private comment =
let anythingExceptNewline = isNoneOf [ '\n'; '\r' ]
skipString "//" >>. spaces >>. manySatisfy anythingExceptNewline

let private ws = comment |>> ignore <|> spaces
let private str_ws s = pstring s .>> ws

let private float_ws = pfloat .>> ws

let private identifier =
let isFirstChar c = isLetter c || c = '_'
let isChar c = isLetter c || isDigit c || c = '_'
many1Satisfy2L isFirstChar isChar "identifier" .>> ws

let private pspecies = identifier .>> ws |>> SpeciesS
let private pnumber = float_ws |>> PNumber

let private pexpr = sepBy pspecies (str_ws "+") .>> ws |>> Expr

let private start_bracket bcopen start = str_ws start .>> str_ws bcopen

let private end_bracket bcclose = str_ws bcclose

let private comma = str_ws ","

let private brackets2 popen pclose t1 t2 cons =
pipe2 (popen >>. t1) (comma >>. t2 .>> pclose) (fun v1 v2 -> cons (v1, v2))

let private brackets3 popen pclose t1 t2 t3 cons =
pipe3 (popen >>. t1) (comma >>. t2) (comma >>. t3 .>> pclose) (fun v1 v2 v3 -> cons (v1, v2, v3))

let private pconc =
brackets2 (start_bracket "[" "conc") (end_bracket "]") pspecies pnumber ConcS.Conc

let private brackets3species name =
brackets3 (start_bracket "[" name) (end_bracket "]") pspecies pspecies pspecies

let private brackets2species name =
brackets2 (start_bracket "[" name) (end_bracket "]") pspecies pspecies

let private pmoduleld = brackets2species "ld" Ld
let private pmoduleadd = brackets3species "add" Add
let private pmodulesub = brackets3species "sub" Sub
let private pmodulemul = brackets3species "mul" Mul
let private pmodulediv = brackets3species "div" Div
let private pmodulesqrt = brackets2species "sqrt" Sqrt
let private pmodulecmp = brackets2species "cmp" Cmp

let private pmodule =
choice
[ pmoduleld
pmoduleadd
pmodulesub
pmodulemul
pmodulediv
pmodulesqrt
pmodulecmp ]

let private prxn =
brackets3 (start_bracket "[" "rxn") (end_bracket "]") pexpr pexpr pnumber ReactionS.Reaction

let private listparser popen pclose listelem =
between popen pclose (sepBy listelem (str_ws ","))

let private pcon, pconref = createParserForwardedToRef<'a, 'u> ()

let private pcommand =
choice
[ pmodule |>> CommandS.Module
prxn |>> CommandS.Reaction
pcon |>> CommandS.Condition ]

Check warning on line 77 in src/crncc/Parser.fs

View workflow job for this annotation

GitHub Actions / build

This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'ConditionS'.

Check warning on line 77 in src/crncc/Parser.fs

View workflow job for this annotation

GitHub Actions / build

This construct causes code to be less generic than indicated by the type annotations. The type variable 'a has been constrained to be type 'ConditionS'.

let private commandopen start =
str_ws start >>. str_ws "[" .>> str_ws "{"

let private commandclose = str_ws "}" .>> str_ws "]"

let private pcommandlist start =
listparser (commandopen start) commandclose pcommand

let private pcmdif = pcommandlist "ifGT" |>> Gt
let private pcmdge = pcommandlist "ifGE" |>> Ge
let private pcmdeq = pcommandlist "ifEQ" |>> Eq
let private pcmdlt = pcommandlist "ifLT" |>> Lt
let private pcmdle = pcommandlist "ifLE" |>> Le

pconref.Value <- choice [ pcmdif; pcmdge; pcmdeq; pcmdlt; pcmdle ]

let private pstep = pcommandlist "step" |>> StepS.Step

let private proot = choice [ pstep |>> RootS.Step; pconc |>> RootS.Conc ]

let private crnopen = str_ws "crn" >>. str_ws "=" .>> str_ws "{"

let private crnclose = str_ws "}"
let private curlyparser = listparser crnopen crnclose
let private pcrn = ws >>. curlyparser proot .>> eof |>> Crn


let tryParse str =
let result = run pcrn str

Check warning on line 107 in src/crncc/Parser.fs

View workflow job for this annotation

GitHub Actions / build

This construct causes code to be less generic than indicated by the type annotations. The type variable 'u has been constrained to be type 'unit'.

Check warning on line 107 in src/crncc/Parser.fs

View workflow job for this annotation

GitHub Actions / build

This construct causes code to be less generic than indicated by the type annotations. The type variable 'u has been constrained to be type 'unit'.

match result with
| Success(output, _, _) -> Some(output)
| Failure(errorMsg, _, _) ->
printfn "Failure: %s" errorMsg
None
6 changes: 6 additions & 0 deletions src/crncc/crncc.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
</PropertyGroup>

<ItemGroup>
<Compile Include="AST.fs" />
<Compile Include="Parser.fs" />
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="FParsec" Version="1.1.1" />
</ItemGroup>

</Project>
21 changes: 19 additions & 2 deletions test/crncc_test/Tests.fs
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
module Tests

open System
open Xunit
open CRN.Parser


let example =
"crn = {
conc[c, 5.0], conc[cInitial, 4.0],
conc[one, 1], conc[zero, 0],
step[{
sub[c, one, cnext],
cmp[c, zero]
}],
step[{
ifGT[{ ld[cnext, c] }],
ifLE[{ ld[cInitial, c] }]
}]
}"

[<Fact>]
let ``My test`` () =
Assert.True(true)

let maybeast = tryParse example
Assert.True(maybeast.IsSome)