From 295c93e38af79c832ba058fca50fd392f9045a17 Mon Sep 17 00:00:00 2001 From: Danila Fedorin Date: Sun, 26 Nov 2023 11:40:15 -0800 Subject: [PATCH] Add a parser for the tiny language Signed-off-by: Danila Fedorin --- elm.json | 3 ++- src/Bergamot/Parser.elm | 59 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/Bergamot/Parser.elm diff --git a/elm.json b/elm.json index ce2a08d..319ec40 100644 --- a/elm.json +++ b/elm.json @@ -8,7 +8,8 @@ "direct": { "elm/browser": "1.0.2", "elm/core": "1.0.5", - "elm/html": "1.0.0" + "elm/html": "1.0.0", + "elm/parser": "1.1.0" }, "indirect": { "elm/json": "1.1.3", diff --git a/src/Bergamot/Parser.elm b/src/Bergamot/Parser.elm new file mode 100644 index 0000000..eeb6619 --- /dev/null +++ b/src/Bergamot/Parser.elm @@ -0,0 +1,59 @@ +module Bergamot.Parser exposing (..) + +import Bergamot.Syntax exposing (Term(..), Metavariable) +import Bergamot.Rules exposing (Rule) + +import Parser exposing (Parser, Trailing(..), (|.), (|=)) +import Set + +intLit : Parser Int +intLit = Parser.int + +name : Parser String +name = Parser.variable + { start = \c -> Char.isAlphaNum c || c == '_' + , inner = \c -> Char.isAlphaNum c || c == '_' + , reserved = Set.empty + } + +variable : Parser String +variable = Parser.variable + { start = \c -> c == '?' + , inner = \c -> Char.isAlphaNum c || c == '_' + , reserved = Set.empty + } + +term : Parser (Term Metavariable) +term = Parser.lazy (\() -> Parser.oneOf + [ Parser.succeed IntLit |= intLit + , Parser.succeed Call + |= name + |= Parser.sequence + { start = "(" + , separator = "," + , end = ")" + , spaces = Parser.spaces + , item = term + , trailing = Forbidden + } + , Parser.succeed Var |= variable + ]) + +rule : Parser Rule +rule = + let + makeRule n c ps = { name = n, conclusion = c, premises = ps } + in + Parser.succeed makeRule + |= name + |. Parser.spaces |. Parser.symbol "@" |. Parser.spaces + |= term + |. Parser.spaces |. Parser.symbol "<-" |. Parser.spaces + |= Parser.sequence + { start = "" + , separator = "," + , end = "" + , spaces = Parser.spaces + , item = term + , trailing = Forbidden + }