2017-02-10 23 views
0

Я пишу код для выражения оценщика с использованием Lex и Yacc, который может иметь следующие операции:Использования Ьса из C кода

/, *, +, -, пау (а, б), sqrt (a), log (a)

также могут быть скобки в выражении.

Входное выражение в файле «calculator.input»

я должен сравнить время моего кода с Ьс, я столкнулся следующие проблемы:

1) Ьс не принимает пау (а, б) и журнал (а) вместо этого он принимает а^Ь и л (а). Как его изменить?

2) Как использовать Ьс от главного Funtion в программе Yacc? или это невозможно сделать?

ответ

0

Я думаю, что было бы легче изменить код, чем изменить bc, но если вы хотите попробовать, вы можете найти указатели на исходные пучки bc «s на GNU project page и в FreeBSD source mirror. Конечно, конечный результат, строго говоря, не был бы bc, поэтому я не знаю, будет ли он по-прежнему рассчитываться для целей вашего задания.

Я не знаю, что спецификации для функции pow вы должны реализовать, но обратите внимание, что ^ оператор bc «s допускает только целые показатели, поэтому он не может работать на всех тестовых случаях (если, Конечно, все ваши тестовые случаи имеют целые экспонент) Можно вычислить a^b с e(l(a)*b), но это не будет столь же точным для целочисленных индексов:.

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

Вы можете проконсультироваться с вашим преподавателем, профессором, или обучения помощник.

Если вы не хотите (или не могут) генерировать bc эквивалентных тестовых случаев вручную, вы могли бы автоматизировать этот процесс с sed (если экспоненциальные подвыражения не сложны), или путем адаптации вашего калькулятора для вывода выражения в синтаксисе bc. Последний будет довольно простым проектом, и вы, вероятно, узнаете что-то, выполнив его.

Если вы используете Unix-подобную систему, вы можете легко запустить любую утилиту из командной строки из программы C. (Действительно, вы можете сделать это и для не-Unix-подобных систем, но функции библиотеки будут отличаться.) Если вам не нужно передавать данные до bc через свой stdin, вы можете использовать библиотечную функцию popen(3), которая безусловно, самое простое решение.

В противном случае вам придется создать пару pipe(2) с (один для записи bc «s stdin, а другой для чтения в stdout), fork(2) дочернего процесса, а также использовать один из вызовов функций в exec*, вероятно, execlp(3) или execvp(3), для запуска bc у ребенка. (Остерегайтесь тупика трубы, когда вы пишете и читаете от ребенка.) Как только дочерний процесс закончится (что вы заметите, потому что вы получите EOF на трубе, которую используете, чтобы читать из своего stdout, вы следует использовать wait(3) или waitpid(3), чтобы получить свой код статуса.

Если все, что кажется слишком сложным, вы могли бы использовать гораздо более простое решение работает как программу и bc из вашей оболочки. (вы можете использовать time оболочки встроены на Unix-подобных оболочках, чтобы получить меру времени выполнения, хотя это будет не микросекундное разрешение, которое может потребоваться для такой простой программы.)

+0

Спасибо за ответ:). Мне разрешено использовать время из оболочки. Не могли бы вы ответить на вопрос? – nequit