句子:
名词动词
句子连词句
连词:
“和”
“要么”
“但”
名词:
“鸟类”
“鱼”
“C ”
动词:
“规则”
“飞”
“游泳”
文章:
“中的”
写这个语法很简单.它正在实施给我一些麻烦的代码.我的psuedocode为它是:
- main()
- get user input (string words;)
- while loop (cin >> words)
- call sentence()
- end main()
- sentence()
- call noun()
- if noun() call verb() (if verb is true return "OK" ???)(else "not ok"???)
- else if not noun() call article()
- if article() call sentence() (if sentence is true "OK"???)(else "not"?)
- else if not noun() call conjunction()
- if sentence() conjunction() sentence() - no idea how to implement
- return "OK"
- else "not ok"
所以有我非常草率的伪装代码.我有几个关于实施的问题.
>对于单词功能(名词,动词等),我应该如何检查它们是否为真? (如在检查用户的输入是否有鸟,鱼,飞,游泳等)
>我应该如何处理连接调用和输出?
>我应该处理主函数或调用函数的输出吗?
>如果我的伪代码完全错误,上述问题都不重要.基础知识有什么问题吗?
另外值得注意的是,我正在第6章编程:练习和原则使用C,所以我更喜欢使用我已经学习的语言语法,所以属于高级编程类的任何东西都可能不是“ t非常有帮助(练习中具体说不要使用令牌,所以算出来).
提前致谢
最后编辑:在这本书的公共小组中,我问了同样的问题,Bjarne Stroustrup回答说他把练习解决方案放在了网上.他基本上将输入读入了句子函数,并使用if语句返回true或false.不过,他没有使用文章,所以我的复杂性更大.我猜,如果我从这个练习中学到了什么,那么在处理很多用户输入时,标记化是关键的(从目前为止我所知道的).现在我的代码是.我可以稍后回来,因为它还是非常漂亮的,基本上只有在句子好的时候才能返回,不能处理像(名词,连词,句子)这样的东西,但现在我正在继续.
- #include "std_lib_facilities.h"
- bool article(string words)
- {
- if (words == "the")
- return true;
- else return false;
- }
- bool verb(string words)
- {
- if (words == "rules" || words == "fly" || words == "swim")
- return true;
- else return false;
- }
- bool noun(string words)
- {
- if (words == "birds" || words == "fish" || words == "c++")
- return true;
- else return false;
- }
- bool conjunction(string words)
- {
- if (words == "and" || words == "but" || words == "or")
- return true;
- else return false;
- }
- bool sentence()
- {
- string w1;
- string w2;
- string w3;
- string w4;
- cin >> w1;
- if (!noun(w1) && !article(w1)) return false; // grammar of IFS!
- cin >> w2;
- if (noun(w1) && !verb(w2)) return false;
- if (article(w1) && !noun(w2)) return false;
- cin >> w3;
- if (noun(w1) && verb(w2) && (w3 == ".")) return true;
- if (verb(w2) && !conjunction(w3)) return false;
- if (noun(w2) && !verb(w3)) return false;
- if (conjunction(w3)) return sentence();
- cin >> w4;
- if (article(w1) && noun(w2) && verb(w3) && (w4 == ".")) return true;
- if (!conjunction(w4)) return false;
- if (conjunction(w4)) return sentence();
- }
- int main()
- {
- cout << "Enter sentence. Use space then period to end.\n";
- bool test = sentence();
- if (test)
- cout << "OK\n";
- else
- cout << "not OK\n";
keep_window_open();
}
解决方法
这个问题有两个部分:
>词汇分析
>句法分析.
>我们可以忽略Symantic分析,因为这就是为什么.
首先,您将输入流标记为可共鸣令牌.词语将是一个obvios选择,但这将为句法阶段留下大量的工作.所以我会把你的话分成以下类型(Conjunction,Noun,Verb,Article),然后写一个词法分析器来返回正确的Lexems.
- Lexer.cpp
- enum Lexeme { END,Conjunction,Article };
- Lexem getNextLexme(std::istream in)
- {
- std::string word;
- in >> word;
- if (!in) {return END;}
- if (word == "and") return Conjunction;
- else if (word == "birds") return Noun;
- else if (word == "fly") return Verb;
- else if (word == "the") return Article;
- ... etc
- }
所以现在你可以用简化的标记流来描述你的句法解析器.
- bool ParseSentence(std::istream in)
- {
- Lexeme token = getNextLexme(in);
- switch(token)
- {
- case Noun: if (!parseVerb(in))
- { return false;
- }
- return parseConjunctionOrEnd(in);
- case Article: return ParseSentence();
- case END: return true;
- }
- }
- bool parseVerb(std::istream in)
- {
- Lexeme token = getNextLexeme(in);
- if (token != Verb) { /*ERROR*/ return false;}
- return true;
- }
- // etc
语法分析的其他选项是构建状态表.但这涉及手分析语法和确定各州.这应该只是用最简单的语法表达,任何比这里大的东西应该留给可以自动产生状态表的工具.
所以假设我在下面的原始帖子中定义了这个语法:
并希望我得到正确的,因为我不是一个充气工具:-)
- State 1: Start <Nothing Happened>
- Article -> State 2
- Noun -> State 3
- Otherwise Error
- State 2: Seen Article.
- Noun -> State 3
- Otherwise Error
- State 3: Seen Noun in Sentence.
- Verb -> State 4
- Otherwise Error
- State 4: Seen Noun Verb
- End -> State 5
- Conjunction -> State 1
- State 5: Finished:
- State 0: Error State.
- int stateTable[][] // CurrentState,CurrentObject
- = {/*State 0: Error State:*/{},// END,Article
- /*State 1: Start*/ { 0,3,2},/*State 2: Article*/ { 0,0},/*State 3: Noun*/ { 0,4,/*State 4: Noun Verb*/ { 5,1,/*State 5: End*/ {}
- };
- bool parseSentence(std::iostream& in)
- {
- int currentState = 1;
- while((currentState != 0) && (currentState != 5))
- {
- int token = getNextLexme(in);
- currentState = stateTable[currentState][token];
- }
- return currentState == 5;
- }