CS 330 Lecture 30 – ANTLR and C++
April 18, 2012 by Chris Johnson. Filed under cs330, lectures, spring 2012.
Agenda
- A Cartesian grid walker language
- Translating calculator + functions to C++
TODO
ANTLR C++ REPL
*LANGUAGE*Lexer::InputStreamType input((ANTLR_UINT8 *) "", ANTLR_ENC_8BIT, 0, (ANTLR_UINT8 *) "userinput");
std::string command;
std::cout << "> ";
while (getline(std::cin, command)) {
input.reuse((ANTLR_UINT8 *) command.c_str(), command.length(), (ANTLR_UINT8 *) "userinput");
*LANGUAGE*Lexer lexer(&input);
*LANGUAGE*Parser::TokenStreamType token_stream(ANTLR_SIZE_HINT, lexer.get_tokSource());
*LANGUAGE*Parser parser(&token_stream);
// set up parser as necessary
parser.starting_rule();
std::cout << "> ";
}
Code
makefile
all: cart
CartesianLexer.cpp CartesianParser.cpp: Cartesian.g Player.h
java -jar antlr-3.4-with-cpp.jar Cartesian.g
cart: cart_interpreter.cpp CartesianLexer.cpp CartesianParser.cpp Player.h
g++ -I include -o cart cart_interpreter.cpp CartesianLexer.cpp CartesianParser.cpp
clean:
rm -f CartesianLexer.cpp CartesianParser.cpp cart CartesianLexer.hpp CartesianParser.hpp
Cartesian.g
grammar Cartesian;
options {
language = Cpp;
}
@parser::includes {
#include <iostream>
#include "CartesianLexer.hpp"
#include "Player.h"
}
@lexer::traits {
class CartesianLexer;
class CartesianParser;
typedef antlr3::Traits<CartesianLexer, CartesianParser> CartesianLexerTraits;
typedef CartesianLexerTraits CartesianParserTraits;
}
@context {
private:
Player *player;
public:
void SetPlayer(Player *player);
}
@members {
void CartesianParser::SetPlayer(Player *player) {
this->player = player;
}
}
command
: direction EOF
| LOOK EOF {std::cout << "You are at " << player->x << ", " << player->y << "." << std::endl; }
;
direction
: EAST {++player->x;}
| WEST {--player->x;}
| NORTH {++player->y;}
| SOUTH {--player->y;}
;
LOOK
: 'l'
;
EAST
: 'e'
;
WEST
: 'w'
;
NORTH
: 'n'
;
SOUTH
: 's'
;
cart_interpreter.cpp
#include <iostream>
#include "CartesianLexer.hpp"
#include "CartesianParser.hpp"
#include "Player.h"
int main() {
CartesianLexer::InputStreamType input((ANTLR_UINT8 *) "", ANTLR_ENC_8BIT, 0, (ANTLR_UINT8 *) "userinput");
Player player;
std::string command;
std::cout << "> ";
while (getline(std::cin, command)) {
input.reuse((ANTLR_UINT8 *) command.c_str(), command.length(), (ANTLR_UINT8 *) "userinput");
CartesianLexer lexer(&input);
CartesianParser::TokenStreamType token_stream(ANTLR_SIZE_HINT, lexer.get_tokSource());
CartesianParser parser(&token_stream);
// set up parser as necessary
parser.SetPlayer(&player);
parser.command();
std::cout << "> ";
}
std::cout << "" << std::endl;
}
Player.h
#ifndef PLAYER_H
#define PLAYER_H
struct Player {
int x;
int y;
Player() :
x(0),
y(0) {
}
};
#endif
Haiku
A is solved. B not.
Solve B – A. Not B.
That’s a translation.
show