bergamot-elm/src/Bergamot/Parser.elm

73 lines
1.8 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 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
}
program : Parser RuleEnv
program =
Parser.succeed (\rs -> { rules = rs })
|= Parser.sequence
{ start = ""
, separator = ";"
, end = ""
, spaces = Parser.spaces
, item = rule
, trailing = Mandatory
}
|. Parser.end