Proggers - это программная игровая площадка для простого, императивного языка.
Зависимости:
Ни Elina, ни LLVM, ни Z3 не требуются для проверки типов и визуализации CFG, следовательно, они могут быть превращены в функцию ящика. Пожалуйста, не стесняйтесь вносить свой вклад!
После установки предварительных условий вы можете установить Proggers с: cargo install --git https://github.com/skius/progge.rs
proggers
<sourcefile> # the sourcefile to analyze
--cfg # visualize the control flow graph
--typecheck # type-check the source
--analyze # shorthand for --symex --ai
--symex # run symbolic execution
--ai # run abstract interpretation
--ast # print the abstract syntax tree
-o <outputfile> # compile source into the executable <outputfile>
--verbose # print LLVM IR when compiling
Проггеры могут анализировать программы, написанные на языке Progge.
program: funcdef*
funcdef: fn var((var: type,)*) -> type { block }
block: stmt;*
stmt: let var = expr
| var = expr
| expr[expr] = expr
| var(expr,*)
| testcase!
| unreachable!
| if expr { block } [ else { block } ]
| while expr { block }
| return [expr]
expr: var
| int
| bool
| expr binop expr
| unop expr
| var(expr,*)
| [expr,*]
| [expr; expr]
binop: + | - | * | / | % | < | <= | > | >= | == | !=
unop: - | !
var: [A-Za-z_][A-Za-z0-9_]*
type: int | bool | [type]
Ничего особенного. Посвящения разрешено тенировать предыдущие привязки.
Специальные настройки Progge и какая часть Proggers использует их:
| Встроенный | Описание | Ай | Сельский | ТК | В |
|---|---|---|---|---|---|
unreachable! | Утверждает, что потоки управления могут никогда не достичь этого утверждения | [x] | [x] | ||
testcase! | Инструктирует генерацию тестовых областей, которые достигают этого утверждения | [x] | [x] | ||
assume!(expr) | Предполагает данное выражение Bool как истинное | [x] | [x] | ||
analyze!(expr) | Инструктирует численный анализ для печати чрезмерной аппксимации экспрессии int | [x] | |||
int_arg(expr) | Возвращает аргумент командной строки expr-th | [x] | [x] | ||
print_int(expr) | Печатает заданный int to stdout | [x] |
Легенда : TC: Проверка типа, SE: Символическое исполнение, AI: Аннотация Интерпертации, C: Компиляция
Проггерс способен анализировать программу ниже и найти возможные возвратные значения, как можно видеть из правого нижнего « z: [-1,0] », указывающего на z может быть -1 или 0 .
fn analyze ( x : int , y : int ) -> int {
if x < y {
while x < y {
x = x + 1 ;
y = y - 1 ;
}
let z = y - x ;
return z ;
}
return - 2 ;
} 
Проггеры также поддерживают несколько директив, которые используют результаты абстрактной интерпретации.
Проанализируйте! : Явно печатает возможные значения для данного выражения. Например, запуск proggers --typecheck --analyze analyzer-examples/analyze_loop.progge дает следующую обратную связь (изображение не показывает полного выхода):
Обратите внимание, что возвращаемые возможные значения для выражения являются чрезмерной оценкой .

Недоступно! : Утверждает, что заявление недоступно. Например, запуск proggers --typecheck --analyze analyzer-examples/unreachable.progge Дает следующую обратную связь:
Обратите внимание, что опять же, анализ недоступности с использованием абстрактной интерпретации вычисляет чрезмерную оценку - то есть он может дать ложные срабатывания (предупреждайте о достижении unreachable! Заявления, которые на самом деле недоступны), но никогда не могут дать ложные негативы (если нет никаких предупреждений о unreachable! То, то гарантируется, что это утверждение объясняется). См. Символическое исполнение для гарантированных заявлений о достижении.

Абстрактная интерпретация (Wikipedia) вычисляет чрезмерную оценку, что означает, что все возможные программы поведения (возможно, больше, но не меньше), захватываются им, то есть значение «если реальная программа демонстрирует поведение, то это поведение содержится в чрезмерной интерпретации».
Короче говоря, абстрактная интерпретация может доказать отсутствие нежелательного поведения программы, что может быть исключительно исключительными изделиями (TODO), исполнение unreachable! Заявления или функциональные вызовы, аргументы которых не удовлетворяют предварительные условия функции.
Теста! : Генерирует тестовые шкафы (т.е. значения аргумента для функции), которые достигают оператора. Например, запуск proggers --typecheck --symex analyzer-examples/symex_arr_hard.progge дает:
Примечание. Генерация Testcase также работает для вызовов int_arg - см. symex_blackbox.progge
analyzer-examples/symex_arr_hard.progge:7:13: sample inputs reaching this statement:
{ x = 1, y = 0 }
{ x = 0, y = 1 }
{ x = 0, y = 2 }
{ x = 2, y = 1 }
{ x = 1, y = 2 }
Недоступно! : Кроме того, если данный unreachable! На самом деле не недоступно, символическое выполнение вынесет ошибку и даст образец вход, который достигает оператора. Например, запуск proggers --typecheck --symex analyzer-examples/unreachable.progge дает: 
Символическое выполнение (Wikipedia) вычисляет недооценку, что означает, что значение является «если символическое выполнение сообщает о пути (набор входных значений), то реальная программа также должна следовать этому пути».
Короче говоря, символическое выполнение может доказать достижение операторов, приведя конкретные примеры входов, или, другими словами, оно может доказать наличие определенных программ поведения программы.
let затенение/лексические прицелы: Proggers замечает, что существует пять различных переменных, называемых x , как можно увидеть в очищенном AST, что прогнозы возвращаются:
// Original source code
fn analyze ( x : int ) -> int {
x = 0 ;
let x_2 = 10 ;
let x = x ;
let x = x + 1 ;
x_2 = 5 ;
if true {
let x = 2 ;
x = 3 ;
} else {
let x = 4 ;
}
// returns 1
return x ;
}
// Type-checked AST
fn analyze ( x_1 : int ) {
x_1 = 0 ;
let x_2_1 = 10 ;
let x_2 = x_1 ;
let x_3 = ( x_2 + 1 ) ;
x_2_1 = 5 ;
if true {
let x_4 = 2 ;
x_4 = 3 ;
} else {
let x_5 = 4 ;
}
return x_3 ;
}Кроме того, Proggers может дать хорошие сообщения об ошибках (благодаря Ariadne):
// Source
fn foo ( ) -> int {
return true ;
} 
См. analyzer-examples/tc_bad для получения дополнительных примеров.
Проггеры могут компилировать программы на собственный код.
$ proggers codegen-examples/factorial.progge -t -o factorial
$ ./factorial 4
24
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24Лицензирован под одним из
на вашем варианте.
Если вы явно не заявляете иное, какой-либо вклад, преднамеренно предназначенный для включения в работу вами, как определено в лицензии Apache-2.0, должен быть двойной лицензией, как указано выше, без каких-либо дополнительных условий или условий.