
#include <string>
#include <cstdio>
#include <cstring>
#include "../bnf.hpp"  // 適当なパスに修正してください


using namespace std;


// コールバック関数の例
bool semantic_action(
    void * option, char const * rule_name, int start, int len)
{
  static string matched = "";
  
  if (len < 0)
  {
    // メタ情報はこのサンプルでは無視
  }
  else if (strcmp(rule_name, "rule") == 0)
  {
    printf("マッチしたルール:%s\n", matched.c_str());
  }
  else
  {
    // マッチしたルールをメモしていく
    matched += " ";
    matched += rule_name;
  }

  return true;  // 戻り値は，実は現バージョンでは使われていません．わらぃ
}

// 改良版コールバック関数の例
bool semantic_action2(
    void * option, char const * rule_name, int start, int len)
{
  static string foo_buf = "";
  static string bar_or_baz_buf = "";

  if (len < 0)
  {
    // メタ情報はこのサンプルでは無視
  }
  else if (strcmp(rule_name, "rule") == 0)
  {
    printf("マッチしたルール: %s\n", (foo_buf + " " + bar_or_baz_buf).c_str());
  }
  else if (strcmp(rule_name, "foo") == 0)
  {
    foo_buf = rule_name;
  }
  else if (strcmp(rule_name, "bar") == 0
      || strcmp(rule_name, "baz") == 0)
  {
    bar_or_baz_buf = rule_name;
  }

  return true;
}

// おためし
int main()
{
  try
  {
    // ルールを与えてパーザを初期化
    bnf::BnfParser c (
           "rule ::= foo bar | foo baz \n"
           "foo  ::= 'foo' \n"
           "bar  ::= 'bar' \n"
           "baz  ::= 'baz'");

    // データを解析
    // コールバックとして semantic_action を与えるか semantic_action2 を
    // 与えるかによって動作が変わる事を確認してください．
    c.parse("foobaz", "rule", 0, semantic_action);

  }
  catch (...)
  {
    puts("something wrong");
  }
}


