2017-02-10 1 views
0

Je vous écris le code pour évaluateur d'expression en utilisant lex et yacc qui peut avoir des opérations suivantes:En utilisant bc à partir du code C

/, *, +, -, pow (a, b), sqrt (a), log (a)

également il peut y avoir des crochets dans l'expression.

expression est entrée dans le fichier "calculator.input"

Je dois comparer le temps de mon code avec bc, je suis confronté à des problèmes suivants:

1) bc n'accepte pas Pow (a, b) et log (a) il accepte au lieu a^b et l (a). Comment puis-je le changer?

2) Comment puis-je utiliser le bc de la principale funtion dans le yacc programme? ou qui ne peut pas être fait?

Répondre

0

Je pense qu'il serait plus facile de changer votre code que de changer bc, mais si vous voulez essayer, vous pouvez trouver des pointeurs vers des faisceaux de sources de bc sur le GNU project page et dans le FreeBSD source mirror. Bien sûr, le résultat final ne serait plus à proprement parler, donc je ne sais pas si cela compterait encore, pour les besoins de votre mission.

Je ne sais pas ce que les spécifications sont pour la fonction pow vous êtes censé mettre en œuvre, mais notez que l'opérateur de ^bc ne permet que des exposants entiers, il pourrait ne pas fonctionner sur tous vos cas de test (à moins, Bien sûr, tous vos cas de test ont des exposants entiers) Vous pouvez calculer a^b avec e(l(a)*b), mais il ne sera pas aussi précis pour les exposants entiers.

e(l(10)*100) 
99999999999999999920085453156357924020916787698393558126052191252537\ 
96016108317256511712576426623511.11829711443225035170 
10^100 
10000000000000000000000000000000000000000000000000000000000000000000\ 
000000000000000000000000000000000 

Vous pouvez consulter votre tuteur, professeur, ou d'enseignement assistant.

Si vous ne voulez pas (ou ne sont pas autorisés à) générer les cas de test équivalent bc à la main, vous pourriez être en mesure d'automatiser le processus avec sed (si les sous-expressions exponentielles ne sont pas compliquées), ou en adaptant votre calculatrice pour afficher l'expression dans la syntaxe bc. Ce dernier serait un projet assez facile, et vous apprendrez probablement quelque chose en l'implémentant.

Si vous utilisez un système de type Unix, vous pouvez facilement exécuter n'importe quel utilitaire de ligne de commande à partir d'un programme C. (En effet, vous pouvez le faire sur des systèmes non-Unix, mais les fonctions de bibliothèque seront différentes.) Si vous n'avez pas besoin de transmettre des données à bc via stdin, vous pouvez utiliser la fonction de bibliothèque popen(3), qui est certainement la solution la plus simple.

Sinon, vous devrez mettre en place une paire de pipe(2) s (un pour écrire à l » stdinbc et l'autre pour la lecture de son stdout), fork(2) un processus enfant, et utiliser l'un des appels de fonction exec*, probablement execlp(3) ou execvp(3), pour exécuter bc chez l'enfant. (Faites attention à l'impasse du tuyau pendant que vous écrivez à l'enfant et lisez.) Une fois le processus enfant terminé (ce que vous remarquerez car vous obtiendrez une EOF sur le tuyau que vous utilisez pour lire depuis son stdout, vous devrait utiliser wait(3) ou waitpid(3) pour obtenir son code d'état.

Si tout cela semble trop compliqué, vous pouvez utiliser la solution beaucoup plus simple de gérer à la fois votre programme et bc de votre shell. (vous pouvez utiliser le haut-shell time sur des shells de type Unix pour obtenir une mesure du temps d'exécution, bien que ce ne soit pas une résolution de microsecondes qui pourrait être nécessaire pour un programme aussi simple.)

+0

Merci pour la réponse:). Je suis autorisé à utiliser le temps de shell. Pouvez-vous s'il vous plaît modifier la question? – nequit