view interps/rhotor/Parser.hs @ 9554:23f43464694e

<Zarutian> le/rn Frams\xc3\xb3knarflokkurinn/A, now defunct, political party in Iceland. Like its sister party Sj\xc3\xa1lfst\xc3\xa6\xc3\xb0isflokkurinn it is named by the antonym of what it is. (The name means the Progressive Party but they have nearly always been highly regressive). Think dumb Hill-Billies in ill fitting suits and you get their constiuents.
author HackBot
date Sun, 30 Oct 2016 14:33:24 +0000
parents 859f9b4339e6
children
line wrap: on
line source

module Parser (parse)
where

import Data.List
import Uniqs
import Node

data Token =	Variable String 			|
				NewVariable String 			|
				TFunction 					|
				Fail						|
				TCons						|
				TLT		| TGT				|
				String String				|
				Number Integer  			|
				SubExp [Token]  			|
				NCons Token Token			|
				NFunction Token Token Token	|
				NApplication Token Token	|
				TNil						


parse		:: String -> Node
parse x		= tokenToNode (parseIntern (tokenize x)) [] Root
			
{- Tokenizer -}			

tokenize									:: String -> [Token]
tokenize []									= []
tokenize ( '/' :t)							= (TFunction : tokenize t)
tokenize ( '\\':t)							= (Fail		: tokenize t)
tokenize ( ',' :t)							= (TCons		: tokenize t)
tokenize ( '<' :t)							= (TLT		: tokenize t)
tokenize ( '>' :t)							= (TGT		: tokenize t)
tokenize ( '%' :( '"' :t )) 				= (String text : tokenize q) 
											where (text,q) = (textTokenize t)
tokenize ( '%' :( '\'' :(c:t))) 			= (Number (toInteger (fromEnum c)) : tokenize t) 
tokenize ( '%' :t)							= (Number (read text) : tokenize q)
											where (text,q) = (numberTokenize t)
tokenize ( ':' :t)							= (NewVariable text : tokenize q)	
											where (text,q) = (varTokenize t)
tokenize y@( x  :t)             			
	| (x >= 'a' && x <= 'z') 				= (Variable text : tokenize q)								
	| elem x ". \n\t\r"						= tokenize t
	| (x >= 'A' && x <= 'Z') 				= tokenize t
	where (text,q) = (varTokenize y)
						

textTokenize						:: String -> (String,String)
textTokenize ( '\\' : ( 'n' :t) )	= (( '\n' :text), q)
									where (text,q) = (textTokenize t)
textTokenize ( '\\' : (  x  :t) )	= ((x:text), q)
									where (text,q) = (textTokenize t)
textTokenize ( '"' : t)				= ("",t)
textTokenize ( x   : t)				= ((x:text), q)
									where (text,q) = (textTokenize t)


numberTokenize						:: String -> (String,String)
numberTokenize	[]					= ("",[])
numberTokenize y@( x   : t)		
	| x >= '0' && x <= '9' 			= ((x:text), q)  									
	| otherwise				 		= ("",y)
	where (text,q) = (numberTokenize t)

	
varTokenize							:: String -> (String,String)
varTokenize	[]						= ("",[])
varTokenize y@( x   : t)		
	| x >= 'a' && x <= 'z' 			= ((x:text), q)								
	| otherwise				 		= ("",y)
	where (text,q) = (varTokenize t) 

									
instance Show Token where
	show (Variable x)		= "Variable " ++ (show x)
	show (NewVariable x)	= "NewVariable " ++ (show x)
	show (TFunction)		= "TFunction"
	show (Fail)				= "Fail"
	show (TCons)			= "TCons"
	show (TLT)				= "TLT"
	show (TGT)				= "TGT"
	show (String x)			= "String " ++ (show x)
	show (Number x)			= "Number " ++ (show x)
	show (SubExp x)			= "SubExp " ++ (show x)
	show (NCons x y)		= "NCons (" ++ (show x) ++ ") (" ++ (show y) ++ ")"
	show (NFunction x y z)	= "NFunction (" ++ (show x) ++ ") (" ++ (show y) ++ ") (" ++ (show z) ++ ")"
	show (NApplication x y)	= "NApplication (" ++ (show x) ++ ") (" ++ (show y) ++ ")"
	show (TNil)			= "TNil"

instance Eq Token where
	(==) TFunction TFunction		= True
	(==) Fail Fail					= True
	(==) _ _						= False
	
{- Parser -}

parseIntern		:: [Token] -> Token
parseIntern	x	= stripSubExp (head (parseApplication (parseCons (fst (parseFunctions (fst (parseTT (expandNumbers (expandStrings x)))))))))

onReverse		:: ([a] -> [a]) -> [a] -> [a]
onReverse x y	= (reverse (x (reverse y)))

expandStrings					:: [Token] -> [Token]
expandStrings []				= []
expandStrings ((String x):rest)	= (xtail (concatMap toNums x)) ++ (expandStrings rest)
								where
									toNums x	= [TCons,TLT,Number (toInteger (fromEnum x)),TGT]
									xtail []	= []
									xtail (h:t)	= t
expandStrings (h:rest)			= h:(expandStrings rest)

expandNumbers					:: [Token] -> [Token]
expandNumbers []				= []
expandNumbers ((Number x):rest)	= (toNils x) ++ (expandNumbers rest)
								where
									toNils 0   	= [TNil]
									toNils (n+1)	= TNil:(TCons:(toNils n))
expandNumbers (h:rest)			= h:(expandNumbers rest)

parseTT			:: [Token] -> ([Token],[Token])
parseTT []		= ([],[])
parseTT (TGT:y)	= ([],y)
parseTT (TLT:y)	= ((SubExp frst:snd),thrd)
				where
					(frst,lst) = parseTT y
					(snd,thrd) = parseTT lst
						
parseTT (x:y)	= ((x:frst),lst)
				where (frst,lst) = parseTT y

partitionWhen 			:: (a -> Bool) -> [a] -> Maybe ([a],[a])
partitionWhen f x@(h:t)	= 	if f h then
								Just ([],x)
							else case (partitionWhen f t) of
								Nothing		-> Nothing
								Just (q,r)	-> Just ((h:q),r)
partitionWhen f []		= Nothing

partitionWhen2			:: (a -> Bool) -> [a] -> Maybe ([a],a,[a])
partitionWhen2 f x		= case (partitionWhen f x) of
							Nothing		-> Nothing
							Just (q,h:t)-> Just (q,h,t)



parseFunctions		:: [Token] -> ([Token],[Token])
parseFunctions x	= case (partitionWhen2 (\y -> y == TFunction || y == Fail) x) of
						Nothing					-> ((parseSubFunctions x),[])
						Just (fl,Fail,frst)		-> (fl,frst)
						Just (a,TFunction,c) 	-> let
													(def,rst) = parseFunctions c
													(frst,lrst) = parseFunctions rst
													in ([NFunction (SubExp (fst (parseFunctions a))) (SubExp (fst (parseFunctions def))) (SubExp (fst (parseFunctions frst)))],lrst)
											
parseSubFunctions					:: [Token] -> [Token]
parseSubFunctions []				= []
parseSubFunctions ((SubExp x):t)	= (SubExp (fst (parseFunctions x))):(parseSubFunctions t)
parseSubFunctions (x:t)				= x:(parseSubFunctions t)

parseApplication					:: [Token] -> [Token]
parseApplication x					= foldr iteration [] (reverse x)
										where
											iteration itema (itemb:rest)	= (NApplication itemb (parseSubApplication itema)):rest
											iteration item []				= [parseSubApplication item]
											
parseSubApplication						:: Token -> Token
parseSubApplication (SubExp x)			= SubExp (parseApplication x)
parseSubApplication (NFunction x y z)	= NFunction (parseSubApplication x) (parseSubApplication y) (parseSubApplication z)
parseSubApplication (NCons x y)			= NCons (parseSubApplication x) (parseSubApplication y) 
parseSubApplication	x					= x

parseCons							:: [Token] -> [Token]
parseCons x							= foldr iteration [] x
										where
											iteration itema (TCons:(itemb:rest))	= (NCons (parseSubCons itema) itemb):rest
											iteration item list						= (parseSubCons item):list
											
parseSubCons					:: Token -> Token
parseSubCons (SubExp x)			= SubExp (parseCons x)
parseSubCons (NFunction x y z)	= NFunction (parseSubCons x) (parseSubCons y) (parseSubCons z)
parseSubCons x					= x


stripSubExp						:: Token -> Token
stripSubExp (SubExp [a])		= stripSubExp a
stripSubExp (SubExp [])			= TNil
stripSubExp (NCons a b)			= NCons (stripSubExp a) (stripSubExp b)
stripSubExp (NFunction a b c)	= NFunction (stripSubExp a) (stripSubExp b) (stripSubExp c)
stripSubExp (NApplication a b)	= NApplication (stripSubExp a) (stripSubExp b)
stripSubExp a					= a

tokenToNode								:: Token -> [(String,Uniqs)] -> Uniqs -> Node
tokenToNode TNil _ _					= Nil
tokenToNode (NCons a b) tab cn			= Cons (tokenToNode a tab (A cn)) (tokenToNode b tab (B cn))
tokenToNode (NApplication a b) tab cn	= Application (tokenToNode a tab (A cn)) (tokenToNode b tab (B cn))
tokenToNode (NFunction a b c) tab cn	= let (ac,ntab) = functionPtrnToNode a tab (C cn)
											in (Function ac (tokenToNode b ntab (A cn)) (tokenToNode c tab (B cn)))
tokenToNode (Variable n) tab _			= let Just a = (lookup n tab)
											in (Symbol a)

functionPtrnToNode								:: Token -> [(String,Uniqs)] -> Uniqs -> (Node,[(String,Uniqs)])
functionPtrnToNode TNil tab	_					= (Nil,tab)
functionPtrnToNode (NCons a b) tab cn 			= 	let
														(newa,tab2) = functionPtrnToNode a tab (A cn)
														(newb,tab3) = functionPtrnToNode b tab2 (B cn)
													in ((Cons newa newb),tab3)
functionPtrnToNode (NApplication a b) tab cn	= 	let
										   	 			(newa,tab2) = functionPtrnToNode a tab (A cn)
										   	 			(newb,tab3) = functionPtrnToNode b tab2 (B cn)
										   	 		in ((Application newa newb),tab3)
functionPtrnToNode a@(NFunction _ _ _) tab cn	= ((tokenToNode a tab cn),tab)

functionPtrnToNode (Variable n)	tab cn			= case (lookup n tab) of
													Just a -> (Symbol a,tab)
													Nothing -> (Symbol cn,((n,cn):tab))
																
functionPtrnToNode (NewVariable n) tab cn  		= (Symbol cn,((n,cn):(deleteBy filter (n,cn) tab)))
												where filter (a,_) (b,_) = a == b