我为一种语言编写语法(下面的示例代码)
//this is a procedure
procedure main()
$i := 0
begin
if ($i = 0)
$i := 10
loop while ($i != 0)
print($i)
$i := $i - 1
end loop
end if
end procedure
的树语法
@members {
private Map<String, Integer> variablesTable = new HashMap<String, Integer>();
}
procedure
: ^('procedure' IDENTIFIER assignment_expression* 'begin' statement+)
;
statement
: assignment_expression | selection_statement
;
assignment_expression
: ^(':=' IDENTIFIER e=expression)
{ variablesTable.put($IDENTIFIER.text, e); }
;
expression returns [int result]
: ^('+' op1=expression op2=expression) { result = op1 + op2; }
/* removed similar lines */
| IDENTIFIER { result = variablesTable.get($IDENTIFIER.text); }
| INTEGER { result = Integer.parseInt($INTEGER.text); }
;
equality_expression returns [boolean truth]
: ^('=' op1=expression op2=expression) { truth = op1 == op2; }
| ^('!=' op1=expression op2=expression) { truth = op1 != op2; }
;
selection_statement
: ^('if' e=equality_expression block1=statement+ ('else' block2=statement+)? )
{
if (e) {
//What do I put here?
}
}
;
虽然我可以评估表达式,打印消息等,但我无法弄清楚如何更改程序的执行(解释)。
与上面的代码一样,对于if-else,如果谓词为true,我如何执行if-block,并跳转到else(如果有)?
循环也是如此,如何在循环结束时评估循环谓词?
谢谢!
答案 0 :(得分:3)
在树语法中嵌入代码仅适用于非常简单的语言(计算器等)。嵌入它将(IMO)导致混合语法规则,编程逻辑和规则参数以及规则返回值的难以理解的混乱。几乎每个规则都需要至少一个boolean
值,以跟踪是否需要执行它的(子)规则(是否在if
- 或else
块内?)。
在解释由if
- 和while
语句组成的语言时,尽可能简单,我建议创建自定义树/节点并对其进行评估。
我写了一个博客系列,展示了如何做到这一点:http://bkiers.blogspot.com/2011/03/creating-your-own-programming-language.html