自从毕业学校以来,我没有以正式方式构建语言或解析器,并且忘记了当时我所知道的大部分内容。我现在有一个可能从这样的事情中受益的项目,但我不确定如何处理以下情况。
假设在我要解析的语言中有一个令牌,表示在表达式中“生成一个随机浮点数”。
exp: NUMBER
{$$ = $1;}
| NUMBER PLUS exp
{$$ = $1 + $3;}
| R PLUS exp
{$$ = random() + $3;}
;
我还想要一个“list”生成运算符,它将重新评估“exp”一些次数。也许像:
listExp: NUMBER COLON exp
{
for (int i = 0; i < $1; i++) {
print $3;
}
}
;
我看到的问题是,循环开始时“exp”已经减少了。如果我有输入
2 : R + 2
然后我认为随机数将在解析“exp”并添加2时生成 - 假设结果为2.0055。然后在列表表达式中我认为2.0055将被打印两次。
有没有办法在评估之前标记“exp”,然后按照列表循环计数的要求解析它多次?想法是在每次评估中获得不同的随机数。
答案 0 :(得分:4)
最好的办法是在解析结束时构建AST并评估整个AST。在线评估只适用于非常简单(即“类似计算器”)的项目。
您可以为堆栈或三地址虚拟机构建代码,而不是AST。这通常更有效,特别是如果您打算经常执行代码,但AST构建起来要简单得多,执行它是一次深度优先扫描。
答案 1 :(得分:0)
根据您的语言设计,至少有5个不同的点可以将语言中的标记绑定到某个值。他们是:
如果您有一个可以多次出现的令牌,并且您希望每次都为其分配一个不同的随机值,那么第4阶段就是这样做的地方。如果生成AST,请遍历树并分配值。如果您直接进行代码生成(或解释器),那么就这样做。