#P17047. [SGU215] PL/Cool

[SGU215] PL/Cool

题目描述

新的 IMB 编译器 Unvisual Age for PL/Cool 即将发布。你的任务是实现 PL/Cool 语言的解释器。

PL/Cool 程序由若干行语句组成,每行恰好是一条语句。语言中只有两种语句:printdefine

表达式

表达式由非负整数常量、变量、括号以及下列运算符组成:

  • +:加法;
  • -:减法;
  • *:乘法;
  • /:整数除法;
  • %:取模;
  • ^:乘方。

优先级从高到低为:

  1. 一元 +、一元 -
  2. ^
  3. */%
  4. +-

^ 外,其余同级二元运算均从左到右计算;^ 从右到左结合

例如,2^2^32^(2^3) 计算。

括号可以像通常一样改变计算顺序。

除法和取模

PL/Cool 的 /% 与部分编程语言对负数的处理方式不同。

对于 a / b

  1. 先取 |a||b|
  2. 做整数除法并舍去余数;
  3. 最后根据真实商 a/b 的正负决定结果符号。

对于 a % b,过程相同,但保留余数、舍去商,并同样按照真实商的符号决定余数符号。

例如:

(80+4*75)/(56-2^2^3) = -1

变量

变量名:

  • 以英文字母开头;
  • 后面可以包含英文字母或数字;
  • 长度不超过 1010
  • 不区分大小写

print

语法:

print <expression>

计算表达式并输出其值。

define

语法:

define <operand1> <operand2>

其中两个操作数都只能是:

  • 变量;或
  • 非负整数常量。

执行后,程序中所有出现的 operand1 都会被递归替换成 operand2

例如:

define 2 4

之后常量 2 的值实际上变为 4,因此 2+2 的值为 8

替换会递归进行,直到到达一个没有继续定义的操作数。

如果试图再次定义一个已经定义过的变量或常量,这条 define 被忽略

如果一条定义会产生循环依赖,这条定义同样被忽略

如果表达式中的某个标识符最终不能递归替换成一个整数常量,则它的值视为 0

输入格式

输入为一段 PL/Cool 程序,直到文件结束。

保证:

  • define 语句总数不超过 3000030000
  • print 语句总数不超过 20002000
  • 每行长度不超过 200200
  • 表达式中直接出现的数,以及表达式求值过程中出现的所有数,其绝对值均不超过 10910^9
  • 除法和取模的除数不会为 00
  • 不会出现 000^0
  • 乘方运算的指数始终为非负整数。

输出格式

对于每一条 print 语句,按照执行顺序输出一行,表示对应表达式的值。

样例 1

样例输入

print (80+4*75)/(56-2^ 2^ 3)
print 30/-1
print 31%-5
print 0^3
print 2+2
define 2 3
print 2+2
define 3 x
print 2+2
define x 2
print 2+2
define 2 5
print 2+2
define x 7
print 2+2

样例输出

-1
-30
-1
0
4
6
0
0
0
14