#list #antlr #typechecking
#Список #antlr #проверка типов
Вопрос:
Я работаю над ANLTR для поддержки проверки типов. В какой-то момент у меня проблемы. Я попытаюсь объяснить это с помощью примера грамматики, предположим, что у меня есть следующее:
@members {
private java.util.HashMap<String, String> mapping = new java.util.HashMap<String, String>();
}
var_dec
: type_specifiers d=dec_list? SEMICOLON
{
mapping.put($d.ids.get(0).toString(), $type_specifiers.type_name);
System.out.println("identext = " $d.ids.get(0).toString() " - " $type_specifiers.type_name);
};
type_specifiers returns [String type_name]
: 'int' { $type_name = "int";}
| 'float' {$type_name = "float"; }
;
dec_list returns [List ids]
: ( a = ID brackets*) (COMMA ( a = ID brackets* ) )*
{$ids = $a;}
;
brackets : LBRACKET (ICONST | ID) RBRACKET;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
LBRACKET : '[';
RBRACKET : ']';
В правиле dec_list
вы увидите, что я возвращаю список с идентификаторами. Однако, var_dec
когда я пытаюсь поместить первый элемент списка (я использую get(0)
только для просмотра возвращаемого значения из dec_list
правила, я могу повторить его позже, это не моя точка зрения) в сопоставление, я получаю целую строку, например
[@4,6:6='a',<17>,1:6]
для ввода
int a, b;
Что я пытаюсь сделать, так это получить текст каждого идентификатора, в данном случае a
и b
в списке индексов 0 и 1 соответственно.
У кого-нибудь есть идеи?
Ответ №1:
=
Оператор создает a List
из Token
s, а не только текст Token
, которому соответствуют эти s. Вам нужно будет инициализировать List
в @init{...}
блоке правила и добавить внутренний текст токенов самостоятельно.
Кроме того, вам не нужно этого делать:
type_specifiers returns [String type_name]
: 'int' { $type_name = "int";}
| ...
;
просто получите доступ type_specifiers
к text
атрибуту из правила, в котором вы его используете, и удалите returns
инструкцию, например:
var_dec
: t=type_specifiers ... {System.out.println($t.text);}
;
type_specifiers
: 'int'
| ...
;
Попробуйте что-то вроде этого:
grammar T;
var_dec
: type dec_list? ';'
{
System.out.println("type = " $type.text);
System.out.println("ids = " $dec_list.ids);
}
;
type
: Int
| Float
;
dec_list returns [List ids]
@init{$ids = new ArrayList();}
: a=ID {$ids.add($a.text);} (',' b=ID {$ids.add($b.text);})*
;
Int : 'int';
Float : 'float';
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Space : ' ' {skip();};
который выведет на консоль следующее:
type = int
ids = [a, b, foo]
Если вы запустите следующий класс:
import org.antlr.runtime.*;
public class Main {
public static void main(String[] args) throws Exception {
TLexer lexer = new TLexer(new ANTLRStringStream("int a, b, foo;"));
TParser parser = new TParser(new CommonTokenStream(lexer));
parser.var_dec();
}
}