58f7807e794077607eef3feecab8056cdefed5f2
[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 SEP: [ \n\r\t]+ -> type(SEP);
51
52 // Special-cased identifier string
53 IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_\-.]* -> type(IDENTIFIER);
54
55 // RFC6020 section 6.1.3:
56 //   If a string contains any space or tab characters, a semicolon (";"),
57 //   braces ("{" or "}"), or comment sequences ("//", "/*", or "*/"), then
58 //   it MUST be enclosed within double or single quotes.
59 //
60 // RFC7950 section 6.1.3:
61 //   An unquoted string is any sequence of characters that does not
62 //   contain any space, tab, carriage return, or line feed characters, a
63 //   single or double quote character, a semicolon (";"), braces ("{" or
64 //   "}"), or comment sequences ("//", "/*", or "*/").
65 //
66 // Since we need tokenization to work in both worlds, we are taking only
67 // RFC6020 with CR/LF clarifications -- and allow quotes to appear in the body
68 // of a string. We additionally exclude COLON, so as to prefer IDENTIFIER
69 // tokenization -- which allows us to make keyword work properly.
70 //
71 // Furthermore we need to exclude PLUS so that concatenation works as expected
72 // when + is not separated by whitespace -- even RFC7950 is far from being
73 // well-specified in this regard.
74 //
75 // The most problematic here is the comment sequence exclusion, as we cannot
76 // just exclude it from productions. We therefore provide single-char
77 // tokenizations of both '*' and '/', and deal with them separately in the
78 // parser.
79 SLASH : '/' -> type(SLASH);
80 STAR : '*' -> type(STAR);
81 UQUOT_STRING :
82     // Any eager span that does not start with single/double quote and does not
83     // have slash/star.
84     ~([ \n\r\t] | [;{}:+] | [/*] | ['"])
85     ~([ \n\r\t] | [;{}:+] | [/*])*
86     -> type(UQUOT_STRING);
87
88 // Double/single-quoted strings. We deal with these using specialized modes.
89 DQUOT_START : '"' -> pushMode(DQUOT_STRING_MODE), skip;
90 SQUOT_START : '\'' -> pushMode(SQUOT_STRING_MODE), skip;
91
92 //
93 // Double-quoted string lexing mode. We do not need to recognize all possible
94 // escapes here -- just enough not to get confused by runs of backslashes and
95 // recognize escaped double quotes.
96 //
97 mode DQUOT_STRING_MODE;
98 DQUOT_STRING : (~["\\] | ('\\' .))+ -> type(DQUOT_STRING);
99 DQUOT_END : '"' -> popMode;
100
101 //
102 // Single-quoted string lexing mode. We do not interpret anything within single
103 // quotes.
104 //
105 mode SQUOT_STRING_MODE;
106 SQUOT_STRING : ~[']+ -> type(SQUOT_STRING);
107 SQUOT_END : '\'' -> popMode;
108