1 using System.Net.Http;
 2 using HttpTokens;
 3 
 4 parser Http
 5 {
 6     uselexer HttpLexer;
 7     
 8     token(var string s) : string
 9         ::= (((chr:ch - (ctl:c | tspecial:t)){ s.Append(ch); })+){ return s; }
10         ;
11         
12     comment(var string s) : string
13         ::= (LPAREN (ctext:ct{ s.Append(ct); } quoted_pair:qp{ s.Append(qp); } | comment:c{ s.Append(c); })* RPAREN){ return s; }
14         ;
15         
16     parameter : Pair<string, string>
17         ::= (attribute:a EQ attrval:av){ return MakePair(a, av); }
18         ;
19         
20     attribute : string
21         ::= token:t{ return t; }
22         ;
23         
24     attrval : string
25         ::= token:t{ return t; } | quoted_string:qs{ return qs; }
26         ;
27 
28     hex : char
29         ::= DIGIT{ return lexer.GetChar(pos); } | HEX{ return lexer.GetChar(pos); }
30         ;
31         
32     chr : char
33         ::= DIGIT{ return lexer.GetChar(pos); } | HEX{ return lexer.GetChar(pos); } | 
34             ALPHA{ return lexer.GetChar(pos); } | HT{ return '\t'; } | DQ{ return '"'; } | CR{ return '\r'; } | LF{ return '\n'; } | 
35             CTL{ return lexer.GetChar(pos); } | SP{ return ' '; } | COLON{ return ':'; } | SEMICOLON{ return ';'; } | COMMA{ return ','; } | DOT{ return '.'; } |
36             LPAREN{ return '('; } | RPAREN{ return ')'; } | LANGLE{ return '<'; } | RANGLE{ return '>'; } | LBRACKET{ return '['; } | RBRACKET{ return ']'; } |
37             LBRACE{ return '{'; } | RBRACE{ return '}'; } | SLASH{ return '/'; } | BACKSLASH{ return '\\'; } | EQ{ return '='; } | CHAR{ return lexer.GetChar(pos); }
38         ;
39         
40     text : char
41         ::= (octet:o - ctl:c){ return o; }
42         ;
43         
44     ctext : char
45         ::= (text:t - (LPAREN | RPAREN)){ return t; }
46         ;
47         
48     quoted_string(var string s) : string
49         ::= (DQ (qdtext:qdt{ s.Append(qdt); } | quoted_pair:qp{ s.Append(qp); })* DQ){ return s; }
50         ;
51 
52     qdtext : char
53         ::= (text:t - DQ){ return t; }
54         ;
55         
56     quoted_pair : char
57         ::= BACKSLASH chr:ch{ return ch; }
58         ;
59 
60     ctl : char
61         ::= HT{ return '\t'; } | CR{ return '\r'; } | LF{ return '\n'; } | CTL{ return lexer.GetChar(pos); }
62         ;
63         
64     tspecial : char
65         ::= LPAREN{ return '('; } | RPAREN{ return ')'; } | LANGLE{ return '<'; } | RANGLE{ return '>'; } | AT{ return '@'; } | COMMA{ return ','; } | SEMICOLON{ return ';'; } | COLON{ return ':'; } |
66             BACKSLASH{ return '\\'; } | DQ{ return '"'; } | SLASH{ return '/'; } | LBRACKET{ return '['; } | RBRACKET{ return ']'; } | QUEST{ return '?'; } | EQ{ return '='; } |
67             LBRACE{ return '{'; } | RBRACE{ return '}'; } | SP{ return ' '; } | HT{ return '\t'; } 
68         ;
69                         
70     octet : char
71         ::= chr:c{ return c; } | OCTET{ return lexer.GetChar(pos); }
72         ;
73 
74     lws
75         ::= ((CR | LF)? (SP | HT))+
76         ;
77 }