Run Time: 0.000
Ranking (as of 2016-09-16): 290 out of 808
Language: C++
Another simple implementation of recursive descent parser.
/* UVa 134 - Loglan-A Logical Language To build using Visual Studio 2012: cl -EHsc -O2 UVa_134_Loglan-A_Logical_Language.cpp */ #include <algorithm> #include <iostream> #include <string> #include <cctype> using namespace std; string sentence; const char *ps, *pws, *pwe; bool get_word_or_name(const char** s, const char** e) { while (isspace(*ps)) ps++; *s = ps; while (*ps && !isspace(*ps) && *ps != '.') ps++; *e = ps; return *s < *e; } bool is_vowel(char c) { return c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u'; } enum {A, MOD, BA, DA, LA, NAM, PREDA}; bool accept(int wn) { if (pws == pwe) { if (!get_word_or_name(&pws, &pwe)) return false; } bool result = false; switch (wn) { case A: result = pwe - pws == 1 && is_vowel(*pws); break; case MOD: result = pwe - pws == 2 && *pws == 'g' && is_vowel(*(pws + 1)); break; case BA: result = pwe - pws == 2 && *pws == 'b' && is_vowel(*(pws + 1)); break; case DA: result = pwe - pws == 2 && *pws == 'd' && is_vowel(*(pws + 1)); break; case LA: result = pwe - pws == 2 && *pws == 'l' && is_vowel(*(pws + 1)); break; case NAM: result = pwe > pws && !is_vowel(*(pwe - 1)); break; case PREDA: result = pwe - pws == 5 && !is_vowel(*pws) && (!is_vowel(*(pws + 1)) && is_vowel(*(pws + 2)) || is_vowel(*(pws + 1)) && !is_vowel(*(pws + 2))) && !is_vowel(*(pws + 3)) && is_vowel(*(pws + 4)); break; } if (result) pws = pwe; return result; } void predclaim(), preds(), predname(), predstring(), statement(), verbpred(); void predclaim() { if (accept(DA)) preds(); else { predname(); if (accept(BA)) preds(); else throw -1; } } void preds() { predstring(); while (accept(A)) predstring(); } void predname() { if (accept(LA)) predstring(); else if (accept(NAM)) ; else throw -1; } void predstring() { if (accept(PREDA)) { while (accept(PREDA)) ; } else throw -1; } void statement() { predname(); verbpred(); if (*ps && *ps != '.') predname(); } void verbpred() { if (accept(MOD)) predstring(); else throw -1; } int main() { while (true) { string line; getline(cin, line); if (line[0] == '#') break; sentence.clear(); while (true) { sentence += line; if (sentence.find_first_of('.') != string::npos) break; sentence += ' '; getline(cin, line); } #ifdef DEBUG cout << sentence << endl; #endif // transform(sentence.begin(), sentence.end(), sentence.begin(), (int(*)(int))tolower); bool good = false; try { ps = pws = pwe = sentence.c_str(); statement(); if (*ps == '.') good = true; else throw -1; } catch (int) { try { ps = pws = pwe = sentence.c_str(); predclaim(); if (*ps == '.') good = true; } catch (int) { } } cout << ((good) ? "Good\n" : "Bad!\n"); } return 0; }
No comments:
Post a Comment