Lex 0.1

囲碁の棋譜フォーマット SGF の構文解析処理 (parsing / syntactic analysis) を作る前段階として、字句解析 (lexical analysis) のクラス Lex を作成し、Jasmine という単体テストのフレームワークを使ってテストしてみました。

ドキュメント

JsDoc Toolkit で作成したドキュメントはこちら

ソース


lextest01.html

このソースコードは Jasmine のサンプル SpecRunner.html から大部分を持ってきました。前半はスタイルシートとスクリプトを読み込んでいる部分です。
<head>
<meta charset="UTF-8">
<title>JavaScriptでプログラミング - Lex 0.1</title>

<link type="text/css" rel="stylesheet" href="lib/jasmine-1.3.1/jasmine.css">
<link type="text/css" rel="stylesheet" href="css/spec.css">
<link type="text/css" rel="stylesheet" href="css/shCoreEclipse.css">
<link type="text/css" rel="stylesheet" href="css/shThemeEclipse.css">
<script type="text/javascript" src="js/XRegExp.js"></script>
<script type="text/javascript" src="js/shCore.js"></script>
<script type="text/javascript" src="js/shBrushJScript.js"></script>
<script type="text/javascript" src="js/shBrushXml.js"></script>
<script type="text/javascript" src="js/shBrushCss.js"></script>
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-1.3.1/jasmine-html.js"></script>

<!-- include source files here... -->
<script type="text/javascript" src="js/lex01/lex01.js"></script>

<!-- include spec files here... -->
<script type="text/javascript" src="js/lex01/lexspec01.js"></script>
後半は Jasmine によるテスト結果を HTML 上で展開するレポーターと呼ばれる部分です。
<script type="text/javascript">
  SyntaxHighlighter.all();
  (function() {
    var jasmineEnv = jasmine.getEnv();
    jasmineEnv.updateInterval = 1000;

    var htmlReporter = new jasmine.HtmlReporter();

    jasmineEnv.addReporter(htmlReporter);

    jasmineEnv.specFilter = function(spec) {
      return htmlReporter.specFilter(spec);
    };

    var currentWindowOnload = window.onload;

    window.onload = function() {
      if (currentWindowOnload) {
        currentWindowOnload();
      }
      execJasmine();
    };

    function execJasmine() {
      jasmineEnv.execute();
    }

  })();
</script>

lex01.js

クラス Lex のソースコードです。字句解析のためのツールです。 リンク先をご覧下さい。

lexspec01.js

このソースでは Lex のテスト仕様を定義しています。Jasmine のサンプル PlayerSpec.js を参考に作成しました。
describe("Lex 仕様 0.1", function() {
  var exp = "1+2=";
  var la;
  var retval;

  beforeEach(function() {
    la = new Lex(exp);	// Lexical Analiser
  });

  it("eod() は false を返す", function() {
    expect(la.eod()).toBeFalsy();
  });

  it("digit() は '1' を返す", function() {
    expect(la.digit()).toEqual('1');
  });

  it("upper() は null を返す", function() {
    expect(la.upper()).toBeNull();
  });

  it("lower() は null を返す", function() {
    expect(la.lower()).toBeNull();
  });

  it("ch('1') は '1' を返す", function() {
    expect(la.ch('1')).toEqual('1');
  });

  describe("3文字読んだ時点で、", function() {
    beforeEach(function() {
      la.rewind();
      la.digit();
      la.ch('+');
      la.digit();
    });

    it("eod() は false を返す", function() {
      expect(la.eod()).toBe(false);
    });

    it("digit() は null を返す", function() {
      expect(la.digit()).toBe(null);
    });

    it("upper() は null を返す", function() {
      expect(la.upper()).toBe(null);
    });

    it("lower() は null を返す", function() {
      expect(la.lower()).toEqual(null);
    });

    it("ch('=') は '=' を返す", function() {
      expect(la.ch('=')).toBe('=');
    });

  });

  describe("4文字読んだ時点で、", function() {
    beforeEach(function() {
      la.rewind();
      la.digit();
      la.ch('+');
      la.digit();
      la.ch('=');
    });

    it("eod() は true を返す", function() {
      expect(la.eod()).toBeTruthy();
    });

  });

});

テスト結果