Автоматизация разработки программ

advertisement
Автоматизация разработки
программ
На примере синтаксического
анализатора для калькулятор
Постановка задачи
Калькулятор с использованием
функций, выражений любого типа
сложности и имепнованных регистров
хранения
Наличие графического интерфейса
Ограниченный срок исполнения
Тема 13 Автоматизация
разработки программ
2
Декомпозиция
Структурная декомпозиция приводит
к следующим модулям
Графический интерфейс –
требование заказчика
Анализ и вычисление выражения
(строки текста)
Передача данных из интерфейса в
расчетный модуль и наоборот
Тема 13 Автоматизация
разработки программ
3
Графический интерфейс
Представляется наиболее сложным
Автоматизируем разработку
применением визуального
проектирования
Легкий в освоении FLTK и fluid
позволяют сделать интерфейс за
несколько десятков минут…
Тема 13 Автоматизация
разработки программ
4
Интерфейс калькулятора
Тема 13 Автоматизация
разработки программ
5
Главная «сложность» позади
Что дальше? В строке окна
текстового ввода мы получаем
выражение, которое нужно
вычислить… (после написания
callback’ов, см. след.слайд)
Вычисление требует разбора строки с
учетом приоритетов операций
Тема 13 Автоматизация
разработки программ
6
Напишем обработчики кнопок
Тема 13 Автоматизация
разработки программ
7
Синтаксический разбор
Всегда считался сложным
Пока не появились средства
автоматизации (yacc, bison, eli)
Для их использования нужно описать
грамматику используемых выражений
Тема 13 Автоматизация
разработки программ
8
Определим структуру элемента стека разбора
typedef struct Symbol
{
char *name; short type;
union {
double val;
double (*ptr)();
}u;
struct Symbol *next;
} Symbol;
Symbol *symlist =0;
Тема 13 Автоматизация
разработки программ
9
Определим списки используемых
констант и функций
static struct {
char *name;
double cval; } Const[]=
{
"PI", 3.1415926536,
"E", 2.718281828459,
"RAD",57.2958,
0,0
};
static struct {
char *name;
double (*func)(); }
Funcs[]=
{
"sin",sin,
"cos",cos,
"tan",tan,
"sqrt",Sqrt,
"abs",fabs,
0,0
};
%}
Тема 13 Автоматизация
разработки программ
10
Определим состав лексем и операций
%token <val> NUM
%token <sym> VAR FUNC UNDF
%type <val> expr assign
%type <val> prog
%right '='
%left '+' '-'
%left '*' '/'
%right '^'
%left UNMIN
%%
Тема 13 Автоматизация
разработки программ
11
Определим грамматику
prog:
'\n'
| expr '\n'
| prog expr '\n'
{ printf("!\n"); }
{ $$=$1; printf("=>%lf\n",$$);
{ $$=$2; printf("->%lf\n",$$);
;
assign: VAR '=' expr
;
expr:
NUM
| VAR
| FUNC '(' expr ')'
|
expr '+' expr
| expr '-' expr
| expr '*' expr
{
{
{
{
{
{
{
}
}
$$ = $1->u.val=$3; $1->type=VAR; }
$$ = $1; }
$$ = $1->u.val; }
$$ = (($1->u.ptr)($3)); }
$$ = $1+$3; }
$$ = $1 - $3; }
$$ = $1*$3; }
Тема 13 Автоматизация
разработки программ
12
Окончание грамматики
|
expr '/' expr
|
|
|
|
;
{ if ($3!=0) $$ = $1/$3;
else {
printf(" Zero divide\n"); $$=$1; }
}
expr '^' expr
{ $$ = pow($1,$3); }
'-' expr %prec UNMIN { $$ = -$2; }
assign
'(' expr ')'
{ $$ = $2; }
%%
Тема 13 Автоматизация
разработки программ
13
Лексический распознаватель
yylex() {
int c;
Symbol *s;
char sbuf[100], *p=sbuf;
while((c=getchar())==' ');
if (c==EOF) return 0;
if(isalpha(c))
{
do *p++=c;
while (((c=getchar())!=EOF) && isalnum(c));
ungetc(c,stdin); *p='\0';
if ((s=lookup(sbuf))==0) s=install(sbuf,UNDF,0.0);
yylval.sym=s;
return ((s->type==UNDF) ? VAR : s->type);
}
if (c=='.' || isdigit(c))
{
ungetc(c,stdin); scanf("%lf",&yylval); eturn NUM;
};
return c;
Тема 13 Автоматизация
}
разработки программ
14
Переделка лексического распознавателя
В данном варианте лексический парсер
вводит информацию из потока stdin,
переделаем его для ввода из символьной
строки. Саму строку, считанную в массив
типа extern по callback’у кнопки «calc!»
считываем до символа с нулевым кодом.
Выделенные красным цветом строки в
грамматики переделаем так, чтобы вывод
помещался не в stdout, а в строку типа
extern и оттуда был доступен для
графического интерфейса
Тема 13 Автоматизация
разработки программ
15
Компоновка
При компоновке мы сталкиваемся с
различным представлением символов
в GSD языков C и C++.
Будем исправлять это в файле y.tab.c
после компиляции yacc’ем.
Автоматизируем и эту работу,
поручив ее программе sed.
Тема 13 Автоматизация
разработки программ
16
Еще нужно почитать про
Make
Yacc
Autoconf
Тема 13 Автоматизация
разработки программ
17
Download