diff --git a/alib2data/src/automaton/AutomatonFromXMLParser.cpp b/alib2data/src/automaton/AutomatonFromXMLParser.cpp index 59b733fef331c633e97faf8b7e503cc71e05b78e..e7dacefed29c2accf52ff69eefaf15e5bc537882 100644 --- a/alib2data/src/automaton/AutomatonFromXMLParser.cpp +++ b/alib2data/src/automaton/AutomatonFromXMLParser.cpp @@ -65,17 +65,26 @@ Automaton AutomatonFromXMLParser::parseAutomaton(std::list<sax::Token>& input, c if(!features.count(FEATURES::ONE_TAPE_DTM)) throw exception::AlibException(); return Automaton(parseOneTapeDTM(input)); } else - throw sax::ParserException(sax::Token("Automaton / EpsilonNFA / NFA / DFA / CompactNFA / ExtendedNFA / DPDA / SinglePopDPDA / NPDA / SinglePopNPDA / OneTapeDTM", sax::Token::TokenType::START_ELEMENT), input.front()); + throw sax::ParserException(sax::Token("Automaton / EpsilonNFA / NFA / DFA / CompactNFA / ExtendedNFA / DPDA / SinglePopDPDA / InputDrivenNPDA / VisiblyPushdownNPDA / RealTimeHeightDeterministicNPDA / NPDA / SinglePopNPDA / OneTapeDTM", sax::Token::TokenType::START_ELEMENT), input.front()); } bool AutomatonFromXMLParser::first(std::list<sax::Token>& input) const { - if(isToken(input, sax::Token::TokenType::START_ELEMENT, "automaton") || isToken(input, sax::Token::TokenType::START_ELEMENT, "EpsilonNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "CompactNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "ExtendedNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopDPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "InputDrivenNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "VisiblyPushdownNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "OneTapeDTM")) { + if(isToken(input, sax::Token::TokenType::START_ELEMENT, "automaton") || isToken(input, sax::Token::TokenType::START_ELEMENT, "EpsilonNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "CompactNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "ExtendedNFA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "DPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopDPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "InputDrivenNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "VisiblyPushdownNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "RealTimeHeightDeterministicNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "NPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "SinglePopNPDA") || isToken(input, sax::Token::TokenType::START_ELEMENT, "OneTapeDTM")) { return true; } else { return false; } } +template<> +void AutomatonFromXMLParser::parseTransitions(std::list<sax::Token> &input, RealTimeHeightDeterministicNPDA& automaton) const { + popToken(input, sax::Token::TokenType::START_ELEMENT, "transitions"); + while (isTokenType(input, sax::Token::TokenType::START_ELEMENT)) { + parseTransition(input, automaton); + } + popToken(input, sax::Token::TokenType::END_ELEMENT, "transitions"); +} + template<> void AutomatonFromXMLParser::parseTransitions(std::list<sax::Token> &input, VisiblyPushdownNPDA& automaton) const { popToken(input, sax::Token::TokenType::START_ELEMENT, "transitions"); diff --git a/alib2data/test-src/automaton/AutomatonTest.cpp b/alib2data/test-src/automaton/AutomatonTest.cpp index af25df7e30ffbc516f661c6336678f9878f69d32..856d67b0fb5c53b700efb268cbd3ca5affeaac58 100644 --- a/alib2data/test-src/automaton/AutomatonTest.cpp +++ b/alib2data/test-src/automaton/AutomatonTest.cpp @@ -255,7 +255,6 @@ void AutomatonTest::DPDATransitions() { ); automaton.addFinalState(automaton::State(3)); - } void AutomatonTest::testExtendedNFAAlphabet() { @@ -284,3 +283,19 @@ void AutomatonTest::testExtendedNFAAlphabet() { CPPUNIT_ASSERT_NO_THROW(automaton.addTransition(s0, regexp::RegExp{regexp::UnboundedRegExp(goodConcat2)}, s1)); CPPUNIT_ASSERT_NO_THROW(automaton.addTransition(s0, regexp::RegExp{regexp::UnboundedRegExp(regexp::UnboundedRegExpEpsilon())}, s1)); } + +void AutomatonTest::testRHPDATransitions() { + automaton::RealTimeHeightDeterministicNPDA automaton(alphabet::Symbol(alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK)); + automaton.setStates({automaton::State(1), automaton::State(2), automaton::State(3)}); + automaton.setInitialStates({automaton::State(1)}); + + automaton.setInputSymbols({alphabet::symbolFrom("a"), alphabet::symbolFrom("b")}); + automaton.setStackSymbols({alphabet::Symbol(alphabet::BottomOfTheStackSymbol::BOTTOM_OF_THE_STACK), alphabet::symbolFrom("X"), alphabet::symbolFrom("Y")}); + + automaton.addCallTransition(automaton::State(1), alphabet::symbolFrom("a"), automaton::State(2), alphabet::symbolFrom("X")); + automaton.addCallTransition(automaton::State(2), automaton::State(3), alphabet::symbolFrom("X")); + automaton.addReturnTransition(automaton::State(3), alphabet::symbolFrom("Y"), automaton::State(1)); + + automaton.setFinalStates({automaton::State(3)}); + alib::DataFactory::toStdout(automaton); +} diff --git a/alib2data/test-src/automaton/AutomatonTest.h b/alib2data/test-src/automaton/AutomatonTest.h index 1891cdc6a6725661e646459dc44589729c3d259c..c4c2a6ba303ed3013eec4d6ef93fc9ec86bffb41 100644 --- a/alib2data/test-src/automaton/AutomatonTest.h +++ b/alib2data/test-src/automaton/AutomatonTest.h @@ -12,6 +12,7 @@ class AutomatonTest : public CppUnit::TestFixture CPPUNIT_TEST( SinglePopDPDATransitions ); CPPUNIT_TEST( DPDATransitions ); CPPUNIT_TEST( testExtendedNFAAlphabet ); + CPPUNIT_TEST( testRHPDATransitions ); CPPUNIT_TEST_SUITE_END(); public: @@ -24,6 +25,7 @@ public: void SinglePopDPDATransitions(); void DPDATransitions(); void testExtendedNFAAlphabet(); + void testRHPDATransitions(); }; #endif // AUTOMATON_TEST_H_ diff --git a/examples2/automaton/NRHPDA.xml b/examples2/automaton/NRHPDA.xml new file mode 100644 index 0000000000000000000000000000000000000000..4906ee14141b2dbc0f252af676fa311d80e1c6ff --- /dev/null +++ b/examples2/automaton/NRHPDA.xml @@ -0,0 +1,86 @@ +<?xml version="1.0"?> +<RealTimeHeightDeterministicNPDA> + <states> + <IntegerLabel>1</IntegerLabel> + <IntegerLabel>2</IntegerLabel> + <IntegerLabel>3</IntegerLabel> + </states> + <inputAlphabet> + <LabeledSymbol> + <StringLabel>a</StringLabel> + </LabeledSymbol> + <LabeledSymbol> + <StringLabel>b</StringLabel> + </LabeledSymbol> + </inputAlphabet> + <stackAlphabet> + <LabeledSymbol> + <StringLabel>X</StringLabel> + </LabeledSymbol> + <LabeledSymbol> + <StringLabel>Y</StringLabel> + </LabeledSymbol> + <BottomOfTheStackSymbol/> + </stackAlphabet> + <initialStates> + <IntegerLabel>1</IntegerLabel> + </initialStates> + <bottomOfTheStackSymbol> + <BottomOfTheStackSymbol/> + </bottomOfTheStackSymbol> + <finalStates> + <IntegerLabel>3</IntegerLabel> + </finalStates> + <transitions> + <callTransition> + <from> + <IntegerLabel>1</IntegerLabel> + </from> + <input> + <LabeledSymbol> + <StringLabel>a</StringLabel> + </LabeledSymbol> + </input> + <to> + <IntegerLabel>2</IntegerLabel> + </to> + <push> + <LabeledSymbol> + <StringLabel>X</StringLabel> + </LabeledSymbol> + </push> + </callTransition> + <callTransition> + <from> + <IntegerLabel>2</IntegerLabel> + </from> + <input> + <epsilon/> + </input> + <to> + <IntegerLabel>3</IntegerLabel> + </to> + <push> + <LabeledSymbol> + <StringLabel>X</StringLabel> + </LabeledSymbol> + </push> + </callTransition> + <returnTransition> + <from> + <IntegerLabel>3</IntegerLabel> + </from> + <input> + <epsilon/> + </input> + <pop> + <LabeledSymbol> + <StringLabel>Y</StringLabel> + </LabeledSymbol> + </pop> + <to> + <IntegerLabel>1</IntegerLabel> + </to> + </returnTransition> + </transitions> +</RealTimeHeightDeterministicNPDA>