Run Time: 0.000
Ranking (as of 2016-09-17): 154 out of 541
Language: C++
Yet another simple implementation of recursive descent parser.
/*
UVa 10058 - Jimmi's Riddles
To build using Visual Studio 2012:
cl -EHsc -O2 UVa_10058_Jimmis_Riddles.cpp
*/
#include <algorithm>
#include <iostream>
#include <string>
#include <cstring>
#include <cctype>
using namespace std;
const char *ps, *pws, *pwe;
bool get_word(const char** s, const char** e)
{
while (isspace(*ps))
ps++;
*s = ps;
while (*ps && !isspace(*ps))
ps++;
*e = ps;
return *s < *e;
}
enum {COMMA, AND, ARTICLE, NOUN, VERB};
struct word {
int length_;
const char* s_;
};
word articles[] = {
{1, "a"}, {3, "the"}
};
const size_t nr_articles = sizeof(articles) / sizeof(word);
word nouns[] = {
{3, "tom"}, {5, "jerry"}, {5, "goofy"}, {6, "mickey"},
{5, "jimmy"}, {3, "dog"}, {3, "cat"}, {5, "mouse"}
};
const size_t nr_nouns = sizeof(nouns) / sizeof(word);
word verbs[] = {
{4, "hate"}, {4, "love"}, {4, "know"}, {4, "like"}
};
const size_t nr_verbs = sizeof(verbs) / sizeof(word);
bool accept(int wn)
{
if (pws == pwe) {
if (!get_word(&pws, &pwe))
return false;
}
size_t nr_chars = pwe - pws, i;
bool result = false;
switch (wn) {
case COMMA:
result = nr_chars == 1 && *pws == ',';
break;
case AND:
result = nr_chars == 3 && !strncmp(pws, "and", 3);
break;
case ARTICLE:
for (i = 0; i < nr_articles; i++)
if (nr_chars == articles[i].length_ &&
!strncmp(pws, articles[i].s_, articles[i].length_))
break;
result = i < nr_articles;
break;
case NOUN:
for (i = 0; i < nr_nouns; i++)
if (nr_chars == nouns[i].length_ && !strncmp(pws, nouns[i].s_, nouns[i].length_))
break;
result = i < nr_nouns;
break;
case VERB:
for (i = 0; i < nr_verbs; i++)
if (!strncmp(pws, verbs[i].s_, verbs[i].length_)) {
if (nr_chars == verbs[i].length_)
break;
const char* p = pws + verbs[i].length_;
for ( ; p < pwe; p++)
if (*p != 's')
break;
if (p == pwe)
break;
}
result = i < nr_verbs;
break;
}
if (result)
pws = pwe;
return result;
}
void statement(), action(), active_list(), actor();
void statement()
{
action();
while (accept(COMMA))
action();
}
void action()
{
active_list();
if (accept(VERB))
active_list();
else
throw -1;
}
void active_list()
{
actor();
while (accept(AND))
actor();
}
void actor()
{
if (accept(ARTICLE))
;
if (accept(NOUN))
;
else
throw -1;
}
int main()
{
string riddle;
while (getline(cin, riddle)) {
ps = pws = pwe = riddle.c_str();
bool yes = false;
try {
statement();
while (isspace(*pws))
pws++;
if (!*pws)
yes = true;
else
throw -1;
}
catch (int) {
}
cout << ((yes) ? "YES I WILL\n" : "NO I WON'T\n");
}
return 0;
}
No comments:
Post a Comment