我正在尝试制作一个简单的绘图程序来读取translate (rect 10 10 10 10) 50 50
. 我要做的是拆分它,以便与 the50 50
一起使用translate
并rect
保留所有10
s。
这是 PostScript 填充。我听说过哈希表和堆栈,但我不确定如何使用它们。我已经完成了其他所有事情(例如所有形状的计算)。我只是不明白如何解析这些行,以便我可以获得指向正确变量的数字。
我正在尝试制作一个简单的绘图程序来读取translate (rect 10 10 10 10) 50 50
. 我要做的是拆分它,以便与 the50 50
一起使用translate
并rect
保留所有10
s。
这是 PostScript 填充。我听说过哈希表和堆栈,但我不确定如何使用它们。我已经完成了其他所有事情(例如所有形状的计算)。我只是不明白如何解析这些行,以便我可以获得指向正确变量的数字。
您的示例看起来像 Lisp s-expression,因此请尝试搜索“s-expression parser”。出现了一些热门歌曲。
如果你想“全心全意”,你可以将你的 shape 例程实现为 C++ 类,使用 SWIG 将它们公开给 GNU Guile,然后在 Scheme 中编写你的应用程序。不过,这可能不是您的想法。:-)
好吧,这可能有点过时,但它很简单,没有什么比这更快的了。
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;
}
如果你有很多“(translate (rect ...”) 的副本,只需一遍又一遍地调用解析例程,直到它返回 false。
以下是使用AX 库编写此 C++ 解析器的方法:
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());
这将解析 PS 文件中的单个翻译语句。如果您需要解析所有翻译语句并且不关心为 postscript 格式编写完整的解析器,您可以使用*r_find(translate)
规则跳过您不关心的输入。r_find(R)
rule 搜索输入,直到R
找到规则。现在这很容易,它还会生成非常快的代码,可能比使用“if”-s 和“else”-s 手写的要快。
免责声明:我没有测试上面的代码,所以可能会出现小错误。