1 module ctpg.dsl.typed.combinators; 2 3 import ctpg : parse; 4 5 import ctpg.for_unittest; 6 import ctpg.is_wrapper : isSameType; 7 import ctpg.caller : Caller; 8 import ctpg.input : Input; 9 import ctpg.macro_ : MAKE_RESULT; 10 import ctpg.parse_result : ParseResult, getParseResultType; 11 import ctpg.parser_kind : ParserKind; 12 13 import ctpg.dsl.typed.token : Token, TokenType; 14 import ctpg.dsl.typed.node : Node; 15 16 import parsers = ctpg.parsers; 17 import combinators = ctpg.combinators; 18 19 import compile_time_unittest : enableCompileTimeUnittest; 20 mixin enableCompileTimeUnittest; 21 22 23 // 自動でnodeのlineとfileをセットするようにするコンビネータ 24 template setInfo(alias parser) 25 { 26 template build(alias kind, SrcType) 27 { 28 static if(isSameType!(getParseResultType!(parser.build!(kind, SrcType)), Node)) 29 { 30 mixin MAKE_RESULT!q{ Node }; 31 32 Result parse(Input!SrcType input, in Caller caller) 33 { 34 return combinators.convert! 35 ( 36 combinators.sequence! 37 ( 38 parsers.getLine!(), 39 parsers.getCallerLine!(), 40 parsers.getCallerFile!(), 41 parser 42 ), 43 (size_t line, size_t callerLine, string callerFile, Node node) 44 { 45 node.line = callerLine + line + 1; 46 node.file = callerFile; 47 48 return node; 49 } 50 ).build!(kind, SrcType).parse(input, caller); 51 } 52 } 53 else 54 { 55 static assert(false); 56 } 57 } 58 } 59 60 debug(ctpg) unittest 61 { 62 with(parse!(setInfo!(TestParser!(Node())), ParserKind!(true, true))("")) 63 { 64 assert(match == true); 65 assert(value.line == __LINE__ - 2); 66 assert(value.file == __FILE__); 67 assert(nextInput.source == ""); 68 } 69 } 70 71 72 // パーサが返した文字列と、引数のtokenTypeを使ってNodeを作るコンビネータ 73 template makeNode(alias parser, TokenType tokenType) 74 { 75 template build(alias kind, SrcType) 76 { 77 mixin MAKE_RESULT!q{ Node }; 78 79 Result parse(Input!SrcType input, in Caller caller) 80 { 81 return setInfo! 82 ( 83 combinators.convert! 84 ( 85 parser, 86 (string token) => Node(Token(tokenType, token)) 87 ) 88 ).build!(kind, SrcType).parse(input, caller); 89 } 90 } 91 } 92 93 debug(ctpg) unittest 94 { 95 with(parse!(makeNode!(TestParser!"hoge", TokenType.UNDEFINED), ParserKind!(true, true))("")) 96 { 97 assert(match == true); 98 assert(value.token == Token(TokenType.UNDEFINED, "hoge")); 99 assert(value.line == __LINE__ - 3); 100 assert(value.file == __FILE__); 101 assert(nextInput.source == ""); 102 } 103 }