На самом деле нет никакой новой информации, просто некоторые подробности о том, что @bemace уже упоминало.
Нет, правила лексера не могут иметь возвращаемых значений.См. 4.3 Правила из Определенная ссылка ANTLR :
Аргументы правил и возвращаемые значения
Так же, как вызовы функций, ANTLRПравила синтаксического анализатора и синтаксического анализатора дерева могут иметь аргументы и возвращаемые значения.Правила лексера ANTLR не могут иметь возвращаемых значений [...]
Существует две опции:
Опция 1
Вы можете выполнить преобразование вlong
в правиле парсера number
:
number returns [long value]
: INT {$value = Long.parseLong($INT.text);}
| HEX {$value = Long.parseLong($HEX.text.substring(2), 16);}
;
Опция 2
Или создайте свой собственный токен, который имеет, скажем, метод toLong(): long
:
import org.antlr.runtime.*;
public class YourToken extends CommonToken {
public YourToken(CharStream input, int type, int channel, int start, int stop) {
super(input, type, channel, start, stop);
}
// your custom method
public long toLong() {
String text = super.getText();
int radix = text.startsWith("0x") ? 16 : 10;
if(radix == 16) text = text.substring(2);
return Long.parseLong(text, radix);
}
}
и определите в заголовке options {...}
в вашей грамматике использование этого токена и переопределите метод emit(): Token
в своем классе лексеров:
grammar Foo;
options{
TokenLabelType=YourToken;
}
@lexer::members {
public Token emit() {
YourToken t = new YourToken(input, state.type, state.channel,
state.tokenStartCharIndex, getCharIndex()-1);
t.setLine(state.tokenStartLine);
t.setText(state.text);
t.setCharPositionInLine(state.tokenStartCharPositionInLine);
emit(t);
return t;
}
}
parse
: number {System.out.println("parsed: "+$number.value);} EOF
;
number returns [long value]
: INT {$value = $INT.toLong();}
| HEX {$value = $HEX.toLong();}
;
HEX
: '0' 'x' ('0'..'9'|'a'..'f'|'A'..'F')+
;
INT
: '0'..'9'+
;
Когда вы генерируете парсер и лексер и запускаете этоткласс теста:
import org.antlr.runtime.*;
import java.io.*;
public class Main {
public static void main(String[] args) throws Exception {
ANTLRStringStream in = new ANTLRStringStream("0xCafE");
FooLexer lexer = new FooLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
FooParser parser = new FooParser(tokens);
parser.parse();
}
}
он выдаст следующий вывод:
parsed: 51966
Первые варианты кажутся более практичными в вашем случае.
Обратите внимание, что, как выМожно видеть, что примеры приведены на Java.Я понятия не имею, если вариант 2 поддерживается в цель C / время выполнения.Я решил все еще опубликовать его, чтобы иметь возможность использовать его в качестве будущей ссылки здесь на SO.