Rollup merge of #41705 - Mark-Simulacrum:remove-grammar, r=nikomatsakis

Remove ANTLR grammar

I *think* that nothing in-tree references this, but I may be wrong. If anyone thinks of anything, please let me know and I'll work on removing.

Fixes #15677.
This commit is contained in:
Corey Farwell
2017-05-02 21:21:22 -04:00
committed by GitHub
13 changed files with 0 additions and 4221 deletions
-4
View File
@@ -1,4 +0,0 @@
verify
*.class
*.java
*.tokens
-33
View File
@@ -1,33 +0,0 @@
# Reference grammar.
Uses [antlr4](http://www.antlr.org/) and a custom Rust tool to compare
ASTs/token streams generated. You can use the `make check-lexer` target to
run all of the available tests.
The build of the rust part is included with `make tidy` and can be run with `make check-build-lexer-verifier`.
# Manual build
To use manually, assuming antlr4 is installed at `/usr/share/java/antlr-complete.jar`:
```
antlr4 RustLexer.g4
javac -classpath /usr/share/java/antlr-complete.jar *.java
rustc -O verify.rs
for file in ../*/**.rs; do
echo $file;
grun RustLexer tokens -tokens < "$file" | ./verify "$file" RustLexer.tokens || break
done
```
Note that the `../*/**.rs` glob will match every `*.rs` file in the above
directory and all of its recursive children. This is a Zsh extension.
## Cleanup
To cleanup you can use a command like this:
```bash
rm -f verify *.class *.java *.tokens
```
-197
View File
@@ -1,197 +0,0 @@
lexer grammar RustLexer;
@lexer::members {
public boolean is_at(int pos) {
return _input.index() == pos;
}
}
tokens {
EQ, LT, LE, EQEQ, NE, GE, GT, ANDAND, OROR, NOT, TILDE, PLUS,
MINUS, STAR, SLASH, PERCENT, CARET, AND, OR, SHL, SHR, BINOP,
BINOPEQ, LARROW, AT, DOT, DOTDOT, DOTDOTDOT, COMMA, SEMI, COLON,
MOD_SEP, RARROW, FAT_ARROW, LPAREN, RPAREN, LBRACKET, RBRACKET,
LBRACE, RBRACE, POUND, DOLLAR, UNDERSCORE, LIT_CHAR, LIT_BYTE,
LIT_INTEGER, LIT_FLOAT, LIT_STR, LIT_STR_RAW, LIT_BYTE_STR,
LIT_BYTE_STR_RAW, QUESTION, IDENT, LIFETIME, WHITESPACE, DOC_COMMENT,
COMMENT, SHEBANG, UTF8_BOM
}
import xidstart , xidcontinue;
/* Expression-operator symbols */
EQ : '=' ;
LT : '<' ;
LE : '<=' ;
EQEQ : '==' ;
NE : '!=' ;
GE : '>=' ;
GT : '>' ;
ANDAND : '&&' ;
OROR : '||' ;
NOT : '!' ;
TILDE : '~' ;
PLUS : '+' ;
MINUS : '-' ;
STAR : '*' ;
SLASH : '/' ;
PERCENT : '%' ;
CARET : '^' ;
AND : '&' ;
OR : '|' ;
SHL : '<<' ;
SHR : '>>' ;
LARROW : '<-' ;
BINOP
: PLUS
| SLASH
| MINUS
| STAR
| PERCENT
| CARET
| AND
| OR
| SHL
| SHR
| LARROW
;
BINOPEQ : BINOP EQ ;
/* "Structural symbols" */
AT : '@' ;
DOT : '.' ;
DOTDOT : '..' ;
DOTDOTDOT : '...' ;
COMMA : ',' ;
SEMI : ';' ;
COLON : ':' ;
MOD_SEP : '::' ;
RARROW : '->' ;
FAT_ARROW : '=>' ;
LPAREN : '(' ;
RPAREN : ')' ;
LBRACKET : '[' ;
RBRACKET : ']' ;
LBRACE : '{' ;
RBRACE : '}' ;
POUND : '#';
DOLLAR : '$' ;
UNDERSCORE : '_' ;
// Literals
fragment HEXIT
: [0-9a-fA-F]
;
fragment CHAR_ESCAPE
: [nrt\\'"0]
| [xX] HEXIT HEXIT
| 'u' HEXIT HEXIT HEXIT HEXIT
| 'U' HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT
| 'u{' HEXIT '}'
| 'u{' HEXIT HEXIT '}'
| 'u{' HEXIT HEXIT HEXIT '}'
| 'u{' HEXIT HEXIT HEXIT HEXIT '}'
| 'u{' HEXIT HEXIT HEXIT HEXIT HEXIT '}'
| 'u{' HEXIT HEXIT HEXIT HEXIT HEXIT HEXIT '}'
;
fragment SUFFIX
: IDENT
;
fragment INTEGER_SUFFIX
: { _input.LA(1) != 'e' && _input.LA(1) != 'E' }? SUFFIX
;
LIT_CHAR
: '\'' ( '\\' CHAR_ESCAPE
| ~[\\'\n\t\r]
| '\ud800' .. '\udbff' '\udc00' .. '\udfff'
)
'\'' SUFFIX?
;
LIT_BYTE
: 'b\'' ( '\\' ( [xX] HEXIT HEXIT
| [nrt\\'"0] )
| ~[\\'\n\t\r] '\udc00'..'\udfff'?
)
'\'' SUFFIX?
;
LIT_INTEGER
: [0-9][0-9_]* INTEGER_SUFFIX?
| '0b' [01_]+ INTEGER_SUFFIX?
| '0o' [0-7_]+ INTEGER_SUFFIX?
| '0x' [0-9a-fA-F_]+ INTEGER_SUFFIX?
;
LIT_FLOAT
: [0-9][0-9_]* ('.' {
/* dot followed by another dot is a range, not a float */
_input.LA(1) != '.' &&
/* dot followed by an identifier is an integer with a function call, not a float */
_input.LA(1) != '_' &&
!(_input.LA(1) >= 'a' && _input.LA(1) <= 'z') &&
!(_input.LA(1) >= 'A' && _input.LA(1) <= 'Z')
}? | ('.' [0-9][0-9_]*)? ([eE] [-+]? [0-9][0-9_]*)? SUFFIX?)
;
LIT_STR
: '"' ('\\\n' | '\\\r\n' | '\\' CHAR_ESCAPE | .)*? '"' SUFFIX?
;
LIT_BYTE_STR : 'b' LIT_STR ;
LIT_BYTE_STR_RAW : 'b' LIT_STR_RAW ;
/* this is a bit messy */
fragment LIT_STR_RAW_INNER
: '"' .*? '"'
| LIT_STR_RAW_INNER2
;
fragment LIT_STR_RAW_INNER2
: POUND LIT_STR_RAW_INNER POUND
;
LIT_STR_RAW
: 'r' LIT_STR_RAW_INNER SUFFIX?
;
QUESTION : '?';
IDENT : XID_Start XID_Continue* ;
fragment QUESTION_IDENTIFIER : QUESTION? IDENT;
LIFETIME : '\'' IDENT ;
WHITESPACE : [ \r\n\t]+ ;
UNDOC_COMMENT : '////' ~[\n]* -> type(COMMENT) ;
YESDOC_COMMENT : '///' ~[\r\n]* -> type(DOC_COMMENT) ;
OUTER_DOC_COMMENT : '//!' ~[\r\n]* -> type(DOC_COMMENT) ;
LINE_COMMENT : '//' ( ~[/\n] ~[\n]* )? -> type(COMMENT) ;
DOC_BLOCK_COMMENT
: ('/**' ~[*] | '/*!') (DOC_BLOCK_COMMENT | .)*? '*/' -> type(DOC_COMMENT)
;
BLOCK_COMMENT : '/*' (BLOCK_COMMENT | .)*? '*/' -> type(COMMENT) ;
/* these appear at the beginning of a file */
SHEBANG : '#!' { is_at(2) && _input.LA(1) != '[' }? ~[\r\n]* -> type(SHEBANG) ;
UTF8_BOM : '\ufeff' { is_at(1) }? -> skip ;
-52
View File
@@ -1,52 +0,0 @@
#!/bin/sh
# ignore-license
# Run the reference lexer against libsyntax and compare the tokens and spans.
# If "// ignore-lexer-test" is present in the file, it will be ignored.
# Argument $1 is the file to check, $2 is the classpath to use, $3 is the path
# to the grun binary, $4 is the path to the verify binary, $5 is the path to
# RustLexer.tokens
if [ "${VERBOSE}" == "1" ]; then
set -x
fi
passed=0
failed=0
skipped=0
check() {
grep --silent "// ignore-lexer-test" "$1";
# if it is *not* found...
if [ $? -eq 1 ]; then
cd $2 # This `cd` is so java will pick up RustLexer.class. I could not
# figure out how to wrangle the CLASSPATH, just adding build/grammar
# did not seem to have any effect.
if $3 RustLexer tokens -tokens < $1 | $4 $1 $5; then
echo "pass: $1"
passed=`expr $passed + 1`
else
echo "fail: $1"
failed=`expr $failed + 1`
fi
else
echo "skip: $1"
skipped=`expr $skipped + 1`
fi
}
for file in $(find $1 -iname '*.rs' ! -path '*/test/compile-fail*'); do
check "$file" $2 $3 $4 $5
done
printf "\ntest result: "
if [ $failed -eq 0 ]; then
printf "ok. $passed passed; $failed failed; $skipped skipped\n\n"
else
printf "failed. $passed passed; $failed failed; $skipped skipped\n\n"
exit 1
fi
-343
View File
@@ -1,343 +0,0 @@
%{
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#include <stdio.h>
#include <ctype.h>
static int num_hashes;
static int end_hashes;
static int saw_non_hash;
%}
%option stack
%option yylineno
%x str
%x rawstr
%x rawstr_esc_begin
%x rawstr_esc_body
%x rawstr_esc_end
%x byte
%x bytestr
%x rawbytestr
%x rawbytestr_nohash
%x pound
%x shebang_or_attr
%x ltorchar
%x linecomment
%x doc_line
%x blockcomment
%x doc_block
%x suffix
ident [a-zA-Z\x80-\xff_][a-zA-Z0-9\x80-\xff_]*
%%
<suffix>{ident} { BEGIN(INITIAL); }
<suffix>(.|\n) { yyless(0); BEGIN(INITIAL); }
[ \n\t\r] { }
\xef\xbb\xbf {
// UTF-8 byte order mark (BOM), ignore if in line 1, error otherwise
if (yyget_lineno() != 1) {
return -1;
}
}
\/\/(\/|\!) { BEGIN(doc_line); yymore(); }
<doc_line>\n { BEGIN(INITIAL);
yyleng--;
yytext[yyleng] = 0;
return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
}
<doc_line>[^\n]* { yymore(); }
\/\/|\/\/\/\/ { BEGIN(linecomment); }
<linecomment>\n { BEGIN(INITIAL); }
<linecomment>[^\n]* { }
\/\*(\*|\!)[^*] { yy_push_state(INITIAL); yy_push_state(doc_block); yymore(); }
<doc_block>\/\* { yy_push_state(doc_block); yymore(); }
<doc_block>\*\/ {
yy_pop_state();
if (yy_top_state() == doc_block) {
yymore();
} else {
return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
}
}
<doc_block>(.|\n) { yymore(); }
\/\* { yy_push_state(blockcomment); }
<blockcomment>\/\* { yy_push_state(blockcomment); }
<blockcomment>\*\/ { yy_pop_state(); }
<blockcomment>(.|\n) { }
_ { return UNDERSCORE; }
as { return AS; }
box { return BOX; }
break { return BREAK; }
const { return CONST; }
continue { return CONTINUE; }
crate { return CRATE; }
else { return ELSE; }
enum { return ENUM; }
extern { return EXTERN; }
false { return FALSE; }
fn { return FN; }
for { return FOR; }
if { return IF; }
impl { return IMPL; }
in { return IN; }
let { return LET; }
loop { return LOOP; }
match { return MATCH; }
mod { return MOD; }
move { return MOVE; }
mut { return MUT; }
priv { return PRIV; }
proc { return PROC; }
pub { return PUB; }
ref { return REF; }
return { return RETURN; }
self { return SELF; }
static { return STATIC; }
struct { return STRUCT; }
trait { return TRAIT; }
true { return TRUE; }
type { return TYPE; }
typeof { return TYPEOF; }
unsafe { return UNSAFE; }
use { return USE; }
where { return WHERE; }
while { return WHILE; }
{ident} { return IDENT; }
0x[0-9a-fA-F_]+ { BEGIN(suffix); return LIT_INTEGER; }
0o[0-8_]+ { BEGIN(suffix); return LIT_INTEGER; }
0b[01_]+ { BEGIN(suffix); return LIT_INTEGER; }
[0-9][0-9_]* { BEGIN(suffix); return LIT_INTEGER; }
[0-9][0-9_]*\.(\.|[a-zA-Z]) { yyless(yyleng - 2); BEGIN(suffix); return LIT_INTEGER; }
[0-9][0-9_]*\.[0-9_]*([eE][-\+]?[0-9_]+)? { BEGIN(suffix); return LIT_FLOAT; }
[0-9][0-9_]*(\.[0-9_]*)?[eE][-\+]?[0-9_]+ { BEGIN(suffix); return LIT_FLOAT; }
; { return ';'; }
, { return ','; }
\.\.\. { return DOTDOTDOT; }
\.\. { return DOTDOT; }
\. { return '.'; }
\( { return '('; }
\) { return ')'; }
\{ { return '{'; }
\} { return '}'; }
\[ { return '['; }
\] { return ']'; }
@ { return '@'; }
# { BEGIN(pound); yymore(); }
<pound>\! { BEGIN(shebang_or_attr); yymore(); }
<shebang_or_attr>\[ {
BEGIN(INITIAL);
yyless(2);
return SHEBANG;
}
<shebang_or_attr>[^\[\n]*\n {
// Since the \n was eaten as part of the token, yylineno will have
// been incremented to the value 2 if the shebang was on the first
// line. This yyless undoes that, setting yylineno back to 1.
yyless(yyleng - 1);
if (yyget_lineno() == 1) {
BEGIN(INITIAL);
return SHEBANG_LINE;
} else {
BEGIN(INITIAL);
yyless(2);
return SHEBANG;
}
}
<pound>. { BEGIN(INITIAL); yyless(1); return '#'; }
\~ { return '~'; }
:: { return MOD_SEP; }
: { return ':'; }
\$ { return '$'; }
\? { return '?'; }
== { return EQEQ; }
=> { return FAT_ARROW; }
= { return '='; }
\!= { return NE; }
\! { return '!'; }
\<= { return LE; }
\<\< { return SHL; }
\<\<= { return SHLEQ; }
\< { return '<'; }
\>= { return GE; }
\>\> { return SHR; }
\>\>= { return SHREQ; }
\> { return '>'; }
\x27 { BEGIN(ltorchar); yymore(); }
<ltorchar>static { BEGIN(INITIAL); return STATIC_LIFETIME; }
<ltorchar>{ident} { BEGIN(INITIAL); return LIFETIME; }
<ltorchar>\\[nrt\\\x27\x220]\x27 { BEGIN(suffix); return LIT_CHAR; }
<ltorchar>\\x[0-9a-fA-F]{2}\x27 { BEGIN(suffix); return LIT_CHAR; }
<ltorchar>\\u\{[0-9a-fA-F]?{6}\}\x27 { BEGIN(suffix); return LIT_CHAR; }
<ltorchar>.\x27 { BEGIN(suffix); return LIT_CHAR; }
<ltorchar>[\x80-\xff]{2,4}\x27 { BEGIN(suffix); return LIT_CHAR; }
<ltorchar><<EOF>> { BEGIN(INITIAL); return -1; }
b\x22 { BEGIN(bytestr); yymore(); }
<bytestr>\x22 { BEGIN(suffix); return LIT_BYTE_STR; }
<bytestr><<EOF>> { return -1; }
<bytestr>\\[n\nrt\\\x27\x220] { yymore(); }
<bytestr>\\x[0-9a-fA-F]{2} { yymore(); }
<bytestr>\\u\{[0-9a-fA-F]?{6}\} { yymore(); }
<bytestr>\\[^n\nrt\\\x27\x220] { return -1; }
<bytestr>(.|\n) { yymore(); }
br\x22 { BEGIN(rawbytestr_nohash); yymore(); }
<rawbytestr_nohash>\x22 { BEGIN(suffix); return LIT_BYTE_STR_RAW; }
<rawbytestr_nohash>(.|\n) { yymore(); }
<rawbytestr_nohash><<EOF>> { return -1; }
br/# {
BEGIN(rawbytestr);
yymore();
num_hashes = 0;
saw_non_hash = 0;
end_hashes = 0;
}
<rawbytestr># {
if (!saw_non_hash) {
num_hashes++;
} else if (end_hashes != 0) {
end_hashes++;
if (end_hashes == num_hashes) {
BEGIN(INITIAL);
return LIT_BYTE_STR_RAW;
}
}
yymore();
}
<rawbytestr>\x22# {
end_hashes = 1;
if (end_hashes == num_hashes) {
BEGIN(INITIAL);
return LIT_BYTE_STR_RAW;
}
yymore();
}
<rawbytestr>(.|\n) {
if (!saw_non_hash) {
saw_non_hash = 1;
}
if (end_hashes != 0) {
end_hashes = 0;
}
yymore();
}
<rawbytestr><<EOF>> { return -1; }
b\x27 { BEGIN(byte); yymore(); }
<byte>\\[nrt\\\x27\x220]\x27 { BEGIN(INITIAL); return LIT_BYTE; }
<byte>\\x[0-9a-fA-F]{2}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
<byte>\\u[0-9a-fA-F]{4}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
<byte>\\U[0-9a-fA-F]{8}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
<byte>.\x27 { BEGIN(INITIAL); return LIT_BYTE; }
<byte><<EOF>> { BEGIN(INITIAL); return -1; }
r\x22 { BEGIN(rawstr); yymore(); }
<rawstr>\x22 { BEGIN(suffix); return LIT_STR_RAW; }
<rawstr>(.|\n) { yymore(); }
<rawstr><<EOF>> { return -1; }
r/# {
BEGIN(rawstr_esc_begin);
yymore();
num_hashes = 0;
saw_non_hash = 0;
end_hashes = 0;
}
<rawstr_esc_begin># {
num_hashes++;
yymore();
}
<rawstr_esc_begin>\x22 {
BEGIN(rawstr_esc_body);
yymore();
}
<rawstr_esc_begin>(.|\n) { return -1; }
<rawstr_esc_body>\x22/# {
BEGIN(rawstr_esc_end);
yymore();
}
<rawstr_esc_body>(.|\n) {
yymore();
}
<rawstr_esc_end># {
end_hashes++;
if (end_hashes == num_hashes) {
BEGIN(INITIAL);
return LIT_STR_RAW;
}
yymore();
}
<rawstr_esc_end>[^#] {
end_hashes = 0;
BEGIN(rawstr_esc_body);
yymore();
}
<rawstr_esc_begin,rawstr_esc_body,rawstr_esc_end><<EOF>> { return -1; }
\x22 { BEGIN(str); yymore(); }
<str>\x22 { BEGIN(suffix); return LIT_STR; }
<str><<EOF>> { return -1; }
<str>\\[n\nr\rt\\\x27\x220] { yymore(); }
<str>\\x[0-9a-fA-F]{2} { yymore(); }
<str>\\u\{[0-9a-fA-F]?{6}\} { yymore(); }
<str>\\[^n\nrt\\\x27\x220] { return -1; }
<str>(.|\n) { yymore(); }
\<- { return LARROW; }
-\> { return RARROW; }
- { return '-'; }
-= { return MINUSEQ; }
&& { return ANDAND; }
& { return '&'; }
&= { return ANDEQ; }
\|\| { return OROR; }
\| { return '|'; }
\|= { return OREQ; }
\+ { return '+'; }
\+= { return PLUSEQ; }
\* { return '*'; }
\*= { return STAREQ; }
\/ { return '/'; }
\/= { return SLASHEQ; }
\^ { return '^'; }
\^= { return CARETEQ; }
% { return '%'; }
%= { return PERCENTEQ; }
<<EOF>> { return 0; }
%%
-203
View File
@@ -1,203 +0,0 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
extern int yylex();
extern int rsparse();
#define PUSHBACK_LEN 4
static char pushback[PUSHBACK_LEN];
static int verbose;
void print(const char* format, ...) {
va_list args;
va_start(args, format);
if (verbose) {
vprintf(format, args);
}
va_end(args);
}
// If there is a non-null char at the head of the pushback queue,
// dequeue it and shift the rest of the queue forwards. Otherwise,
// return the token from calling yylex.
int rslex() {
if (pushback[0] == '\0') {
return yylex();
} else {
char c = pushback[0];
memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
pushback[PUSHBACK_LEN - 1] = '\0';
return c;
}
}
// Note: this does nothing if the pushback queue is full. As long as
// there aren't more than PUSHBACK_LEN consecutive calls to push_back
// in an action, this shouldn't be a problem.
void push_back(char c) {
for (int i = 0; i < PUSHBACK_LEN; ++i) {
if (pushback[i] == '\0') {
pushback[i] = c;
break;
}
}
}
extern int rsdebug;
struct node {
struct node *next;
struct node *prev;
int own_string;
char const *name;
int n_elems;
struct node *elems[];
};
struct node *nodes = NULL;
int n_nodes;
struct node *mk_node(char const *name, int n, ...) {
va_list ap;
int i = 0;
unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
struct node *nn, *nd = (struct node *)malloc(sz);
print("# New %d-ary node: %s = %p\n", n, name, nd);
nd->own_string = 0;
nd->prev = NULL;
nd->next = nodes;
if (nodes) {
nodes->prev = nd;
}
nodes = nd;
nd->name = name;
nd->n_elems = n;
va_start(ap, n);
while (i < n) {
nn = va_arg(ap, struct node *);
print("# arg[%d]: %p\n", i, nn);
print("# (%s ...)\n", nn->name);
nd->elems[i++] = nn;
}
va_end(ap);
n_nodes++;
return nd;
}
struct node *mk_atom(char *name) {
struct node *nd = mk_node((char const *)strdup(name), 0);
nd->own_string = 1;
return nd;
}
struct node *mk_none() {
return mk_atom("<none>");
}
struct node *ext_node(struct node *nd, int n, ...) {
va_list ap;
int i = 0, c = nd->n_elems + n;
unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
struct node *nn;
print("# Extending %d-ary node by %d nodes: %s = %p",
nd->n_elems, c, nd->name, nd);
if (nd->next) {
nd->next->prev = nd->prev;
}
if (nd->prev) {
nd->prev->next = nd->next;
}
nd = realloc(nd, sz);
nd->prev = NULL;
nd->next = nodes;
nodes->prev = nd;
nodes = nd;
print(" ==> %p\n", nd);
va_start(ap, n);
while (i < n) {
nn = va_arg(ap, struct node *);
print("# arg[%d]: %p\n", i, nn);
print("# (%s ...)\n", nn->name);
nd->elems[nd->n_elems++] = nn;
++i;
}
va_end(ap);
return nd;
}
int const indent_step = 4;
void print_indent(int depth) {
while (depth) {
if (depth-- % indent_step == 0) {
print("|");
} else {
print(" ");
}
}
}
void print_node(struct node *n, int depth) {
int i = 0;
print_indent(depth);
if (n->n_elems == 0) {
print("%s\n", n->name);
} else {
print("(%s\n", n->name);
for (i = 0; i < n->n_elems; ++i) {
print_node(n->elems[i], depth + indent_step);
}
print_indent(depth);
print(")\n");
}
}
int main(int argc, char **argv) {
if (argc == 2 && strcmp(argv[1], "-v") == 0) {
verbose = 1;
} else {
verbose = 0;
}
int ret = 0;
struct node *tmp;
memset(pushback, '\0', PUSHBACK_LEN);
ret = rsparse();
print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
if (nodes) {
print_node(nodes, 0);
}
while (nodes) {
tmp = nodes;
nodes = tmp->next;
if (tmp->own_string) {
free((void*)tmp->name);
}
free(tmp);
}
return ret;
}
void rserror(char const *s) {
fprintf(stderr, "%s\n", s);
}
-1945
View File
@@ -1,1945 +0,0 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
%{
#define YYERROR_VERBOSE
#define YYSTYPE struct node *
struct node;
extern int yylex();
extern void yyerror(char const *s);
extern struct node *mk_node(char const *name, int n, ...);
extern struct node *mk_atom(char *text);
extern struct node *mk_none();
extern struct node *ext_node(struct node *nd, int n, ...);
extern void push_back(char c);
extern char *yytext;
%}
%debug
%token SHL
%token SHR
%token LE
%token EQEQ
%token NE
%token GE
%token ANDAND
%token OROR
%token SHLEQ
%token SHREQ
%token MINUSEQ
%token ANDEQ
%token OREQ
%token PLUSEQ
%token STAREQ
%token SLASHEQ
%token CARETEQ
%token PERCENTEQ
%token DOTDOT
%token DOTDOTDOT
%token MOD_SEP
%token RARROW
%token LARROW
%token FAT_ARROW
%token LIT_BYTE
%token LIT_CHAR
%token LIT_INTEGER
%token LIT_FLOAT
%token LIT_STR
%token LIT_STR_RAW
%token LIT_BYTE_STR
%token LIT_BYTE_STR_RAW
%token IDENT
%token UNDERSCORE
%token LIFETIME
// keywords
%token SELF
%token STATIC
%token AS
%token BREAK
%token CRATE
%token ELSE
%token ENUM
%token EXTERN
%token FALSE
%token FN
%token FOR
%token IF
%token IMPL
%token IN
%token LET
%token LOOP
%token MATCH
%token MOD
%token MOVE
%token MUT
%token PRIV
%token PUB
%token REF
%token RETURN
%token STRUCT
%token TRUE
%token TRAIT
%token TYPE
%token UNSAFE
%token DEFAULT
%token USE
%token WHILE
%token CONTINUE
%token PROC
%token BOX
%token CONST
%token WHERE
%token TYPEOF
%token INNER_DOC_COMMENT
%token OUTER_DOC_COMMENT
%token SHEBANG
%token SHEBANG_LINE
%token STATIC_LIFETIME
/*
Quoting from the Bison manual:
"Finally, the resolution of conflicts works by comparing the precedence
of the rule being considered with that of the lookahead token. If the
token's precedence is higher, the choice is to shift. If the rule's
precedence is higher, the choice is to reduce. If they have equal
precedence, the choice is made based on the associativity of that
precedence level. The verbose output file made by -v (see Invoking
Bison) says how each conflict was resolved"
*/
// We expect no shift/reduce or reduce/reduce conflicts in this grammar;
// all potential ambiguities are scrutinized and eliminated manually.
%expect 0
// fake-precedence symbol to cause '|' bars in lambda context to parse
// at low precedence, permit things like |x| foo = bar, where '=' is
// otherwise lower-precedence than '|'. Also used for proc() to cause
// things like proc() a + b to parse as proc() { a + b }.
%precedence LAMBDA
%precedence SELF
// MUT should be lower precedence than IDENT so that in the pat rule,
// "& MUT pat" has higher precedence than "binding_mode ident [@ pat]"
%precedence MUT
// IDENT needs to be lower than '{' so that 'foo {' is shifted when
// trying to decide if we've got a struct-construction expr (esp. in
// contexts like 'if foo { .')
//
// IDENT also needs to be lower precedence than '<' so that '<' in
// 'foo:bar . <' is shifted (in a trait reference occurring in a
// bounds list), parsing as foo:(bar<baz>) rather than (foo:bar)<baz>.
%precedence IDENT
// A couple fake-precedence symbols to use in rules associated with +
// and < in trailing type contexts. These come up when you have a type
// in the RHS of operator-AS, such as "foo as bar<baz>". The "<" there
// has to be shifted so the parser keeps trying to parse a type, even
// though it might well consider reducing the type "bar" and then
// going on to "<" as a subsequent binop. The "+" case is with
// trailing type-bounds ("foo as bar:A+B"), for the same reason.
%precedence SHIFTPLUS
%precedence MOD_SEP
%precedence RARROW ':'
// In where clauses, "for" should have greater precedence when used as
// a higher ranked constraint than when used as the beginning of a
// for_in_type (which is a ty)
%precedence FORTYPE
%precedence FOR
// Binops & unops, and their precedences
%precedence BOX
%precedence BOXPLACE
%nonassoc DOTDOT
// RETURN needs to be lower-precedence than tokens that start
// prefix_exprs
%precedence RETURN
%right '=' SHLEQ SHREQ MINUSEQ ANDEQ OREQ PLUSEQ STAREQ SLASHEQ CARETEQ PERCENTEQ
%right LARROW
%left OROR
%left ANDAND
%left EQEQ NE
%left '<' '>' LE GE
%left '|'
%left '^'
%left '&'
%left SHL SHR
%left '+' '-'
%precedence AS
%left '*' '/' '%'
%precedence '!'
%precedence '{' '[' '(' '.'
%precedence RANGE
%start crate
%%
////////////////////////////////////////////////////////////////////////
// Part 1: Items and attributes
////////////////////////////////////////////////////////////////////////
crate
: maybe_shebang inner_attrs maybe_mod_items { mk_node("crate", 2, $2, $3); }
| maybe_shebang maybe_mod_items { mk_node("crate", 1, $2); }
;
maybe_shebang
: SHEBANG_LINE
| %empty
;
maybe_inner_attrs
: inner_attrs
| %empty { $$ = mk_none(); }
;
inner_attrs
: inner_attr { $$ = mk_node("InnerAttrs", 1, $1); }
| inner_attrs inner_attr { $$ = ext_node($1, 1, $2); }
;
inner_attr
: SHEBANG '[' meta_item ']' { $$ = mk_node("InnerAttr", 1, $3); }
| INNER_DOC_COMMENT { $$ = mk_node("InnerAttr", 1, mk_node("doc-comment", 1, mk_atom(yytext))); }
;
maybe_outer_attrs
: outer_attrs
| %empty { $$ = mk_none(); }
;
outer_attrs
: outer_attr { $$ = mk_node("OuterAttrs", 1, $1); }
| outer_attrs outer_attr { $$ = ext_node($1, 1, $2); }
;
outer_attr
: '#' '[' meta_item ']' { $$ = $3; }
| OUTER_DOC_COMMENT { $$ = mk_node("doc-comment", 1, mk_atom(yytext)); }
;
meta_item
: ident { $$ = mk_node("MetaWord", 1, $1); }
| ident '=' lit { $$ = mk_node("MetaNameValue", 2, $1, $3); }
| ident '(' meta_seq ')' { $$ = mk_node("MetaList", 2, $1, $3); }
| ident '(' meta_seq ',' ')' { $$ = mk_node("MetaList", 2, $1, $3); }
;
meta_seq
: %empty { $$ = mk_none(); }
| meta_item { $$ = mk_node("MetaItems", 1, $1); }
| meta_seq ',' meta_item { $$ = ext_node($1, 1, $3); }
;
maybe_mod_items
: mod_items
| %empty { $$ = mk_none(); }
;
mod_items
: mod_item { $$ = mk_node("Items", 1, $1); }
| mod_items mod_item { $$ = ext_node($1, 1, $2); }
;
attrs_and_vis
: maybe_outer_attrs visibility { $$ = mk_node("AttrsAndVis", 2, $1, $2); }
;
mod_item
: attrs_and_vis item { $$ = mk_node("Item", 2, $1, $2); }
;
// items that can appear outside of a fn block
item
: stmt_item
| item_macro
;
// items that can appear in "stmts"
stmt_item
: item_static
| item_const
| item_type
| block_item
| view_item
;
item_static
: STATIC ident ':' ty '=' expr ';' { $$ = mk_node("ItemStatic", 3, $2, $4, $6); }
| STATIC MUT ident ':' ty '=' expr ';' { $$ = mk_node("ItemStatic", 3, $3, $5, $7); }
;
item_const
: CONST ident ':' ty '=' expr ';' { $$ = mk_node("ItemConst", 3, $2, $4, $6); }
;
item_macro
: path_expr '!' maybe_ident parens_delimited_token_trees ';' { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
| path_expr '!' maybe_ident brackets_delimited_token_trees ';'{ $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
;
view_item
: use_item
| extern_fn_item
| EXTERN CRATE ident ';' { $$ = mk_node("ViewItemExternCrate", 1, $3); }
| EXTERN CRATE ident AS ident ';' { $$ = mk_node("ViewItemExternCrate", 2, $3, $5); }
;
extern_fn_item
: EXTERN maybe_abi item_fn { $$ = mk_node("ViewItemExternFn", 2, $2, $3); }
;
use_item
: USE view_path ';' { $$ = mk_node("ViewItemUse", 1, $2); }
;
view_path
: path_no_types_allowed { $$ = mk_node("ViewPathSimple", 1, $1); }
| path_no_types_allowed MOD_SEP '{' '}' { $$ = mk_node("ViewPathList", 2, $1, mk_atom("ViewPathListEmpty")); }
| MOD_SEP '{' '}' { $$ = mk_node("ViewPathList", 1, mk_atom("ViewPathListEmpty")); }
| path_no_types_allowed MOD_SEP '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
| MOD_SEP '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 1, $3); }
| path_no_types_allowed MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
| MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $3); }
| path_no_types_allowed MOD_SEP '*' { $$ = mk_node("ViewPathGlob", 1, $1); }
| '{' '}' { $$ = mk_atom("ViewPathListEmpty"); }
| '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 1, $2); }
| '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $2); }
| path_no_types_allowed AS ident { $$ = mk_node("ViewPathSimple", 2, $1, $3); }
;
block_item
: item_fn
| item_unsafe_fn
| item_mod
| item_foreign_mod { $$ = mk_node("ItemForeignMod", 1, $1); }
| item_struct
| item_enum
| item_trait
| item_impl
;
maybe_ty_ascription
: ':' ty_sum { $$ = $2; }
| %empty { $$ = mk_none(); }
;
maybe_init_expr
: '=' expr { $$ = $2; }
| %empty { $$ = mk_none(); }
;
// structs
item_struct
: STRUCT ident generic_params maybe_where_clause struct_decl_args
{
$$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
}
| STRUCT ident generic_params struct_tuple_args maybe_where_clause ';'
{
$$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
}
| STRUCT ident generic_params maybe_where_clause ';'
{
$$ = mk_node("ItemStruct", 3, $2, $3, $4);
}
;
struct_decl_args
: '{' struct_decl_fields '}' { $$ = $2; }
| '{' struct_decl_fields ',' '}' { $$ = $2; }
;
struct_tuple_args
: '(' struct_tuple_fields ')' { $$ = $2; }
| '(' struct_tuple_fields ',' ')' { $$ = $2; }
;
struct_decl_fields
: struct_decl_field { $$ = mk_node("StructFields", 1, $1); }
| struct_decl_fields ',' struct_decl_field { $$ = ext_node($1, 1, $3); }
| %empty { $$ = mk_none(); }
;
struct_decl_field
: attrs_and_vis ident ':' ty_sum { $$ = mk_node("StructField", 3, $1, $2, $4); }
;
struct_tuple_fields
: struct_tuple_field { $$ = mk_node("StructFields", 1, $1); }
| struct_tuple_fields ',' struct_tuple_field { $$ = ext_node($1, 1, $3); }
;
struct_tuple_field
: attrs_and_vis ty_sum { $$ = mk_node("StructField", 2, $1, $2); }
;
// enums
item_enum
: ENUM ident generic_params maybe_where_clause '{' enum_defs '}' { $$ = mk_node("ItemEnum", 0); }
| ENUM ident generic_params maybe_where_clause '{' enum_defs ',' '}' { $$ = mk_node("ItemEnum", 0); }
;
enum_defs
: enum_def { $$ = mk_node("EnumDefs", 1, $1); }
| enum_defs ',' enum_def { $$ = ext_node($1, 1, $3); }
| %empty { $$ = mk_none(); }
;
enum_def
: attrs_and_vis ident enum_args { $$ = mk_node("EnumDef", 3, $1, $2, $3); }
;
enum_args
: '{' struct_decl_fields '}' { $$ = mk_node("EnumArgs", 1, $2); }
| '{' struct_decl_fields ',' '}' { $$ = mk_node("EnumArgs", 1, $2); }
| '(' maybe_ty_sums ')' { $$ = mk_node("EnumArgs", 1, $2); }
| '=' expr { $$ = mk_node("EnumArgs", 1, $2); }
| %empty { $$ = mk_none(); }
;
item_mod
: MOD ident ';' { $$ = mk_node("ItemMod", 1, $2); }
| MOD ident '{' maybe_mod_items '}' { $$ = mk_node("ItemMod", 2, $2, $4); }
| MOD ident '{' inner_attrs maybe_mod_items '}' { $$ = mk_node("ItemMod", 3, $2, $4, $5); }
;
item_foreign_mod
: EXTERN maybe_abi '{' maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 1, $4); }
| EXTERN maybe_abi '{' inner_attrs maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 2, $4, $5); }
;
maybe_abi
: str
| %empty { $$ = mk_none(); }
;
maybe_foreign_items
: foreign_items
| %empty { $$ = mk_none(); }
;
foreign_items
: foreign_item { $$ = mk_node("ForeignItems", 1, $1); }
| foreign_items foreign_item { $$ = ext_node($1, 1, $2); }
;
foreign_item
: attrs_and_vis STATIC item_foreign_static { $$ = mk_node("ForeignItem", 2, $1, $3); }
| attrs_and_vis item_foreign_fn { $$ = mk_node("ForeignItem", 2, $1, $2); }
| attrs_and_vis UNSAFE item_foreign_fn { $$ = mk_node("ForeignItem", 2, $1, $3); }
;
item_foreign_static
: maybe_mut ident ':' ty ';' { $$ = mk_node("StaticItem", 3, $1, $2, $4); }
;
item_foreign_fn
: FN ident generic_params fn_decl_allow_variadic maybe_where_clause ';' { $$ = mk_node("ForeignFn", 4, $2, $3, $4, $5); }
;
fn_decl_allow_variadic
: fn_params_allow_variadic ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
;
fn_params_allow_variadic
: '(' ')' { $$ = mk_none(); }
| '(' params ')' { $$ = $2; }
| '(' params ',' ')' { $$ = $2; }
| '(' params ',' DOTDOTDOT ')' { $$ = $2; }
;
visibility
: PUB { $$ = mk_atom("Public"); }
| %empty { $$ = mk_atom("Inherited"); }
;
idents_or_self
: ident_or_self { $$ = mk_node("IdentsOrSelf", 1, $1); }
| ident_or_self AS ident { $$ = mk_node("IdentsOrSelf", 2, $1, $3); }
| idents_or_self ',' ident_or_self { $$ = ext_node($1, 1, $3); }
;
ident_or_self
: ident
| SELF { $$ = mk_atom(yytext); }
;
item_type
: TYPE ident generic_params maybe_where_clause '=' ty_sum ';' { $$ = mk_node("ItemTy", 4, $2, $3, $4, $6); }
;
for_sized
: FOR '?' ident { $$ = mk_node("ForSized", 1, $3); }
| FOR ident '?' { $$ = mk_node("ForSized", 1, $2); }
| %empty { $$ = mk_none(); }
;
item_trait
: maybe_unsafe TRAIT ident generic_params for_sized maybe_ty_param_bounds maybe_where_clause '{' maybe_trait_items '}'
{
$$ = mk_node("ItemTrait", 7, $1, $3, $4, $5, $6, $7, $9);
}
;
maybe_trait_items
: trait_items
| %empty { $$ = mk_none(); }
;
trait_items
: trait_item { $$ = mk_node("TraitItems", 1, $1); }
| trait_items trait_item { $$ = ext_node($1, 1, $2); }
;
trait_item
: trait_const
| trait_type
| trait_method
;
trait_const
: maybe_outer_attrs CONST ident maybe_ty_ascription maybe_const_default ';' { $$ = mk_node("ConstTraitItem", 4, $1, $3, $4, $5); }
;
maybe_const_default
: '=' expr { $$ = mk_node("ConstDefault", 1, $2); }
| %empty { $$ = mk_none(); }
;
trait_type
: maybe_outer_attrs TYPE ty_param ';' { $$ = mk_node("TypeTraitItem", 2, $1, $3); }
;
maybe_unsafe
: UNSAFE { $$ = mk_atom("Unsafe"); }
| %empty { $$ = mk_none(); }
;
maybe_default_maybe_unsafe
: DEFAULT UNSAFE { $$ = mk_atom("DefaultUnsafe"); }
| DEFAULT { $$ = mk_atom("Default"); }
| UNSAFE { $$ = mk_atom("Unsafe"); }
| %empty { $$ = mk_none(); }
trait_method
: type_method { $$ = mk_node("Required", 1, $1); }
| method { $$ = mk_node("Provided", 1, $1); }
;
type_method
: attrs_and_vis maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
{
$$ = mk_node("TypeMethod", 6, $1, $2, $4, $5, $6, $7);
}
| attrs_and_vis maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
{
$$ = mk_node("TypeMethod", 7, $1, $2, $4, $6, $7, $8, $9);
}
;
method
: attrs_and_vis maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("Method", 7, $1, $2, $4, $5, $6, $7, $8);
}
| attrs_and_vis maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
}
;
impl_method
: attrs_and_vis maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("Method", 7, $1, $2, $4, $5, $6, $7, $8);
}
| attrs_and_vis maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
}
;
// There are two forms of impl:
//
// impl (<...>)? TY { ... }
// impl (<...>)? TRAIT for TY { ... }
//
// Unfortunately since TY can begin with '<' itself -- as part of a
// TyQualifiedPath type -- there's an s/r conflict when we see '<' after IMPL:
// should we reduce one of the early rules of TY (such as maybe_once)
// or shall we continue shifting into the generic_params list for the
// impl?
//
// The production parser disambiguates a different case here by
// permitting / requiring the user to provide parens around types when
// they are ambiguous with traits. We do the same here, regrettably,
// by splitting ty into ty and ty_prim.
item_impl
: maybe_default_maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
$$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8);
}
| maybe_default_maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
$$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10);
}
| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
$$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10);
}
| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
{
$$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
}
| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
{
$$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
}
| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
{
$$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
}
;
maybe_impl_items
: impl_items
| %empty { $$ = mk_none(); }
;
impl_items
: impl_item { $$ = mk_node("ImplItems", 1, $1); }
| impl_item impl_items { $$ = ext_node($1, 1, $2); }
;
impl_item
: impl_method
| attrs_and_vis item_macro { $$ = mk_node("ImplMacroItem", 2, $1, $2); }
| impl_const
| impl_type
;
impl_const
: attrs_and_vis item_const { $$ = mk_node("ImplConst", 1, $1, $2); }
;
impl_type
: attrs_and_vis TYPE ident generic_params '=' ty_sum ';' { $$ = mk_node("ImplType", 4, $1, $3, $4, $6); }
;
item_fn
: FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("ItemFn", 5, $2, $3, $4, $5, $6);
}
;
item_unsafe_fn
: UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("ItemUnsafeFn", 5, $3, $4, $5, $6, $7);
}
| UNSAFE EXTERN maybe_abi FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
{
$$ = mk_node("ItemUnsafeFn", 6, $3, $5, $6, $7, $8, $9);
}
;
fn_decl
: fn_params ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
;
fn_decl_with_self
: fn_params_with_self ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
;
fn_decl_with_self_allow_anon_params
: fn_anon_params_with_self ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
;
fn_params
: '(' maybe_params ')' { $$ = $2; }
;
fn_anon_params
: '(' anon_param anon_params_allow_variadic_tail ')' { $$ = ext_node($2, 1, $3); }
| '(' ')' { $$ = mk_none(); }
;
fn_params_with_self
: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfValue", 3, $2, $4, $5); }
| '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
| '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
| '(' maybe_params ')' { $$ = mk_node("SelfStatic", 1, $2); }
;
fn_anon_params_with_self
: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfValue", 3, $2, $4, $5); }
| '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
| '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
| '(' maybe_anon_params ')' { $$ = mk_node("SelfStatic", 1, $2); }
;
maybe_params
: params
| params ','
| %empty { $$ = mk_none(); }
;
params
: param { $$ = mk_node("Args", 1, $1); }
| params ',' param { $$ = ext_node($1, 1, $3); }
;
param
: pat ':' ty_sum { $$ = mk_node("Arg", 2, $1, $3); }
;
inferrable_params
: inferrable_param { $$ = mk_node("InferrableParams", 1, $1); }
| inferrable_params ',' inferrable_param { $$ = ext_node($1, 1, $3); }
;
inferrable_param
: pat maybe_ty_ascription { $$ = mk_node("InferrableParam", 2, $1, $2); }
;
maybe_unboxed_closure_kind
: %empty
| ':'
| '&' maybe_mut ':'
;
maybe_comma_params
: ',' { $$ = mk_none(); }
| ',' params { $$ = $2; }
| ',' params ',' { $$ = $2; }
| %empty { $$ = mk_none(); }
;
maybe_comma_anon_params
: ',' { $$ = mk_none(); }
| ',' anon_params { $$ = $2; }
| ',' anon_params ',' { $$ = $2; }
| %empty { $$ = mk_none(); }
;
maybe_anon_params
: anon_params
| anon_params ','
| %empty { $$ = mk_none(); }
;
anon_params
: anon_param { $$ = mk_node("Args", 1, $1); }
| anon_params ',' anon_param { $$ = ext_node($1, 1, $3); }
;
// anon means it's allowed to be anonymous (type-only), but it can
// still have a name
anon_param
: named_arg ':' ty { $$ = mk_node("Arg", 2, $1, $3); }
| ty
;
anon_params_allow_variadic_tail
: ',' DOTDOTDOT { $$ = mk_none(); }
| ',' anon_param anon_params_allow_variadic_tail { $$ = mk_node("Args", 2, $2, $3); }
| %empty { $$ = mk_none(); }
;
named_arg
: ident
| UNDERSCORE { $$ = mk_atom("PatWild"); }
| '&' ident { $$ = $2; }
| '&' UNDERSCORE { $$ = mk_atom("PatWild"); }
| ANDAND ident { $$ = $2; }
| ANDAND UNDERSCORE { $$ = mk_atom("PatWild"); }
| MUT ident { $$ = $2; }
;
ret_ty
: RARROW '!' { $$ = mk_none(); }
| RARROW ty { $$ = mk_node("ret-ty", 1, $2); }
| %prec IDENT %empty { $$ = mk_none(); }
;
generic_params
: '<' lifetimes '>' { $$ = mk_node("Generics", 2, $2, mk_none()); }
| '<' lifetimes ',' '>' { $$ = mk_node("Generics", 2, $2, mk_none()); }
| '<' lifetimes SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
| '<' lifetimes ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
| '<' lifetimes ',' ty_params '>' { $$ = mk_node("Generics", 2, $2, $4); }
| '<' lifetimes ',' ty_params ',' '>' { $$ = mk_node("Generics", 2, $2, $4); }
| '<' lifetimes ',' ty_params SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
| '<' lifetimes ',' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
| '<' ty_params '>' { $$ = mk_node("Generics", 2, mk_none(), $2); }
| '<' ty_params ',' '>' { $$ = mk_node("Generics", 2, mk_none(), $2); }
| '<' ty_params SHR { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
| '<' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
| %empty { $$ = mk_none(); }
;
maybe_where_clause
: %empty { $$ = mk_none(); }
| where_clause
;
where_clause
: WHERE where_predicates { $$ = mk_node("WhereClause", 1, $2); }
| WHERE where_predicates ',' { $$ = mk_node("WhereClause", 1, $2); }
;
where_predicates
: where_predicate { $$ = mk_node("WherePredicates", 1, $1); }
| where_predicates ',' where_predicate { $$ = ext_node($1, 1, $3); }
;
where_predicate
: maybe_for_lifetimes lifetime ':' bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
| maybe_for_lifetimes ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
;
maybe_for_lifetimes
: FOR '<' lifetimes '>' { $$ = mk_none(); }
| %prec FORTYPE %empty { $$ = mk_none(); }
ty_params
: ty_param { $$ = mk_node("TyParams", 1, $1); }
| ty_params ',' ty_param { $$ = ext_node($1, 1, $3); }
;
// A path with no type parameters; e.g. `foo::bar::Baz`
//
// These show up in 'use' view-items, because these are processed
// without respect to types.
path_no_types_allowed
: ident { $$ = mk_node("ViewPath", 1, $1); }
| MOD_SEP ident { $$ = mk_node("ViewPath", 1, $2); }
| SELF { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
| MOD_SEP SELF { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
| path_no_types_allowed MOD_SEP ident { $$ = ext_node($1, 1, $3); }
;
// A path with a lifetime and type parameters, with no double colons
// before the type parameters; e.g. `foo::bar<'a>::Baz<T>`
//
// These show up in "trait references", the components of
// type-parameter bounds lists, as well as in the prefix of the
// path_generic_args_and_bounds rule, which is the full form of a
// named typed expression.
//
// They do not have (nor need) an extra '::' before '<' because
// unlike in expr context, there are no "less-than" type exprs to
// be ambiguous with.
path_generic_args_without_colons
: %prec IDENT
ident { $$ = mk_node("components", 1, $1); }
| %prec IDENT
ident generic_args { $$ = mk_node("components", 2, $1, $2); }
| %prec IDENT
ident '(' maybe_ty_sums ')' ret_ty { $$ = mk_node("components", 2, $1, $3); }
| %prec IDENT
path_generic_args_without_colons MOD_SEP ident { $$ = ext_node($1, 1, $3); }
| %prec IDENT
path_generic_args_without_colons MOD_SEP ident generic_args { $$ = ext_node($1, 2, $3, $4); }
| %prec IDENT
path_generic_args_without_colons MOD_SEP ident '(' maybe_ty_sums ')' ret_ty { $$ = ext_node($1, 2, $3, $5); }
;
generic_args
: '<' generic_values '>' { $$ = $2; }
| '<' generic_values SHR { push_back('>'); $$ = $2; }
| '<' generic_values GE { push_back('='); $$ = $2; }
| '<' generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
// If generic_args starts with "<<", the first arg must be a
// TyQualifiedPath because that's the only type that can start with a
// '<'. This rule parses that as the first ty_sum and then continues
// with the rest of generic_values.
| SHL ty_qualified_path_and_generic_values '>' { $$ = $2; }
| SHL ty_qualified_path_and_generic_values SHR { push_back('>'); $$ = $2; }
| SHL ty_qualified_path_and_generic_values GE { push_back('='); $$ = $2; }
| SHL ty_qualified_path_and_generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
;
generic_values
: maybe_lifetimes maybe_ty_sums_and_or_bindings { $$ = mk_node("GenericValues", 2, $1, $2); }
;
maybe_ty_sums_and_or_bindings
: ty_sums
| ty_sums ','
| ty_sums ',' bindings { $$ = mk_node("TySumsAndBindings", 2, $1, $3); }
| bindings
| bindings ','
| %empty { $$ = mk_none(); }
;
maybe_bindings
: ',' bindings { $$ = $2; }
| %empty { $$ = mk_none(); }
;
////////////////////////////////////////////////////////////////////////
// Part 2: Patterns
////////////////////////////////////////////////////////////////////////
pat
: UNDERSCORE { $$ = mk_atom("PatWild"); }
| '&' pat { $$ = mk_node("PatRegion", 1, $2); }
| '&' MUT pat { $$ = mk_node("PatRegion", 1, $3); }
| ANDAND pat { $$ = mk_node("PatRegion", 1, mk_node("PatRegion", 1, $2)); }
| '(' ')' { $$ = mk_atom("PatUnit"); }
| '(' pat_tup ')' { $$ = mk_node("PatTup", 1, $2); }
| '(' pat_tup ',' ')' { $$ = mk_node("PatTup", 1, $2); }
| '[' pat_vec ']' { $$ = mk_node("PatVec", 1, $2); }
| lit_or_path
| lit_or_path DOTDOTDOT lit_or_path { $$ = mk_node("PatRange", 2, $1, $3); }
| path_expr '{' pat_struct '}' { $$ = mk_node("PatStruct", 2, $1, $3); }
| path_expr '(' DOTDOT ')' { $$ = mk_node("PatEnum", 1, $1); }
| path_expr '(' pat_tup ')' { $$ = mk_node("PatEnum", 2, $1, $3); }
| path_expr '!' maybe_ident delimited_token_trees { $$ = mk_node("PatMac", 3, $1, $3, $4); }
| binding_mode ident { $$ = mk_node("PatIdent", 2, $1, $2); }
| ident '@' pat { $$ = mk_node("PatIdent", 3, mk_node("BindByValue", 1, mk_atom("MutImmutable")), $1, $3); }
| binding_mode ident '@' pat { $$ = mk_node("PatIdent", 3, $1, $2, $4); }
| BOX pat { $$ = mk_node("PatUniq", 1, $2); }
| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("PatQualifiedPath", 3, $2, $3, $6); }
| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
{
$$ = mk_node("PatQualifiedPath", 3, mk_node("PatQualifiedPath", 3, $2, $3, $6), $7, $10);
}
;
pats_or
: pat { $$ = mk_node("Pats", 1, $1); }
| pats_or '|' pat { $$ = ext_node($1, 1, $3); }
;
binding_mode
: REF { $$ = mk_node("BindByRef", 1, mk_atom("MutImmutable")); }
| REF MUT { $$ = mk_node("BindByRef", 1, mk_atom("MutMutable")); }
| MUT { $$ = mk_node("BindByValue", 1, mk_atom("MutMutable")); }
;
lit_or_path
: path_expr { $$ = mk_node("PatLit", 1, $1); }
| lit { $$ = mk_node("PatLit", 1, $1); }
| '-' lit { $$ = mk_node("PatLit", 1, $2); }
;
pat_field
: ident { $$ = mk_node("PatField", 1, $1); }
| binding_mode ident { $$ = mk_node("PatField", 2, $1, $2); }
| BOX ident { $$ = mk_node("PatField", 2, mk_atom("box"), $2); }
| BOX binding_mode ident { $$ = mk_node("PatField", 3, mk_atom("box"), $2, $3); }
| ident ':' pat { $$ = mk_node("PatField", 2, $1, $3); }
| binding_mode ident ':' pat { $$ = mk_node("PatField", 3, $1, $2, $4); }
;
pat_fields
: pat_field { $$ = mk_node("PatFields", 1, $1); }
| pat_fields ',' pat_field { $$ = ext_node($1, 1, $3); }
;
pat_struct
: pat_fields { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
| pat_fields ',' { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
| pat_fields ',' DOTDOT { $$ = mk_node("PatStruct", 2, $1, mk_atom("true")); }
| DOTDOT { $$ = mk_node("PatStruct", 1, mk_atom("true")); }
;
pat_tup
: pat { $$ = mk_node("pat_tup", 1, $1); }
| pat_tup ',' pat { $$ = ext_node($1, 1, $3); }
;
pat_vec
: pat_vec_elts { $$ = mk_node("PatVec", 2, $1, mk_none()); }
| pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, mk_none()); }
| pat_vec_elts DOTDOT { $$ = mk_node("PatVec", 2, $1, mk_none()); }
| pat_vec_elts ',' DOTDOT { $$ = mk_node("PatVec", 2, $1, mk_none()); }
| pat_vec_elts DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, $1, $4); }
| pat_vec_elts DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, $4); }
| pat_vec_elts ',' DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, $1, $5); }
| pat_vec_elts ',' DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, $5); }
| DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, mk_none(), $3); }
| DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, mk_none(), $3); }
| DOTDOT { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
| %empty { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
;
pat_vec_elts
: pat { $$ = mk_node("PatVecElts", 1, $1); }
| pat_vec_elts ',' pat { $$ = ext_node($1, 1, $3); }
;
////////////////////////////////////////////////////////////////////////
// Part 3: Types
////////////////////////////////////////////////////////////////////////
ty
: ty_prim
| ty_closure
| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, $2, $3, $6); }
| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, mk_node("TyQualifiedPath", 3, $2, $3, $6), $7, $10); }
| '(' ty_sums ')' { $$ = mk_node("TyTup", 1, $2); }
| '(' ty_sums ',' ')' { $$ = mk_node("TyTup", 1, $2); }
| '(' ')' { $$ = mk_atom("TyNil"); }
;
ty_prim
: %prec IDENT path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("false")), $1); }
| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("true")), $2); }
| %prec IDENT SELF MOD_SEP path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("self", 1, mk_atom("true")), $3); }
| BOX ty { $$ = mk_node("TyBox", 1, $2); }
| '*' maybe_mut_or_const ty { $$ = mk_node("TyPtr", 2, $2, $3); }
| '&' ty { $$ = mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2); }
| '&' MUT ty { $$ = mk_node("TyRptr", 2, mk_atom("MutMutable"), $3); }
| ANDAND ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2)); }
| ANDAND MUT ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutMutable"), $3)); }
| '&' lifetime maybe_mut ty { $$ = mk_node("TyRptr", 3, $2, $3, $4); }
| ANDAND lifetime maybe_mut ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 3, $2, $3, $4)); }
| '[' ty ']' { $$ = mk_node("TyVec", 1, $2); }
| '[' ty ',' DOTDOT expr ']' { $$ = mk_node("TyFixedLengthVec", 2, $2, $5); }
| '[' ty ';' expr ']' { $$ = mk_node("TyFixedLengthVec", 2, $2, $4); }
| TYPEOF '(' expr ')' { $$ = mk_node("TyTypeof", 1, $3); }
| UNDERSCORE { $$ = mk_atom("TyInfer"); }
| ty_bare_fn
| ty_proc
| for_in_type
;
ty_bare_fn
: FN ty_fn_decl { $$ = $2; }
| UNSAFE FN ty_fn_decl { $$ = $3; }
| EXTERN maybe_abi FN ty_fn_decl { $$ = $4; }
| UNSAFE EXTERN maybe_abi FN ty_fn_decl { $$ = $5; }
;
ty_fn_decl
: generic_params fn_anon_params ret_ty { $$ = mk_node("TyFnDecl", 3, $1, $2, $3); }
;
ty_closure
: UNSAFE '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $3, $5, $6); }
| '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $2, $4, $5); }
| UNSAFE OROR maybe_bounds ret_ty { $$ = mk_node("TyClosure", 2, $3, $4); }
| OROR maybe_bounds ret_ty { $$ = mk_node("TyClosure", 2, $2, $3); }
;
ty_proc
: PROC generic_params fn_params maybe_bounds ret_ty { $$ = mk_node("TyProc", 4, $2, $3, $4, $5); }
;
for_in_type
: FOR '<' maybe_lifetimes '>' for_in_type_suffix { $$ = mk_node("ForInType", 2, $3, $5); }
;
for_in_type_suffix
: ty_proc
| ty_bare_fn
| trait_ref
| ty_closure
;
maybe_mut
: MUT { $$ = mk_atom("MutMutable"); }
| %prec MUT %empty { $$ = mk_atom("MutImmutable"); }
;
maybe_mut_or_const
: MUT { $$ = mk_atom("MutMutable"); }
| CONST { $$ = mk_atom("MutImmutable"); }
| %empty { $$ = mk_atom("MutImmutable"); }
;
ty_qualified_path_and_generic_values
: ty_qualified_path maybe_bindings
{
$$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 1, mk_node("TySum", 1, $1)), $2);
}
| ty_qualified_path ',' ty_sums maybe_bindings
{
$$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 2, $1, $3), $4);
}
;
ty_qualified_path
: ty_sum AS trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
| ty_sum AS trait_ref '>' MOD_SEP ident '+' ty_param_bounds { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
;
maybe_ty_sums
: ty_sums
| ty_sums ','
| %empty { $$ = mk_none(); }
;
ty_sums
: ty_sum { $$ = mk_node("TySums", 1, $1); }
| ty_sums ',' ty_sum { $$ = ext_node($1, 1, $3); }
;
ty_sum
: ty { $$ = mk_node("TySum", 1, $1); }
| ty '+' ty_param_bounds { $$ = mk_node("TySum", 2, $1, $3); }
;
ty_prim_sum
: ty_prim { $$ = mk_node("TySum", 1, $1); }
| ty_prim '+' ty_param_bounds { $$ = mk_node("TySum", 2, $1, $3); }
;
maybe_ty_param_bounds
: ':' ty_param_bounds { $$ = $2; }
| %empty { $$ = mk_none(); }
;
ty_param_bounds
: boundseq
| %empty { $$ = mk_none(); }
;
boundseq
: polybound
| boundseq '+' polybound { $$ = ext_node($1, 1, $3); }
;
polybound
: FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $3, $5); }
| bound
| '?' bound { $$ = $2; }
;
bindings
: binding { $$ = mk_node("Bindings", 1, $1); }
| bindings ',' binding { $$ = ext_node($1, 1, $3); }
;
binding
: ident '=' ty { mk_node("Binding", 2, $1, $3); }
;
ty_param
: ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 3, $1, $2, $3); }
| ident '?' ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 4, $1, $3, $4, $5); }
;
maybe_bounds
: %prec SHIFTPLUS
':' bounds { $$ = $2; }
| %prec SHIFTPLUS %empty { $$ = mk_none(); }
;
bounds
: bound { $$ = mk_node("bounds", 1, $1); }
| bounds '+' bound { $$ = ext_node($1, 1, $3); }
;
bound
: lifetime
| trait_ref
;
maybe_ltbounds
: %prec SHIFTPLUS
':' ltbounds { $$ = $2; }
| %empty { $$ = mk_none(); }
;
ltbounds
: lifetime { $$ = mk_node("ltbounds", 1, $1); }
| ltbounds '+' lifetime { $$ = ext_node($1, 1, $3); }
;
maybe_ty_default
: '=' ty_sum { $$ = mk_node("TyDefault", 1, $2); }
| %empty { $$ = mk_none(); }
;
maybe_lifetimes
: lifetimes
| lifetimes ','
| %empty { $$ = mk_none(); }
;
lifetimes
: lifetime_and_bounds { $$ = mk_node("Lifetimes", 1, $1); }
| lifetimes ',' lifetime_and_bounds { $$ = ext_node($1, 1, $3); }
;
lifetime_and_bounds
: LIFETIME maybe_ltbounds { $$ = mk_node("lifetime", 2, mk_atom(yytext), $2); }
| STATIC_LIFETIME { $$ = mk_atom("static_lifetime"); }
;
lifetime
: LIFETIME { $$ = mk_node("lifetime", 1, mk_atom(yytext)); }
| STATIC_LIFETIME { $$ = mk_atom("static_lifetime"); }
;
trait_ref
: %prec IDENT path_generic_args_without_colons
| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = $2; }
;
////////////////////////////////////////////////////////////////////////
// Part 4: Blocks, statements, and expressions
////////////////////////////////////////////////////////////////////////
inner_attrs_and_block
: '{' maybe_inner_attrs maybe_stmts '}' { $$ = mk_node("ExprBlock", 2, $2, $3); }
;
block
: '{' maybe_stmts '}' { $$ = mk_node("ExprBlock", 1, $2); }
;
maybe_stmts
: stmts
| stmts nonblock_expr { $$ = ext_node($1, 1, $2); }
| nonblock_expr
| %empty { $$ = mk_none(); }
;
// There are two sub-grammars within a "stmts: exprs" derivation
// depending on whether each stmt-expr is a block-expr form; this is to
// handle the "semicolon rule" for stmt sequencing that permits
// writing
//
// if foo { bar } 10
//
// as a sequence of two stmts (one if-expr stmt, one lit-10-expr
// stmt). Unfortunately by permitting juxtaposition of exprs in
// sequence like that, the non-block expr grammar has to have a
// second limited sub-grammar that excludes the prefix exprs that
// are ambiguous with binops. That is to say:
//
// {10} - 1
//
// should parse as (progn (progn 10) (- 1)) not (- (progn 10) 1), that
// is to say, two statements rather than one, at least according to
// the mainline rust parser.
//
// So we wind up with a 3-way split in exprs that occur in stmt lists:
// block, nonblock-prefix, and nonblock-nonprefix.
//
// In non-stmts contexts, expr can relax this trichotomy.
//
// There is also one other expr subtype: nonparen_expr disallows exprs
// surrounded by parens (including tuple expressions), this is
// necessary for BOX (place) expressions, so a parens expr following
// the BOX is always parsed as the place.
stmts
: stmt { $$ = mk_node("stmts", 1, $1); }
| stmts stmt { $$ = ext_node($1, 1, $2); }
;
stmt
: let
| stmt_item
| PUB stmt_item { $$ = $2; }
| outer_attrs stmt_item { $$ = $2; }
| outer_attrs PUB stmt_item { $$ = $3; }
| full_block_expr
| block
| nonblock_expr ';'
| ';' { $$ = mk_none(); }
;
maybe_exprs
: exprs
| exprs ','
| %empty { $$ = mk_none(); }
;
maybe_expr
: expr
| %empty { $$ = mk_none(); }
;
exprs
: expr { $$ = mk_node("exprs", 1, $1); }
| exprs ',' expr { $$ = ext_node($1, 1, $3); }
;
path_expr
: path_generic_args_with_colons
| MOD_SEP path_generic_args_with_colons { $$ = $2; }
| SELF MOD_SEP path_generic_args_with_colons { $$ = mk_node("SelfPath", 1, $3); }
;
// A path with a lifetime and type parameters with double colons before
// the type parameters; e.g. `foo::bar::<'a>::Baz::<T>`
//
// These show up in expr context, in order to disambiguate from "less-than"
// expressions.
path_generic_args_with_colons
: ident { $$ = mk_node("components", 1, $1); }
| path_generic_args_with_colons MOD_SEP ident { $$ = ext_node($1, 1, $3); }
| path_generic_args_with_colons MOD_SEP generic_args { $$ = ext_node($1, 1, $3); }
;
// the braces-delimited macro is a block_expr so it doesn't appear here
macro_expr
: path_expr '!' maybe_ident parens_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
| path_expr '!' maybe_ident brackets_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
;
nonblock_expr
: lit { $$ = mk_node("ExprLit", 1, $1); }
| %prec IDENT
path_expr { $$ = mk_node("ExprPath", 1, $1); }
| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
| nonblock_expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
| nonblock_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
| nonblock_expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
| nonblock_expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
| CONTINUE { $$ = mk_node("ExprAgain", 0); }
| CONTINUE lifetime { $$ = mk_node("ExprAgain", 1, $2); }
| RETURN { $$ = mk_node("ExprRet", 0); }
| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
| BREAK { $$ = mk_node("ExprBreak", 0); }
| BREAK lifetime { $$ = mk_node("ExprBreak", 1, $2); }
| nonblock_expr LARROW expr { $$ = mk_node("ExprInPlace", 2, $1, $3); }
| nonblock_expr '=' expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
| nonblock_expr SHLEQ expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
| nonblock_expr SHREQ expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
| nonblock_expr MINUSEQ expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
| nonblock_expr ANDEQ expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
| nonblock_expr OREQ expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
| nonblock_expr PLUSEQ expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
| nonblock_expr STAREQ expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
| nonblock_expr SLASHEQ expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
| nonblock_expr CARETEQ expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
| nonblock_expr PERCENTEQ expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
| nonblock_expr OROR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
| nonblock_expr ANDAND expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
| nonblock_expr EQEQ expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
| nonblock_expr NE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
| nonblock_expr '<' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
| nonblock_expr '>' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
| nonblock_expr LE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
| nonblock_expr GE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
| nonblock_expr '|' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
| nonblock_expr '^' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
| nonblock_expr '&' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
| nonblock_expr SHL expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
| nonblock_expr SHR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
| nonblock_expr '+' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
| nonblock_expr '-' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
| nonblock_expr '*' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
| nonblock_expr '/' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
| nonblock_expr '%' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
| nonblock_expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
| nonblock_expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); }
| DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
| nonblock_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
| BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); }
| %prec BOXPLACE BOX '(' maybe_expr ')' nonblock_expr { $$ = mk_node("ExprBox", 2, $3, $5); }
| expr_qualified_path
| nonblock_prefix_expr
;
expr
: lit { $$ = mk_node("ExprLit", 1, $1); }
| %prec IDENT
path_expr { $$ = mk_node("ExprPath", 1, $1); }
| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
| expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
| expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
| expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
| expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
| CONTINUE { $$ = mk_node("ExprAgain", 0); }
| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
| RETURN { $$ = mk_node("ExprRet", 0); }
| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
| BREAK { $$ = mk_node("ExprBreak", 0); }
| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
| expr LARROW expr { $$ = mk_node("ExprInPlace", 2, $1, $3); }
| expr '=' expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
| expr SHLEQ expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
| expr SHREQ expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
| expr MINUSEQ expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
| expr ANDEQ expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
| expr OREQ expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
| expr PLUSEQ expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
| expr STAREQ expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
| expr SLASHEQ expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
| expr CARETEQ expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
| expr PERCENTEQ expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
| expr OROR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
| expr ANDAND expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
| expr EQEQ expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
| expr NE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
| expr '<' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
| expr '>' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
| expr LE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
| expr GE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
| expr '|' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
| expr '^' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
| expr '&' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
| expr SHL expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
| expr SHR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
| expr '+' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
| expr '-' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
| expr '*' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
| expr '/' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
| expr '%' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
| expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
| expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); }
| DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
| expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
| BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); }
| %prec BOXPLACE BOX '(' maybe_expr ')' expr { $$ = mk_node("ExprBox", 2, $3, $5); }
| expr_qualified_path
| block_expr
| block
| nonblock_prefix_expr
;
nonparen_expr
: lit { $$ = mk_node("ExprLit", 1, $1); }
| %prec IDENT
path_expr { $$ = mk_node("ExprPath", 1, $1); }
| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
| nonparen_expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
| nonparen_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
| nonparen_expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
| nonparen_expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
| CONTINUE { $$ = mk_node("ExprAgain", 0); }
| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
| RETURN { $$ = mk_node("ExprRet", 0); }
| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
| BREAK { $$ = mk_node("ExprBreak", 0); }
| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
| nonparen_expr LARROW nonparen_expr { $$ = mk_node("ExprInPlace", 2, $1, $3); }
| nonparen_expr '=' nonparen_expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
| nonparen_expr SHLEQ nonparen_expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
| nonparen_expr SHREQ nonparen_expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
| nonparen_expr MINUSEQ nonparen_expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
| nonparen_expr ANDEQ nonparen_expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
| nonparen_expr OREQ nonparen_expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
| nonparen_expr PLUSEQ nonparen_expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
| nonparen_expr STAREQ nonparen_expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
| nonparen_expr SLASHEQ nonparen_expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
| nonparen_expr CARETEQ nonparen_expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
| nonparen_expr PERCENTEQ nonparen_expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
| nonparen_expr OROR nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
| nonparen_expr ANDAND nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
| nonparen_expr EQEQ nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
| nonparen_expr NE nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
| nonparen_expr '<' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
| nonparen_expr '>' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
| nonparen_expr LE nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
| nonparen_expr GE nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
| nonparen_expr '|' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
| nonparen_expr '^' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
| nonparen_expr '&' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
| nonparen_expr SHL nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
| nonparen_expr SHR nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
| nonparen_expr '+' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
| nonparen_expr '-' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
| nonparen_expr '*' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
| nonparen_expr '/' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
| nonparen_expr '%' nonparen_expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
| nonparen_expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
| nonparen_expr DOTDOT nonparen_expr { $$ = mk_node("ExprRange", 2, $1, $3); }
| DOTDOT nonparen_expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
| nonparen_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
| BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); }
| %prec BOXPLACE BOX '(' maybe_expr ')' expr { $$ = mk_node("ExprBox", 1, $3, $5); }
| expr_qualified_path
| block_expr
| block
| nonblock_prefix_expr
;
expr_nostruct
: lit { $$ = mk_node("ExprLit", 1, $1); }
| %prec IDENT
path_expr { $$ = mk_node("ExprPath", 1, $1); }
| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
| expr_nostruct '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
| expr_nostruct '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
| expr_nostruct '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
| expr_nostruct '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
| CONTINUE { $$ = mk_node("ExprAgain", 0); }
| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
| RETURN { $$ = mk_node("ExprRet", 0); }
| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
| BREAK { $$ = mk_node("ExprBreak", 0); }
| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
| expr_nostruct LARROW expr_nostruct { $$ = mk_node("ExprInPlace", 2, $1, $3); }
| expr_nostruct '=' expr_nostruct { $$ = mk_node("ExprAssign", 2, $1, $3); }
| expr_nostruct SHLEQ expr_nostruct { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
| expr_nostruct SHREQ expr_nostruct { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
| expr_nostruct MINUSEQ expr_nostruct { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
| expr_nostruct ANDEQ expr_nostruct { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
| expr_nostruct OREQ expr_nostruct { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
| expr_nostruct PLUSEQ expr_nostruct { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
| expr_nostruct STAREQ expr_nostruct { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
| expr_nostruct SLASHEQ expr_nostruct { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
| expr_nostruct CARETEQ expr_nostruct { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
| expr_nostruct PERCENTEQ expr_nostruct { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
| expr_nostruct OROR expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
| expr_nostruct ANDAND expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
| expr_nostruct EQEQ expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
| expr_nostruct NE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
| expr_nostruct '<' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
| expr_nostruct '>' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
| expr_nostruct LE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
| expr_nostruct GE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
| expr_nostruct '|' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
| expr_nostruct '^' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
| expr_nostruct '&' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
| expr_nostruct SHL expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
| expr_nostruct SHR expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
| expr_nostruct '+' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
| expr_nostruct '-' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
| expr_nostruct '*' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
| expr_nostruct '/' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
| expr_nostruct '%' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
| expr_nostruct DOTDOT %prec RANGE { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
| expr_nostruct DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, $1, $3); }
| DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
| expr_nostruct AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
| BOX nonparen_expr { $$ = mk_node("ExprBox", 1, $2); }
| %prec BOXPLACE BOX '(' maybe_expr ')' expr_nostruct { $$ = mk_node("ExprBox", 1, $3, $5); }
| expr_qualified_path
| block_expr
| block
| nonblock_prefix_expr_nostruct
;
nonblock_prefix_expr_nostruct
: '-' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
| '!' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
| '*' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
| '&' maybe_mut expr_nostruct { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
| ANDAND maybe_mut expr_nostruct { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
| lambda_expr_nostruct
| MOVE lambda_expr_nostruct { $$ = $2; }
| proc_expr_nostruct
;
nonblock_prefix_expr
: '-' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
| '!' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
| '*' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
| '&' maybe_mut expr { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
| ANDAND maybe_mut expr { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
| lambda_expr
| MOVE lambda_expr { $$ = $2; }
| proc_expr
;
expr_qualified_path
: '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_qpath_params
{
$$ = mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7);
}
| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
{
$$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10);
}
| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident
{
$$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11);
}
| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident generic_args
{
$$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10, $11);
}
| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident generic_args
{
$$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11, $12);
}
maybe_qpath_params
: MOD_SEP generic_args { $$ = $2; }
| %empty { $$ = mk_none(); }
;
maybe_as_trait_ref
: AS trait_ref { $$ = $2; }
| %empty { $$ = mk_none(); }
;
lambda_expr
: %prec LAMBDA
OROR ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
| %prec LAMBDA
'|' maybe_unboxed_closure_kind '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $4, $5); }
| %prec LAMBDA
'|' inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $2, $4, $5); }
| %prec LAMBDA
'|' '&' maybe_mut ':' inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $5, $7, $8); }
| %prec LAMBDA
'|' ':' inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $3, $5, $6); }
;
lambda_expr_nostruct
: %prec LAMBDA
OROR expr_nostruct { $$ = mk_node("ExprFnBlock", 2, mk_none(), $2); }
| %prec LAMBDA
'|' maybe_unboxed_closure_kind '|' expr_nostruct { $$ = mk_node("ExprFnBlock", 2, mk_none(), $4); }
| %prec LAMBDA
'|' inferrable_params '|' expr_nostruct { $$ = mk_node("ExprFnBlock", 2, $2, $4); }
| %prec LAMBDA
'|' '&' maybe_mut ':' inferrable_params '|' expr_nostruct { $$ = mk_node("ExprFnBlock", 2, $5, $7); }
| %prec LAMBDA
'|' ':' inferrable_params '|' expr_nostruct { $$ = mk_node("ExprFnBlock", 2, $3, $5); }
;
proc_expr
: %prec LAMBDA
PROC '(' ')' expr { $$ = mk_node("ExprProc", 2, mk_none(), $4); }
| %prec LAMBDA
PROC '(' inferrable_params ')' expr { $$ = mk_node("ExprProc", 2, $3, $5); }
;
proc_expr_nostruct
: %prec LAMBDA
PROC '(' ')' expr_nostruct { $$ = mk_node("ExprProc", 2, mk_none(), $4); }
| %prec LAMBDA
PROC '(' inferrable_params ')' expr_nostruct { $$ = mk_node("ExprProc", 2, $3, $5); }
;
vec_expr
: maybe_exprs
| exprs ';' expr { $$ = mk_node("VecRepeat", 2, $1, $3); }
;
struct_expr_fields
: field_inits
| field_inits ','
| maybe_field_inits default_field_init { $$ = ext_node($1, 1, $2); }
;
maybe_field_inits
: field_inits
| field_inits ','
| %empty { $$ = mk_none(); }
;
field_inits
: field_init { $$ = mk_node("FieldInits", 1, $1); }
| field_inits ',' field_init { $$ = ext_node($1, 1, $3); }
;
field_init
: ident ':' expr { $$ = mk_node("FieldInit", 2, $1, $3); }
;
default_field_init
: DOTDOT expr { $$ = mk_node("DefaultFieldInit", 1, $2); }
;
block_expr
: expr_match
| expr_if
| expr_if_let
| expr_while
| expr_while_let
| expr_loop
| expr_for
| UNSAFE block { $$ = mk_node("UnsafeBlock", 1, $2); }
| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("Macro", 3, $1, $3, $4); }
;
full_block_expr
: block_expr
| full_block_expr '.' path_generic_args_with_colons %prec IDENT { $$ = mk_node("ExprField", 2, $1, $3); }
| full_block_expr '.' path_generic_args_with_colons '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
| full_block_expr '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
| full_block_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
;
expr_match
: MATCH expr_nostruct '{' '}' { $$ = mk_node("ExprMatch", 1, $2); }
| MATCH expr_nostruct '{' match_clauses '}' { $$ = mk_node("ExprMatch", 2, $2, $4); }
| MATCH expr_nostruct '{' match_clauses nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, ext_node($4, 1, $5)); }
| MATCH expr_nostruct '{' nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, mk_node("Arms", 1, $4)); }
;
match_clauses
: match_clause { $$ = mk_node("Arms", 1, $1); }
| match_clauses match_clause { $$ = ext_node($1, 1, $2); }
;
match_clause
: nonblock_match_clause ','
| block_match_clause
| block_match_clause ','
;
nonblock_match_clause
: maybe_outer_attrs pats_or maybe_guard FAT_ARROW nonblock_expr { $$ = mk_node("Arm", 4, $1, $2, $3, $5); }
| maybe_outer_attrs pats_or maybe_guard FAT_ARROW full_block_expr { $$ = mk_node("Arm", 4, $1, $2, $3, $5); }
;
block_match_clause
: maybe_outer_attrs pats_or maybe_guard FAT_ARROW block { $$ = mk_node("Arm", 4, $1, $2, $3, $5); }
;
maybe_guard
: IF expr_nostruct { $$ = $2; }
| %empty { $$ = mk_none(); }
;
expr_if
: IF expr_nostruct block { $$ = mk_node("ExprIf", 2, $2, $3); }
| IF expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIf", 3, $2, $3, $5); }
;
expr_if_let
: IF LET pat '=' expr_nostruct block { $$ = mk_node("ExprIfLet", 3, $3, $5, $6); }
| IF LET pat '=' expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIfLet", 4, $3, $5, $6, $8); }
;
block_or_if
: block
| expr_if
| expr_if_let
;
expr_while
: maybe_label WHILE expr_nostruct block { $$ = mk_node("ExprWhile", 3, $1, $3, $4); }
;
expr_while_let
: maybe_label WHILE LET pat '=' expr_nostruct block { $$ = mk_node("ExprWhileLet", 4, $1, $4, $6, $7); }
;
expr_loop
: maybe_label LOOP block { $$ = mk_node("ExprLoop", 2, $1, $3); }
;
expr_for
: maybe_label FOR pat IN expr_nostruct block { $$ = mk_node("ExprForLoop", 4, $1, $3, $5, $6); }
;
maybe_label
: lifetime ':'
| %empty { $$ = mk_none(); }
;
let
: LET pat maybe_ty_ascription maybe_init_expr ';' { $$ = mk_node("DeclLocal", 3, $2, $3, $4); }
;
////////////////////////////////////////////////////////////////////////
// Part 5: Macros and misc. rules
////////////////////////////////////////////////////////////////////////
lit
: LIT_BYTE { $$ = mk_node("LitByte", 1, mk_atom(yytext)); }
| LIT_CHAR { $$ = mk_node("LitChar", 1, mk_atom(yytext)); }
| LIT_INTEGER { $$ = mk_node("LitInteger", 1, mk_atom(yytext)); }
| LIT_FLOAT { $$ = mk_node("LitFloat", 1, mk_atom(yytext)); }
| TRUE { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
| FALSE { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
| str
;
str
: LIT_STR { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("CookedStr")); }
| LIT_STR_RAW { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("RawStr")); }
| LIT_BYTE_STR { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("ByteStr")); }
| LIT_BYTE_STR_RAW { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("RawByteStr")); }
;
maybe_ident
: %empty { $$ = mk_none(); }
| ident
;
ident
: IDENT { $$ = mk_node("ident", 1, mk_atom(yytext)); }
;
unpaired_token
: SHL { $$ = mk_atom(yytext); }
| SHR { $$ = mk_atom(yytext); }
| LE { $$ = mk_atom(yytext); }
| EQEQ { $$ = mk_atom(yytext); }
| NE { $$ = mk_atom(yytext); }
| GE { $$ = mk_atom(yytext); }
| ANDAND { $$ = mk_atom(yytext); }
| OROR { $$ = mk_atom(yytext); }
| LARROW { $$ = mk_atom(yytext); }
| SHLEQ { $$ = mk_atom(yytext); }
| SHREQ { $$ = mk_atom(yytext); }
| MINUSEQ { $$ = mk_atom(yytext); }
| ANDEQ { $$ = mk_atom(yytext); }
| OREQ { $$ = mk_atom(yytext); }
| PLUSEQ { $$ = mk_atom(yytext); }
| STAREQ { $$ = mk_atom(yytext); }
| SLASHEQ { $$ = mk_atom(yytext); }
| CARETEQ { $$ = mk_atom(yytext); }
| PERCENTEQ { $$ = mk_atom(yytext); }
| DOTDOT { $$ = mk_atom(yytext); }
| DOTDOTDOT { $$ = mk_atom(yytext); }
| MOD_SEP { $$ = mk_atom(yytext); }
| RARROW { $$ = mk_atom(yytext); }
| FAT_ARROW { $$ = mk_atom(yytext); }
| LIT_BYTE { $$ = mk_atom(yytext); }
| LIT_CHAR { $$ = mk_atom(yytext); }
| LIT_INTEGER { $$ = mk_atom(yytext); }
| LIT_FLOAT { $$ = mk_atom(yytext); }
| LIT_STR { $$ = mk_atom(yytext); }
| LIT_STR_RAW { $$ = mk_atom(yytext); }
| LIT_BYTE_STR { $$ = mk_atom(yytext); }
| LIT_BYTE_STR_RAW { $$ = mk_atom(yytext); }
| IDENT { $$ = mk_atom(yytext); }
| UNDERSCORE { $$ = mk_atom(yytext); }
| LIFETIME { $$ = mk_atom(yytext); }
| SELF { $$ = mk_atom(yytext); }
| STATIC { $$ = mk_atom(yytext); }
| AS { $$ = mk_atom(yytext); }
| BREAK { $$ = mk_atom(yytext); }
| CRATE { $$ = mk_atom(yytext); }
| ELSE { $$ = mk_atom(yytext); }
| ENUM { $$ = mk_atom(yytext); }
| EXTERN { $$ = mk_atom(yytext); }
| FALSE { $$ = mk_atom(yytext); }
| FN { $$ = mk_atom(yytext); }
| FOR { $$ = mk_atom(yytext); }
| IF { $$ = mk_atom(yytext); }
| IMPL { $$ = mk_atom(yytext); }
| IN { $$ = mk_atom(yytext); }
| LET { $$ = mk_atom(yytext); }
| LOOP { $$ = mk_atom(yytext); }
| MATCH { $$ = mk_atom(yytext); }
| MOD { $$ = mk_atom(yytext); }
| MOVE { $$ = mk_atom(yytext); }
| MUT { $$ = mk_atom(yytext); }
| PRIV { $$ = mk_atom(yytext); }
| PUB { $$ = mk_atom(yytext); }
| REF { $$ = mk_atom(yytext); }
| RETURN { $$ = mk_atom(yytext); }
| STRUCT { $$ = mk_atom(yytext); }
| TRUE { $$ = mk_atom(yytext); }
| TRAIT { $$ = mk_atom(yytext); }
| TYPE { $$ = mk_atom(yytext); }
| UNSAFE { $$ = mk_atom(yytext); }
| USE { $$ = mk_atom(yytext); }
| WHILE { $$ = mk_atom(yytext); }
| CONTINUE { $$ = mk_atom(yytext); }
| PROC { $$ = mk_atom(yytext); }
| BOX { $$ = mk_atom(yytext); }
| CONST { $$ = mk_atom(yytext); }
| WHERE { $$ = mk_atom(yytext); }
| TYPEOF { $$ = mk_atom(yytext); }
| INNER_DOC_COMMENT { $$ = mk_atom(yytext); }
| OUTER_DOC_COMMENT { $$ = mk_atom(yytext); }
| SHEBANG { $$ = mk_atom(yytext); }
| STATIC_LIFETIME { $$ = mk_atom(yytext); }
| ';' { $$ = mk_atom(yytext); }
| ',' { $$ = mk_atom(yytext); }
| '.' { $$ = mk_atom(yytext); }
| '@' { $$ = mk_atom(yytext); }
| '#' { $$ = mk_atom(yytext); }
| '~' { $$ = mk_atom(yytext); }
| ':' { $$ = mk_atom(yytext); }
| '$' { $$ = mk_atom(yytext); }
| '=' { $$ = mk_atom(yytext); }
| '?' { $$ = mk_atom(yytext); }
| '!' { $$ = mk_atom(yytext); }
| '<' { $$ = mk_atom(yytext); }
| '>' { $$ = mk_atom(yytext); }
| '-' { $$ = mk_atom(yytext); }
| '&' { $$ = mk_atom(yytext); }
| '|' { $$ = mk_atom(yytext); }
| '+' { $$ = mk_atom(yytext); }
| '*' { $$ = mk_atom(yytext); }
| '/' { $$ = mk_atom(yytext); }
| '^' { $$ = mk_atom(yytext); }
| '%' { $$ = mk_atom(yytext); }
;
token_trees
: %empty { $$ = mk_node("TokenTrees", 0); }
| token_trees token_tree { $$ = ext_node($1, 1, $2); }
;
token_tree
: delimited_token_trees
| unpaired_token { $$ = mk_node("TTTok", 1, $1); }
;
delimited_token_trees
: parens_delimited_token_trees
| braces_delimited_token_trees
| brackets_delimited_token_trees
;
parens_delimited_token_trees
: '(' token_trees ')'
{
$$ = mk_node("TTDelim", 3,
mk_node("TTTok", 1, mk_atom("(")),
$2,
mk_node("TTTok", 1, mk_atom(")")));
}
;
braces_delimited_token_trees
: '{' token_trees '}'
{
$$ = mk_node("TTDelim", 3,
mk_node("TTTok", 1, mk_atom("{")),
$2,
mk_node("TTTok", 1, mk_atom("}")));
}
;
brackets_delimited_token_trees
: '[' token_trees ']'
{
$$ = mk_node("TTDelim", 3,
mk_node("TTTok", 1, mk_atom("[")),
$2,
mk_node("TTTok", 1, mk_atom("]")));
}
;
@@ -1,64 +0,0 @@
Rust's lexical grammar is not context-free. Raw string literals are the source
of the problem. Informally, a raw string literal is an `r`, followed by `N`
hashes (where N can be zero), a quote, any characters, then a quote followed
by `N` hashes. Critically, once inside the first pair of quotes,
another quote cannot be followed by `N` consecutive hashes. e.g.
`r###""###"###` is invalid.
This grammar describes this as best possible:
R -> 'r' S
S -> '"' B '"'
S -> '#' S '#'
B -> . B
B -> ε
Where `.` represents any character, and `ε` the empty string. Consider the
string `r#""#"#`. This string is not a valid raw string literal, but can be
accepted as one by the above grammar, using the derivation:
R : #""#"#
S : ""#"
S : "#
B : #
B : ε
(Where `T : U` means the rule `T` is applied, and `U` is the remainder of the
string.) The difficulty arises from the fact that it is fundamentally
context-sensitive. In particular, the context needed is the number of hashes.
To prove that Rust's string literals are not context-free, we will use
the fact that context-free languages are closed under intersection with
regular languages, and the
[pumping lemma for context-free languages](https://en.wikipedia.org/wiki/Pumping_lemma_for_context-free_languages).
Consider the regular language `R = r#+""#*"#+`. If Rust's raw string literals are
context-free, then their intersection with `R`, `R'`, should also be context-free.
Therefore, to prove that raw string literals are not context-free,
it is sufficient to prove that `R'` is not context-free.
The language `R'` is `{r#^n""#^m"#^n | m < n}`.
Assume `R'` *is* context-free. Then `R'` has some pumping length `p > 0` for which
the pumping lemma applies. Consider the following string `s` in `R'`:
`r#^p""#^{p-1}"#^p`
e.g. for `p = 2`: `s = r##""#"##`
Then `s = uvwxy` for some choice of `uvwxy` such that `vx` is non-empty,
`|vwx| < p+1`, and `uv^iwx^iy` is in `R'` for all `i >= 0`.
Neither `v` nor `x` can contain a `"` or `r`, as the number of these characters
in any string in `R'` is fixed. So `v` and `x` contain only hashes.
Consequently, of the three sequences of hashes, `v` and `x` combined
can only pump two of them.
If we ever choose the central sequence of hashes, then one of the outer sequences
will not grow when we pump, leading to an imbalance between the outer sequences.
Therefore, we must pump both outer sequences of hashes. However,
there are `p+2` characters between these two sequences of hashes, and `|vwx|` must
be less than `p+1`. Therefore we have a contradiction, and `R'` must not be
context-free.
Since `R'` is not context-free, it follows that the Rust's raw string literals
must not be context-free.
-76
View File
@@ -1,76 +0,0 @@
#!/usr/bin/env python
#
# Copyright 2015 The Rust Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
# ignore-tidy-linelength
import sys
import os
import subprocess
import argparse
# usage: testparser.py [-h] [-p PARSER [PARSER ...]] -s SOURCE_DIR
# Parsers should read from stdin and return exit status 0 for a
# successful parse, and nonzero for an unsuccessful parse
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--parser', nargs='+')
parser.add_argument('-s', '--source-dir', nargs=1, required=True)
args = parser.parse_args(sys.argv[1:])
total = 0
ok = {}
bad = {}
for parser in args.parser:
ok[parser] = 0
bad[parser] = []
devnull = open(os.devnull, 'w')
print("\n")
for base, dirs, files in os.walk(args.source_dir[0]):
for f in filter(lambda p: p.endswith('.rs'), files):
p = os.path.join(base, f)
parse_fail = 'parse-fail' in p
if sys.version_info.major == 3:
lines = open(p, encoding='utf-8').readlines()
else:
lines = open(p).readlines()
if any('ignore-test' in line or 'ignore-lexer-test' in line for line in lines):
continue
total += 1
for parser in args.parser:
if subprocess.call(parser, stdin=open(p), stderr=subprocess.STDOUT, stdout=devnull) == 0:
if parse_fail:
bad[parser].append(p)
else:
ok[parser] += 1
else:
if parse_fail:
ok[parser] += 1
else:
bad[parser].append(p)
parser_stats = ', '.join(['{}: {}'.format(parser, ok[parser]) for parser in args.parser])
sys.stdout.write("\033[K\r total: {}, {}, scanned {}"
.format(total, os.path.relpath(parser_stats), os.path.relpath(p)))
devnull.close()
print("\n")
for parser in args.parser:
filename = os.path.basename(parser) + '.bad'
print("writing {} files that did not yield the correct result with {} to {}".format(len(bad[parser]), parser, filename))
with open(filename, "w") as f:
for p in bad[parser]:
f.write(p)
f.write("\n")
-91
View File
@@ -1,91 +0,0 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
enum Token {
SHL = 257, // Parser generators reserve 0-256 for char literals
SHR,
LE,
EQEQ,
NE,
GE,
ANDAND,
OROR,
SHLEQ,
SHREQ,
MINUSEQ,
ANDEQ,
OREQ,
PLUSEQ,
STAREQ,
SLASHEQ,
CARETEQ,
PERCENTEQ,
DOTDOT,
DOTDOTDOT,
MOD_SEP,
RARROW,
FAT_ARROW,
LIT_BYTE,
LIT_CHAR,
LIT_INTEGER,
LIT_FLOAT,
LIT_STR,
LIT_STR_RAW,
LIT_BYTE_STR,
LIT_BYTE_STR_RAW,
IDENT,
UNDERSCORE,
LIFETIME,
// keywords
SELF,
STATIC,
AS,
BREAK,
CRATE,
ELSE,
ENUM,
EXTERN,
FALSE,
FN,
FOR,
IF,
IMPL,
IN,
LET,
LOOP,
MATCH,
MOD,
MOVE,
MUT,
PRIV,
PUB,
REF,
RETURN,
STRUCT,
TRUE,
TRAIT,
TYPE,
UNSAFE,
USE,
WHILE,
CONTINUE,
PROC,
BOX,
CONST,
WHERE,
TYPEOF,
INNER_DOC_COMMENT,
OUTER_DOC_COMMENT,
SHEBANG,
SHEBANG_LINE,
STATIC_LIFETIME
};
-361
View File
@@ -1,361 +0,0 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(plugin, rustc_private)]
extern crate syntax;
extern crate syntax_pos;
extern crate rustc;
#[macro_use]
extern crate log;
use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{BufRead, Read};
use std::path::Path;
use syntax::parse::lexer;
use rustc::dep_graph::DepGraph;
use rustc::session::{self, config};
use rustc::middle::cstore::DummyCrateStore;
use std::rc::Rc;
use syntax::ast;
use syntax::codemap;
use syntax::parse::token::{self, BinOpToken, DelimToken, Lit, Token};
use syntax::parse::lexer::TokenAndSpan;
use syntax_pos::Pos;
use syntax::symbol::{Symbol, keywords};
fn parse_token_list(file: &str) -> HashMap<String, token::Token> {
fn id() -> token::Token {
Token::Ident(ast::Ident::with_empty_ctxt(keywords::Invalid.name()))
}
let mut res = HashMap::new();
res.insert("-1".to_string(), Token::Eof);
for line in file.split('\n') {
let eq = match line.trim().rfind('=') {
Some(val) => val,
None => continue
};
let val = &line[..eq];
let num = &line[eq + 1..];
let tok = match val {
"SHR" => Token::BinOp(BinOpToken::Shr),
"DOLLAR" => Token::Dollar,
"LT" => Token::Lt,
"STAR" => Token::BinOp(BinOpToken::Star),
"FLOAT_SUFFIX" => id(),
"INT_SUFFIX" => id(),
"SHL" => Token::BinOp(BinOpToken::Shl),
"LBRACE" => Token::OpenDelim(DelimToken::Brace),
"RARROW" => Token::RArrow,
"LIT_STR" => Token::Literal(Lit::Str_(keywords::Invalid.name()), None),
"DOTDOT" => Token::DotDot,
"MOD_SEP" => Token::ModSep,
"DOTDOTDOT" => Token::DotDotDot,
"NOT" => Token::Not,
"AND" => Token::BinOp(BinOpToken::And),
"LPAREN" => Token::OpenDelim(DelimToken::Paren),
"ANDAND" => Token::AndAnd,
"AT" => Token::At,
"LBRACKET" => Token::OpenDelim(DelimToken::Bracket),
"LIT_STR_RAW" => Token::Literal(Lit::StrRaw(keywords::Invalid.name(), 0), None),
"RPAREN" => Token::CloseDelim(DelimToken::Paren),
"SLASH" => Token::BinOp(BinOpToken::Slash),
"COMMA" => Token::Comma,
"LIFETIME" => Token::Lifetime(
ast::Ident::with_empty_ctxt(keywords::Invalid.name())),
"CARET" => Token::BinOp(BinOpToken::Caret),
"TILDE" => Token::Tilde,
"IDENT" => id(),
"PLUS" => Token::BinOp(BinOpToken::Plus),
"LIT_CHAR" => Token::Literal(Lit::Char(keywords::Invalid.name()), None),
"LIT_BYTE" => Token::Literal(Lit::Byte(keywords::Invalid.name()), None),
"EQ" => Token::Eq,
"RBRACKET" => Token::CloseDelim(DelimToken::Bracket),
"COMMENT" => Token::Comment,
"DOC_COMMENT" => Token::DocComment(keywords::Invalid.name()),
"DOT" => Token::Dot,
"EQEQ" => Token::EqEq,
"NE" => Token::Ne,
"GE" => Token::Ge,
"PERCENT" => Token::BinOp(BinOpToken::Percent),
"RBRACE" => Token::CloseDelim(DelimToken::Brace),
"BINOP" => Token::BinOp(BinOpToken::Plus),
"POUND" => Token::Pound,
"OROR" => Token::OrOr,
"LIT_INTEGER" => Token::Literal(Lit::Integer(keywords::Invalid.name()), None),
"BINOPEQ" => Token::BinOpEq(BinOpToken::Plus),
"LIT_FLOAT" => Token::Literal(Lit::Float(keywords::Invalid.name()), None),
"WHITESPACE" => Token::Whitespace,
"UNDERSCORE" => Token::Underscore,
"MINUS" => Token::BinOp(BinOpToken::Minus),
"SEMI" => Token::Semi,
"COLON" => Token::Colon,
"FAT_ARROW" => Token::FatArrow,
"OR" => Token::BinOp(BinOpToken::Or),
"GT" => Token::Gt,
"LE" => Token::Le,
"LIT_BINARY" => Token::Literal(Lit::ByteStr(keywords::Invalid.name()), None),
"LIT_BINARY_RAW" => Token::Literal(
Lit::ByteStrRaw(keywords::Invalid.name(), 0), None),
"QUESTION" => Token::Question,
"SHEBANG" => Token::Shebang(keywords::Invalid.name()),
_ => continue,
};
res.insert(num.to_string(), tok);
}
debug!("Token map: {:?}", res);
res
}
fn str_to_binop(s: &str) -> token::BinOpToken {
match s {
"+" => BinOpToken::Plus,
"/" => BinOpToken::Slash,
"-" => BinOpToken::Minus,
"*" => BinOpToken::Star,
"%" => BinOpToken::Percent,
"^" => BinOpToken::Caret,
"&" => BinOpToken::And,
"|" => BinOpToken::Or,
"<<" => BinOpToken::Shl,
">>" => BinOpToken::Shr,
_ => panic!("Bad binop str `{}`", s),
}
}
/// Assuming a string/byte string literal, strip out the leading/trailing
/// hashes and surrounding quotes/raw/byte prefix.
fn fix(mut lit: &str) -> ast::Name {
let prefix: Vec<char> = lit.chars().take(2).collect();
if prefix[0] == 'r' {
if prefix[1] == 'b' {
lit = &lit[2..]
} else {
lit = &lit[1..];
}
} else if prefix[0] == 'b' {
lit = &lit[1..];
}
let leading_hashes = count(lit);
// +1/-1 to adjust for single quotes
Symbol::intern(&lit[leading_hashes + 1..lit.len() - leading_hashes - 1])
}
/// Assuming a char/byte literal, strip the 'b' prefix and the single quotes.
fn fixchar(mut lit: &str) -> ast::Name {
let prefix = lit.chars().next().unwrap();
if prefix == 'b' {
lit = &lit[1..];
}
Symbol::intern(&lit[1..lit.len() - 1])
}
fn count(lit: &str) -> usize {
lit.chars().take_while(|c| *c == '#').count()
}
fn parse_antlr_token(s: &str, tokens: &HashMap<String, token::Token>, surrogate_pairs_pos: &[usize],
has_bom: bool)
-> TokenAndSpan {
// old regex:
// \[@(?P<seq>\d+),(?P<start>\d+):(?P<end>\d+)='(?P<content>.+?)',<(?P<toknum>-?\d+)>,\d+:\d+]
let start = s.find("[@").unwrap();
let comma = start + s[start..].find(",").unwrap();
let colon = comma + s[comma..].find(":").unwrap();
let content_start = colon + s[colon..].find("='").unwrap();
// Use rfind instead of find, because we don't want to stop at the content
let content_end = content_start + s[content_start..].rfind("',<").unwrap();
let toknum_end = content_end + s[content_end..].find(">,").unwrap();
let start = &s[comma + 1 .. colon];
let end = &s[colon + 1 .. content_start];
let content = &s[content_start + 2 .. content_end];
let toknum = &s[content_end + 3 .. toknum_end];
let not_found = format!("didn't find token {:?} in the map", toknum);
let proto_tok = tokens.get(toknum).expect(&not_found);
let nm = Symbol::intern(content);
debug!("What we got: content (`{}`), proto: {:?}", content, proto_tok);
let real_tok = match *proto_tok {
Token::BinOp(..) => Token::BinOp(str_to_binop(content)),
Token::BinOpEq(..) => Token::BinOpEq(str_to_binop(&content[..content.len() - 1])),
Token::Literal(Lit::Str_(..), n) => Token::Literal(Lit::Str_(fix(content)), n),
Token::Literal(Lit::StrRaw(..), n) => Token::Literal(Lit::StrRaw(fix(content),
count(content)), n),
Token::Literal(Lit::Char(..), n) => Token::Literal(Lit::Char(fixchar(content)), n),
Token::Literal(Lit::Byte(..), n) => Token::Literal(Lit::Byte(fixchar(content)), n),
Token::DocComment(..) => Token::DocComment(nm),
Token::Literal(Lit::Integer(..), n) => Token::Literal(Lit::Integer(nm), n),
Token::Literal(Lit::Float(..), n) => Token::Literal(Lit::Float(nm), n),
Token::Literal(Lit::ByteStr(..), n) => Token::Literal(Lit::ByteStr(nm), n),
Token::Literal(Lit::ByteStrRaw(..), n) => Token::Literal(Lit::ByteStrRaw(fix(content),
count(content)), n),
Token::Ident(..) => Token::Ident(ast::Ident::with_empty_ctxt(nm)),
Token::Lifetime(..) => Token::Lifetime(ast::Ident::with_empty_ctxt(nm)),
ref t => t.clone()
};
let start_offset = if real_tok == Token::Eof {
1
} else {
0
};
let offset = if has_bom { 1 } else { 0 };
let mut lo = start.parse::<u32>().unwrap() - start_offset - offset;
let mut hi = end.parse::<u32>().unwrap() + 1 - offset;
// Adjust the span: For each surrogate pair already encountered, subtract one position.
lo -= surrogate_pairs_pos.binary_search(&(lo as usize)).unwrap_or_else(|x| x) as u32;
hi -= surrogate_pairs_pos.binary_search(&(hi as usize)).unwrap_or_else(|x| x) as u32;
let sp = syntax_pos::Span {
lo: syntax_pos::BytePos(lo),
hi: syntax_pos::BytePos(hi),
expn_id: syntax_pos::NO_EXPANSION
};
TokenAndSpan {
tok: real_tok,
sp: sp
}
}
fn tok_cmp(a: &token::Token, b: &token::Token) -> bool {
match a {
&Token::Ident(id) => match b {
&Token::Ident(id2) => id == id2,
_ => false
},
_ => a == b
}
}
fn span_cmp(antlr_sp: codemap::Span, rust_sp: codemap::Span, cm: &codemap::CodeMap) -> bool {
antlr_sp.expn_id == rust_sp.expn_id &&
antlr_sp.lo.to_usize() == cm.bytepos_to_file_charpos(rust_sp.lo).to_usize() &&
antlr_sp.hi.to_usize() == cm.bytepos_to_file_charpos(rust_sp.hi).to_usize()
}
fn main() {
fn next(r: &mut lexer::StringReader) -> TokenAndSpan {
use syntax::parse::lexer::Reader;
r.next_token()
}
let mut args = env::args().skip(1);
let filename = args.next().unwrap();
if filename.find("parse-fail").is_some() {
return;
}
// Rust's lexer
let mut code = String::new();
File::open(&Path::new(&filename)).unwrap().read_to_string(&mut code).unwrap();
let surrogate_pairs_pos: Vec<usize> = code.chars().enumerate()
.filter(|&(_, c)| c as usize > 0xFFFF)
.map(|(n, _)| n)
.enumerate()
.map(|(x, n)| x + n)
.collect();
let has_bom = code.starts_with("\u{feff}");
debug!("Pairs: {:?}", surrogate_pairs_pos);
let options = config::basic_options();
let session = session::build_session(options, &DepGraph::new(false), None,
syntax::errors::registry::Registry::new(&[]),
Rc::new(DummyCrateStore));
let filemap = session.parse_sess.codemap()
.new_filemap("<n/a>".to_string(), code);
let mut lexer = lexer::StringReader::new(session.diagnostic(), filemap);
let cm = session.codemap();
// ANTLR
let mut token_file = File::open(&Path::new(&args.next().unwrap())).unwrap();
let mut token_list = String::new();
token_file.read_to_string(&mut token_list).unwrap();
let token_map = parse_token_list(&token_list);
let stdin = std::io::stdin();
let lock = stdin.lock();
let lines = lock.lines();
let antlr_tokens = lines.map(|l| parse_antlr_token(l.unwrap().trim(),
&token_map,
&surrogate_pairs_pos,
has_bom));
for antlr_tok in antlr_tokens {
let rustc_tok = next(&mut lexer);
if rustc_tok.tok == Token::Eof && antlr_tok.tok == Token::Eof {
continue
}
assert!(span_cmp(antlr_tok.sp, rustc_tok.sp, cm), "{:?} and {:?} have different spans",
rustc_tok,
antlr_tok);
macro_rules! matches {
( $($x:pat),+ ) => (
match rustc_tok.tok {
$($x => match antlr_tok.tok {
$x => {
if !tok_cmp(&rustc_tok.tok, &antlr_tok.tok) {
// FIXME #15677: needs more robust escaping in
// antlr
warn!("Different names for {:?} and {:?}", rustc_tok, antlr_tok);
}
}
_ => panic!("{:?} is not {:?}", antlr_tok, rustc_tok)
},)*
ref c => assert!(c == &antlr_tok.tok, "{:?} is not {:?}", antlr_tok, rustc_tok)
}
)
}
matches!(
Token::Literal(Lit::Byte(..), _),
Token::Literal(Lit::Char(..), _),
Token::Literal(Lit::Integer(..), _),
Token::Literal(Lit::Float(..), _),
Token::Literal(Lit::Str_(..), _),
Token::Literal(Lit::StrRaw(..), _),
Token::Literal(Lit::ByteStr(..), _),
Token::Literal(Lit::ByteStrRaw(..), _),
Token::Ident(..),
Token::Lifetime(..),
Token::Interpolated(..),
Token::DocComment(..),
Token::Shebang(..)
);
}
}
-473
View File
@@ -1,473 +0,0 @@
lexer grammar Xidcontinue;
fragment XID_Continue:
'\u0030' .. '\u0039'
| '\u0041' .. '\u005a'
| '\u005f'
| '\u0061' .. '\u007a'
| '\u00aa'
| '\u00b5'
| '\u00b7'
| '\u00ba'
| '\u00c0' .. '\u00d6'
| '\u00d8' .. '\u00f6'
| '\u00f8' .. '\u0236'
| '\u0250' .. '\u02c1'
| '\u02c6' .. '\u02d1'
| '\u02e0' .. '\u02e4'
| '\u02ee'
| '\u0300' .. '\u0357'
| '\u035d' .. '\u036f'
| '\u0386'
| '\u0388' .. '\u038a'
| '\u038c'
| '\u038e' .. '\u03a1'
| '\u03a3' .. '\u03ce'
| '\u03d0' .. '\u03f5'
| '\u03f7' .. '\u03fb'
| '\u0400' .. '\u0481'
| '\u0483' .. '\u0486'
| '\u048a' .. '\u04ce'
| '\u04d0' .. '\u04f5'
| '\u04f8' .. '\u04f9'
| '\u0500' .. '\u050f'
| '\u0531' .. '\u0556'
| '\u0559'
| '\u0561' .. '\u0587'
| '\u0591' .. '\u05a1'
| '\u05a3' .. '\u05b9'
| '\u05bb' .. '\u05bd'
| '\u05bf'
| '\u05c1' .. '\u05c2'
| '\u05c4'
| '\u05d0' .. '\u05ea'
| '\u05f0' .. '\u05f2'
| '\u0610' .. '\u0615'
| '\u0621' .. '\u063a'
| '\u0640' .. '\u0658'
| '\u0660' .. '\u0669'
| '\u066e' .. '\u06d3'
| '\u06d5' .. '\u06dc'
| '\u06df' .. '\u06e8'
| '\u06ea' .. '\u06fc'
| '\u06ff'
| '\u0710' .. '\u074a'
| '\u074d' .. '\u074f'
| '\u0780' .. '\u07b1'
| '\u0901' .. '\u0939'
| '\u093c' .. '\u094d'
| '\u0950' .. '\u0954'
| '\u0958' .. '\u0963'
| '\u0966' .. '\u096f'
| '\u0981' .. '\u0983'
| '\u0985' .. '\u098c'
| '\u098f' .. '\u0990'
| '\u0993' .. '\u09a8'
| '\u09aa' .. '\u09b0'
| '\u09b2'
| '\u09b6' .. '\u09b9'
| '\u09bc' .. '\u09c4'
| '\u09c7' .. '\u09c8'
| '\u09cb' .. '\u09cd'
| '\u09d7'
| '\u09dc' .. '\u09dd'
| '\u09df' .. '\u09e3'
| '\u09e6' .. '\u09f1'
| '\u0a01' .. '\u0a03'
| '\u0a05' .. '\u0a0a'
| '\u0a0f' .. '\u0a10'
| '\u0a13' .. '\u0a28'
| '\u0a2a' .. '\u0a30'
| '\u0a32' .. '\u0a33'
| '\u0a35' .. '\u0a36'
| '\u0a38' .. '\u0a39'
| '\u0a3c'
| '\u0a3e' .. '\u0a42'
| '\u0a47' .. '\u0a48'
| '\u0a4b' .. '\u0a4d'
| '\u0a59' .. '\u0a5c'
| '\u0a5e'
| '\u0a66' .. '\u0a74'
| '\u0a81' .. '\u0a83'
| '\u0a85' .. '\u0a8d'
| '\u0a8f' .. '\u0a91'
| '\u0a93' .. '\u0aa8'
| '\u0aaa' .. '\u0ab0'
| '\u0ab2' .. '\u0ab3'
| '\u0ab5' .. '\u0ab9'
| '\u0abc' .. '\u0ac5'
| '\u0ac7' .. '\u0ac9'
| '\u0acb' .. '\u0acd'
| '\u0ad0'
| '\u0ae0' .. '\u0ae3'
| '\u0ae6' .. '\u0aef'
| '\u0b01' .. '\u0b03'
| '\u0b05' .. '\u0b0c'
| '\u0b0f' .. '\u0b10'
| '\u0b13' .. '\u0b28'
| '\u0b2a' .. '\u0b30'
| '\u0b32' .. '\u0b33'
| '\u0b35' .. '\u0b39'
| '\u0b3c' .. '\u0b43'
| '\u0b47' .. '\u0b48'
| '\u0b4b' .. '\u0b4d'
| '\u0b56' .. '\u0b57'
| '\u0b5c' .. '\u0b5d'
| '\u0b5f' .. '\u0b61'
| '\u0b66' .. '\u0b6f'
| '\u0b71'
| '\u0b82' .. '\u0b83'
| '\u0b85' .. '\u0b8a'
| '\u0b8e' .. '\u0b90'
| '\u0b92' .. '\u0b95'
| '\u0b99' .. '\u0b9a'
| '\u0b9c'
| '\u0b9e' .. '\u0b9f'
| '\u0ba3' .. '\u0ba4'
| '\u0ba8' .. '\u0baa'
| '\u0bae' .. '\u0bb5'
| '\u0bb7' .. '\u0bb9'
| '\u0bbe' .. '\u0bc2'
| '\u0bc6' .. '\u0bc8'
| '\u0bca' .. '\u0bcd'
| '\u0bd7'
| '\u0be7' .. '\u0bef'
| '\u0c01' .. '\u0c03'
| '\u0c05' .. '\u0c0c'
| '\u0c0e' .. '\u0c10'
| '\u0c12' .. '\u0c28'
| '\u0c2a' .. '\u0c33'
| '\u0c35' .. '\u0c39'
| '\u0c3e' .. '\u0c44'
| '\u0c46' .. '\u0c48'
| '\u0c4a' .. '\u0c4d'
| '\u0c55' .. '\u0c56'
| '\u0c60' .. '\u0c61'
| '\u0c66' .. '\u0c6f'
| '\u0c82' .. '\u0c83'
| '\u0c85' .. '\u0c8c'
| '\u0c8e' .. '\u0c90'
| '\u0c92' .. '\u0ca8'
| '\u0caa' .. '\u0cb3'
| '\u0cb5' .. '\u0cb9'
| '\u0cbc' .. '\u0cc4'
| '\u0cc6' .. '\u0cc8'
| '\u0cca' .. '\u0ccd'
| '\u0cd5' .. '\u0cd6'
| '\u0cde'
| '\u0ce0' .. '\u0ce1'
| '\u0ce6' .. '\u0cef'
| '\u0d02' .. '\u0d03'
| '\u0d05' .. '\u0d0c'
| '\u0d0e' .. '\u0d10'
| '\u0d12' .. '\u0d28'
| '\u0d2a' .. '\u0d39'
| '\u0d3e' .. '\u0d43'
| '\u0d46' .. '\u0d48'
| '\u0d4a' .. '\u0d4d'
| '\u0d57'
| '\u0d60' .. '\u0d61'
| '\u0d66' .. '\u0d6f'
| '\u0d82' .. '\u0d83'
| '\u0d85' .. '\u0d96'
| '\u0d9a' .. '\u0db1'
| '\u0db3' .. '\u0dbb'
| '\u0dbd'
| '\u0dc0' .. '\u0dc6'
| '\u0dca'
| '\u0dcf' .. '\u0dd4'
| '\u0dd6'
| '\u0dd8' .. '\u0ddf'
| '\u0df2' .. '\u0df3'
| '\u0e01' .. '\u0e3a'
| '\u0e40' .. '\u0e4e'
| '\u0e50' .. '\u0e59'
| '\u0e81' .. '\u0e82'
| '\u0e84'
| '\u0e87' .. '\u0e88'
| '\u0e8a'
| '\u0e8d'
| '\u0e94' .. '\u0e97'
| '\u0e99' .. '\u0e9f'
| '\u0ea1' .. '\u0ea3'
| '\u0ea5'
| '\u0ea7'
| '\u0eaa' .. '\u0eab'
| '\u0ead' .. '\u0eb9'
| '\u0ebb' .. '\u0ebd'
| '\u0ec0' .. '\u0ec4'
| '\u0ec6'
| '\u0ec8' .. '\u0ecd'
| '\u0ed0' .. '\u0ed9'
| '\u0edc' .. '\u0edd'
| '\u0f00'
| '\u0f18' .. '\u0f19'
| '\u0f20' .. '\u0f29'
| '\u0f35'
| '\u0f37'
| '\u0f39'
| '\u0f3e' .. '\u0f47'
| '\u0f49' .. '\u0f6a'
| '\u0f71' .. '\u0f84'
| '\u0f86' .. '\u0f8b'
| '\u0f90' .. '\u0f97'
| '\u0f99' .. '\u0fbc'
| '\u0fc6'
| '\u1000' .. '\u1021'
| '\u1023' .. '\u1027'
| '\u1029' .. '\u102a'
| '\u102c' .. '\u1032'
| '\u1036' .. '\u1039'
| '\u1040' .. '\u1049'
| '\u1050' .. '\u1059'
| '\u10a0' .. '\u10c5'
| '\u10d0' .. '\u10f8'
| '\u1100' .. '\u1159'
| '\u115f' .. '\u11a2'
| '\u11a8' .. '\u11f9'
| '\u1200' .. '\u1206'
| '\u1208' .. '\u1246'
| '\u1248'
| '\u124a' .. '\u124d'
| '\u1250' .. '\u1256'
| '\u1258'
| '\u125a' .. '\u125d'
| '\u1260' .. '\u1286'
| '\u1288'
| '\u128a' .. '\u128d'
| '\u1290' .. '\u12ae'
| '\u12b0'
| '\u12b2' .. '\u12b5'
| '\u12b8' .. '\u12be'
| '\u12c0'
| '\u12c2' .. '\u12c5'
| '\u12c8' .. '\u12ce'
| '\u12d0' .. '\u12d6'
| '\u12d8' .. '\u12ee'
| '\u12f0' .. '\u130e'
| '\u1310'
| '\u1312' .. '\u1315'
| '\u1318' .. '\u131e'
| '\u1320' .. '\u1346'
| '\u1348' .. '\u135a'
| '\u1369' .. '\u1371'
| '\u13a0' .. '\u13f4'
| '\u1401' .. '\u166c'
| '\u166f' .. '\u1676'
| '\u1681' .. '\u169a'
| '\u16a0' .. '\u16ea'
| '\u16ee' .. '\u16f0'
| '\u1700' .. '\u170c'
| '\u170e' .. '\u1714'
| '\u1720' .. '\u1734'
| '\u1740' .. '\u1753'
| '\u1760' .. '\u176c'
| '\u176e' .. '\u1770'
| '\u1772' .. '\u1773'
| '\u1780' .. '\u17b3'
| '\u17b6' .. '\u17d3'
| '\u17d7'
| '\u17dc' .. '\u17dd'
| '\u17e0' .. '\u17e9'
| '\u180b' .. '\u180d'
| '\u1810' .. '\u1819'
| '\u1820' .. '\u1877'
| '\u1880' .. '\u18a9'
| '\u1900' .. '\u191c'
| '\u1920' .. '\u192b'
| '\u1930' .. '\u193b'
| '\u1946' .. '\u196d'
| '\u1970' .. '\u1974'
| '\u1d00' .. '\u1d6b'
| '\u1e00' .. '\u1e9b'
| '\u1ea0' .. '\u1ef9'
| '\u1f00' .. '\u1f15'
| '\u1f18' .. '\u1f1d'
| '\u1f20' .. '\u1f45'
| '\u1f48' .. '\u1f4d'
| '\u1f50' .. '\u1f57'
| '\u1f59'
| '\u1f5b'
| '\u1f5d'
| '\u1f5f' .. '\u1f7d'
| '\u1f80' .. '\u1fb4'
| '\u1fb6' .. '\u1fbc'
| '\u1fbe'
| '\u1fc2' .. '\u1fc4'
| '\u1fc6' .. '\u1fcc'
| '\u1fd0' .. '\u1fd3'
| '\u1fd6' .. '\u1fdb'
| '\u1fe0' .. '\u1fec'
| '\u1ff2' .. '\u1ff4'
| '\u1ff6' .. '\u1ffc'
| '\u203f' .. '\u2040'
| '\u2054'
| '\u2071'
| '\u207f'
| '\u20d0' .. '\u20dc'
| '\u20e1'
| '\u20e5' .. '\u20ea'
| '\u2102'
| '\u2107'
| '\u210a' .. '\u2113'
| '\u2115'
| '\u2118' .. '\u211d'
| '\u2124'
| '\u2126'
| '\u2128'
| '\u212a' .. '\u2131'
| '\u2133' .. '\u2139'
| '\u213d' .. '\u213f'
| '\u2145' .. '\u2149'
| '\u2160' .. '\u2183'
| '\u3005' .. '\u3007'
| '\u3021' .. '\u302f'
| '\u3031' .. '\u3035'
| '\u3038' .. '\u303c'
| '\u3041' .. '\u3096'
| '\u3099' .. '\u309a'
| '\u309d' .. '\u309f'
| '\u30a1' .. '\u30ff'
| '\u3105' .. '\u312c'
| '\u3131' .. '\u318e'
| '\u31a0' .. '\u31b7'
| '\u31f0' .. '\u31ff'
| '\u3400' .. '\u4db5'
| '\u4e00' .. '\u9fa5'
| '\ua000' .. '\ua48c'
| '\uac00' .. '\ud7a3'
| '\uf900' .. '\ufa2d'
| '\ufa30' .. '\ufa6a'
| '\ufb00' .. '\ufb06'
| '\ufb13' .. '\ufb17'
| '\ufb1d' .. '\ufb28'
| '\ufb2a' .. '\ufb36'
| '\ufb38' .. '\ufb3c'
| '\ufb3e'
| '\ufb40' .. '\ufb41'
| '\ufb43' .. '\ufb44'
| '\ufb46' .. '\ufbb1'
| '\ufbd3' .. '\ufc5d'
| '\ufc64' .. '\ufd3d'
| '\ufd50' .. '\ufd8f'
| '\ufd92' .. '\ufdc7'
| '\ufdf0' .. '\ufdf9'
| '\ufe00' .. '\ufe0f'
| '\ufe20' .. '\ufe23'
| '\ufe33' .. '\ufe34'
| '\ufe4d' .. '\ufe4f'
| '\ufe71'
| '\ufe73'
| '\ufe77'
| '\ufe79'
| '\ufe7b'
| '\ufe7d'
| '\ufe7f' .. '\ufefc'
| '\uff10' .. '\uff19'
| '\uff21' .. '\uff3a'
| '\uff3f'
| '\uff41' .. '\uff5a'
| '\uff65' .. '\uffbe'
| '\uffc2' .. '\uffc7'
| '\uffca' .. '\uffcf'
| '\uffd2' .. '\uffd7'
| '\uffda' .. '\uffdc'
| '\ud800' '\udc00' .. '\udc0a'
| '\ud800' '\udc0d' .. '\udc25'
| '\ud800' '\udc28' .. '\udc39'
| '\ud800' '\udc3c' .. '\udc3c'
| '\ud800' '\udc3f' .. '\udc4c'
| '\ud800' '\udc50' .. '\udc5c'
| '\ud800' '\udc80' .. '\udcf9'
| '\ud800' '\udf00' .. '\udf1d'
| '\ud800' '\udf30' .. '\udf49'
| '\ud800' '\udf80' .. '\udf9c'
| '\ud801' '\ue000' .. '\ue09c'
| '\ud801' '\ue0a0' .. '\ue0a8'
| '\ud802' '\ue400' .. '\ue404'
| '\ud802' '\u0808'
| '\ud802' '\ue40a' .. '\ue434'
| '\ud802' '\ue437' .. '\ue437'
| '\ud802' '\u083c'
| '\ud802' '\u083f'
| '\ud834' '\uad65' .. '\uad68'
| '\ud834' '\uad6d' .. '\uad71'
| '\ud834' '\uad7b' .. '\uad81'
| '\ud834' '\uad85' .. '\uad8a'
| '\ud834' '\uadaa' .. '\uadac'
| '\ud835' '\ub000' .. '\ub053'
| '\ud835' '\ub056' .. '\ub09b'
| '\ud835' '\ub09e' .. '\ub09e'
| '\ud835' '\ud4a2'
| '\ud835' '\ub0a5' .. '\ub0a5'
| '\ud835' '\ub0a9' .. '\ub0ab'
| '\ud835' '\ub0ae' .. '\ub0b8'
| '\ud835' '\ud4bb'
| '\ud835' '\ub0bd' .. '\ub0c2'
| '\ud835' '\ub0c5' .. '\ub104'
| '\ud835' '\ub107' .. '\ub109'
| '\ud835' '\ub10d' .. '\ub113'
| '\ud835' '\ub116' .. '\ub11b'
| '\ud835' '\ub11e' .. '\ub138'
| '\ud835' '\ub13b' .. '\ub13d'
| '\ud835' '\ub140' .. '\ub143'
| '\ud835' '\ud546'
| '\ud835' '\ub14a' .. '\ub14f'
| '\ud835' '\ub152' .. '\ub2a2'
| '\ud835' '\ub2a8' .. '\ub2bf'
| '\ud835' '\ub2c2' .. '\ub2d9'
| '\ud835' '\ub2dc' .. '\ub2f9'
| '\ud835' '\ub2fc' .. '\ub313'
| '\ud835' '\ub316' .. '\ub333'
| '\ud835' '\ub336' .. '\ub34d'
| '\ud835' '\ub350' .. '\ub36d'
| '\ud835' '\ub370' .. '\ub387'
| '\ud835' '\ub38a' .. '\ub3a7'
| '\ud835' '\ub3aa' .. '\ub3c1'
| '\ud835' '\ub3c4' .. '\ub3c8'
| '\ud835' '\ub3ce' .. '\ub3fe'
| '\ud840' '\udc00' .. '\udffe'
| '\ud841' '\ue000' .. '\ue3fe'
| '\ud842' '\ue400' .. '\ue7fe'
| '\ud843' '\ue800' .. '\uebfe'
| '\ud844' '\uec00' .. '\ueffe'
| '\ud845' '\uf000' .. '\uf3fe'
| '\ud846' '\uf400' .. '\uf7fe'
| '\ud847' '\uf800' .. '\ufbfe'
| '\ud848' '\ufc00' .. '\ufffe'
| '\ud849' '\u0000' .. '\u03fe'
| '\ud84a' '\u0400' .. '\u07fe'
| '\ud84b' '\u0800' .. '\u0bfe'
| '\ud84c' '\u0c00' .. '\u0ffe'
| '\ud84d' '\u1000' .. '\u13fe'
| '\ud84e' '\u1400' .. '\u17fe'
| '\ud84f' '\u1800' .. '\u1bfe'
| '\ud850' '\u1c00' .. '\u1ffe'
| '\ud851' '\u2000' .. '\u23fe'
| '\ud852' '\u2400' .. '\u27fe'
| '\ud853' '\u2800' .. '\u2bfe'
| '\ud854' '\u2c00' .. '\u2ffe'
| '\ud855' '\u3000' .. '\u33fe'
| '\ud856' '\u3400' .. '\u37fe'
| '\ud857' '\u3800' .. '\u3bfe'
| '\ud858' '\u3c00' .. '\u3ffe'
| '\ud859' '\u4000' .. '\u43fe'
| '\ud85a' '\u4400' .. '\u47fe'
| '\ud85b' '\u4800' .. '\u4bfe'
| '\ud85c' '\u4c00' .. '\u4ffe'
| '\ud85d' '\u5000' .. '\u53fe'
| '\ud85e' '\u5400' .. '\u57fe'
| '\ud85f' '\u5800' .. '\u5bfe'
| '\ud860' '\u5c00' .. '\u5ffe'
| '\ud861' '\u6000' .. '\u63fe'
| '\ud862' '\u6400' .. '\u67fe'
| '\ud863' '\u6800' .. '\u6bfe'
| '\ud864' '\u6c00' .. '\u6ffe'
| '\ud865' '\u7000' .. '\u73fe'
| '\ud866' '\u7400' .. '\u77fe'
| '\ud867' '\u7800' .. '\u7bfe'
| '\ud868' '\u7c00' .. '\u7ffe'
| '\ud869' '\u8000' .. '\u82d5'
| '\ud87e' '\ud400' .. '\ud61c'
| '\udb40' '\udd00' .. '\uddee'
;
-379
View File
@@ -1,379 +0,0 @@
lexer grammar Xidstart;
fragment XID_Start :
'\u0041' .. '\u005a'
| '_'
| '\u0061' .. '\u007a'
| '\u00aa'
| '\u00b5'
| '\u00ba'
| '\u00c0' .. '\u00d6'
| '\u00d8' .. '\u00f6'
| '\u00f8' .. '\u0236'
| '\u0250' .. '\u02c1'
| '\u02c6' .. '\u02d1'
| '\u02e0' .. '\u02e4'
| '\u02ee'
| '\u0386'
| '\u0388' .. '\u038a'
| '\u038c'
| '\u038e' .. '\u03a1'
| '\u03a3' .. '\u03ce'
| '\u03d0' .. '\u03f5'
| '\u03f7' .. '\u03fb'
| '\u0400' .. '\u0481'
| '\u048a' .. '\u04ce'
| '\u04d0' .. '\u04f5'
| '\u04f8' .. '\u04f9'
| '\u0500' .. '\u050f'
| '\u0531' .. '\u0556'
| '\u0559'
| '\u0561' .. '\u0587'
| '\u05d0' .. '\u05ea'
| '\u05f0' .. '\u05f2'
| '\u0621' .. '\u063a'
| '\u0640' .. '\u064a'
| '\u066e' .. '\u066f'
| '\u0671' .. '\u06d3'
| '\u06d5'
| '\u06e5' .. '\u06e6'
| '\u06ee' .. '\u06ef'
| '\u06fa' .. '\u06fc'
| '\u06ff'
| '\u0710'
| '\u0712' .. '\u072f'
| '\u074d' .. '\u074f'
| '\u0780' .. '\u07a5'
| '\u07b1'
| '\u0904' .. '\u0939'
| '\u093d'
| '\u0950'
| '\u0958' .. '\u0961'
| '\u0985' .. '\u098c'
| '\u098f' .. '\u0990'
| '\u0993' .. '\u09a8'
| '\u09aa' .. '\u09b0'
| '\u09b2'
| '\u09b6' .. '\u09b9'
| '\u09bd'
| '\u09dc' .. '\u09dd'
| '\u09df' .. '\u09e1'
| '\u09f0' .. '\u09f1'
| '\u0a05' .. '\u0a0a'
| '\u0a0f' .. '\u0a10'
| '\u0a13' .. '\u0a28'
| '\u0a2a' .. '\u0a30'
| '\u0a32' .. '\u0a33'
| '\u0a35' .. '\u0a36'
| '\u0a38' .. '\u0a39'
| '\u0a59' .. '\u0a5c'
| '\u0a5e'
| '\u0a72' .. '\u0a74'
| '\u0a85' .. '\u0a8d'
| '\u0a8f' .. '\u0a91'
| '\u0a93' .. '\u0aa8'
| '\u0aaa' .. '\u0ab0'
| '\u0ab2' .. '\u0ab3'
| '\u0ab5' .. '\u0ab9'
| '\u0abd'
| '\u0ad0'
| '\u0ae0' .. '\u0ae1'
| '\u0b05' .. '\u0b0c'
| '\u0b0f' .. '\u0b10'
| '\u0b13' .. '\u0b28'
| '\u0b2a' .. '\u0b30'
| '\u0b32' .. '\u0b33'
| '\u0b35' .. '\u0b39'
| '\u0b3d'
| '\u0b5c' .. '\u0b5d'
| '\u0b5f' .. '\u0b61'
| '\u0b71'
| '\u0b83'
| '\u0b85' .. '\u0b8a'
| '\u0b8e' .. '\u0b90'
| '\u0b92' .. '\u0b95'
| '\u0b99' .. '\u0b9a'
| '\u0b9c'
| '\u0b9e' .. '\u0b9f'
| '\u0ba3' .. '\u0ba4'
| '\u0ba8' .. '\u0baa'
| '\u0bae' .. '\u0bb5'
| '\u0bb7' .. '\u0bb9'
| '\u0c05' .. '\u0c0c'
| '\u0c0e' .. '\u0c10'
| '\u0c12' .. '\u0c28'
| '\u0c2a' .. '\u0c33'
| '\u0c35' .. '\u0c39'
| '\u0c60' .. '\u0c61'
| '\u0c85' .. '\u0c8c'
| '\u0c8e' .. '\u0c90'
| '\u0c92' .. '\u0ca8'
| '\u0caa' .. '\u0cb3'
| '\u0cb5' .. '\u0cb9'
| '\u0cbd'
| '\u0cde'
| '\u0ce0' .. '\u0ce1'
| '\u0d05' .. '\u0d0c'
| '\u0d0e' .. '\u0d10'
| '\u0d12' .. '\u0d28'
| '\u0d2a' .. '\u0d39'
| '\u0d60' .. '\u0d61'
| '\u0d85' .. '\u0d96'
| '\u0d9a' .. '\u0db1'
| '\u0db3' .. '\u0dbb'
| '\u0dbd'
| '\u0dc0' .. '\u0dc6'
| '\u0e01' .. '\u0e30'
| '\u0e32'
| '\u0e40' .. '\u0e46'
| '\u0e81' .. '\u0e82'
| '\u0e84'
| '\u0e87' .. '\u0e88'
| '\u0e8a'
| '\u0e8d'
| '\u0e94' .. '\u0e97'
| '\u0e99' .. '\u0e9f'
| '\u0ea1' .. '\u0ea3'
| '\u0ea5'
| '\u0ea7'
| '\u0eaa' .. '\u0eab'
| '\u0ead' .. '\u0eb0'
| '\u0eb2'
| '\u0ebd'
| '\u0ec0' .. '\u0ec4'
| '\u0ec6'
| '\u0edc' .. '\u0edd'
| '\u0f00'
| '\u0f40' .. '\u0f47'
| '\u0f49' .. '\u0f6a'
| '\u0f88' .. '\u0f8b'
| '\u1000' .. '\u1021'
| '\u1023' .. '\u1027'
| '\u1029' .. '\u102a'
| '\u1050' .. '\u1055'
| '\u10a0' .. '\u10c5'
| '\u10d0' .. '\u10f8'
| '\u1100' .. '\u1159'
| '\u115f' .. '\u11a2'
| '\u11a8' .. '\u11f9'
| '\u1200' .. '\u1206'
| '\u1208' .. '\u1246'
| '\u1248'
| '\u124a' .. '\u124d'
| '\u1250' .. '\u1256'
| '\u1258'
| '\u125a' .. '\u125d'
| '\u1260' .. '\u1286'
| '\u1288'
| '\u128a' .. '\u128d'
| '\u1290' .. '\u12ae'
| '\u12b0'
| '\u12b2' .. '\u12b5'
| '\u12b8' .. '\u12be'
| '\u12c0'
| '\u12c2' .. '\u12c5'
| '\u12c8' .. '\u12ce'
| '\u12d0' .. '\u12d6'
| '\u12d8' .. '\u12ee'
| '\u12f0' .. '\u130e'
| '\u1310'
| '\u1312' .. '\u1315'
| '\u1318' .. '\u131e'
| '\u1320' .. '\u1346'
| '\u1348' .. '\u135a'
| '\u13a0' .. '\u13f4'
| '\u1401' .. '\u166c'
| '\u166f' .. '\u1676'
| '\u1681' .. '\u169a'
| '\u16a0' .. '\u16ea'
| '\u16ee' .. '\u16f0'
| '\u1700' .. '\u170c'
| '\u170e' .. '\u1711'
| '\u1720' .. '\u1731'
| '\u1740' .. '\u1751'
| '\u1760' .. '\u176c'
| '\u176e' .. '\u1770'
| '\u1780' .. '\u17b3'
| '\u17d7'
| '\u17dc'
| '\u1820' .. '\u1877'
| '\u1880' .. '\u18a8'
| '\u1900' .. '\u191c'
| '\u1950' .. '\u196d'
| '\u1970' .. '\u1974'
| '\u1d00' .. '\u1d6b'
| '\u1e00' .. '\u1e9b'
| '\u1ea0' .. '\u1ef9'
| '\u1f00' .. '\u1f15'
| '\u1f18' .. '\u1f1d'
| '\u1f20' .. '\u1f45'
| '\u1f48' .. '\u1f4d'
| '\u1f50' .. '\u1f57'
| '\u1f59'
| '\u1f5b'
| '\u1f5d'
| '\u1f5f' .. '\u1f7d'
| '\u1f80' .. '\u1fb4'
| '\u1fb6' .. '\u1fbc'
| '\u1fbe'
| '\u1fc2' .. '\u1fc4'
| '\u1fc6' .. '\u1fcc'
| '\u1fd0' .. '\u1fd3'
| '\u1fd6' .. '\u1fdb'
| '\u1fe0' .. '\u1fec'
| '\u1ff2' .. '\u1ff4'
| '\u1ff6' .. '\u1ffc'
| '\u2071'
| '\u207f'
| '\u2102'
| '\u2107'
| '\u210a' .. '\u2113'
| '\u2115'
| '\u2118' .. '\u211d'
| '\u2124'
| '\u2126'
| '\u2128'
| '\u212a' .. '\u2131'
| '\u2133' .. '\u2139'
| '\u213d' .. '\u213f'
| '\u2145' .. '\u2149'
| '\u2160' .. '\u2183'
| '\u3005' .. '\u3007'
| '\u3021' .. '\u3029'
| '\u3031' .. '\u3035'
| '\u3038' .. '\u303c'
| '\u3041' .. '\u3096'
| '\u309d' .. '\u309f'
| '\u30a1' .. '\u30fa'
| '\u30fc' .. '\u30ff'
| '\u3105' .. '\u312c'
| '\u3131' .. '\u318e'
| '\u31a0' .. '\u31b7'
| '\u31f0' .. '\u31ff'
| '\u3400' .. '\u4db5'
| '\u4e00' .. '\u9fa5'
| '\ua000' .. '\ua48c'
| '\uac00' .. '\ud7a3'
| '\uf900' .. '\ufa2d'
| '\ufa30' .. '\ufa6a'
| '\ufb00' .. '\ufb06'
| '\ufb13' .. '\ufb17'
| '\ufb1d'
| '\ufb1f' .. '\ufb28'
| '\ufb2a' .. '\ufb36'
| '\ufb38' .. '\ufb3c'
| '\ufb3e'
| '\ufb40' .. '\ufb41'
| '\ufb43' .. '\ufb44'
| '\ufb46' .. '\ufbb1'
| '\ufbd3' .. '\ufc5d'
| '\ufc64' .. '\ufd3d'
| '\ufd50' .. '\ufd8f'
| '\ufd92' .. '\ufdc7'
| '\ufdf0' .. '\ufdf9'
| '\ufe71'
| '\ufe73'
| '\ufe77'
| '\ufe79'
| '\ufe7b'
| '\ufe7d'
| '\ufe7f' .. '\ufefc'
| '\uff21' .. '\uff3a'
| '\uff41' .. '\uff5a'
| '\uff66' .. '\uff9d'
| '\uffa0' .. '\uffbe'
| '\uffc2' .. '\uffc7'
| '\uffca' .. '\uffcf'
| '\uffd2' .. '\uffd7'
| '\uffda' .. '\uffdc'
| '\ud800' '\udc00' .. '\udc0a'
| '\ud800' '\udc0d' .. '\udc25'
| '\ud800' '\udc28' .. '\udc39'
| '\ud800' '\udc3c' .. '\udc3c'
| '\ud800' '\udc3f' .. '\udc4c'
| '\ud800' '\udc50' .. '\udc5c'
| '\ud800' '\udc80' .. '\udcf9'
| '\ud800' '\udf00' .. '\udf1d'
| '\ud800' '\udf30' .. '\udf49'
| '\ud800' '\udf80' .. '\udf9c'
| '\ud801' '\ue000' .. '\ue09c'
| '\ud802' '\ue400' .. '\ue404'
| '\ud802' '\u0808'
| '\ud802' '\ue40a' .. '\ue434'
| '\ud802' '\ue437' .. '\ue437'
| '\ud802' '\u083c'
| '\ud802' '\u083f'
| '\ud835' '\ub000' .. '\ub053'
| '\ud835' '\ub056' .. '\ub09b'
| '\ud835' '\ub09e' .. '\ub09e'
| '\ud835' '\ud4a2'
| '\ud835' '\ub0a5' .. '\ub0a5'
| '\ud835' '\ub0a9' .. '\ub0ab'
| '\ud835' '\ub0ae' .. '\ub0b8'
| '\ud835' '\ud4bb'
| '\ud835' '\ub0bd' .. '\ub0c2'
| '\ud835' '\ub0c5' .. '\ub104'
| '\ud835' '\ub107' .. '\ub109'
| '\ud835' '\ub10d' .. '\ub113'
| '\ud835' '\ub116' .. '\ub11b'
| '\ud835' '\ub11e' .. '\ub138'
| '\ud835' '\ub13b' .. '\ub13d'
| '\ud835' '\ub140' .. '\ub143'
| '\ud835' '\ud546'
| '\ud835' '\ub14a' .. '\ub14f'
| '\ud835' '\ub152' .. '\ub2a2'
| '\ud835' '\ub2a8' .. '\ub2bf'
| '\ud835' '\ub2c2' .. '\ub2d9'
| '\ud835' '\ub2dc' .. '\ub2f9'
| '\ud835' '\ub2fc' .. '\ub313'
| '\ud835' '\ub316' .. '\ub333'
| '\ud835' '\ub336' .. '\ub34d'
| '\ud835' '\ub350' .. '\ub36d'
| '\ud835' '\ub370' .. '\ub387'
| '\ud835' '\ub38a' .. '\ub3a7'
| '\ud835' '\ub3aa' .. '\ub3c1'
| '\ud835' '\ub3c4' .. '\ub3c8'
| '\ud840' '\udc00' .. '\udffe'
| '\ud841' '\ue000' .. '\ue3fe'
| '\ud842' '\ue400' .. '\ue7fe'
| '\ud843' '\ue800' .. '\uebfe'
| '\ud844' '\uec00' .. '\ueffe'
| '\ud845' '\uf000' .. '\uf3fe'
| '\ud846' '\uf400' .. '\uf7fe'
| '\ud847' '\uf800' .. '\ufbfe'
| '\ud848' '\ufc00' .. '\ufffe'
| '\ud849' '\u0000' .. '\u03fe'
| '\ud84a' '\u0400' .. '\u07fe'
| '\ud84b' '\u0800' .. '\u0bfe'
| '\ud84c' '\u0c00' .. '\u0ffe'
| '\ud84d' '\u1000' .. '\u13fe'
| '\ud84e' '\u1400' .. '\u17fe'
| '\ud84f' '\u1800' .. '\u1bfe'
| '\ud850' '\u1c00' .. '\u1ffe'
| '\ud851' '\u2000' .. '\u23fe'
| '\ud852' '\u2400' .. '\u27fe'
| '\ud853' '\u2800' .. '\u2bfe'
| '\ud854' '\u2c00' .. '\u2ffe'
| '\ud855' '\u3000' .. '\u33fe'
| '\ud856' '\u3400' .. '\u37fe'
| '\ud857' '\u3800' .. '\u3bfe'
| '\ud858' '\u3c00' .. '\u3ffe'
| '\ud859' '\u4000' .. '\u43fe'
| '\ud85a' '\u4400' .. '\u47fe'
| '\ud85b' '\u4800' .. '\u4bfe'
| '\ud85c' '\u4c00' .. '\u4ffe'
| '\ud85d' '\u5000' .. '\u53fe'
| '\ud85e' '\u5400' .. '\u57fe'
| '\ud85f' '\u5800' .. '\u5bfe'
| '\ud860' '\u5c00' .. '\u5ffe'
| '\ud861' '\u6000' .. '\u63fe'
| '\ud862' '\u6400' .. '\u67fe'
| '\ud863' '\u6800' .. '\u6bfe'
| '\ud864' '\u6c00' .. '\u6ffe'
| '\ud865' '\u7000' .. '\u73fe'
| '\ud866' '\u7400' .. '\u77fe'
| '\ud867' '\u7800' .. '\u7bfe'
| '\ud868' '\u7c00' .. '\u7ffe'
| '\ud869' '\u8000' .. '\u82d5'
| '\ud87e' '\ud400' .. '\ud61c'
;