+++ /dev/null
-implementation module GenParse\r
-\r
-import StdGeneric, StdEnv, StdMaybe\r
-\r
-//---------------------------------------------------------------------------\r
-\r
-\r
-:: StringInput = { si_str :: !String, si_pos :: !Int} \r
-\r
-mkStringInput :: String -> StringInput \r
-mkStringInput str = {si_str = str, si_pos = 0}\r
-\r
-instance ParseInput StringInput where\r
- parseInput s=:{si_pos, si_str}\r
- #! size_str = size si_str\r
- | size_str == si_pos \r
- = (Nothing, {s & si_str = si_str})\r
- | otherwise\r
- #! ch = si_str.[si_pos]\r
- = (Just ch, {s & si_str = si_str, si_pos = inc si_pos})\r
-\r
-instance ParseInput File where \r
- parseInput file \r
- # (ok, c, file) = sfreadc file\r
- | ok\r
- = (Just c, file)\r
- = (Nothing, file)\r
- \r
-//---------------------------------------------------------------------------\r
-\r
-// lex tokens\r
-:: Token \r
- = TokenInt Int\r
- | TokenChar Char\r
- | TokenReal Real \r
- | TokenBool Bool\r
- | TokenString String\r
- | TokenIdent String\r
- | TokenOpenPar\r
- | TokenClosePar\r
- | TokenOpenCurly\r
- | TokenCloseCurly\r
- | TokenOpenList\r
- | TokenCloseList\r
- | TokenComma\r
- | TokenEnd\r
- | TokenError String\r
-\r
-instance toString Token where\r
- toString (TokenInt x) = toString x\r
- toString (TokenChar x) = toString x\r
- toString (TokenReal x) = toString x\r
- toString (TokenBool x) = toString x\r
- toString (TokenString x) = x\r
- toString (TokenIdent x) = x\r
- toString TokenOpenPar = "("\r
- toString TokenClosePar = ")"\r
- toString TokenOpenCurly = "{"\r
- toString TokenCloseCurly = "}"\r
- toString TokenOpenList = "["\r
- toString TokenCloseList = "]" \r
- toString TokenComma = ","\r
- toString TokenEnd = "<end>"\r
- toString (TokenError err) = "<error: " +++ err +++ ">"\r
-\r
-// preparsed expressions\r
-:: Expr \r
- = ExprInt Int\r
- | ExprChar Char\r
- | ExprReal Real \r
- | ExprBool Bool\r
- | ExprString String\r
- | ExprIdent String\r
- | ExprApp {Expr} \r
- | ExprTuple {Expr}\r
- | ExprField String Expr\r
- | ExprRecord (Maybe String) {Expr}\r
- | ExprList [Expr]\r
- | ExprArray [Expr]\r
- | ExprEnd Token\r
- | ExprError String\r
-\r
- // aux\r
- | ExprUnit\r
- | ExprAppInInfix {Expr} GenConsAssoc Int GenConsAssoc\r
- | ExprPair Expr Expr\r
-\r
-\r
-instance toString Expr where\r
- toString (ExprInt x) = toString x\r
- toString (ExprChar x) = toString x\r
- toString (ExprBool x) = toString x\r
- toString (ExprReal x) = toString x\r
- toString (ExprString x) = x\r
- toString (ExprIdent x) = x\r
- toString (ExprApp xs) = "(" +++ tostr [x\\x<-:xs] +++ ")"\r
- where\r
- tostr [] = ""\r
- tostr [x] = toString x\r
- tostr [x:xs] = toString x +++ " " +++ tostr xs\r
- toString (ExprTuple xs) = "(" +++ tostr [x\\x<-:xs] +++ ")"\r
- where\r
- tostr [] = ""\r
- tostr [x] = toString x\r
- tostr [x:xs] = toString x +++ ", " +++ tostr xs\r
- toString (ExprRecord name xs) = "{" +++ tostr [x\\x<-:xs] +++ "}"\r
- where\r
- tostr [] = ""\r
- tostr [x] = toString x\r
- tostr [x:xs] = toString x +++ ", " +++ tostr xs\r
- toString (ExprField name expr) = name +++ "=" +++ toString expr\r
-\r
- \r
-:: ParseState s =\r
- { ps_input :: !s // lex input\r
- , ps_char :: !Maybe Char // unget char\r
- , ps_tokens :: ![Token] // unget tokens\r
- }\r
-\r
-lexGetChar ps=:{ps_char=Nothing, ps_input}\r
- # (mc, ps_input) = parseInput ps_input\r
- = (mc, {ps & ps_input = ps_input})\r
-lexGetChar ps=:{ps_char} = (ps_char, {ps & ps_char = Nothing})\r
-\r
-lexUngetChar c ps=:{ps_char=Nothing} = {ps & ps_char = Just c}\r
-lexUngetChar c ps = abort "cannot unget\n" \r
-\r
-isSpecialChar :: !Char -> Bool\r
-isSpecialChar '~' = True\r
-isSpecialChar '@' = True\r
-isSpecialChar '#' = True\r
-isSpecialChar '$' = True\r
-isSpecialChar '%' = True\r
-isSpecialChar '^' = True\r
-isSpecialChar '?' = True\r
-isSpecialChar '!' = True\r
-isSpecialChar '+' = True\r
-isSpecialChar '-' = True\r
-isSpecialChar '*' = True\r
-isSpecialChar '<' = True\r
-isSpecialChar '>' = True\r
-isSpecialChar '\\' = True\r
-isSpecialChar '/' = True\r
-isSpecialChar '|' = True\r
-isSpecialChar '&' = True\r
-isSpecialChar '=' = True\r
-isSpecialChar ':' = True\r
-isSpecialChar '.' = True\r
-isSpecialChar c = False\r
-\r
-//---------------------------------------------------------------------------------- \r
-// lex input\r
-\r
-lexUngetToken token ps=:{ps_tokens} = {ps & ps_tokens = [token:ps_tokens]}\r
-\r
-lexGetToken ps=:{ps_tokens=[token:tokens]} = (token, {ps & ps_tokens = tokens})\r
-lexGetToken ps=:{ps_tokens=[]}\r
- = lex ps\r
-where\r
- lex s \r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing -> (TokenEnd, s)\r
- Just '\0' -> (TokenEnd, s)\r
- Just '(' -> (TokenOpenPar, s)\r
- Just ')' -> (TokenClosePar, s)\r
- Just '{' -> (TokenOpenCurly, s)\r
- Just '}' -> (TokenCloseCurly, s)\r
- Just '[' -> (TokenOpenList, s)\r
- Just ']' -> (TokenCloseList, s)\r
- Just ',' -> (TokenComma, s)\r
- Just '\'' -> lex_char 0 [] s\r
- Just '"' -> lex_string 0 [] s\r
- Just '_' -> lex_ident 1 ['_'] s\r
- Just '`' -> lex_ident 1 ['`'] s\r
- Just '+'\r
- # (mc, s) = lexGetChar s\r
- -> case mc of\r
- Nothing -> (TokenIdent "+", s)\r
- Just c\r
- | isDigit c\r
- -> lex_number +1 (lexUngetChar c s)\r
- | otherwise\r
- -> lex_ident 1 ['+'] (lexUngetChar c s)\r
- Just '-'\r
- # (mc, s) = lexGetChar s\r
- -> case mc of\r
- Nothing -> (TokenIdent "-", s)\r
- Just c\r
- | isDigit c\r
- -> lex_number -1 (lexUngetChar c s)\r
- | otherwise\r
- -> lex_funny_ident 1 ['-'] (lexUngetChar c s) // PK\r
- // -> lex_ident 1 ['-'] (lexUngetChar c s)\r
- Just c\r
- | isSpace c\r
- -> lex s \r
- | isDigit c\r
- -> lex_number +1 (lexUngetChar c s)\r
- | isAlpha c\r
- -> lex_ident 1 [c] s\r
- | isSpecialChar c\r
- -> lex_funny_ident 1 [c] s\r
- | otherwise\r
- -> (TokenError ("Unknown character " +++ toString c), s)\r
-\r
- lex_digits s \r
- = lex_digits_acc 0 [] s \r
- lex_digits_acc num acc s\r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing \r
- -> (num, acc, s)\r
- Just c\r
- | isDigit c\r
- -> lex_digits_acc (inc num) [digitToInt c:acc] s\r
- | otherwise \r
- -> (num, acc, lexUngetChar c s) \r
-\r
- digits_to_int :: [Int] -> Int\r
- digits_to_int [] = 0\r
- digits_to_int [digit:digits] = digit + 10 * digits_to_int digits \r
-\r
- digits_to_real :: [Int] -> Real \r
- digits_to_real [] = 0.0\r
- digits_to_real [digit:digits] = toReal digit + 10.0 * digits_to_real digits\r
-\r
- lex_number sign s\r
- #! (num_digits, digits, s) = lex_digits s\r
- #! (mc, s) = lexGetChar s\r
- = case mc of \r
- Nothing -> (TokenInt (sign * digits_to_int digits), s)\r
- Just '.'\r
- -> lex_real_with_fraction (toReal sign) (digits_to_real digits) s\r
- Just 'E'\r
- #! real = toReal sign * digits_to_real digits \r
- -> lex_real_with_exp real s\r
- Just 'e'\r
- #! real = toReal sign * digits_to_real digits \r
- -> lex_real_with_exp real s\r
- Just c \r
- -> (TokenInt (sign * digits_to_int digits), lexUngetChar c s) \r
-\r
- lex_real_with_fraction sign real s\r
- #! (num_digits, digits, s) = lex_digits s\r
- #! fraction = digits_to_real digits / 10.0^ toReal num_digits \r
- #! real = sign * (real + fraction) \r
- #! (mc, s) = lexGetChar s\r
- = case mc of \r
- Nothing -> (TokenReal real, s)\r
- Just 'E'\r
- -> lex_real_with_exp real s\r
- Just 'e'\r
- -> lex_real_with_exp real s\r
- Just c \r
- -> (TokenReal real, lexUngetChar c s) \r
-\r
- lex_real_with_exp real s\r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing -> (TokenReal real, s)\r
- Just '+' \r
- #! (num_digits, digits, s) = lex_digits s\r
- -> (TokenReal (real * 10.0 ^ digits_to_real digits), s) \r
- Just '-' \r
- #! (num_digits, digits, s) = lex_digits s\r
- -> (TokenReal (real * 10.0 ^ (-1.0 * digits_to_real digits)), s) \r
- Just c \r
- | isDigit c\r
- #! (num_digits, digits, s) = lex_digits (lexUngetChar c s)\r
- -> (TokenReal (real * 10.0 ^ digits_to_real digits), s) \r
- | otherwise \r
- -> (TokenError "error in real constant", s)\r
- \r
- lex_ident num_chars acc_chars s\r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing -> (mktoken num_chars acc_chars, s)\r
- Just '_' -> lex_ident (inc num_chars) ['_':acc_chars] s\r
- Just '`' -> lex_ident (inc num_chars) ['`':acc_chars] s\r
- Just c \r
- | isAlphanum c\r
- -> lex_ident (inc num_chars) [c:acc_chars] s\r
- | otherwise \r
- -> (mktoken num_chars acc_chars, lexUngetChar c s) \r
- where\r
- mktoken num_chars acc_chars\r
- = case mk_str num_chars acc_chars of\r
- "True" -> TokenBool True\r
- "False" -> TokenBool False\r
- str -> TokenIdent str \r
-\r
- lex_funny_ident num_chars acc_chars s\r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing -> (TokenIdent (mk_str num_chars acc_chars), s)\r
- Just c\r
- | isSpecialChar c\r
- -> lex_funny_ident (inc num_chars) [c:acc_chars] s\r
- | otherwise \r
- -> (TokenIdent (mk_str num_chars acc_chars), lexUngetChar c s) \r
-\r
- lex_string num_chars acc_chars s\r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing -> (TokenError "error in string constant", s)\r
- Just '"' -> (TokenString (mk_str num_chars acc_chars), s)\r
- Just '\\' \r
- #! (mc, s) = lex_special_char s\r
- -> case mc of\r
- Nothing -> (TokenError "error in string constant", s)\r
- Just c -> lex_string (inc num_chars) [c:acc_chars] s\r
- Just c -> lex_string (inc num_chars) [c:acc_chars] s\r
-\r
-\r
- lex_char num_chars acc_chars s\r
- # (mc, s) = lexGetChar s\r
- = case mc of\r
- Nothing -> (TokenError "error in char constant", s)\r
- Just '\'' \r
- | num_chars == 1\r
- -> (TokenChar (hd acc_chars), s)\r
- | num_chars == 0\r
- -> (TokenError "char constant contains no characters ", s)\r
- | otherwise \r
- -> (TokenError "char constant contains more than one character", s)\r
- Just '\\' \r
- #! (mc, s) = lex_special_char s\r
- -> case mc of\r
- Nothing -> (TokenError "error in char constant", s)\r
- Just c -> lex_char (inc num_chars) [c:acc_chars] s\r
- Just c -> lex_char (inc num_chars) [c:acc_chars] s\r
-\r
- lex_special_char s \r
- #! (mc, s) = lexGetChar s\r
- = case mc of\r
- Just 'n' -> (Just '\n', s)\r
- Just 'r' -> (Just '\r', s)\r
- Just 'f' -> (Just '\f', s)\r
- Just 'b' -> (Just '\b', s)\r
- Just 't' -> (Just '\t', s)\r
- Just '\\' -> (Just '\\', s)\r
- Just '\'' -> (Just '\'', s)\r
- Just '\"' -> (Just '\"', s)\r
- Just '\0' -> (Just '\0', s)\r
- //Just '\x' -> abort "lex: hex char not implemented\n"\r
- //Just '\0' -> abort "lex: oct char not implemented\n"\r
- _ -> (mc, s)\r
-\r
- mk_str num_chars acc_chars\r
- # str = createArray num_chars ' '\r
- = fill (dec num_chars) acc_chars str\r
- where \r
- fill i [] str = str\r
- fill i [x:xs] str = fill (dec i) xs {str & [i] = x}\r
- \r
-\r
-//---------------------------------------------------------------------------------- \r
-// preparse input\r
-\r
-\r
-:: ParseEnv = PETop | PETuple | PEPar | PERecord | PEList\r
-\r
-preParse :: (ParseState s) -> (Expr, ParseState s) | ParseInput s\r
-preParse s \r
- = parse_expr PETop s\r
-where\r
- parse_expr env s\r
- = parse_app env [] s\r
- \r
- parse_app env exprs s\r
- #! (token, s) = lexGetToken s\r
- = parse token env exprs s\r
- where\r
- parse TokenComma PETuple exprs s = (mkexpr exprs, lexUngetToken TokenComma s)\r
- parse TokenComma PERecord exprs s = (mkexpr exprs, lexUngetToken TokenComma s)\r
- parse TokenComma PEList exprs s = (mkexpr exprs, lexUngetToken TokenComma s)\r
- parse TokenComma PETop exprs s = (ExprError "end of input expected instead of ,", s)\r
- parse TokenComma PEPar exprs s = (ExprError ") expected instead of ,", s)\r
- parse TokenComma env exprs s = abort "unknown env\n"\r
-\r
- parse TokenClosePar PETuple exprs s = (mkexpr exprs, lexUngetToken TokenClosePar s)\r
- parse TokenClosePar PERecord exprs s = (ExprError "} expected instead of )", s)\r
- parse TokenClosePar PEList exprs s = (ExprError "] expected instead of )", s)\r
- parse TokenClosePar PETop exprs s = (ExprError "end of input expected instead of )", s)\r
- parse TokenClosePar PEPar exprs s = (mkexpr exprs, lexUngetToken TokenClosePar s)\r
- parse TokenClosePar env exprs s = abort "unknown env\n"\r
-\r
- parse TokenCloseCurly PETuple exprs s = (ExprError ") expected instead of }", s)\r
- parse TokenCloseCurly PEList exprs s = (ExprError "] expected instead of }", s)\r
- parse TokenCloseCurly PERecord exprs s = (mkexpr exprs, lexUngetToken TokenCloseCurly s)\r
- parse TokenCloseCurly PETop exprs s = (ExprError "end of input expected instead of )", s)\r
- parse TokenCloseCurly PEPar exprs s = (mkexpr exprs, lexUngetToken TokenCloseCurly s)\r
- parse TokenCloseCurly env exprs s = abort "unknown env\n"\r
-\r
- parse TokenCloseList PETuple exprs s = (ExprError ") expected instead of ]", s)\r
- parse TokenCloseList PERecord exprs s = (ExprError "} expected instead of ]", s)\r
- parse TokenCloseList PEList exprs s = (mkexpr exprs, lexUngetToken TokenCloseList s)\r
- parse TokenCloseList PETop exprs s = (ExprError "end of input expected instead of )", s)\r
- parse TokenCloseList PEPar exprs s = (mkexpr exprs, lexUngetToken TokenCloseList s)\r
- parse TokenCloseList env exprs s = abort "unknown env\n"\r
-\r
- parse TokenEnd PETuple exprs s = (ExprError ") or, expected instead of end of input", s)\r
- parse TokenEnd PERecord exprs s = (ExprError "} or, expected instead of end of input", s)\r
- parse TokenEnd PEList exprs s = (ExprError "] or, expected instead of end of input", s)\r
- parse TokenEnd PETop exprs s = (mkexpr exprs, lexUngetToken TokenEnd s)\r
- parse TokenEnd PEPar exprs s = (ExprError ") expected instead of end of input",s)\r
- parse TokenEnd env exprs s = abort "unknown env\n"\r
- \r
- parse (TokenInt x) env exprs s = parse_app env [ExprInt x:exprs] s\r
- parse (TokenBool x) env exprs s = parse_app env [ExprBool x:exprs] s\r
- parse (TokenReal x) env exprs s = parse_app env [ExprReal x:exprs] s\r
- parse (TokenChar x) env exprs s = parse_app env [ExprChar x:exprs] s\r
- parse (TokenString x) env exprs s = parse_app env [ExprString x:exprs] s\r
- parse (TokenIdent x) env exprs s = parse_app env [ExprIdent x:exprs] s\r
- parse TokenOpenPar env exprs s \r
- # (expr, s) = parse_par_expr s\r
- = case expr of\r
- ExprError err -> (ExprError err, s)\r
- _ -> parse_app env [expr:exprs] s\r
- parse TokenOpenCurly env exprs s\r
- # (expr, s) = parse_record_or_array s\r
- = case expr of\r
- ExprError err -> (ExprError err, s)\r
- _ -> parse_app env [expr:exprs] s\r
- parse TokenOpenList env exprs s \r
- # (expr, s) = parse_list s\r
- = case expr of\r
- ExprError err -> (ExprError err, s)\r
- _ -> parse_app env [expr:exprs] s\r
- parse (TokenError err) env exprs s \r
- = (ExprError ("lex error in parse_app: " +++ err), s) \r
- \r
- parse token env exprs s \r
- = abort ("parse app - unknown token " +++ toString token)\r
- \r
- \r
- mkexpr [] = ExprError "expression expected"\r
- mkexpr [expr] = expr\r
- mkexpr exprs = ExprApp {e\\e <- reverse exprs}\r
-\r
- parse_par_expr s\r
- #! (expr, s) = parse_expr PETuple s\r
- = case expr of\r
- ExprError err -> (ExprError err, s)\r
- _\r
- #! (token, s) = lexGetToken s\r
- -> case token of\r
- TokenClosePar -> (expr, s)\r
- TokenComma -> parse_tuple [expr] (lexUngetToken token s)\r
- _ -> (ExprError (", or ) expected, found " +++ toString token), s)\r
- \r
- parse_tuple exprs s \r
- #! (token, s) = lexGetToken s\r
- = case token of\r
- TokenComma \r
- #! (expr, s) = parse_expr PETuple s\r
- -> case expr of\r
- ExprError err -> (ExprError err, s)\r
- _ -> parse_tuple [expr:exprs] s\r
- TokenClosePar \r
- -> (ExprTuple {e\\e<-reverse exprs}, s)\r
- _ \r
- -> (ExprError "parse tuple: , or ) expected", s) \r
-\r
- parse_list s\r
- #! (token, s) = lexGetToken s\r
- = case token of\r
- TokenCloseList \r
- -> (ExprList [], s)\r
- _ \r
- #! (expr, s) = parse_expr PEList (lexUngetToken token s)\r
- -> case expr of\r
- ExprError err -> (ExprError (err +++ " ; parse list"), s)\r
- _ -> parse_rest [expr] s\r
- where\r
- parse_rest exprs s \r
- #! (token, s) = lexGetToken s\r
- = case token of\r
- TokenComma \r
- #! (expr, s) = parse_expr PEList s\r
- -> case expr of\r
- ExprError err -> (ExprError err, s)\r
- _ -> parse_rest [expr:exprs] s\r
- TokenCloseList \r
- -> (ExprList (reverse exprs), s)\r
- _ \r
- -> (ExprError "parse list: , or ] expected", s) \r
-\r
- \r
- parse_record_or_array s \r
- #! (token, s) = lexGetToken s\r
- = case token of\r
- TokenCloseCurly \r
- -> (ExprArray [], s)\r
- TokenIdent name\r
- #! (token, s) = lexGetToken s\r
- -> case token of\r
- TokenIdent "="\r
- #! (expr, s) = parse_expr PERecord s\r
- -> parse_record Nothing [ExprField name expr] s\r
- TokenIdent "|"\r
- -> parse_record (Just ("_" +++ name)) [] (lexUngetToken TokenComma s)\r
- _\r
- #! (expr, s) = parse_expr PERecord \r
- (lexUngetToken (TokenIdent name) (lexUngetToken token s))\r
- -> parse_array [expr] s\r
- _ \r
- #! (expr, s) = parse_expr PERecord (lexUngetToken token s)\r
- -> parse_array [expr] s\r
- where\r
- parse_record rec_name fields s\r
- #! (token, s) = lexGetToken s\r
- = case token of\r
- TokenCloseCurly \r
- -> (ExprRecord rec_name {e\\e<- reverse fields}, s)\r
- TokenComma\r
- #! (token, s) = lexGetToken s\r
- -> case token of\r
- TokenIdent field_name\r
- #! (token, s) = lexGetToken s\r
- -> case token of\r
- TokenIdent "=" \r
- #! (expr, s) = parse_expr PERecord s\r
- -> parse_record rec_name [ExprField field_name expr:fields] s\r
- _ -> (ExprError ("parse record failed on token " +++ toString token), s) \r
-\r
- parse_array exprs s\r
- #! (token, s) = lexGetToken s\r
- = case token of\r
- TokenCloseCurly \r
- -> (ExprArray (reverse exprs), s)\r
- TokenComma\r
- #! (expr, s) = parse_expr PERecord s\r
- -> parse_array [expr:exprs] s\r
- _ -> (ExprError ("parse array failed on token " +++ toString token), s) \r
-\r
-\r
-//---------------------------------------------------------------------------------- \r
-\r
-generic gParse a :: Expr -> Maybe a\r
-\r
-gParse{|Int|} (ExprInt x) = Just x \r
-gParse{|Int|} _ = Nothing\r
-\r
-gParse{|Char|} (ExprChar x) = Just x \r
-gParse{|Char|} _ = Nothing\r
-\r
-gParse{|Bool|} (ExprBool x) = Just x \r
-gParse{|Bool|} _ = Nothing\r
-\r
-gParse{|Real|} (ExprReal x) = Just x \r
-gParse{|Real|} _ = Nothing\r
-\r
-gParse{|String|} (ExprString x) = Just x\r
-gParse{|String|} _ = Nothing \r
-\r
-gParse{|UNIT|} ExprUnit = Just UNIT\r
-gParse{|UNIT|} _ = Nothing \r
-\r
-gParse{|PAIR|} fx fy (ExprPair ex ey) \r
- = case fx ex of\r
- Just x -> case fy ey of\r
- Just y -> Just (PAIR x y)\r
- Nothing -> Nothing\r
- Nothing -> Nothing\r
-gParse{|PAIR|} fx fy _ = Nothing\r
-\r
-gParse{|EITHER|} fl fr expr \r
- = case fl expr of\r
- Nothing -> case fr expr of\r
- Nothing -> Nothing\r
- Just x -> Just (RIGHT x)\r
- Just x -> Just (LEFT x) \r
- \r
-gParse{|CONS of d|} parse_arg expr\r
- | d.gcd_arity == 0 \r
- = parse_nullary expr\r
- | isEmpty d.gcd_fields\r
- | is_tuple d.gcd_name\r
- = parse_tuple expr \r
- | otherwise\r
- = case d.gcd_prio of\r
- GenConsNoPrio \r
- -> parse_nonfix expr\r
- GenConsPrio assoc prio \r
- -> parse_infix assoc prio expr \r
- | otherwise\r
- = parse_record expr \r
-where\r
- mkprod [] = abort "mkprod\n"\r
- mkprod [expr] = expr\r
- mkprod exprs \r
- # (xs, ys) = splitAt (length exprs / 2) exprs\r
- = ExprPair (mkprod xs) (mkprod ys) \r
- \r
- parse_nullary (ExprIdent name)\r
- | name == d.gcd_name\r
- = mapMaybe CONS (parse_arg ExprUnit)\r
- parse_nullary _\r
- = Nothing\r
-\r
- parse_nonfix (ExprApp exprs)\r
- = parse_nonfix1 exprs\r
- parse_nonfix (ExprAppInInfix exprs _ _ _)\r
- = parse_nonfix1 exprs\r
- parse_nonfix _ \r
- = Nothing\r
-\r
- parse_nonfix1 exprs\r
- #! size_exprs = size exprs\r
- | size_exprs == d.gcd_arity + 1 && is_ident d.gcd_name exprs.[0]\r
- #! arg_exprs = [exprs.[i] \\ i <- [1 .. size_exprs - 1]]\r
- = mapMaybe CONS (parse_arg (mkprod arg_exprs))\r
- | otherwise\r
- = Nothing\r
- \r
- is_ident wanted_name (ExprIdent name) = name == wanted_name\r
- is_ident _ _ = False \r
-\r
- parse_tuple (ExprTuple exprs) \r
- = mapMaybe CONS (parse_arg (mkprod [e\\e<-:exprs]))\r
- parse_tuple expr = Nothing\r
- \r
- parse_record (ExprRecord rec_name exprs) \r
- | check_name rec_name d.gcd_name\r
- = mapMaybe CONS (parse_arg (mkprod [e\\e<-:exprs]))\r
- = Nothing\r
- where\r
- check_name Nothing cons_name = True\r
- check_name (Just rec_name) cons_name = rec_name == cons_name\r
- parse_record expr = Nothing\r
-\r
- parse_infix this_assoc this_prio (ExprApp exprs)\r
- = parse_infix1 this_assoc this_prio exprs\r
- parse_infix this_assoc this_prio (ExprAppInInfix exprs outer_assoc outer_prio branch)\r
- | this_prio > outer_prio\r
- = parse_infix1 this_assoc this_prio exprs\r
- | this_prio < outer_prio\r
- = Nothing\r
- | otherwise\r
- = case (this_assoc, outer_assoc, branch) of\r
- (GenConsAssocLeft, GenConsAssocLeft, GenConsAssocLeft)\r
- -> parse_infix1 this_assoc this_prio exprs\r
- (GenConsAssocRight, GenConsAssocRight, GenConsAssocRight)\r
- -> parse_infix1 this_assoc this_prio exprs\r
- _ -> Nothing\r
- parse_infix this_assoc this_prio expr\r
- = Nothing\r
- \r
- parse_infix1 this_assoc this_prio exprs\r
- #! size_exprs = size exprs\r
- | size_exprs < 3 = Nothing\r
- = case (case this_assoc of GenConsAssocLeft -> find_last; _ -> find_first) exprs of\r
- Nothing -> Nothing\r
- Just op_index\r
- #! left_arg = mkarg GenConsAssocLeft {exprs.[i] \\ i <- [0 .. op_index - 1]}\r
- #! right_arg = mkarg GenConsAssocRight {exprs.[i] \\ i <- [op_index + 1 .. size_exprs - 1]}\r
- -> mapMaybe CONS (parse_arg (ExprPair left_arg right_arg))\r
- where\r
- mkarg branch exprs\r
- = case size exprs of\r
- 0 -> abort "mkarg\n"\r
- 1 -> exprs.[0]\r
- _ -> ExprAppInInfix exprs this_assoc this_prio branch\r
- \r
- find_last exprs \r
- = find (size exprs - 2) exprs\r
- where\r
- find i exprs\r
- | i < 1\r
- = Nothing\r
- | otherwise \r
- = case exprs.[i] of\r
- ExprIdent s | s == d.gcd_name -> Just i \r
- _ -> find (dec i) exprs \r
- find_first exprs\r
- = find 1 exprs\r
- where\r
- find i exprs\r
- | i >= size exprs - 1\r
- = Nothing\r
- | otherwise \r
- = case exprs.[i] of\r
- ExprIdent s | s == d.gcd_name -> Just i \r
- _ -> find (inc i) exprs \r
-\r
- is_tuple name \r
- #! size_name = size name\r
- = (size_name == 7 || size_name == 8)\r
- && name.[0] == '_'\r
- && name.[1] == 'T'\r
- && name.[2] == 'u'\r
- && name.[3] == 'p'\r
- && name.[4] == 'l'\r
- && name.[5] == 'e'\r
- && isDigit name.[6]\r
- && (size_name == 7 || isDigit name.[7])\r
-\r
-gParse{|FIELD of d|} parse_arg (ExprField name value) \r
- | d.gfd_name == name\r
- = mapMaybe FIELD (parse_arg value)\r
- = Nothing\r
-gParse{|OBJECT|} parse_arg expr\r
- = mapMaybe OBJECT (parse_arg expr)\r
-\r
-gParse{|[]|} parse_arg (ExprList exprs) \r
- = maybeAll (map parse_arg exprs)\r
-gParse{|[]|} parse_arg _ = Nothing\r
-\r
-gParse{|{}|} parse_arg (ExprArray exprs)\r
- = mapMaybe (\xs -> {x\\x<-xs}) (maybeAll (map parse_arg exprs)) \r
-gParse{|{}|} parse_arg _ = Nothing\r
- \r
-gParse{|{!}|} parse_arg (ExprArray exprs)\r
- = mapMaybe (\xs -> {x\\x<-xs}) (maybeAll (map parse_arg exprs))\r
-gParse{|{!}|} parse_arg _ = Nothing\r
-\r
-maybeAll [] = Just []\r
-maybeAll [Nothing:_] = Nothing\r
-maybeAll [Just x: mxs] \r
- = case maybeAll mxs of\r
- Nothing -> Nothing\r
- Just xs -> Just [x:xs] \r
-\r
-//---------------------------------------------------------------------------------- \r
-\r
-preParseInput :: s -> Expr | ParseInput s\r
-preParseInput input \r
- # (expr, s) = preParse {ps_input=input, ps_char = Nothing, ps_tokens = [] }\r
- = expr\r
- \r
-preParseString :: String -> Expr\r
-preParseString str = preParseInput {si_pos = 0, si_str = str}\r
-\r
-preParseFile :: File -> Expr \r
-preParseFile file = preParseInput file\r
-\r
-parseString :: String -> Maybe a | gParse{|*|} a\r
-parseString str = gParse{|*|} (preParseString str)\r
-\r
-parseFile :: File -> Maybe a | gParse{|*|} a\r
-parseFile file = gParse{|*|} (preParseFile file)\r
-\r
-//Start = preParseString "{rec_field = A (B1, B2) (C D), rec_field2 = (X,Y)}"\r
-//Start = preParseString "123.456e1"\r
-//Start = preParseString "([1,2,3], [4,5,6])"\r
-//Start = preParseString "{A B D,X Y Z,I J K}"\r
-\r
-//---------------------------------------------------------------------------------- \r
-\r
-:: Tree a b = Tip a | Bin b (Tree a b) (Tree a b)\r
-:: T\r
- = :+: infixl 2 T T\r
- | :-: infixl 2 T T\r
- | :*: infixl 3 T T\r
- | :->: infixr 4 T T\r
- | U\r
-\r
-:: Rec = { rec_x :: T, rec_y :: (.Tree Int Real, Real) }\r
-\r
-derive gParse (,), (,,), (,,,), Tree, T, Rec\r
-derive bimap Maybe, ParseState, []\r
-\r
-//Start :: Maybe T\r
-//Start = parseString "U :+: U :+: U"\r
-\r
-//Start :: Maybe (Tree Int Int)\r
-//Start = parseString "Bin 1 (Tip 2) (Tip 3)"\r
-\r
-//Start :: Maybe (Tree Int Int, Int)\r
-//Start = parseString "((Bin 1 (Tip (2)) (Tip 3), 1000))"\r
-\r
-//Start :: Maybe Rec\r
-//Start = parseString "{ Rec | rec_x = U :+: U :+: U, rec_y = (Bin 1.1 (Tip 2) (Tip 3), 1.09) }"\r
-\r
-//Start :: Maybe [Tree Int Int]\r
-//Start = parseString "[Bin 1 (Tip (2)) (Tip 3), Tip 100, Tip 200]" \r
-\r
-//Start = preParseString "1.23e12"\r
-\r
-/*\r
-Start :: *World -> (Maybe Rec, *World)\r
-Start w \r
- #! (ok, f, w) = sfopen "test.txt" FReadText w\r
- | not ok\r
- = (abort "sfopen failed", w)\r
- = (parseFile f, w) \r
-*/
\ No newline at end of file