82 lines
2.0 KiB
Elm
82 lines
2.0 KiB
Elm
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 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.backtrackable <|
|
|
Parser.succeed Call
|
|
|= name
|
|
|= Parser.sequence
|
|
{ start = "("
|
|
, separator = ","
|
|
, end = ")"
|
|
, spaces = Parser.spaces
|
|
, item = term
|
|
, trailing = Forbidden
|
|
}
|
|
, 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
|
|
|
|
run : Parser a -> String -> Maybe a
|
|
run prs s =
|
|
case Parser.run prs s of
|
|
Ok a -> Just a
|
|
Err _ -> Nothing
|