Use correct key-arg splitting
[yangtools.git] / yang / yang-parser-antlr / src / main / antlr4 / org / opendaylight / yangtools / yang / parser / antlr / YangStatementLexer.g4
1 //
2 // Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3 //
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 // and is available at http://www.eclipse.org/legal/epl-v10.html
7 //
8 lexer grammar YangStatementLexer;
9
10 tokens {
11     SEMICOLON,
12     LEFT_BRACE,
13     RIGHT_BRACE,
14     SEP,
15     IDENTIFIER,
16     COLON,
17     PLUS,
18     SLASH,
19     STAR,
20     DQUOT_STRING,
21     SQUOT_STRING,
22     UQUOT_STRING
23 }
24
25 SEMICOLON : ';' -> type(SEMICOLON);
26 LEFT_BRACE : '{' -> type(LEFT_BRACE);
27 RIGHT_BRACE : '}' -> type(RIGHT_BRACE);
28 COLON : ':' -> type(COLON);
29 PLUS : '+' -> type(PLUS);
30
31 // RFC6020 section 6.1.1:
32 //   Comments are C++ style.  A single line comment starts with "//" and
33 //   ends at the end of the line.  A block comment is enclosed within "/*"
34 //   and "*/".
35 //
36 // RFC7950 section 6.1.1:
37 //   Comments are C++ style.  A single line comment starts with "//" and
38 //   ends at the end of the line.  A block comment starts with "/*" and
39 //   ends with the nearest following "*/".
40 //
41 //   Note that inside a quoted string (Section 6.1.3), these character
42 //   pairs are never interpreted as the start or end of a comment.
43 //
44 // What constitutes 'end of the line' is not specified in RFC7950, hence
45 // we are using RFC7950-clarified definition. Note we also need to handle
46 // the case of EOF, as the user may not have included a newline.
47 LINE_COMMENT : '//' .*? '\r'? ('\n' | EOF) -> skip;
48 BLOCK_COMMENT : '/*' .*? '*/' -> skip;
49
50 // Note: if this changes, also update KeyStatementSupport's Splitter
51 SEP: [ \n\r\t]+ -> type(SEP);
52
53 // Special-cased identifier string
54 IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_\-.]* -> type(IDENTIFIER);
55
56 // RFC6020 section 6.1.3:
57 //   If a string contains any space or tab characters, a semicolon (";"),
58 //   braces ("{" or "}"), or comment sequences ("//", "/*", or "*/"), then
59 //   it MUST be enclosed within double or single quotes.
60 //
61 // RFC7950 section 6.1.3:
62 //   An unquoted string is any sequence of characters that does not
63 //   contain any space, tab, carriage return, or line feed characters, a
64 //   single or double quote character, a semicolon (";"), braces ("{" or
65 //   "}"), or comment sequences ("//", "/*", or "*/").
66 //
67 // Since we need tokenization to work in both worlds, we are taking only
68 // RFC6020 with CR/LF clarifications -- and allow quotes to appear in the body
69 // of a string. We additionally exclude COLON, so as to prefer IDENTIFIER
70 // tokenization -- which allows us to make keyword work properly.
71 //
72 // Furthermore we need to exclude PLUS so that concatenation works as expected
73 // when + is not separated by whitespace -- even RFC7950 is far from being
74 // well-specified in this regard.
75 //
76 // The most problematic here is the comment sequence exclusion, as we cannot
77 // just exclude it from productions. We therefore provide single-char
78 // tokenizations of both '*' and '/', and deal with them separately in the
79 // parser.
80 SLASH : '/' -> type(SLASH);
81 STAR : '*' -> type(STAR);
82 UQUOT_STRING :
83     // Any eager span that does not start with single/double quote and does not
84     // have slash/star.
85     ~([ \n\r\t] | [;{}:+] | [/*] | ['"])
86     ~([ \n\r\t] | [;{}:+] | [/*])*
87     -> type(UQUOT_STRING);
88
89 // Double/single-quoted strings. We deal with these using specialized modes.
90 DQUOT_START : '"' -> pushMode(DQUOT_STRING_MODE), skip;
91 SQUOT_START : '\'' -> pushMode(SQUOT_STRING_MODE), skip;
92
93 //
94 // Double-quoted string lexing mode. We do not need to recognize all possible
95 // escapes here -- just enough not to get confused by runs of backslashes and
96 // recognize escaped double quotes.
97 //
98 mode DQUOT_STRING_MODE;
99 DQUOT_STRING : (~["\\] | ('\\' .))+ -> type(DQUOT_STRING);
100 DQUOT_END : '"' -> popMode;
101
102 //
103 // Single-quoted string lexing mode. We do not interpret anything within single
104 // quotes.
105 //
106 mode SQUOT_STRING_MODE;
107 SQUOT_STRING : ~[']+ -> type(SQUOT_STRING);
108 SQUOT_END : '\'' -> popMode;
109