Вот грамматика, которая почти делает то, что вы хотите:
grammar PrintLang;
sentence
: statement
;
statement
: functionCall '(' argument ')' ';'
{
if ($functionCall.funName.equals("printf")) {
System.out.println($argument.arg);
}
}
;
functionCall returns [String funName]
: ID
{ $funName = $ID.text; }
;
argument returns [String arg]
: STRING
{ $arg = $STRING.text; }
;
ID : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*
;
WS : ( ' '
| '\t'
| '\r'
| '\n'
) {$channel=HIDDEN;}
;
STRING
: '"' ( ESC_SEQ | ~('\\'|'"') )* '"'
;
fragment
HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| UNICODE_ESC
| OCTAL_ESC
;
fragment
OCTAL_ESC
: '\\' ('0'..'3') ('0'..'7') ('0'..'7')
| '\\' ('0'..'7') ('0'..'7')
| '\\' ('0'..'7')
;
fragment
UNICODE_ESC
: '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
Я создал это в AntlrWorks. Все правила токенов были сгенерированы для меня.
Вот файл java для его проверки.
import org.antlr.runtime.*;
public class PrintIt {
public static void main(String args[]) {
String inputString = "printf(\"HelloWorld\");";
// Create an input character stream from standard in
ANTLRStringStream input = new ANTLRStringStream(inputString);
// Create an ExprLexer that feeds from that stream
PrintLangLexer lexer = new PrintLangLexer(input);
// Create a stream of tokens fed by the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
// Create a parser that feeds off the token stream
PrintLangParser plParser = new PrintLangParser(tokens);
try {
plParser.sentence();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Вы заметите, что этот java-код является почти дословным копированием / вставкой из примера на веб-сайте Antlr (я не верю, что я даже изменил комментарии, именно поэтому комментарий ссылается на Standard in, но код фактически использует строка). А вот командная строка, которую я использовал для этого.
bash$ java -cp ./antlr-3.4-complete.jar org.antlr.Tool PrintLang.g
bash$ javac -cp ./:./antlr-3.4-complete.jar PrintIt.java
bash$ java -cp antlr-3.4-complete.jar:. PrintIt
"HelloWorld"
Ой, я забыл, что строка, которую я хотел напечатать, не совпадает с токеном ("HelloWorld", включая кавычки), это строка внутри кавычек.
Также вы заметите, что я жестко закодировал поиск printf как сравнение строк. В действительности вам понадобится среда, которая содержит символы, доступные в данной области видимости (связанные, см. Конструкцию antlr «scope». Более сложная, хотя иногда полезная: создать среду, которую вы передаете каждому правилу синтаксического анализа).
Самое важное: найти ответы Барт Киерс, выполнив поиск SO для получения дополнительных вопросов. Он публикует отлично примеров.