lexer.tri (1368B)
1 !import 6aa33a710955e5746f322775b9078f57ba4145f6b723ff4b76a292285e919823 * 2 !import 14282088469cc420dd014700da06998f6bb8dcf990fc885a464c0a1e1858e20d * 3 !import 816df1a32853750a1254112aff8ae8c55ca86bf70e809d226969ab1d43a6688b * 4 !import 7f87549d587fa8c3be88af0ea988db3adcc3b35f1ffb48973553491b075614db as N 5 !export scanWord 6 !export scanWhitespace 7 8 -- Positioned prefix scans, not whole-input parsers. The remainder begins 9 -- at the first nonmatching character. Positions count source characters, 10 -- not UTF-8 bytes or display columns: only LF advances the line. 11 -- Edit a predicate below and evaluate scanWord "hello,world" to compare. 12 -- scanWhitespace accepts space, LF and tab, but deliberately not CR. 13 report reply = (let 14 payload = parserReplyPayload reply 15 end = snd payload 16 in [ 17 ["matched" 0 (fst payload)] 18 ["remaining" 0 (parserReplyRest reply)] 19 ["line" 1 (lexerPositionLine end)] 20 ["column" 1 (lexerPositionColumn end)] 21 ["offset" 1 (lexerPositionOffset end)] 22 ["consumed" 2 (parserReplyConsumed reply)]]) 23 24 scan predicate text = report (lexerMapScan reverse 25 (lexerScanWhile text lexerStart [] predicate (state character : pair character state))) 26 scanWord text = scan (character : N.inRange character 97 122) text 27 scanWhitespace text = scan (character : or? (equal? character 32) 28 (or? (equal? character 9) (equal? character 10))) text