function parse_part($part) { //echo 'Parsing part: '.$part."\n"; // Let's start breaking down the reqs into logical units. // XXX ###(, ###, ###, ...) // Example: PHARM 129, 131, 220 // Means: You must take all three courses. // XXX ### or ### // Example: AFM 101 or 128 // Means: You must take one or the other. $operators = array(); $state_machine = 0; $depth = 0; $brackets = array(); $grouped_operators = array(); $in_word = false; $word_buffer = ''; $last_faculty = null; $course_group = array(); $group_operator = 'and'; $last_operand = false; $last_number = null; $last_numerical_count = null; $is_pairing = false; $last_word_type = 0; $numbers = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'); $part = ' ' . $part . ' '; for ($ix = 0; $ix < strlen($part); ++$ix) { $letter = $part[$ix]; if ($letter == '(') { ++$depth; $brackets[] = $ix; } else { if ($letter == ')') { --$depth; $start_bracket = array_pop($brackets); if (!$depth) { $sub_operators = parse_reqs(substr($part, $start_bracket + 1, $ix - $start_bracket - 1)); $course_group = array_merge($course_group, $sub_operators); } } else { if ($depth == 0) { if (eregi('[a-z0-9]', $letter)) { $word_buffer .= $letter; $in_word = true; } else { if ($in_word) { if ($letter == ',') { //echo "found a comma..."; if ($last_operand) { if (!empty($course_group)) { $operators[] = array_merge(array($group_operator), $course_group); $course_group = array(); } $last_operand = false; } } $new_word_type = 0; if (strtolower($word_buffer) == 'or') { if ($last_operand && $group_operator != strtolower($word_buffer)) { // We've already added the last value for the previous operator, so let's // group everything up to this point. $course_group = array(array($group_operator, $course_group)); } //echo "found an or operator\n"; $group_operator = 'or'; $last_operand = true; } else { if (strtolower($word_buffer) == 'and') { //echo "found an and operator\n"; $group_operator = 'and'; $last_operand = true; } else { if (ereg('^[A-Z]+$', $word_buffer)) { //echo 'found a faculty: '.$word_buffer."\n"; if ($is_pairing && $last_word_type == WORD_TYPE_FACULTY) { $last_faculty = array_merge((array) $last_faculty, (array) $word_buffer); $is_pairing = false; } else { $last_faculty = $word_buffer; } $new_word_type = WORD_TYPE_FACULTY; } else { if (ereg('^[0-9]{2,}[A-Z]?$', $word_buffer) && $letter != '%') { foreach ((array) $last_faculty as $faculty) { //echo 'found a course: '.$faculty.' '.$word_buffer."\n"; $course_group[] = new course($faculty, $word_buffer); } if ($is_pairing) { $course2 = array_pop($course_group); $course1 = array_pop($course_group); $course_group[] = array('pair', $course1, $course2); $is_pairing = false; } $new_word_type = WORD_TYPE_CNUM; } else { if (in_array(strtolower($word_buffer), $numbers)) { $value = array_search(strtolower($word_buffer), $numbers) + 1; $last_number = $value; //echo 'found a number: '.$value."\n"; } else { if ($last_number && strtolower($word_buffer) == 'of') { $last_numerical_count = $last_number; $last_number = null; } else { //echo 'found a word: '.$word_buffer."\n"; } } } } } } $last_word_type = $new_word_type; if ($letter == '/') { //echo "found a pairing operator\n"; $is_pairing = true; } $word_buffer = ''; $in_word = false; } } } } } } if (!empty($course_group)) { if ($last_numerical_count) { $group_info = array($last_numerical_count); } else { $group_info = array($group_operator); } $operators[] = array_merge($group_info, $course_group); } //echo "done\n"; return $operators; }
function parse_part($part) { //echo 'Parsing part: '.$part."\n"; // Let's start breaking down the reqs into logical units. // XXX ###(, ###, ###, ...) // Example: PHARM 129, 131, 220 // Means: You must take all three courses. // XXX ### or ### // Example: AFM 101 or 128 // Means: You must take one or the other. $operators = array(); $state_machine = 0; $depth = 0; $brackets = array(); $grouped_operators = array(); $in_word = false; $word_buffer = ''; $last_faculty = null; $course_group = array(); //groups courses that shape same operator $group_operator = 'and'; //operator applying to groups $last_operand = false; $last_number = null; $last_numerical_count = null; $is_pairing = false; $last_word_type = 0; $numbers = array('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'); $part = ' ' . $part . ' '; for ($ix = 0; $ix < strlen($part); ++$ix) { $letter = $part[$ix]; if ($letter == '(') { ++$depth; $brackets[] = $ix; //Add char position to end of $brackets } else { if ($letter == ')') { --$depth; $start_bracket = array_pop($brackets); if (!$depth) { //if we just closed bracket and not at depth 0 $sub_operators = parse_reqs(substr($part, $start_bracket + 1, $ix - $start_bracket - 1)); //parse inside the brackets $course_group = array_merge($course_group, $sub_operators); } } else { if ($depth == 0) { if (eregi('[a-z0-9]', $letter)) { //we run into non-cap letter or # $word_buffer .= $letter; $in_word = true; } else { if ($in_word) { if ($letter == ',') { //echo "found a comma..."; if ($last_operand) { //last operand in a list if (!empty($course_group)) { //we already have courses in our list $operators[] = array_merge(array($group_operator), $course_group); // merge everything up until now $course_group = array(); } $last_operand = false; //something must follow } } //end of comma $new_word_type = 0; if (strtolower($word_buffer) == 'or') { //if we ran into an or if ($last_operand && $group_operator != strtolower($word_buffer)) { //we had *and* operator before, this one is different // We've already added the last value for the previous operator, so let's // group everything up to this point. $course_group = array(array($group_operator, $course_group)); } //echo "found an or operator\n"; $group_operator = 'or'; $last_operand = true; } else { if (strtolower($word_buffer) == 'and') { //echo "found an and operator\n"; $group_operator = 'and'; $last_operand = true; } else { if (ereg('^[A-Z]+$', $word_buffer)) { //echo 'found a faculty: '.$word_buffer."\n"; if ($is_pairing && $last_word_type == WORD_TYPE_FACULTY) { //when faculty only appears once, CS230/MATH330 $last_faculty = array_merge((array) $last_faculty, (array) $word_buffer); //array of faculties? huh? $is_pairing = false; } else { $last_faculty = $word_buffer; } $new_word_type = WORD_TYPE_FACULTY; //we just addressed a faculty } else { if (ereg('^[0-9]{2,}[A-Z]?$', $word_buffer) && $letter != '%') { //need to address what's a course foreach ((array) $last_faculty as $faculty) { //echo 'found a course: '.$faculty.' '.$word_buffer."\n"; $course_group[] = new course($faculty, $word_buffer); //add course to group } if ($is_pairing) { //if course pair $course2 = array_pop($course_group); $course1 = array_pop($course_group); $course_group[] = array('pair', $course1, $course2); $is_pairing = false; } $new_word_type = WORD_TYPE_CNUM; } else { if (in_array(strtolower($word_buffer), $numbers)) { $value = array_search(strtolower($word_buffer), $numbers) + 1; $last_number = $value; //such as 3 of.. //echo 'found a number: '.$value."\n"; } else { if ($last_number && strtolower($word_buffer) == 'of') { $last_numerical_count = $last_number; $last_number = null; } else { //echo 'found a word: '.$word_buffer."\n"; } } } } } } $last_word_type = $new_word_type; if ($letter == '/') { //echo "found a pairing operator\n"; $is_pairing = true; } $word_buffer = ''; $in_word = false; } } //done that we're in a word (new word now?) } } } // done depth 0 actions } // done for loop if (!empty($course_group)) { if ($last_numerical_count) { $group_info = array($last_numerical_count); //ie they are connected by one of } else { $group_info = array($group_operator); //they are connected by operator } $operators[] = array_merge($group_info, $course_group); } //echo "done\n"; return $operators; }