PostScript字符串令牌

编程入门 行业动态 更新时间:2024-10-27 10:20:17
本文介绍了PostScript字符串令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个循环,该循环使用令牌取出字符串中的每个单词,然后我希望能够像这样进行计算:

I have a loop that takes out each word in a string using token, then I want to be able to do computations on it like this:

(1 2加3 4加)

但是无论用什么方式编码,我都会不断得到

But any way you code it i keep getting

7 add 2 1

我要

7 3

这就是我的工作

{ %loop pstack (repl> )print flush (%lineedit)(r)file dup bytesavailable string readstring pop { token {}{exit}ifelse exch dup () eq {pop exec exit}if exec }loop }loop

推荐答案

我建议您最后写堆栈注释每行。

I would advise you to write stack comments at the end of each line. It really helps.

{ %loop pstack (repl> )print flush (%lineedit)(r)file % f dup bytesavailable string readstring pop % s { token % s t b {}{exit}ifelse % s t exch % t s dup () eq {pop exec exit}if % t s exec % t }loop }loop

因此,您正在执行其余的子字符串而不是令牌。在内部循环中的 exec 之前,您还需要另一个 exch 。那将执行令牌而不是子字符串。但是与此有关的一个问题是字符串位于堆栈上。因此 add 将不起作用,因为它将在堆栈顶部找到一个字符串,而不是下面的数字。

So you're executing the remaining substring instead of the token. You need another exch in there before the exec in the inner loop. That would execute the token instead of the substring. But a problem with this is that the string is sitting there on the stack. So add won't work because it will find a string on top of the stack instead of the numbers below.

因此,最好在执行前按名称保存子字符串,然后在下一次迭代之前将其放回去。

So it may be better to save the substring by name before exec-ing, and then put it back before the next iteration.

{ % s token % s t b {}{exit}ifelse % s t exch % t s dup () eq {pop exec exit}if % t s /rem exch def % t exec rem % s }loop

对于刚起步的人来说,这部分可能比帮助更令人困惑。 如果您迷失在中间,请确保从头到尾看到最终的超级简单技术。

后记黑客应该问的下一个问题是:如何在不使用此 rem 名称?

The next question a postscript hacker should ask is: "How can I do this without polluting the name space with this rem name?"

我为此使用的疯狂技巧是利用 loop 运算符具有额外存储空间的过程主体。

The insane trick I would use for this is to exploit the loop operator to make a procedure body with extra storage.

{ procedure body } exec { procedure body exit extra storage } loop

以上两个构造都将执行程序体,然后返回控制。但是,将 loop 与明确的 exit 结合使用,我们可以将多余的东西打包到数组中。

Both constructs above will execute procedure body and then return control. But using loop with an explicit exit lets us pack extra things into the array.

因此,我们从上面进行内循环。

So, we take the inner loop from above.

token{}{exit}ifelse exch dup()eq{pop exec exit}if/rem exch def exec rem

将其包装在出口中-loop。

Wrap it in an "exit-loop".

{ token{}{exit}ifelse exch dup()eq{pop exec exit}if/rem exch def exec rem exit } loop

然后我们要存储 exit 之后的字符串剩余部分。

And we're going to store the string remainder just after exit.

{ token{}{exit}ifelse exch dup()eq{pop exec exit}if/rem exch def exec rem exit STR } loop

用存储在数组中的代码替换 / name exch def 。该数组将是循环主体的子数组,其中仅包含 [STR] 额外的存储空间。

Replace the /name exch def with code that stores into an array. This array will be a subarray of the loop body which just holds the [ STR ] extra storage.

/rem exch def --> ARR exch 0 exch put rem --> ARR 0 get { token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get exit STR } loop

当然,此循环是直截了当的:实际上并没有循环。因此,要从上方替换内部循环,请将其包装在另一个循环中。

This loop is of course a straight-shot: it doesn't actually loop. So to replace the inner loop from above, we wrap it in another loop.

{ { token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get exit STR } loop } loop

然后,我们需要在代码中的 ARR 处插入子数组。这是(内部)内部循环的子数组,其中包含(虚拟) STR 令牌。

Then we need to insert the subarray where ARR is in the code. This is the subarray of the (inner) inner loop that contains the (dummy) STR token.

% 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { { token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get exit STR } loop } loop

子数组[20,1]将插入到数组[10]和数组[16]处。我们可以在外部范围调用 loop 之前完成此操作。

So we need a subarray [20, 1] to be inserted at array[10] and array[16]. And we can do this before calling loop at the outer scope.

{ { token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec ARR 0 get exit STR } loop } dup 0 get % loop-body inner-loop get a copy of the exit-loop dup 20 1 getinterval % loop-body inner-loop [STR] take a subarray of the exit-loop 2 copy 10 exch put % loop-body inner-loop [STR] insert in position 10 16 exch put % loop-body' insert in position 16 loop % call the loop operator

那里是一个没有名字的循环。 :)

There, a loop with no name. :)

注意,我们在代码中仍然有虚拟名称 STR ,这没关系。它将解析为一个名称,并在数组中分配一个额外的插槽。而且不需要在任何地方定义它,因为它永远不会执行。

Notice, we still have the dummy name STR in the code, and that's ok. It will parse as a name and allocate an extra slot in the array. And it doesn't need to be defined anywhere because it never gets executed.

对上述内容的改进。我们确实不需要模板代码中的第二个 ARR 。我们可以将字符串直接存储到过程数组中所需的位置。然后,我们甚至不需要退出循环。因此模板变为:

An improvement over the above. We really do not need the second ARR in the template code. We can store the string directly into the procedure array at the position where it is needed. Then we don't even need the "exit-loop". So the template becomes:

% 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec STR } loop

和完全铰接的循环

{ token{}{exit}ifelse exch dup()eq{pop exec exit}if ARR exch 0 exch put exec STR } dup dup 10 exch % loop loop 10 loop prepare stack 16 1 getinterval % loop loop 10 [STR] take a subarray put % loop insert in position 10 loop % call loop operator

改进的改进。我们实际上也不需要子数组。我们可以将整个循环数组存储在ARR位置,并在存储代码中使用索引16而不是0。

An improvement of the improvement. We don't actually need a subarray either. We can store the entire loop array in the ARR position and use the index 16 instead of 0 in the storing code.

{ token not{exit}if exch dup()eq{pop exec exit}if ARR exch 16 exch put exec STR } dup 10 1 index % loop loop 10 loop prepare stack put % loop insert in position 10 loop % call loop operator

-

更晚的时间...

这比需要的复杂得多。我们可以简单地排列一个数组来对这两件事的执行进行排序。

This is way more complicated than it needs to be. We can simply make a little array to sequence the execution of these two things.

{exec rem}

因此:

{ % s token % s t b not{exit}if % s t exch % t s dup () eq {pop exec exit}if % t s /exec cvx exch 2 array astore cvx % t {exec s} exec }loop

更多推荐

PostScript字符串令牌

本文发布于:2023-10-29 20:36:37,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1540683.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:令牌   字符串   PostScript

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!