Created
September 13, 2012 19:33
-
-
Save osa1/3716984 to your computer and use it in GitHub Desktop.
left-recursion ;-(
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var :: Parser Var | |
var = buildVar <$> namePart <*> funcalls <*> selectors | |
where namePart :: Parser (Either Name Exp) | |
namePart = (Right <$> between (spChar '(') (spChar ')') exp) | |
<|> (Left <$> name) | |
funcalls :: Parser [(Maybe Name, FunArg)] | |
funcalls = many argPart | |
selectors :: Parser [(Either Exp Name)] | |
selectors = many $ | |
(Left <$> between (spChar '[') (spChar ']') exp) | |
<|> (Right <$> (spChar '.' >> name)) | |
methodName :: Parser Name | |
methodName = spChar ':' >> name | |
argPart :: Parser (Maybe Name, FunArg) | |
argPart = (,) <$> optionMaybe methodName <*> funArg | |
buildVar :: Either Name Exp -> [(Maybe Name, FunArg)] -> [(Either Exp Name)] -> Var | |
buildVar (Left name) ((Just methodName, args):rest) selectors = | |
buildVar' (PEFunCall (MethodCall (PEVar (Name name)) methodName args)) rest selectors | |
buildVar (Left name) ((Nothing, args):rest) selectors = | |
buildVar' (PEFunCall (NormalFunCall (PEVar (Name name)) args)) rest selectors | |
buildVar (Right exp) ((Just methodName, args):rest) selectors = | |
buildVar' (PEFunCall (MethodCall (Paren exp) methodName args)) rest selectors | |
buildVar (Right exp) ((Nothing, args):rest) selectors = | |
buildVar' (PEFunCall (NormalFunCall (Paren exp) args)) rest selectors | |
buildVar (Left name) [] ((Left exp):rest) = | |
buildVar'' (Select (PEVar (Name name)) exp) rest | |
buildVar (Left name) [] ((Right name'):rest) = | |
buildVar'' (SelectName (PEVar (Name name)) name') rest | |
buildVar (Right exp) [] ((Left exp'):rest) = | |
buildVar'' (Select (Paren exp) exp') rest | |
buildVar (Right exp) [] ((Right name):rest) = | |
buildVar'' (SelectName (Paren exp) name) rest | |
buildVar (Left name) [] [] = Name name | |
buildVar (Right _) [] [] = undefined -- this is an error | |
buildVar' :: PrefixExp -> [(Maybe Name, FunArg)] -> [(Either Exp Name)] -> Var | |
buildVar' pe ((Just name, args):rest) selectors = | |
buildVar' (PEFunCall (MethodCall pe name args)) rest selectors | |
buildVar' pe ((Nothing, args):rest) selectors = | |
buildVar' (PEFunCall (NormalFunCall pe args)) rest selectors | |
buildVar' pe [] ((Left exp):rest) = | |
buildVar'' (Select pe exp) rest | |
buildVar' pe [] ((Right name):rest) = | |
buildVar'' (SelectName pe name) rest | |
buildVar' _ [] [] = undefined -- error | |
buildVar'' :: Var -> [(Either Exp Name)] -> Var | |
buildVar'' var ((Left exp):rest) = | |
buildVar'' (Select (PEVar var) exp) rest | |
buildVar'' var ((Right name):rest) = | |
buildVar'' (SelectName (PEVar var) name) rest | |
buildVar'' var [] = var |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment