-3

何らかの理由で、コード ブロック 12.11 を使用する私のコンピューターまたは VMware を使用する私の教授のコンピューターでは、私のプログラムは動作しないようですが、Visual C++ 2012 を使用する 2 人のクラスメートのコンピューターでは完全に正常に動作します。 Windows XP では、Visual C++ 2012 も 2010 も使用できないため、コード ブロックを使用する必要があります。私のプログラムは、ファイルから文字列のリストを読み取り、それらの文字列が BNF 文法に含まれているかどうかを確認するように設計されています。

エラーは出力されません。プログラムは正常にコンパイルされますが、私または私の教授のコンピューターで実行すると出力がありません。

編集: 期待される出力は、それを読み取るテキスト ファイルの名前を要求することです。次に、ファイル内の各文字列に対して、その文字列が言語に含まれているかどうかにかかわらず、プログラムは出力する必要があります。ファイルが存在しない場合、プログラムは「操作に失敗しました」と出力します。これの代わりに、プログラムは「終了するには任意のキーを押してください」に直接進みます。これは、プログラムの実行が既に終了したときにのみ表示されると想定されています。

/* This is a recursive descent parser that uses the following productions. The
   '||' operator stands for concatenation. The '|' operator for alternatives.

P_statement -> P_Identifier = P_Expression | P_Expression
P_Expression -> P_Term + P_Expression | P_Term - P_Expression | P_Term
P_Term -> P_Factor * P_Term | P_Factor / P_Term | P_Factor
P_Factor -> P_Exponential ^ P_Factor | P_Exponential
P_Exponential -> P_Identifier | L | UI | UL | (P_statement)
P_Unary -> + | - | !
P_Identifier -> P_Character | P_Character||P_Identifier
P_Character -> a | b | ... | y | z
P_Number -> P_Digit | P_Digid||P_Number
P_Digit -> 0 | 1 | ... | 8 | 9
*/

#include <iostream>
#include <string>
#include <fstream>

using std::cout;
using std::cin;
using std::endl;
using std::ifstream;
using std::ios;
using std::ofstream;
using std::string;

// The functions that test whether the current string matches a particular
// production, hence the 'P_' prefix.
bool P_statement(void);
bool P_Expression(void);
bool P_Term(void);
bool P_Factor(void);
bool P_Exponential(void);
bool P_Unary(void);
bool P_Identifier(void);
bool P_Character(void);
bool P_Number(void);
bool P_Digit(void);

string s;

int main(){
   string mystr;
   cout << "What is your text file? ";
   cin >> mystr;
   ifstream input(mystr.c_str());

   if(input.is_open()){
      while(input.good()){
         getline(input, s);
         string C = s;
         if (P_statement() && s == ""){
            cout << "The string \"" << C << "\" is in the language." <<endl;
         }
         else {
            cout << "The string \"" << C << "\" is not in the language." <<endl;
         }
      }
      input.close();
   }
   else cout << "Operation failed" << endl;

   return 0;
}

bool P_statement(void) {

   if (P_Identifier()) {
      if (s[0] == '=') {
         s = s.substr(1);
         if (P_Expression()) {
            return true;
         }
      }
      s = s.substr(1);
   }
   if(P_Expression()){
      return true;
   }
   return false;
}

bool P_Expression(void) {

  if (P_Term()) {
     if (s[0] == '+' || s[0] == '-') {
         s = s.substr(1);
         if (P_Expression()) {
            return true;
         }
     }
     return true;
  }
  return false;
}

bool P_Term(void) {

   if(P_Factor()){
      if (s[0]=='*' || s[0]=='/'){
         s = s.substr(1);
         if (P_Term()) {
            return true;
         }
      }
      return true;
   }
   return false;
}

bool P_Factor(void){
   if (P_Exponential()) {
      if (s[0] == '^') {
         s = s.substr(1);
         if (P_Factor()) {
            return true;
         }
      }
      return true;
   }
   return false;
}

bool P_Exponential(void){
   if(P_Identifier()){
      return true;
   }
   else if(P_Number()){
      return true;
   }
   else if(P_Unary()){
      if (P_Identifier()){
         return true;
      }
      else if(P_Number()){
         return true;
      }
   }
   else if (s[0] == '(') {
      s = s.substr(1);
      if (P_statement()) {
         if (s[0] == ')') {
            s = s.substr(1);
            return true;
         }
      }
   }
   return false;
}

bool P_Unary(void){
   if (s[0] =='+' || s[0]=='-' || s[0]=='!'){
      s = s.substr(1);
      return true;
   }
   return false;
}

bool P_Identifier(void) {
   if(P_Character()) {
      if(P_Identifier()){
         return true;
      }
      return true;
   }
   return false;
}

bool P_Character(void){
   if ('a' <= s[0] && s[0] <= 'z') {
      s = s.substr(1);
      return true;
   }
   return false;
}

bool P_Number(void) {
   if(P_Digit()){
      if(P_Number()){
         return true;
      }
      return true;
   }
   return false;
}

bool P_Digit(void){
   if ('0' <= s[0] && s[0] <= '9') {
      s = s.substr(1);
      return true;
   }
   return false;
}
4

3 に答える 3

2

テスト関数には副作用があり、グローバル文字列s. 文字列の長さをチェックせずに、配列インデックスを文字列に使用します。ほとんどの場合、未定義の動作が発生します。これは、プラットフォーム間のバリエーションの原因である可能性があります。

ただし、実際の問題は、コードが不明確であり、実際に何をするかを理解する価値がないことです。

アップデート:

「エラーは出力されません」および「出力はありません」と言います。これは、コード ブロックでの標準ライブラリの動作が異なるため、std::cout をフラッシュしないのと同じくらい簡単な場合があります。最初のメッセージの最後と同じよう<< endlに、フラッシュされたバッファが得られるかどうかを確認してください。コード内の未定義の動作に関する私の他のコメントは引き続き適用されますが、メッセージがまったく表示されない場合は、最初の問題である可能性があります。

于 2013-03-25T06:20:14.343 に答える
1

書かれたプログラムは、この無効なステートメントを受け入れ、それを有効と呼びます。

a=(a7-62)^2

識別子に数字を使用できないため、このプログラムはあなたの文法では有効ではありません。しかし、あなたのプログラムはそれを受け入れます。

なぜそうなるかを理解し、問題を修正すると、プログラムはさまざまなプラットフォームでより予測可能な動作をするようになります。

于 2013-03-25T06:36:06.240 に答える
-3
bool A(void);
bool E(void);
bool T(void);
bool F(void);
bool P(void);
bool U(void);
bool I(void);
bool C(void);
bool L(void);
bool D(void);

いいえ。

于 2013-03-25T05:56:42.950 に答える