/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Copyright (C) 1998-2009 Gerwin Klein * * 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 { \\ { even = false; return '\\'; } \\ / \\ { even = !even; return '\\'; } \\ / "u" { if (even) { even = false; return '\\'; } else yybegin(DIGITS); } .|\n { return zzBuffer[zzStartRead]; } <> { return -1; } } { {UnicodeEscape} { yybegin(YYINITIAL); return value(); } .|\n { throw new Error("incorrect Unicode escape"); } <> { throw new Error("EOF in Unicode escape"); } }