Ejemplo n.º 1
0
 def _parse_phases(self, v_str):
     if v_str == 'all':
         self.val[kw.PHASES] = v_str  # list(all_phase_labels)
     else:
         phase_labels = ParseUtil.comma_split_strip(v_str)
         for phase_label in phase_labels:
             if len(phase_label) == 0:
                 return "Expected comma-separated list of phase labels, found {}".format(
                     phase_labels)
             # else:
             #     if phase_label not in all_phase_labels:
             #         return "Undefined phase label '{}'.".format(phase_label)
         self.val[kw.PHASES] = phase_labels
     return None
Ejemplo n.º 2
0
    def __init__(self, phase_obj, lineno, label, after_label, all_linelabels, parameters, global_variables):
        self.lineno = lineno
        self.label = label
        self.parameters = parameters
        self.all_linelabels = all_linelabels

        self.is_help_line = False
        self.stimulus = None  # A dict with an intensity for each element in stimulus_elememts
        self.action = None

        self.action, logic = ParseUtil.split1_strip(after_label, sep=PHASEDIV)
        if logic is None:
            raise ParseException(lineno, f"Missing separator '{PHASEDIV}' on phase line.")
        action_list = ParseUtil.comma_split_strip(self.action)

        first_element, _, _ = ParseUtil.parse_element_and_intensity(action_list[0], variables=None,
                                                                    safe_intensity_eval=True)
        self.is_help_line = (len(action_list) == 1) and (first_element not in parameters.get(STIMULUS_ELEMENTS))
        if self.is_help_line:
            self.stimulus = None
            if action_list[0] != '':
                check_action(action_list[0], parameters, global_variables, lineno, all_linelabels)
        else:
            self.stimulus, err = ParseUtil.parse_elements_and_intensities(self.action, global_variables,
                                                                          safe_intensity_eval=True)
            if err:
                raise ParseException(lineno, err)

            for element in self.stimulus:
                if element not in parameters.get(STIMULUS_ELEMENTS):
                    raise ParseException(lineno, f"Expected a stimulus element, got '{element}'.")

            self.action = None

        if len(logic) == 0:
            raise ParseException(lineno, f"Line with label '{label}' has no conditions.")
        self.conditions = PhaseLineConditions(phase_obj, lineno, self.is_help_line, logic, parameters,
                                              all_linelabels, global_variables)
Ejemplo n.º 3
0
    def _parse(self, lineno, is_help_line, condition_and_actions, logicpart_index, n_logicparts, parameters,
               all_linelabels, global_variables):
        '''
        Args:
            condition_and_actions (str): Examples are
                "b=5: x:2, y=2, ROWLBL",
                "x:2, y:2, ROWLBL",
                "@break"
                "x=1: @break"
                "x:1"
                "@break, x:1"
        '''
        self.condition = None

        ca_list = ParseUtil.comma_split_strip(condition_and_actions)

        found_condition = False
        any_rowlbl_prob = False
        found_rowlbl = False
        goto_list = list()
        goto_list_index = list()
        for i, ca in enumerate(ca_list):
            err = f"Invalid statement '{ca}'."
            n_colons = ca.count(':')
            if n_colons == 0:
                contains_condition = False
                action = ca
            elif n_colons == 1:
                before_colon, after_colon = ParseUtil.split1_strip(ca, ':')
                contains_condition = self._is_condition(before_colon, parameters)
                if contains_condition:
                    if self.condition is not None:  # Cannot have multiple conditions
                        raise ParseException(lineno, f"Multiple conditions ('{self.condition}' and '{before_colon}') found in '{condition_and_actions}'.")
                    self.condition = before_colon
                    action = after_colon
                else:
                    action = ca
            elif n_colons == 2:
                colon_inds = [m.start() for m in re.finditer(':', ca)]
                if colon_inds[1] - colon_inds[0] == 1:
                    raise ParseException(lineno, err)
                before_first_colon, after_first_colon = ParseUtil.split1_strip(ca, ':')
                if not self._is_condition(before_first_colon, parameters):
                    raise ParseException(lineno, err)
                if self.condition is not None:  # Cannot have multiple conditions
                    raise ParseException(lineno, f"Multiple conditions ('{self.condition}' and '{before_first_colon}') found in '{condition_and_actions}'.")
                contains_condition = True
                self.condition = before_first_colon
                action = after_first_colon
            else:
                raise ParseException(lineno, err)

            if contains_condition and found_rowlbl:
                raise ParseException(lineno, f"Found condition '{self.condition}' after row label '{','.join(goto_list)}'.")

            found_condition = found_condition or contains_condition
            is_rowlbl, is_rowlbl_prob = self._is_rowlbl(action, all_linelabels)
            any_rowlbl_prob = (any_rowlbl_prob or is_rowlbl_prob)
            if is_rowlbl:
                found_rowlbl = True
                goto_list.append(action)
                goto_list_index.append(i)
            else:
                check_action(action, parameters, global_variables, lineno, all_linelabels)
                if found_rowlbl:
                    err = f"Row label(s) must be the last action(s). Found '{action}' after row-label."
                    raise ParseException(lineno, err)
                if found_condition:  # self.condition is not None:
                    self.conditional_actions.append(action)
                else:
                    self.unconditional_actions.append(action)

            is_last_action = (i == len(ca_list) - 1)
            if is_last_action and not is_rowlbl:
                raise ParseException(lineno, f"Last action must be a row label, found '{action}'.")

        if found_condition:
            self.condition_is_behavior = (self.condition in parameters.get(BEHAVIORS))
            cond_depends_on_behavior, err = ParseUtil.depends_on(self.condition, parameters.get(BEHAVIORS))
            if err is not None:
                raise ParseException(lineno, err)
            if cond_depends_on_behavior and is_help_line:
                raise ParseException(lineno, "Condition on help line cannot depend on response.")

        goto_str = ','.join(goto_list)

        # A deterministic ROWLBL cannot have elif/else continuation
        if (not found_condition) and found_rowlbl and not any_rowlbl_prob:
            if logicpart_index < n_logicparts - 1:
                err = f"The unconditional goto row label '{goto_str}' cannot be continued."
                raise ParseException(lineno, err)

        if len(goto_list) > 0:
            self._parse_goto(goto_str, lineno, all_linelabels, global_variables)