• Jump To … +
    data.js dentaku.normal.js env.js evaluator.js fileio.js list.js monad.js monad_transformer.js pair.js parser.js pprinter.js string.js turing.js chap01.spec.js chap02.spec.js chap03.spec.js chap04.spec.js chap05.spec.js chap06.spec.js chap07.spec.js chap08.spec.js data.spec.js dentaku.normal.spec.js evaluator.spec.js interpreter.spec.js list.spec.js monad.spec.js monad_transformer.spec.js pair.spec.js parser.spec.js pprinter.spec.js string.spec.js
  • parser.spec.js

  • ¶
    "use strict";
    
    var expect = require('expect.js');
    var List = require('../lib/list.js');
    var Pair = require('../lib/pair.js');
    var Data = require('../lib/data.js');
    var PP = require('../lib/pprinter.js');
    var Parser = require('../lib/parser.js');
    
    describe('パーサーコンビネーター', () => {
      var abc = List.fromString("abc");
      describe("parse", (next) => {
        it("pure", (next) => {
          expect(
            PP.print(Parser.parse(Parser.pure(1))(abc))
          ).to.eql(
            '[(1,[a,b,c,nil]),nil]'
          );
          next();
        });
        it("item", (next) => {
          expect(
            PP.print(Parser.item(List.empty()))
          ).to.eql(
            '[]'
          );
          expect(
            PP.print(Parser.item(List.fromString("abc")))
          ).to.eql(
            '[(a,[b,c,nil]),nil]'
          );
          next();
        });
      });
      describe("fmap", (next) => {
        it("toUpper", (next) => {
          var input = List.fromString("abc");
          var toUpper = (s) => {
            return s.toUpperCase();
          };
          expect(
            PP.print(
              Parser.parse(Parser.fmap(toUpper)(Parser.item))(input)
            )
          ).to.eql(
            '[(A,[b,c,nil]),nil]'
          );
          next();
        });
      });
      describe("monad", (next) => {
        it("three", (next) => {
          var input = List.fromString("abcdef");
          var three = Parser.flatMap(Parser.item)((x) => {
            return Parser.flatMap(Parser.item)((_) => {
              return Parser.flatMap(Parser.item)((z) => {
                return Parser.pure(Pair.cons(x,z));
              });
            });
          });
          expect(
            PP.print(
              three(input)
            )
          ).to.eql(
            '[((a,c),[d,e,f,nil]),nil]'
          );
          next();
        });
        it("flapMap", (next) => {
            var input = List.fromString("  +  ");
            var add_or_subtract = Parser.alt(Parser.symbol(List.fromString("+")))(Parser.symbol(List.fromString("-")));
            var parser = Parser.flatMap(add_or_subtract)((operator) => {
                return Parser.pure(operator);
            });
            expect(
                PP.print(
                    Parser.parse(parser)(input)
                    )
                ).to.eql('[([+,nil],[]),nil]');
            next();
        });
      });
      describe("alternative", (next) => {
        it("empty", (next) => {
          var input = List.fromString("abc");
          expect(
            PP.print(
              Parser.parse(Parser.empty)(input)
            )
          ).to.eql(
            '[]'
          );
          next();
        });
        it("alt", (next) => {
          var input = List.fromString("abc");
          expect(
            PP.print(
              Parser.parse(
                Parser.alt(Parser.item)(Parser.pure("d"))
              )(input)
            )
          ).to.eql(
            '[(a,[b,c,nil]),nil]'
          );
          expect(
            PP.print(
              Parser.parse(
                Parser.alt(Parser.empty)(Parser.pure("d"))
              )(input)
            )
          ).to.eql(
            '[(d,[a,b,c,nil]),nil]'
          );
          next();
        });
      });
      describe("派生したパーサー", (next) => {
        it("digit", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.digit.call(Parser)
              )(List.fromString("123"))
            )
          ).to.eql(
            '[(1,[2,3,nil]),nil]'
          );
          next();
        });
        it("alphanum", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.alphanum.call(Parser)
              )(List.fromString("123"))
            )
          ).to.eql(
            '[(1,[2,3,nil]),nil]'
          );
    
          next();
        });
        it("string", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.string(List.fromString("abc"))
              )(List.fromString("abcdef"))
            )
          ).to.eql(
            '[([a,b,c,nil],[d,e,f,nil]),nil]'
          );
    
          next();
        });
      });
      describe("manyパーサ", (next) => {
        it("many digit", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.many(Parser.digit.call(Parser))
              )(List.fromString("123abc"))
            )
          ).to.eql(
            '[([1,2,3,nil],[a,b,c,nil]),nil]'
          );
          expect(
            PP.print(
              Parser.parse(
                Parser.many(Parser.digit.call(Parser))
              )(List.fromString("abc"))
            )
          ).to.eql(
            '[([],[a,b,c,nil]),nil]'
          );
          next();
        });
        it("some digit", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.some(Parser.digit.call(Parser))
              )(List.fromString("abc"))
            )
          ).to.eql(
            '[]'
          );
          next();
        });
      });
      it("ident", (next) => {
        expect(
          PP.print(
            Parser.parse(
              Parser.ident.call(Parser)
            )(List.fromString("abc def"))
          )
        ).to.eql(
          '[([a,b,c,nil],[ ,d,e,f,nil]),nil]'
        );
        next();
      });
      it("nat", (next) => {
        expect(
          PP.print(
            Parser.parse(
              Parser.nat.call(Parser)
            )(List.fromString("123"))
          )
        ).to.eql(
          '[(123,[]),nil]'
        );
        next();
      });
      it("space", (next) => {
        expect(
          PP.print(
            Parser.parse(
              Parser.space.call(Parser)
            )(List.fromString("   abc"))
          )
        ).to.eql(
          '[((),[a,b,c,nil]),nil]'
        );
        next();
      });
      it("int", (next) => {
        expect(
          PP.print(
            Parser.parse(
              Parser.int.call(Parser)
            )(List.fromString("-123 abc"))
          )
        ).to.eql(
          '[(-123,[a,b,c,nil]),nil]'
        );
        expect(
          PP.print(
            Parser.parse(
              Parser.int.call(Parser)
            )(List.fromString("123 abc"))
          )
        ).to.eql(
          '[(123,[a,b,c,nil]),nil]'
        );
        next();
      });
      it("float", (next) => {
        expect(
          PP.print(
            Parser.parse(
              Parser.float.call(Parser)
            )(List.fromString("0.1"))
          )
        ).to.eql(
          '[(0.1,[]),nil]'
        );
        expect(
          PP.print(
            Parser.parse(
              Parser.float.call(Parser)
            )(List.fromString("0.123"))
          )
        ).to.eql(
          '[(0.123,[]),nil]'
        );
        expect(
          PP.print(
            Parser.parse(
              Parser.float.call(Parser)
            )(List.fromString("1.1"))
          )
        ).to.eql(
          '[(1.1,[]),nil]'
        );
        expect(
          PP.print(
            Parser.parse(
              Parser.float.call(Parser)
            )(List.fromString("-1.1"))
          )
        ).to.eql(
          '[(-1.1,[]),nil]'
        );
        next();
      });
      describe("トークン", (next) => {
        it("identifier", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.identifier.call(Parser)
              )(List.fromString("   abc"))
            )
          ).to.eql(
            '[([a,b,c,nil],[]),nil]'
          );
          next();
        });
        it("natural", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.natural.call(Parser)
              )(List.fromString("   123   "))
            )
          ).to.eql(
            '[(123,[]),nil]'
          );
          next();
        });
        it("integer", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.integer.call(Parser)
              )(List.fromString("   -123   "))
            )
          ).to.eql(
            '[(-123,[]),nil]'
          );
          next();
        });
        it("numeric", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.numeric.call(Parser)
              )(List.fromString("   -123   "))
            )
          ).to.eql(
            '[(-123,[]),nil]'
          );
          expect(
            PP.print(
              Parser.parse(
                Parser.numeric.call(Parser)
              )(List.fromString("   0.123   "))
            )
          ).to.eql(
            '[(0.123,[]),nil]'
          );
          next();
        });
        it("symbol", (next) => {
          expect(
            PP.print(
              Parser.parse(
                Parser.symbol(List.fromString("+"))
              )(List.fromString("  +  "))
            )
          ).to.eql(
            '[([+,nil],[]),nil]'
          );
          next();
        });
      });
    });