Haskell , 74 67 63 bytes
r=read
f x|(a,(c,s:d):_)<-lex<$>lex x!!0=show(r a*r d+r c)++s:d
Experimente online!
Explicação
Como H.PWiz descobriu, podemos usar o lexer de Haskell aqui para quebrar a corda em suas partes. (No começo eu estava usando span(>'/')) E Laikoni apontou que <$>funciona exatamente como mapSndem Data.Tuple.
O protetor de padrão divide nosso código nos três números que queremos usar lex. lexchama o lexer de haskell para interromper o primeiro token. Ele retorna uma lista com cada elemento representando uma maneira possível de analisar a sequência. Esses elementos são tuplas, com o primeiro elemento sendo o primeiro token e o restante da string sendo o segundo elemento. Agora, como o formato de entrada é muito regular, apenas teremos exatamente uma análise, para que possamos sempre fazer a primeira. A primeira coisa que fazemos é chamar lexna entrada
lex x
Em seguida, desembrulhámo-lo da lista, fornecendo uma
lex x!!0
O primeiro token será a parte inteira da fração mista, deixando a fração precedida por um espaço para análise. Então, como as tuplas são Functors, podemos usar (<$>)um alias para fmapaplicar lexao segundo elemento da tupla.
lex<$>lex x!!0
Isso consome o espaço e interrompe o próximo token, o numerador da nossa fração. Agora, vinculamos isso a uma correspondência de padrão usando <-. Nosso padrão é
(a,(c,s:d):_)
aagarra a parte inteira da fração, nosso primeiro token. :_desembrulha a lista resultante do nosso segundo lex. cpega o segundo token que inserimos, que é o numerador da fração. Tudo o que resta está vinculado ao s:dque o divide em seu primeiro caractere, garantido pelo formato de a /e o restante, que será o denominador.
Agora que analisamos a entrada, fazemos o cálculo real:
show(r a*r d+r c)++s:d
Onde restá a função de leitura que ligamos anteriormente.
É importante observar que lexretorna uma lista vazia se falhar e não vazia se for bem-sucedida. Por que isso não é um Maybeeu não sei.