blob: 31af811a72e73cdd34cd425b2c0d8e5d22ffb202 [file] [log] [blame]
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Copyright (C) 1998-2004 Gerwin Klein <lsf@jflex.de> *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License. See the file *
* COPYRIGHT for more information. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* ยง3.3 of the Java Language Specification :
UnicodeInputCharacter:
UnicodeEscape
RawInputCharacter
UnicodeEscape:
\ UnicodeMarker HexDigit HexDigit HexDigit HexDigit
UnicodeMarker:
u
UnicodeMarker u
RawInputCharacter:
any Unicode character
HexDigit: one of
0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F
only an even number of '\' is eligible to start a Unicode escape sequence
*/
import java.io.*;
%%
%public
%final
%class UnicodeEscapes
%extends FilterReader
%int
%function read
%switch
%16bit
UnicodeEscape = {UnicodeMarker} {HexDigit} {4}
UnicodeMarker = "u"+
HexDigit = [0-9a-fA-F]
%state DIGITS
%init{
super(in);
%init}
%{
private boolean even;
private int value() {
int r = 0;
for (int k = zzMarkedPos-4; k < zzMarkedPos; k++) {
int c = zzBuffer[k];
if (c >= 'a')
c-= 'a'-10;
else if (c >= 'A')
c-= 'A'-10;
else
c-= '0';
r <<= 4;
r += c;
}
return r;
}
public int read(char cbuf[], int off, int len) throws IOException {
if ( !ready() ) return -1;
len+= off;
for (int i=off; i<len; i++) {
int c = read();
if (c < 0)
return i-off;
else
cbuf[i] = (char) c;
}
return len-off;
}
public boolean markSupported() {
return false;
}
public boolean ready() throws IOException {
return !zzAtEOF && (zzCurrentPos < zzEndRead || zzReader.ready());
}
%}
%%
<YYINITIAL> {
\\ { even = false; return '\\'; }
\\ / \\ { even = !even; return '\\'; }
\\ / "u" {
if (even) {
even = false;
return '\\';
}
else
yybegin(DIGITS);
}
.|\n { return zzBuffer[zzStartRead]; }
<<EOF>> { return -1; }
}
<DIGITS> {
{UnicodeEscape} { yybegin(YYINITIAL); return value(); }
.|\n { throw new Error("incorrect Unicode escape"); }
<<EOF>> { throw new Error("EOF in Unicode escape"); }
}