# PyFlies: A Domain-Specific Language for Designing Experiments in Psychology
## 4 Language Abstract and Concrete Syntaxes
### Tests  
_Test_ is the core concept of the PyFiles language. Each test consists of a condition table and trials' components specification.  
The definition of Test concrete syntax in textX grammar language is given in Listing 1. TestType grammar rule specifies test definition that starts with keyword test followed by attribute name matched by the textX built-in rule ID. It is further followed by the test body that starts with the literal string match \"{\" (line 2). The body of the test starts with condition table specification which is matched by the ConditionsTable grammar rule (Section 4.3). After the condition table, we have optional variable assignments matched by the rule VariableAssignment. At the end, we have component conditions specifications represented by textX attribute component_cond and matched by the rule ComponentsCondition. The closing curly brace ends the test body.  
```
1 TestType:
2\"test\"name=ID\"(\" table_spec=ConditionsTable
4 vars=VariableAssignment
5 components_cond==ComponentsCondition
6
7\")\"
8;
```  
Listing 2 shows an example of a test definition (the used example test is a parity judgment task [37]; a complete test is given in the examples folder of the PyFiles project repository.). Test definition starts at line 4 with the keyword test and the name of the test Parity. The first part of the test definition is a condition table defined at lines 6-8, which describes trial variables (number and parity) and their values for each trial (line 8) in a compact form (see Section 4.3 for details).  
```
1 numbers=1..9
2 parities=[odd,even]
3
4 testParity{
5
6|number|parity|

Figure 2: A simplified PyFiles abstract syntax.

7|-------|-------|
8|numbersloop|parities|
9
10 fix->cross()for700
11 exec->text(contentnumber)
12 keyboard(validparities,correctparity)
13
14 correct->sound(freq500)for300
15 error->sound(freq1000)for300
16}
```
The second part of the test definition specifies trial phases with component specifications.  
PyFiles divides each trial into three phases: _fix_, _exec_, and _error/correct_. The fix phase is a fixture phase during which a fixture stimulus is shown to the subject. After the _fix_ phase, we have the _exec_ phase that is the main phase of the trial and the only mandatory phase (all others are optional). Depending on the subject's response, the third phase can be either _correct_, if the response was correct, or _error_, if the response was incorrect. We provide the correct response in the definition of the input components (e.g., correct property of the keyboard component is set to a symbol or a list of symbols describing the correct response).  
We provide each component specification in the following form:
```
<booleanexpression> -><componentsspecificationswithtimings>
```
The Boolean expression on the left side, when evaluated as true, enables the execution of components specified on the right side. There can be more components defined for each Boolean expression.  
During the execution of each phase Boolean variables fix, exec, error, and correct will have a corresponding value. For example, exec will be true during the _exec_ phase and false in all other phases. That enables creating Boolean expressions on the left side of each trial definition expression that matches a particular phase. For example:
```
fix->cross()for700
```
Will match the fixation phase and show a cross component for the duration of 700 ms in this phase.  
The optional duration is specified after the keyword for. It is given as a PyFlies expression that evaluates to an integer interpreted as a duration in milliseconds. If the duration is not given the component runs until the end of the trial phase.  
Most of the time a Boolean expression on the left side is just a phase variable but can be an arbitrary Boolean expression. For example:
```
fixandparity==odd ->circle(colorgreen)for700
```  
Will show a green circle in the _fix_ phase if parity is odd.