Skip to content

Commit fa130ae

Browse files
committed
rollup merge of rust-lang#20330: fhahn/issue-15877-model-lexer-range-2
This patch resolves the second problem mentioned in rust-lang#15877: function calls to integers, e.g. `3.b()`. It does so, by checking whether the character following the first dot of a FLOAT_LIT is a character or an underscore (these should denote a valid identifier). This does not look like a particularly, but it seems like a lookahead of 1 is needed for this distinction. Another interesting aspect are ranges that start with a integer constant, but end with a function call, e.g. `1..b()`. Rust treats this as a range from 1 to `b()`, but given that `1.` is a valid FLOAT_LIT, `1..b()` could be a function call to a float as well. cc @cmr
2 parents ecf48fb + 1e278c1 commit fa130ae

File tree

3 files changed

+77
-4
lines changed

3 files changed

+77
-4
lines changed

src/grammar/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Reference grammar.
22

33
Uses [antlr4](http://www.antlr.org/) and a custom Rust tool to compare
4-
ASTs/token streams generated. You can use the `check-syntax` make target to
4+
ASTs/token streams generated. You can use the `check-lexer` make target to
55
run all of the available tests.
66

77
To use manually:
@@ -12,7 +12,7 @@ javac *.java
1212
rustc -O verify.rs
1313
for file in ../*/**.rs; do
1414
echo $file;
15-
grun RustLexer tokens -tokens < $file | ./verify $file || break
15+
grun RustLexer tokens -tokens < $file | ./verify $file RustLexer.tokens || break
1616
done
1717
```
1818

src/grammar/RustLexer.g4

+58-2
Original file line numberDiff line numberDiff line change
@@ -112,8 +112,64 @@ LIT_INTEGER
112112
;
113113

114114
LIT_FLOAT
115-
: [0-9][0-9_]* ( '.' {_input.LA(1) != '.'}?
116-
| ('.' [0-9][0-9_]*)? ([eE] [-+]? [0-9][0-9_]*)? SUFFIX?)
115+
: [0-9][0-9_]* ('.' {
116+
/* dot followed by another dot is a range, no float */
117+
_input.LA(1) != '.' &&
118+
/* dot followed by an identifier is an integer with a function call, no float */
119+
_input.LA(1) != '_' &&
120+
_input.LA(1) != 'a' &&
121+
_input.LA(1) != 'b' &&
122+
_input.LA(1) != 'c' &&
123+
_input.LA(1) != 'd' &&
124+
_input.LA(1) != 'e' &&
125+
_input.LA(1) != 'f' &&
126+
_input.LA(1) != 'g' &&
127+
_input.LA(1) != 'h' &&
128+
_input.LA(1) != 'i' &&
129+
_input.LA(1) != 'j' &&
130+
_input.LA(1) != 'k' &&
131+
_input.LA(1) != 'l' &&
132+
_input.LA(1) != 'm' &&
133+
_input.LA(1) != 'n' &&
134+
_input.LA(1) != 'o' &&
135+
_input.LA(1) != 'p' &&
136+
_input.LA(1) != 'q' &&
137+
_input.LA(1) != 'r' &&
138+
_input.LA(1) != 's' &&
139+
_input.LA(1) != 't' &&
140+
_input.LA(1) != 'u' &&
141+
_input.LA(1) != 'v' &&
142+
_input.LA(1) != 'w' &&
143+
_input.LA(1) != 'x' &&
144+
_input.LA(1) != 'y' &&
145+
_input.LA(1) != 'z' &&
146+
_input.LA(1) != 'A' &&
147+
_input.LA(1) != 'B' &&
148+
_input.LA(1) != 'C' &&
149+
_input.LA(1) != 'D' &&
150+
_input.LA(1) != 'E' &&
151+
_input.LA(1) != 'F' &&
152+
_input.LA(1) != 'G' &&
153+
_input.LA(1) != 'H' &&
154+
_input.LA(1) != 'I' &&
155+
_input.LA(1) != 'J' &&
156+
_input.LA(1) != 'K' &&
157+
_input.LA(1) != 'L' &&
158+
_input.LA(1) != 'M' &&
159+
_input.LA(1) != 'N' &&
160+
_input.LA(1) != 'O' &&
161+
_input.LA(1) != 'P' &&
162+
_input.LA(1) != 'Q' &&
163+
_input.LA(1) != 'R' &&
164+
_input.LA(1) != 'S' &&
165+
_input.LA(1) != 'T' &&
166+
_input.LA(1) != 'U' &&
167+
_input.LA(1) != 'V' &&
168+
_input.LA(1) != 'W' &&
169+
_input.LA(1) != 'X' &&
170+
_input.LA(1) != 'Y' &&
171+
_input.LA(1) != 'Z'
172+
}? | ('.' [0-9][0-9_]*)? ([eE] [-+]? [0-9][0-9_]*)? SUFFIX?)
117173
;
118174

119175
LIT_STR

src/grammar/check.sh

+17
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ if [ "${VERBOSE}" == "1" ]; then
1111
set -x
1212
fi
1313

14+
passed=0
15+
failed=0
16+
skipped=0
17+
1418
check() {
1519
grep --silent "// ignore-lexer-test" $1;
1620

@@ -21,14 +25,27 @@ check() {
2125
# seem to have anny effect.
2226
if $3 RustLexer tokens -tokens < $1 | $4 $1 $5; then
2327
echo "pass: $1"
28+
passed=`expr $passed + 1`
2429
else
2530
echo "fail: $1"
31+
failed=`expr $failed + 1`
2632
fi
2733
else
2834
echo "skip: $1"
35+
skipped=`expr $skipped + 1`
2936
fi
3037
}
3138

3239
for file in $(find $1 -iname '*.rs' ! -path '*/test/compile-fail*'); do
3340
check $file $2 $3 $4 $5
3441
done
42+
43+
printf "\ntest result: "
44+
45+
if [ $failed -eq 0 ]; then
46+
printf "ok. $passed passed; $failed failed; $skipped skipped\n\n"
47+
else
48+
printf "failed. $passed passed; $failed failed; $skipped skipped\n\n"
49+
exit 1
50+
fi
51+

0 commit comments

Comments
 (0)