X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Ftests%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Ftests%2Fscl%2FParsing.scl;fp=bundles%2Forg.simantics.scl.compiler%2Ftests%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Ftests%2Fscl%2FParsing.scl;h=0ca342a34b4aa294fb8be2899a04b4622e36baf5;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Parsing.scl b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Parsing.scl new file mode 100644 index 000000000..0ca342a34 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/tests/org/simantics/scl/compiler/tests/scl/Parsing.scl @@ -0,0 +1,62 @@ +import "Prelude" + +""" +Parser is a function from a string and a position in the +string to a possible semantics of a substring and the +end of the substring. +""" +data Parser a = Parser (String -> Integer -> Maybe (a, Integer)) + +runParser :: Parser a -> String -> Integer -> Maybe (a, Integer) +runParser (Parser f) = f + +instance Functor Parser where + fmap f (Parser p) = Parser (\input pos -> match p input pos with + Nothing -> Nothing + Just (a, newPos) -> Just (f a, newPos) + ) + +instance Monad Parser where + return x = Parser (\_ pos -> Just (x, pos)) + (pa >>= f) = Parser (\input pos -> match runParser pa input pos with + Nothing -> Nothing + Just (a, newPos) -> runParser (f a) input newPos + ) + +(|||) :: Parser a -> Parser a -> Parser a +Parser a ||| Parser b = Parser (\input pos -> match a input pos with + Nothing -> b input pos + Just x -> Just x +) + +keyword :: String -> Parser () +keyword word = Parser (\input pos -> + if regionMatches word 0 input pos (length word) + then Just ((), pos + (length word)) + else Nothing +) + +data List a = Nil | Cons a (List a) + +listSepL :: Parser () -> Parser a -> Parser (List a) +listSepL sep el = mdo + head <- el + tail <- (sep >> listSepL sep el) ||| return Nil + return (Cons head tail) + +fromList :: List a -> [a] +fromList = unfoldr gen + where + gen Nil = Nothing + gen (Cons h t) = Just (h, t) + +listSep :: Parser () -> Parser a -> Parser [a] +listSep sep el = fmap fromList (listSepL sep el) + +aOrB = (keyword "a" >> return "a") ||| (keyword "b" >> return "b") + +myParser = listSep (keyword ",") aOrB + +main = show (runParser myParser "a,b,b,a" 0) +-- +Just (["a", "b", "b", "a"], 7) \ No newline at end of file