Verified Commit b42c904a authored by Camil Staps's avatar Camil Staps 🙂

Basic parsing (no escapes yet)

parent 2a5771fe
......@@ -4,7 +4,7 @@ CLMFLAGS:=\
-I $$CLEAN_HOME/lib/Generics\
-nt
DEPMODS:=Regex Regex/Match Regex/Print
DEPMODS:=Regex Regex/Match Regex/Parse Regex/Print
DEPS:=$(addsuffix .dcl,$(DEPMODS)) $(addsuffix .icl,$(DEPMODS))
EXE:=test
......
......@@ -3,6 +3,7 @@ definition module Regex
from Data.Maybe import :: Maybe (Just, Nothing)
import Regex.Match
import Regex.Parse
import Regex.Print
:: Regex
......
definition module Regex.Parse
from Data.Maybe import :: Maybe
from Regex import :: Regex
compile :: [Char] -> Maybe Regex
parse :: [Regex] [Char] -> Maybe ([Regex], [Char])
implementation module Regex.Parse
import StdBool
from StdFunc import o, flip
import StdList
import StdTuple
import Control.Applicative
import Control.Monad
from Data.Func import $
import Data.Functor
import Data.Maybe
import Data.Tuple
import Regex
compile :: [Char] -> Maybe Regex
compile cs = compile` [] cs
where
compile` :: [Regex] [Char] -> Maybe Regex
compile` [] [] = Just $ Concat []
compile` [r] [] = Just r
compile` rs [] = Just $ Concat $ reverse rs
where
itlt :: [a] -> ([a], a)
itlt [x] = ([], x)
itlt [x:xs] = let (it,lt) = itlt xs in ([x:it], lt)
compile` rs cs = parse rs cs >>= uncurry compile`
parse :: [Regex] [Char] -> Maybe ([Regex], [Char])
parse rs [] = Just (rs, [])
parse rs ['^':cs] = Just ([StartOfString:rs], cs)
parse rs ['$':cs] = Just ([EndOfString:rs], cs)
parse [r:rs] ['+':'?':cs] = Just ([Some False r:rs], cs)
parse [r:rs] ['+':cs] = Just ([Some True r:rs], cs)
parse [r:rs] ['*':'?':cs] = Just ([Many False r:rs], cs)
parse [r:rs] ['*':cs] = Just ([Many True r:rs], cs)
parse [r:rs] ['?':'?':cs] = Just ([Optional False r:rs], cs)
parse [r:rs] ['?':cs] = Just ([Optional True r:rs], cs)
parse [r:rs] ['{':cs]
| isNothing fr = Nothing
| hd cs` == '}'
| length cs` > 1 && cs`!!1 == '?'
= Just ([Repeated False fr` (Just fr`) r:rs], drop 2 cs`)
= Just ([Repeated True fr` (Just fr`) r:rs], tl cs`)
| isNothing to = Nothing
| hd cs` == ',' && hd cs`` == '}'
| length cs`` > 1 && cs``!!1 == '?'
= Just ([Repeated False fr` to` r:rs], drop 2 cs``)
= Just ([Repeated True fr` to` r:rs], tl cs``)
| otherwise = Nothing
where
(fr`, to`) = (fromJust fr, fromJust to)
(fr, cs`) = appFst parseInt $ span isDigit cs
(to, cs``) = appFst toEnd $ span isDigit $ tl cs`
parseInt :: [Char] -> Maybe Int
parseInt [] = Nothing
parseInt cs = if (all isDigit cs) (Just $ toInt $ toString $ cs) Nothing
toEnd :: [Char] -> Maybe (Maybe Int)
toEnd [] = Just Nothing
toEnd cs = Just <$> parseInt cs
parse rs ['[':cs] = case rest of
[']':r] = Just ([CharacterClass chars:rs], r)
_ = Nothing
where (chars, rest) = span ((<>) ']') cs
parse rs ['(':'?':':':cs] = case parse` [] cs of
Nothing = Nothing
(Just ([], cs)) = Just (rs, cs)
(Just ([r], cs)) = Just ([r:rs], cs)
(Just (rs`, cs)) = Just ([Concat $ reverse rs`:rs], cs)
where
parse` :: [Regex] [Char] -> Maybe ([Regex], [Char])
parse` grp [] = Nothing
parse` grp [')':cs] = Just (grp, cs)
parse` grp cs = parse grp cs >>= uncurry parse`
parse rs [c:cs]
= Just ([Literal [c]:rs], cs)
parse _ _ = Nothing
......@@ -4,5 +4,5 @@ import Regex
Start = match rgx string
where
rgx = Concat [Repeated False 1 (Just 2) (CharacterClass ['hel']), CharacterClass ['l']]
(Just rgx) = compile ['[hel]{1,2}?l']
string = ['hello world']
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment