简而言之:如何在 ANTLR 中实现动态变量?
我再次带着一个基本的 ANTLR 问题来找你。
我有这个语法:
grammar Amethyst;
options {
language = Java;
}
@header {
package org.omer.amethyst.generated;
import java.util.HashMap;
}
@lexer::header {
package org.omer.amethyst.generated;
}
@members {
HashMap memory = new HashMap();
}
begin: expr;
expr: (defun | println)*
;
println:
'println' atom {System.out.println($atom.value);}
;
defun:
'defun' VAR INT {memory.put($VAR.text, Integer.parseInt($INT.text));}
| 'defun' VAR STRING_LITERAL {memory.put($VAR.text, $STRING_LITERAL.text);}
;
atom returns [Object value]:
INT {$value = Integer.parseInt($INT.text);}
| ID
{
Object v = memory.get($ID.text);
if (v != null) $value = v;
else System.err.println("undefined variable " + $ID.text);
}
| STRING_LITERAL
{
String v = (String) memory.get($STRING_LITERAL.text);
if (v != null) $value = String.valueOf(v);
else System.err.println("undefined variable " + $STRING_LITERAL.text);
}
;
INT: '0'..'9'+ ;
STRING_LITERAL: '"' .* '"';
VAR: ('a'..'z'|'A'..'Z')('a'..'z'|'A'..'Z'|'0'..'9')* ;
ID: ('a'..'z'|'A'..'Z'|'0'..'9')+ ;
LETTER: ('a..z'|'A'..'Z')+ ;
WS: (' '|'\t'|'\n'|'\r')+ {skip();} ;
到目前为止,它所做的(或应该做的)是有一个内置的“println”函数来做你认为它做的事情,以及一个定义变量的“defun”规则。
当对字符串或整数调用“defun”时,该值被放入“memory”HashMap,第一个参数是变量名,第二个参数是它的值。
当对原子调用 println 时,它应该显示原子的值。原子可以是字符串或整数。它从内存中获取它的值并返回它。例如:
defun greeting "Hello world!"
println greeting
但是当我运行这段代码时,我得到了这个错误:
line 3:8 no viable alternative at input 'greeting'
null
注意:当我这样做时,会出现此输出:
println "greeting"
输出:
undefined variable "greeting"null
有谁知道为什么会这样?对不起,如果我不清楚,我不明白这一点。