From f653735830d537715f2885bd832cf04851d35401 Mon Sep 17 00:00:00 2001 From: Adrian Thurston Date: Sat, 14 Mar 2020 15:29:52 +0200 Subject: moved source files into commit repository --- src/fsmexec.cc | 220 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 src/fsmexec.cc (limited to 'src/fsmexec.cc') diff --git a/src/fsmexec.cc b/src/fsmexec.cc new file mode 100644 index 00000000..8aa4a072 --- /dev/null +++ b/src/fsmexec.cc @@ -0,0 +1,220 @@ +/* + * Copyright 2007-2018 Adrian Thurston + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include + +#include + +#include "redfsm.h" +#include "compiler.h" + +void execAction( struct pda_run *pdaRun, GenAction *genAction ) +{ + for ( InlineList::Iter item = *genAction->inlineList; item.lte(); item++ ) { + switch ( item->type ) { + case InlineItem::Text: + assert(false); + break; + case InlineItem::LmSetActId: + pdaRun->act = item->longestMatchPart->longestMatchId; + break; + case InlineItem::LmSetTokEnd: + pdaRun->tokend = pdaRun->tokpref + ( pdaRun->p - pdaRun->start ) + 1; + break; + case InlineItem::LmInitTokStart: + assert(false); + break; + case InlineItem::LmInitAct: + pdaRun->act = 0; + break; + case InlineItem::LmSetTokStart: + pdaRun->tokstart = pdaRun->p; + break; + case InlineItem::LmSwitch: + /* If the switch handles error then we also forced the error state. It + * will exist. */ + if ( item->tokenRegion->lmSwitchHandlesError && pdaRun->act == 0 ) { + pdaRun->fsm_cs = pdaRun->fsm_tables->error_state; + } + else { + for ( TokenInstanceListReg::Iter lmi = item->tokenRegion->tokenInstanceList; + lmi.lte(); lmi++ ) + { + if ( lmi->inLmSelect && pdaRun->act == lmi->longestMatchId ) + pdaRun->matched_token = lmi->tokenDef->tdLangEl->id; + } + } + pdaRun->return_result = true; + pdaRun->skip_tokpref = true; + break; + case InlineItem::LmOnLast: + pdaRun->p += 1; + pdaRun->tokend = pdaRun->tokpref + ( pdaRun->p - pdaRun->start ); + pdaRun->matched_token = item->longestMatchPart->tokenDef->tdLangEl->id; + pdaRun->return_result = true; + break; + case InlineItem::LmOnNext: + pdaRun->tokend = pdaRun->tokpref + ( pdaRun->p - pdaRun->start ); + pdaRun->matched_token = item->longestMatchPart->tokenDef->tdLangEl->id; + pdaRun->return_result = true; + break; + case InlineItem::LmOnLagBehind: + pdaRun->matched_token = item->longestMatchPart->tokenDef->tdLangEl->id; + pdaRun->return_result = true; + pdaRun->skip_tokpref = true; + break; + } + } + + if ( genAction->markType == MarkMark ) + pdaRun->mark[genAction->markId-1] = pdaRun->p; +} + +extern "C" void internalFsmExecute( struct pda_run *pdaRun, struct input_impl *inputStream ) +{ + int _klen; + unsigned int _trans; + const long *_acts; + unsigned int _nacts; + const char *_keys; + + pdaRun->start = pdaRun->p; + + /* Init the token match to nothing (the sentinal). */ + pdaRun->matched_token = 0; + +/*_resume:*/ + if ( pdaRun->fsm_cs == pdaRun->fsm_tables->error_state ) + goto out; + + if ( pdaRun->p == pdaRun->pe ) + goto out; + +_loop_head: + _acts = pdaRun->fsm_tables->actions + pdaRun->fsm_tables->from_state_actions[pdaRun->fsm_cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + execAction( pdaRun, pdaRun->fsm_tables->action_switch[*_acts++] ); + + _keys = pdaRun->fsm_tables->trans_keys + pdaRun->fsm_tables->key_offsets[pdaRun->fsm_cs]; + _trans = pdaRun->fsm_tables->index_offsets[pdaRun->fsm_cs]; + + _klen = pdaRun->fsm_tables->single_lengths[pdaRun->fsm_cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*pdaRun->p) < *_mid ) + _upper = _mid - 1; + else if ( (*pdaRun->p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = pdaRun->fsm_tables->range_lengths[pdaRun->fsm_cs]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*pdaRun->p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*pdaRun->p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + pdaRun->fsm_cs = pdaRun->fsm_tables->transTargsWI[_trans]; + + if ( pdaRun->fsm_tables->transActionsWI[_trans] == 0 ) + goto _again; + + pdaRun->return_result = false; + pdaRun->skip_tokpref = false; + _acts = pdaRun->fsm_tables->actions + pdaRun->fsm_tables->transActionsWI[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + execAction( pdaRun, pdaRun->fsm_tables->action_switch[*_acts++] ); + if ( pdaRun->return_result ) { + if ( pdaRun->skip_tokpref ) + goto skip_tokpref; + goto final; + } + +_again: + _acts = pdaRun->fsm_tables->actions + pdaRun->fsm_tables->to_state_actions[pdaRun->fsm_cs]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + execAction( pdaRun, pdaRun->fsm_tables->action_switch[*_acts++] ); + + if ( pdaRun->fsm_cs == pdaRun->fsm_tables->error_state ) + goto out; + + if ( ++pdaRun->p != pdaRun->pe ) + goto _loop_head; +out: + if ( pdaRun->scan_eof ) { + pdaRun->return_result = false; + pdaRun->skip_tokpref = false; + _acts = pdaRun->fsm_tables->actions + pdaRun->fsm_tables->eof_actions[pdaRun->fsm_cs]; + _nacts = (unsigned int) *_acts++; + + if ( pdaRun->fsm_tables->eof_targs[pdaRun->fsm_cs] >= 0 ) + pdaRun->fsm_cs = pdaRun->fsm_tables->eof_targs[pdaRun->fsm_cs]; + + while ( _nacts-- > 0 ) + execAction( pdaRun, pdaRun->fsm_tables->action_switch[*_acts++] ); + if ( pdaRun->return_result ) { + if ( pdaRun->skip_tokpref ) + goto skip_tokpref; + goto final; + } + } + +final: + + if ( pdaRun->p != 0 ) + pdaRun->tokpref += pdaRun->p - pdaRun->start; +skip_tokpref: + {} +} -- cgit v1.2.1