parse non-term rule.
| 930 | |
| 931 | // parse non-term rule. |
| 932 | bool _context::parse_non_term(rule& r) { |
| 933 | // save the state of the rule |
| 934 | rule::_state old_state = r.m_state; |
| 935 | // restore the rule's state |
| 936 | rule::_state_guard quard(old_state, &r.m_state); |
| 937 | |
| 938 | // success/failure result |
| 939 | bool ok = false; |
| 940 | |
| 941 | // compute the new position |
| 942 | size_t new_pos = m_pos.m_it - m_begin; |
| 943 | |
| 944 | // check if we have left recursion |
| 945 | bool lr = new_pos == r.m_state.m_pos; |
| 946 | |
| 947 | // update the rule's state |
| 948 | r.m_state.m_pos = new_pos; |
| 949 | |
| 950 | // handle the mode of the rule |
| 951 | switch (r.m_state.m_mode) { |
| 952 | // normal parse |
| 953 | case rule::_PARSE: |
| 954 | if (lr) { |
| 955 | // first try to parse the rule by rejecting it, so alternative branches are examined |
| 956 | r.m_state.m_mode = rule::_REJECT; |
| 957 | ok = _parse_non_term(r); |
| 958 | |
| 959 | // if the first try is successful, try accepting the rule, |
| 960 | // so other elements of the sequence are parsed |
| 961 | if (ok) { |
| 962 | r.m_state.m_mode = rule::_ACCEPT; |
| 963 | |
| 964 | // loop until no more parsing can be done |
| 965 | for (;;) { |
| 966 | // store the correct state, in order to backtrack if the call fails |
| 967 | _state st(*this); |
| 968 | |
| 969 | // update the rule position to the current position, |
| 970 | // because at this state the rule is resolving the left recursion |
| 971 | r.m_state.m_pos = m_pos.m_it - m_begin; |
| 972 | |
| 973 | // if parsing fails, restore the last good state and stop |
| 974 | if (!_parse_non_term(r)) { |
| 975 | restore(st); |
| 976 | break; |
| 977 | } |
| 978 | } |
| 979 | |
| 980 | // since the left recursion was resolved successfully, |
| 981 | // return via a non-local exit |
| 982 | throw _lr_ok(r.this_ptr()); |
| 983 | } |
| 984 | } else { |
| 985 | try { |
| 986 | ok = _parse_non_term(r); |
| 987 | } catch (const _lr_ok& ex) { |
| 988 | // since left recursions may be mutual, we must test which rule's left recursion |
| 989 | // was ended successfully |
no test coverage detected