1 module tcenal.dsl.parsers; 2 3 import compile_time_unittest : enableCompileTimeUnittest; 4 5 import tcenal.parser_combinator.token : Token; 6 import tcenal.parser_combinator.parsing_result : ParsingResult; 7 import tcenal.parser_combinator.parse_tree_node : ParseTreeNode; 8 import tcenal.parser_combinator.memo : Memo; 9 import tcenal.parser_combinator.combinators : parseToken, parseTokenWithType, applyRule, sequence, select, choice, option, zeroOrMore, oneOrMore, zeroOrMoreWithSeparator, oneOrMoreWithSeparator, not; 10 import tcenal.parser_combinator.util : parseWithoutMemo; 11 import tcenal.dsl.lexer : lex; 12 13 import std.ascii : isWhite, isAlpha, isAlphaNum; 14 15 mixin enableCompileTimeUnittest; 16 17 18 ParsingResult rules(Token[] input, size_t position, ref Memo memo) 19 { 20 return applyRule!(oneOrMore!rule)(input, position, memo); 21 } 22 23 24 ParsingResult rule(Token[] input, size_t position, ref Memo memo) 25 { 26 return applyRule!( 27 sequence!( 28 select!(0, 29 parseTokenWithType!"identifier", 30 parseToken!"<-", 31 ), 32 choiceExpr, 33 ) 34 )(input, position, memo); 35 } 36 unittest 37 { 38 Memo memo; 39 with (rule(lex(q{foo <- foo "foo" / "foo"}), 0, memo)) 40 { 41 assert (success); 42 assert (nextPosition == 6); 43 assert (node.ruleName == "rule"); 44 assert (node.children[0].ruleName == "#sequence"); 45 assert (node.children[0].children[0].token.value == "foo"); 46 assert (node.children[0].children[0].token.type == "identifier"); 47 assert (node.children[0].children[1].ruleName == "choiceExpr"); 48 assert (node.children[0].children[1].children[0].ruleName == "#repeat"); 49 assert (node.children[0].children[1].children[0].children[0].ruleName == "sequenceExpr"); 50 assert (node.children[0].children[1].children[0].children[0].children[0].ruleName == "#repeat"); 51 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].ruleName == "prefixExpr"); 52 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].ruleName == "postfixExpr"); 53 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 54 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "ruleName"); 55 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.value == "foo"); 56 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.type == "identifier"); 57 assert (node.children[0].children[1].children[0].children[0].children[0].children[1].ruleName == "prefixExpr"); 58 assert (node.children[0].children[1].children[0].children[0].children[0].children[1].children[0].ruleName == "postfixExpr"); 59 assert (node.children[0].children[1].children[0].children[0].children[0].children[1].children[0].children[0].ruleName == "primaryExpr"); 60 assert (node.children[0].children[1].children[0].children[0].children[0].children[1].children[0].children[0].children[0].ruleName == "tokenValue"); 61 assert (node.children[0].children[1].children[0].children[0].children[0].children[1].children[0].children[0].children[0].children[0].token.value == "foo"); 62 assert (node.children[0].children[1].children[0].children[0].children[0].children[1].children[0].children[0].children[0].children[0].token.type == "stringLiteral"); 63 assert (node.children[0].children[1].children[0].children[1].ruleName == "sequenceExpr"); 64 assert (node.children[0].children[1].children[0].children[1].children[0].ruleName == "#repeat"); 65 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].ruleName == "prefixExpr"); 66 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].ruleName == "postfixExpr"); 67 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 68 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].children[0].children[0].ruleName == "tokenValue"); 69 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].token.value == "foo"); 70 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].token.type == "stringLiteral"); 71 } 72 } 73 74 75 ParsingResult choiceExpr(Token[] input, size_t position, ref Memo memo) 76 { 77 return applyRule!( 78 oneOrMoreWithSeparator!( 79 sequenceExpr, 80 parseToken!"/" 81 ) 82 )(input, position, memo); 83 } 84 unittest 85 { 86 Memo memo; 87 with (choiceExpr(lex(q{foo !bar / buz+ / "foobar"}), 0, memo)) 88 { 89 assert (success); 90 assert (nextPosition == 8); 91 assert (node.ruleName == "choiceExpr"); 92 assert (node.children[0].ruleName == "#repeat"); 93 assert (node.children[0].children[0].ruleName == "sequenceExpr"); 94 assert (node.children[0].children[0].children[0].ruleName == "#repeat"); 95 assert (node.children[0].children[0].children[0].children[0].ruleName == "prefixExpr"); 96 assert (node.children[0].children[0].children[0].children[0].children[0].ruleName == "postfixExpr"); 97 assert (node.children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 98 assert (node.children[0].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "ruleName"); 99 assert (node.children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.value == "foo"); 100 assert (node.children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.type == "identifier"); 101 assert (node.children[0].children[0].children[0].children[1].ruleName == "prefixExpr"); 102 assert (node.children[0].children[0].children[0].children[1].children[0].ruleName == "#sequence"); 103 assert (node.children[0].children[0].children[0].children[1].children[0].children[0].token.value == "!"); 104 assert (node.children[0].children[0].children[0].children[1].children[0].children[1].ruleName == "postfixExpr"); 105 assert (node.children[0].children[0].children[0].children[1].children[0].children[1].children[0].ruleName == "primaryExpr"); 106 assert (node.children[0].children[0].children[0].children[1].children[0].children[1].children[0].children[0].ruleName == "ruleName"); 107 assert (node.children[0].children[0].children[0].children[1].children[0].children[1].children[0].children[0].children[0].token.value == "bar"); 108 assert (node.children[0].children[0].children[0].children[1].children[0].children[1].children[0].children[0].children[0].token.type == "identifier"); 109 assert (node.children[0].children[1].ruleName == "sequenceExpr"); 110 assert (node.children[0].children[1].children[0].ruleName == "#repeat"); 111 assert (node.children[0].children[1].children[0].children[0].ruleName == "prefixExpr"); 112 assert (node.children[0].children[1].children[0].children[0].children[0].ruleName == "postfixExpr"); 113 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].ruleName == "#sequence"); 114 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 115 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "ruleName"); 116 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.value == "buz"); 117 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.type == "identifier"); 118 assert (node.children[0].children[1].children[0].children[0].children[0].children[0].children[1].token.value == "+"); 119 assert (node.children[0].children[2].ruleName == "sequenceExpr"); 120 assert (node.children[0].children[2].children[0].ruleName == "#repeat"); 121 assert (node.children[0].children[2].children[0].children[0].ruleName == "prefixExpr"); 122 assert (node.children[0].children[2].children[0].children[0].children[0].ruleName == "postfixExpr"); 123 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 124 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].ruleName == "tokenValue"); 125 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].token.value == "foobar"); 126 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].token.type == "stringLiteral"); 127 } 128 } 129 130 131 ParsingResult sequenceExpr(Token[] input, size_t position, ref Memo memo) 132 { 133 return applyRule!(oneOrMore!prefixExpr)(input, position, memo); 134 } 135 unittest 136 { 137 Memo memo; 138 with (sequenceExpr(lex(q{foo !bar buz+ "foobar"}), 0, memo)) 139 { 140 assert (success); 141 assert (nextPosition == 6); 142 assert (node.ruleName == "sequenceExpr"); 143 assert (node.children[0].ruleName == "#repeat"); 144 assert (node.children[0].children[0].ruleName == "prefixExpr"); 145 assert (node.children[0].children[0].children[0].ruleName == "postfixExpr"); 146 assert (node.children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 147 assert (node.children[0].children[0].children[0].children[0].children[0].ruleName == "ruleName"); 148 assert (node.children[0].children[0].children[0].children[0].children[0].children[0].token.value == "foo"); 149 assert (node.children[0].children[0].children[0].children[0].children[0].children[0].token.type == "identifier"); 150 assert (node.children[0].children[1].ruleName == "prefixExpr"); 151 assert (node.children[0].children[1].children[0].ruleName == "#sequence"); 152 assert (node.children[0].children[1].children[0].children[0].token.value == "!"); 153 assert (node.children[0].children[1].children[0].children[1].ruleName == "postfixExpr"); 154 assert (node.children[0].children[1].children[0].children[1].children[0].ruleName == "primaryExpr"); 155 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].ruleName == "ruleName"); 156 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].token.value == "bar"); 157 assert (node.children[0].children[1].children[0].children[1].children[0].children[0].children[0].token.type == "identifier"); 158 assert (node.children[0].children[2].ruleName == "prefixExpr"); 159 assert (node.children[0].children[2].children[0].ruleName == "postfixExpr"); 160 assert (node.children[0].children[2].children[0].children[0].ruleName == "#sequence"); 161 assert (node.children[0].children[2].children[0].children[0].children[0].ruleName == "primaryExpr"); 162 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].ruleName == "ruleName"); 163 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].token.value == "buz"); 164 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].token.type == "identifier"); 165 assert (node.children[0].children[2].children[0].children[0].children[1].token.value == "+"); 166 assert (node.children[0].children[3].ruleName == "prefixExpr"); 167 assert (node.children[0].children[3].children[0].ruleName == "postfixExpr"); 168 assert (node.children[0].children[3].children[0].children[0].ruleName == "primaryExpr"); 169 assert (node.children[0].children[3].children[0].children[0].children[0].ruleName == "tokenValue"); 170 assert (node.children[0].children[3].children[0].children[0].children[0].children[0].token.value == "foobar"); 171 assert (node.children[0].children[3].children[0].children[0].children[0].children[0].token.type == "stringLiteral"); 172 } 173 } 174 175 176 ParsingResult prefixExpr(Token[] input, size_t position, ref Memo memo) 177 { 178 return applyRule!( 179 choice!( 180 sequence!( 181 choice!( 182 parseToken!"&", 183 parseToken!"!" 184 ), 185 postfixExpr 186 ), 187 postfixExpr 188 ) 189 )(input, position, memo); 190 } 191 unittest 192 { 193 Memo memo; 194 with (prefixExpr(lex(q{&foo}), 0, memo)) 195 { 196 assert (success); 197 assert (nextPosition == 2); 198 assert (node.ruleName == "prefixExpr"); 199 assert (node.children[0].ruleName == "#sequence"); 200 assert (node.children[0].children[0].token.value == "&"); 201 assert (node.children[0].children[1].ruleName == "postfixExpr"); 202 assert (node.children[0].children[1].children[0].ruleName == "primaryExpr"); 203 assert (node.children[0].children[1].children[0].children[0].ruleName == "ruleName"); 204 assert (node.children[0].children[1].children[0].children[0].children[0].token.value == "foo"); 205 assert (node.children[0].children[1].children[0].children[0].children[0].token.type == "identifier"); 206 } 207 } 208 209 210 ParsingResult postfixExpr(Token[] input, size_t position, ref Memo memo) 211 { 212 return applyRule!( 213 choice!( 214 sequence!( 215 primaryExpr, 216 choice!( 217 parseToken!"*", 218 parseToken!"+", 219 ), 220 option!( 221 select!(1, 222 parseToken!"<", 223 choiceExpr, 224 parseToken!">", 225 ) 226 ) 227 ), 228 sequence!( 229 primaryExpr, 230 parseToken!"?", 231 ), 232 primaryExpr 233 ) 234 )(input, position, memo); 235 } 236 unittest 237 { 238 with (parseWithoutMemo!postfixExpr(lex(q{foo*}))) 239 { 240 assert (success); 241 assert (nextPosition == 2); 242 assert (node.ruleName == "postfixExpr"); 243 assert (node.children[0].ruleName == "#sequence"); 244 assert (node.children[0].children[0].ruleName == "primaryExpr"); 245 assert (node.children[0].children[0].children[0].ruleName == "ruleName"); 246 assert (node.children[0].children[0].children[0].children[0].token.value == "foo"); 247 assert (node.children[0].children[0].children[0].children[0].token.type == "identifier"); 248 assert (node.children[0].children[1].token.value == "*"); 249 assert (node.children[0].children[2].ruleName == "#option"); 250 assert (node.children[0].children[2].children.length == 0); 251 } 252 with (parseWithoutMemo!postfixExpr(lex(q{foo*<foo>}))) 253 { 254 assert (success); 255 assert (nextPosition == 5); 256 assert (node.ruleName == "postfixExpr"); 257 assert (node.children[0].ruleName == "#sequence"); 258 assert (node.children[0].children[0].ruleName == "primaryExpr"); 259 assert (node.children[0].children[0].children[0].ruleName == "ruleName"); 260 assert (node.children[0].children[0].children[0].children[0].token.value == "foo"); 261 assert (node.children[0].children[0].children[0].children[0].token.type == "identifier"); 262 assert (node.children[0].children[1].token.value == "*"); 263 assert (node.children[0].children[2].ruleName == "#option"); 264 assert (node.children[0].children[2].children[0].ruleName == "choiceExpr"); 265 assert (node.children[0].children[2].children[0].children[0].ruleName == "#repeat"); 266 assert (node.children[0].children[2].children[0].children[0].children[0].ruleName == "sequenceExpr"); 267 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].ruleName == "#repeat"); 268 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].ruleName == "prefixExpr"); 269 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "postfixExpr"); 270 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "primaryExpr"); 271 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].ruleName == "ruleName"); 272 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.value == "foo"); 273 assert (node.children[0].children[2].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].children[0].token.type == "identifier"); 274 } 275 } 276 277 278 ParsingResult primaryExpr(Token[] input, size_t position, ref Memo memo) 279 { 280 return applyRule!( 281 choice!( 282 select!(1, 283 parseToken!"(", 284 choiceExpr, 285 parseToken!")" 286 ), 287 tokenValue, 288 tokenType, 289 select!(0, 290 ruleName, 291 not!(parseToken!"<-") 292 ) 293 ) 294 )(input, position, memo); 295 } 296 unittest 297 { 298 Memo memo; 299 with (primaryExpr(lex(q{foo}), 0, memo)) 300 { 301 assert (success); 302 assert (nextPosition == 1); 303 assert (node.ruleName == "primaryExpr"); 304 assert (node.children[0].ruleName == "ruleName"); 305 assert (node.children[0].children[0].token.value == "foo"); 306 assert (node.children[0].children[0].token.type == "identifier"); 307 } 308 309 memo = memo.init; 310 assert (!primaryExpr(lex(q{foo <-}), 0, memo).success); 311 } 312 313 314 ParsingResult ruleName(Token[] input, size_t position, ref Memo memo) 315 { 316 return applyRule!(parseTokenWithType!"identifier")(input, position, memo); 317 } 318 319 320 ParsingResult tokenValue(Token[] input, size_t position, ref Memo memo) 321 { 322 return applyRule!(parseTokenWithType!"stringLiteral")(input, position, memo); 323 } 324 325 326 ParsingResult tokenType(Token[] input, size_t position, ref Memo memo) 327 { 328 return applyRule!(select!(1, parseToken!"@", parseTokenWithType!"identifier"))(input, position, memo); 329 }