1 6 package tests.jfun.parsec.rfc822; 7 8 9 10 import jfun.parsec.pattern.CharPredicates; 11 12 import jfun.parsec.Scanners; 13 import jfun.parsec.pattern.Patterns; 14 import jfun.parsec.Lexers; 15 import jfun.parsec.Parsers; 16 import jfun.parsec.Parser; 17 import jfun.parsec.Tokenizer; 18 import jfun.parsec.tokens.TokenString; 19 import jfun.parsec.Maps; 20 import jfun.parsec.Map; 21 import jfun.parsec.pattern.CharPredicate; 22 import jfun.parsec.pattern.Pattern; 23 28 public final class LexicalRules { 29 private static Parser range(int a, int b, String err){ 30 return Scanners.isChar(CharPredicates.range((char)a, (char)b), err); 31 } 32 public static final Parser backslash = Scanners.isChar('\\'); 33 public static final Parser lbracket = Scanners.isChar('['); 34 public static final Parser rbracket = Scanners.isChar(']'); 35 public static final Parser crlf = Scanners.isString("\r\n", "CRLF"); 36 public static final Parser chr = range(0, 127, "ascii character"); 37 public static final Parser alpha = 38 Scanners.isChar(CharPredicates.isAlpha()); 39 public static final Parser digit = 40 Scanners.isChar(CharPredicates.isDigit()); 41 public static final Parser ctl = Parsers.plus( 42 Scanners.isChar((char)127), range(0,31, "control character") 43 ); 44 public static final Parser cr = Scanners.isChar('\r'); 45 public static final Parser lf = Scanners.isChar('\n'); 46 public static final Parser space = Scanners.isChar(' '); 47 public static final Parser htab = Scanners.isChar('\t'); 48 public static final Parser quote = Scanners.isChar('"'); 49 public static final Pattern lwsp_char = 50 Patterns.among(new char[]{' ','\t'}); 51 public static final Parser lwsp = 52 Scanners.isPattern( 53 Patterns.isString("\r\n").optional().seq(lwsp_char).many1(), 54 "lwsp"); 55 static final char[] ops = new char[]{ 57 '(',')','<','>','@',',',';',':','\\','"','.','[',']' 58 }; 59 public static final Parser specials = Scanners.among(ops); 60 public static final Parser ctext = Parsers.plus( 61 lwsp, 62 cr.not("CR").seq(chr) 63 ); 64 public static final Parser quoted_pair = 65 Scanners.isChar('\\').seq(chr); 66 public static final Parser comment = 67 Scanners.isNestableBlockComment( 68 "(", ")", Parsers.plus(quoted_pair, ctext) 69 ); 70 public static final Parser delimiters = Parsers.plus( 71 specials, lwsp, comment 72 ); 73 public static final Parser text = crlf.not("CRLF").seq(chr); 74 public static final Parser atom_char = Parsers.plus( 75 specials, space, ctl 76 ) 77 .not("[specials, space, control]") 78 .seq(chr); 79 public static final Parser atom = atom_char.many1(); 80 public static final Parser qtext = Parsers.plus( 81 lwsp, 82 Scanners.isPattern( 83 Patterns.among(new char[]{'"','\\','\r'}).not(), 84 "^[quote, backslash, CR]") 85 .seq(chr) 86 ); 87 public static final Parser quoted_string = 88 Scanners.quoted(quote, quote, Parsers.plus(qtext, quoted_pair)); 89 public static final Parser dtext = Parsers.plus( 90 lwsp, 91 Scanners.isPattern( 92 Patterns.among(new char[]{'[',']','\\','\r'}).not(), 93 "^[square brackets, backslash, CR]") 94 .seq(chr) 95 ); 96 public static final Parser domain_literal = 97 Scanners.quoted(lbracket, rbracket, 98 Parsers.plus(dtext, quoted_pair)); 99 public static final Parser delim = 100 Parsers.plus(lwsp, comment).many(); 101 private static final Map to_token = Maps.toToken(); 102 public static Parser toLexer(final Parser s, final Tokenizer tn){ 103 return Lexers.lexer(s, tn).map(to_token); 104 } 105 public static Parser toStringLexer(final Parser s){ 106 return toLexer(s, TokenString.getTokenizer()); 107 } 108 public static final Parser s_atom = toStringLexer(atom); 109 public static final Parser s_quoted_string = 110 toStringLexer(quoted_string); 111 public static final Parser s_domain_literal = 112 toStringLexer(domain_literal); 113 public static Parser lexeme(final Parser p){ 114 return p.followedBy(delim.step(0)); 115 } 116 117 public static Parser isChar(char c){ 118 return lexeme(Scanners.isChar(c)); 119 } 120 public static Parser isChar(CharPredicate cp, String msg){ 121 return lexeme(Scanners.isChar(cp, msg)); 122 } 123 private static final Parser comma = isChar(','); 124 private static final Parser commas = comma.many1(); 125 public static Parser list(Parser p, final Class etype){ 126 return Parsers.sepBy(etype, commas, p); 127 } 128 public static Parser list1(Parser p, final Class etype){ 129 return Parsers.sepBy1(etype, commas, p); 130 } 131 public static Parser keyword(final String s){ 132 return lexeme( 133 toStringLexer(Scanners.isStringCI(s) 134 .followedBy(atom_char.not())) 135 ); 136 } 137 public static Object runParser(CharSequence src, final Parser p){ 138 return Parsers.runParser(src, 139 delim.seq(p).followedBy(Parsers.eof()), "rfc822 parser"); 140 } 141 } 142 | Popular Tags |