1 module Parse(parse_circuit, parse_exact, parse_approx, parse_integer) where 2 3 import Char 4 import List 5 import Maybe 6 import Ratio 7 8 import Types 9 import ParseLib 10 11 parse_circuit = parse (remove_right circuit whitespace) 12 parse_exact = parse (remove_right exact whitespace) 13 parse_approx = parse (remove_right approx whitespace) 14 parse_integer = parse (remove_right integer whitespace) 15 16 circuit :: Parser (Circuit, [Name]) 17 circuit = transform make_indices (repetition1 element) 18 where 19 make_indices list = (circuit, names) 20 where 21 list_with_types = [(e, ("i:" ++ n1, "v:" ++ n2, "v:" ++ n3)) | (e, (n1, n2, n3)) <- list] 22 names = (nub . ("v:ground" :) . concat) [[n1, n2, n3] | (_, (n1, n2, n3)) <- list_with_types] 23 circuit = [(index n1, index n2, index n3, e) | (e, (n1, n2, n3)) <- list_with_types] 24 index name = fromJust (lookup name (zip names [0..])) 25 26 element :: Parser (Element, (Name, Name, Name)) 27 element = choice [conductor, resistor, capacitor, inductor, vsource, isource, junction] 28 where 29 conductor = code 'g' (transform Conductor exact) 30 resistor = code 'r' (transform Resistor exact) 31 capacitor = code 'c' (transform Capacitor (sequence2 exact exact)) 32 inductor = code 'l' (transform Inductor (sequence2 exact exact)) 33 vsource = code 'v' (transform Vsource list) 34 isource = code 'i' (transform Isource list) 35 junction = code 'j' (transform Junction (sequence3 exact exact exact)) 36 37 code c = transform (\(n, e) -> (e, n)) . (sequence2 (remove_left (character c) (sequence3 name name name))) 38 39 list :: Parser List 40 list = repetition1 (enclose (character '(') (glue approx (character ',') approx) (character ')')) 41 42 approx :: Parser Approx 43 approx = transform circa exact 44 45 exact :: Parser Exact 46 exact = transform (\((sign, int), (frac, fact)) -> sign * (int + frac) * fact) (sequence2 (sequence2 sign integer) (sequence2 fraction factor)) 47 where 48 sign = transform make_sign (option (character '-')) 49 make_sign "" = 1 % 1 50 make_sign "-" = -1 % 1 51 52 integer = transform make_integer (parse_while isDigit) 53 make_integer s = read s % 1 54 55 fraction = transform make_fraction (option (remove_left (character' '.') (parse_while isDigit))) 56 make_fraction [ ] = 0 % 1 57 make_fraction [s] = read s % read ('1' : map (const '0') s) 58 59 factor = transform make_factor (option (parse_if' (`elem` "afpnumkMGTPE"))) 60 make_factor "a" = 1 % 1000000000000000000 61 make_factor "f" = 1 % 1000000000000000 62 make_factor "p" = 1 % 1000000000000 63 make_factor "n" = 1 % 1000000000 64 make_factor "u" = 1 % 1000000 65 make_factor "m" = 1 % 1000 66 make_factor "" = 1 % 1 67 make_factor "k" = 1000 % 1 68 make_factor "M" = 1000000 % 1 69 make_factor "G" = 1000000000 % 1 70 make_factor "T" = 1000000000000 % 1 71 make_factor "P" = 1000000000000000 % 1 72 make_factor "E" = 1000000000000000000 % 1 73 74 integer :: Parser Integer 75 integer = transform read (choice [cons (character '-') (parse_while isDigit), parse_while isDigit]) 76 77 name :: Parser Name 78 name = parse_while isAlphaNum