78 lines
1.8 KiB
Elm
78 lines
1.8 KiB
Elm
module SeqSim.Parser exposing (parse, valid, vars, varsValid, Prog, Source(..))
|
|
import Parser exposing (Parser, Step(..), Trailing(..), run, end, succeed, loop, sequence, (|=), (|.), spaces, symbol, int, map, oneOf, variable, sequence)
|
|
import Char exposing (isAlpha, isAlphaNum)
|
|
import Set exposing (empty)
|
|
import Tuple
|
|
|
|
type alias Prog = List (String, Source)
|
|
type Source = Var String | Const Int
|
|
|
|
parseVar : Parser String
|
|
parseVar = variable
|
|
{ start = isAlpha
|
|
, inner = isAlphaNum
|
|
, reserved = Set.empty
|
|
}
|
|
|
|
parseSource : Parser Source
|
|
parseSource = oneOf
|
|
[ Parser.map Const int
|
|
, Parser.map Var parseVar
|
|
]
|
|
|
|
parseCmd : Parser (String, Source)
|
|
parseCmd = succeed Tuple.pair
|
|
|= parseVar
|
|
|. spaces
|
|
|. symbol "="
|
|
|. spaces
|
|
|= parseSource
|
|
|
|
parseProg : Parser Prog
|
|
parseProg =
|
|
let
|
|
step s =
|
|
oneOf
|
|
[ succeed (\cmd -> Loop (cmd::s))
|
|
|= parseCmd
|
|
|. spaces
|
|
, spaces
|
|
|> Parser.map (\_ -> Done (List.reverse s))
|
|
]
|
|
in
|
|
loop [] step
|
|
|
|
parseVars : Parser (List String)
|
|
parseVars = sequence
|
|
{ start = ""
|
|
, separator = ","
|
|
, end = ""
|
|
, spaces = spaces
|
|
, item = parseVar
|
|
, trailing = Optional
|
|
}
|
|
|
|
vars : String -> Maybe (List String)
|
|
vars s =
|
|
case run (succeed (\x -> x) |. spaces |= parseVars |. spaces |. end) s of
|
|
Ok p -> Just p
|
|
Err _ -> Nothing
|
|
|
|
varsValid : String -> Bool
|
|
varsValid s =
|
|
case vars s of
|
|
Just _ -> True
|
|
Nothing -> False
|
|
|
|
parse : String -> Maybe Prog
|
|
parse s =
|
|
case run (succeed (\x->x) |. spaces |= parseProg |. end) s of
|
|
Ok p -> Just p
|
|
Err _ -> Nothing
|
|
|
|
valid : String -> Bool
|
|
valid s =
|
|
case parse s of
|
|
Just _ -> True
|
|
Nothing -> False
|