bergamot-elm/src/Bergamot/Parser.elm

84 lines
2.0 KiB
Elm
Raw Normal View History

module Bergamot.Parser exposing (..)
import Bergamot.Syntax exposing (Term(..), Metavariable(..))
import Bergamot.Rules exposing (Rule, RuleEnv)
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 Metavariable
variable =
Parser.succeed MkMetavariable
|= 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
2023-11-26 11:58:20 -08:00
, Parser.backtrackable <|
Parser.succeed Call
|= name
|= Parser.sequence
{ start = "("
, separator = ","
, end = ")"
, spaces = Parser.spaces
, item = term
, trailing = Forbidden
}
2023-11-26 11:58:20 -08:00
, Parser.succeed (\n -> Call n [])
|= name
, 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
}
program : Parser RuleEnv
program =
Parser.succeed (\rs -> { rules = rs })
|= Parser.sequence
{ start = ""
, separator = ";"
, end = ""
, spaces = Parser.spaces
, item = rule
, trailing = Mandatory
}
|. Parser.end
2023-11-26 11:58:20 -08:00
run : Parser a -> String -> Maybe a
run prs s =
case Parser.run prs s of
Ok a -> Just a
Err _ -> Nothing