Sprawdzanie zdania pod kątem poprawności zgodnie z gramatyką

0

Cześć, mam napisać program sprawdzający poprawność zdania zgodnie z gramatyką języka angielskiego. Każde zdanie kończy się kropką otoczoną białymi znakami np. birds fly but the fish swim . jest zdanie, a birds fly but the fish swim (brak kropki na końcu) i birds fly but the fish swim. (brak spacji przed kropką) nie. Dla każdego wpisanego zdania program ma zwracać tylko prostą odpowiedź Dobrze lub Źle. Pogubiłem się przy pisaniu funkcji sentence. Chciałem aby funkcja sprawdzała czy przekazany string jest poprawnym zdaniem. Postanowiłem więc wczytać łańcuch do strumienia, wyodrębnić pojedyńcze słowa w pętli, jeśli obecne słowo i następne są zgodnie z gramatyką Noun i Verb to zwrócić true, jeśli występuje spójnik to przekazać co zostało z wykluczeniem wczytanych słów ze strumenia do funkcji sentence i z powrotem wykonać sprawdzanie, dopóki funkcja nie zwróci true lub false. Dobrze ja to w ogóle robię? Chcę się upewnić czy dobry mam tok rozumowania czy inaczej mam to rozgryźć.

P2150001.JPG

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

class Words_stream {
public:
    Words_stream() : full{false} { }
    string get();
    void putback(const string& word);
private:
    string buffer;
    bool full;
};

string Words_stream::get() {
    if (full) {
        full = false;
        return buffer;
    }

    string word;
    cin >> word;
    return word;
}

void Words_stream::putback(const string& word) {
    if (full)
        throw runtime_error("Strumień jest już pełny.");
    full = true;
    buffer = word;
}

Words_stream wst;

bool verb(const string& word) {
    return word == "rules" || word == "fly" || word == "swim";
}

bool noun(const string& word) {
    return word == "birds" || word == "fish" || word == "C++";
}

bool conjunction(const string& word) {
    return word == "and" || word == "or" || word == "but";
}

bool sentence(const string& str) {
    istringstream iss(str);
    string word;
    while (iss >> word) {
        string next_word;
        iss >> next_word;
//        if (noun(word) && verb(next_word)) {
//            return true;
//        } else if (conjunction(next_word)) {
//            return sentence(iss.str());
//        } else {
//            return false;
//        }
    }
}

int main() {
    cout << "Wpisz zdanie: ";
    string str;
    for (string word; cin >> word && word != "."; ) {
        str += word + " ";
    }
    bool correct = sentence(str);
    if (correct) {
        cout << "Dobrze.\n";
    } else {
        cout << "Źle.\n";
    }
    return 0;
}


2

W ramach czego to zadanie?
Przedmiot z transatorów / gramatyk, czy ogólne C++ ?

Na kartce jest jakaś wzmianka o innych zdaniach.

BTW przyznajemy +100 punktów do lansu za fotografowanie komórką skośnie, komisja przyznała ci dodatkowe +50 za zwiniętą kartkę

2

Dobrze ja to w ogóle robię? Chcę się upewnić czy dobry mam tok rozumowania czy inaczej mam to rozgryźć.

Parsowanie języków naturalnych to niewyobrażalnie złożona działka - czy zależy Ci na tym, aby Twój program był w stanie rozgryźć takie zdania jak https://pl.wikipedia.org/wiki/Buffalo_buffalo_Buffalo_buffalo_buffalo_buffalo_Buffalo_buffalo czy https://en.wikipedia.org/wiki/Time_flies_like_an_arrow;_fruit_flies_like_a_banana? :-)

1

Na początek może tokenizacja zaś logikę dodać w postaci regexpa:

#include <iostream>
#include <sstream>
#include <vector>
#include <exception>
#include <unordered_map>
using namespace std;

class UnknownWordException:public exception {};

char PartOfSpeechFind(const string &word)
{
	static const unordered_map<string,char> map
	{
		{
			{"rules",'v'},
			{"fly",'v'},
			{"swim",'v'},
			{"birds",'n'},
			{"fish",'n'},
			{"C++",'n'},
			{"and",'c'},
			{"or",'c'},
			{"but",'c'},
		}
	};
	try { return map.at(word); }
	catch(...) { throw UnknownWordException(); }
};

string sentence(istringstream &sin)
{
	ostringstream sout;
	for(string word;sin>>word;) sout<<PartOfSpeechFind(word);
    return sout.str();
}

int main()
{
	istringstream sin("birds fly but fish swim");
	cout<<sentence(sin)<<endl;
    return 0;
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1