-3

出于某种原因,我的程序似乎无法在使用 Code Blocks 12.11 的计算机或使用 VMware 的教授计算机上运行,​​但它在两个使用 Visual C++ 2012 的同学计算机上运行良好。因为我的计算机在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 回答