teaching machines

CS 330 Lecture 30 – ANTLR and C++

April 18, 2012 by . Filed under cs330, lectures, spring 2012.

Agenda

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.