C++ 帮助解析S表达式

C++ 帮助解析S表达式,c++,parsing,s-expression,C++,Parsing,S Expression,我正在尝试制作一个简单的绘图程序,可以读入translate(rect 10 10)50。我要做的是将其拆分,使50 50与translate一起使用,rect保留所有10s 这是一个附言填充。我听说过哈希表和堆栈,但我不知道如何使用它们。我已经做了所有其他的事情(例如所有形状的计算)。我只是不知道如何解析这些行,以便能够得到指向正确变量的数字。您的示例看起来像一个Lisp s表达式,所以请尝试搜索“s表达式解析器”。出现了一些命中率 如果你想“完全HOG”,你可以将你的形状例程实现为C++类,

我正在尝试制作一个简单的绘图程序,可以读入
translate(rect 10 10)50
。我要做的是将其拆分,使
50 50
translate
一起使用,
rect
保留所有
10
s


这是一个附言填充。我听说过哈希表和堆栈,但我不知道如何使用它们。我已经做了所有其他的事情(例如所有形状的计算)。我只是不知道如何解析这些行,以便能够得到指向正确变量的数字。

您的示例看起来像一个Lisp s表达式,所以请尝试搜索“s表达式解析器”。出现了一些命中率


如果你想“完全HOG”,你可以将你的形状例程实现为C++类,使用SWIG将它们暴露给GNU GuILE,并在方案中编写应用程序。不过,这可能不是您的想法。:-)

嗯,这可能有点过时,但它很简单,没有比这更快的了

void scanWhite(char*& p){
  while(*p==' ') p++;
}

bool seeInt(char*& p, int& num){
  scanWhite(p);
  char* p1 = p;
  bool bNegative = false;
  if (*p=='-'){bNegative = true; p++;)
  if (!isdigit(*p){p = p1; return false;}
  num = 0;
  while(isdigit(*p)){
    num *= 10;
    num += (*p - '0');
    p++;
  }
  if (bNegative) num = - num;
  return true;
}

bool seeWord(char*& p, char* word){
  scanWhite(p);
  int len = strlen(word);
  if (strncmp(p, word, len)==0 && !isalphanumeric(p[len])){
    p += len;
    return true;
  }
  else return false;
}

bool seeChar(char*& p, char c){
  scanWhite(p);
  if (*p != c) return false;
  p++;
  return true;
}

bool parseTranslateRect(char*& p
  , int& x0, int& y0, int& x1, int& y1
  , int& dx, int& dy
  )
{
  if (!seeChar(p, '(')) return false;
  if (!seeWord(p, "translate")) return false;
  if (!seeChar(p, '(')) return false;
  if (!seeWord(p, "rect")) return false;
  if (!seeInt(p, &x0)) return false;
  if (!seeInt(p, &y0)) return false;
  if (!seeInt(p, &x1)) return false;
  if (!seeInt(p, &y1)) return false;
  if (!seeChar(p, ')')) return false;
  if (!seeInt(p, &dx)) return false;
  if (!seeInt(p, &dy)) return false;
  if (!seeChar(p, ')')) return false;
  return true;
}

如果你有很多的拷贝(翻译(Rect…),只需一遍遍地调用语法分析程序,直到它返回false。

这里,你可以用以下的方式编写这个C++分析器:

这将解析PS文件中的单个translate语句。如果您需要解析所有translate语句,而不想为postscript格式编写完整的解析器,则可以使用
*r\u find(translate)
规则跳过您不关心的输入。
r\u find(r)
rule搜索输入,直到找到规则
R
。现在这很简单,它还将生成非常快的代码,可能比用“if”-s和“else”-s手写的代码要快


免责声明:我不测试上面的代码,所以可能会出现小错误。

您能告诉我们到目前为止您有什么可以帮助我们吗?我想您需要帮助询问有关堆栈溢出的问题!就因为您说“这是PostScript填充”我发现自己想知道为什么你不把字串倒换成词根,然后把它分解成一个基于堆栈的后缀命令语言,比如……嗯……PASScript。或者你可以从字符串的后面读取令牌。当然,如果你这样做,你就不需要括号了。我只限于C++,我不能使用预先制作的库。散列表、堆栈和数组…我只是不知道如何使用它们来读取line@JrTim:“无法使用预制库”…请解释。StackOverflow允许询问有关家庭作业的问题(只要讲师允许),但你应该清楚地说这是家庭作业。如果不是,更好地描述哪些库可以使用,哪些库不能使用(以及为什么使用)会很有帮助。
Rect r;
auto rect = "(rect " 
    & r_decimal(r.left) & space 
    & r_decimal(r.top) & space
    & r_decimal(r.right) & space
    & r_decimal(r.bottom) & space
    & ')';

Point t;
auto translate = "translate " & rect 
    & space & r_decimal(t.x) 
    & space & r_decimal(t.y);
// test it
std::string str("translate (rect 10 10 10 10) 50 50");
auto match = translate(str.begin(), str.end());