%% %{ /* * Buckwalter+ to Arabic Romanization conversion * v. 2.0, Malcolm D. Hyman, 2004-05-11 * [this is a jflex specification] * * This Romanization now uses i.a. characters from the "Latin Extended * Additional" block of Unicode (1EFF). * * TODO: implement rules 11a-b for tashdid in ALA-LC? */ private String last = ""; private boolean uppercase = false, postconsonantal = true, article = false; private String convert(String s) { if (! (yystate() == ROOT)) yybegin(NONINITIAL); if (s.length() > 0) { char f = s.charAt(s.length() - 1); postconsonantal = ! ((f == '\u0101') || (f == '\u012b') || (f == '\u016b') || (f == 'a') || (f == 'u') || (f == 'i')); } else postconsonantal = false; if (uppercase) s = s.toUpperCase(); uppercase = false; return s; } %} %class ArabicRomanLex %public %implements LexS %type java.lang.String %unicode HAMZA = [\'>&<\}] IDENTITY = [btjdrzsfqklmnhwaui] IDENTITY_ABJ = [btjdrzsfqklmnhyw] VOWEL = [aui] LETTER = [btjdrzsfqklmnhvjHx*$SDTZEGyw\'|>&<\}] NONVOCALIC = [btjdrzsfqklmnhvjHx*$SDTZEG\'|>&<\}o ] %state NONINITIAL ROOT %% /* * Arabic letters in state YYINITIAL in unvowelled words; these cause * scanner to enter ROOT mode. In ROOT mode, YA and WAW are never * transliterated as vowels. */ { "fy"$ { // exception last = "\u012b"; return convert("f\u012b"); } "fy"/" " { last = "\u012b"; return convert("f\u012b"); } "fy"/\n { last = "\u012b"; return convert("f\u012b"); } "v"/{LETTER}+" " { // THAA yybegin(ROOT); last = "\u1e6f"; return convert(last); } // SMALL LETTER T WITH LINE BELOW "j"/{LETTER}+" " { // JEEM yybegin(ROOT); last = "\u01e7"; return convert(last); } // SMALL LETTER G HACEK "H"/{LETTER}+" " { // HAA yybegin(ROOT); last = "\u1e25"; return convert(last); } // SMALL LETTER H WITH DOT BELOW "x"/{LETTER}+" " { // KHAA yybegin(ROOT); last = "\u1e2b"; return convert(last); } // SMALL LETTER H WITH BREVE BELOW "*"/{LETTER}+" " { // THAL yybegin(ROOT); last = "\u1e0f"; return convert(last); } // SMALL LETTER D WITH LINE BELOW "$"/{LETTER}+" " { // SHEEN yybegin(ROOT); last = "\u0161"; return convert(last); } // SMALL LETER S HACEK "S"/{LETTER}+" " { // SAD yybegin(ROOT); last = "\u1e63"; return convert(last); } // SMALL LETTER S WITH DOT BELOW "D"/{LETTER}+" " { // DAD yybegin(ROOT); last = "\u1e0d"; return convert(last); } // SMALL LETTER D WITH DOT BELOW "T"/{LETTER}+" " { // TAH yybegin(ROOT); last = "\u1e6d"; return convert(last); } // SMALL LETTER T WITH DOT BELOW "Z"/{LETTER}+" " { // DHAH yybegin(ROOT); last = "\u1e93"; return convert(last); } // SMALL LETTER Z WITH DOT BELOW "E"/{LETTER}+" " { // AIN yybegin(ROOT); last = "\u02bf"; return convert(last); } // MODIFIER LETTER LEFT HALF RING "g"/{LETTER}+" " { // GHAIN yybegin(ROOT); last = "\u0121"; return convert(last); } // SMALL LETTER G DOT {IDENTITY_ABJ}/{LETTER}+" " { last = yytext(); yybegin(ROOT); return convert(last); } "v"/{LETTER}+\n { // THAA yybegin(ROOT); last = "\u1e6f"; return convert(last); } // SMALL LETTER T WITH LINE BELOW "j"/{LETTER}+\n { // JEEM yybegin(ROOT); last = "\u01e7"; return convert(last); } // SMALL LETTER G HACEK "H"/{LETTER}+\n { // HAA yybegin(ROOT); last = "\u1e25"; return convert(last); } // SMALL LETTER H WITH DOT BELOW "x"/{LETTER}+\n { // KHAA yybegin(ROOT); last = "\u1e2b"; return convert(last); } // SMALL LETTER H WITH BREVE BELOW "*"/{LETTER}+\n { // THAL yybegin(ROOT); last = "\u1e0f"; return convert(last); } // SMALL LETTER D WITH LINE BELOW "$"/{LETTER}+\n { // SHEEN yybegin(ROOT); last = "\u0161"; return convert(last); } // SMALL LETER S HACEK "S"/{LETTER}+\n { // SAD yybegin(ROOT); last = "\u1e63"; return convert(last); } // SMALL LETTER S WITH DOT BELOW "D"/{LETTER}+\n { // DAD yybegin(ROOT); last = "\u1e0d"; return convert(last); } // SMALL LETTER D WITH DOT BELOW "T"/{LETTER}+\n { // TAH yybegin(ROOT); last = "\u1e6d"; return convert(last); } // SMALL LETTER T WITH DOT BELOW "Z"/{LETTER}+\n { // DHAH yybegin(ROOT); last = "\u1e93"; return convert(last); } // SMALL LETTER Z WITH DOT BELOW "E"/{LETTER}+\n { // AIN yybegin(ROOT); last = "\u02bf"; return convert(last); } // MODIFIER LETTER LEFT HALF RING "g"/{LETTER}+\n { // GHAIN yybegin(ROOT); last = "\u0121"; return convert(last); } // SMALL LETTER G DOT {IDENTITY_ABJ}/{LETTER}+\n { last = yytext(); yybegin(ROOT); return convert(last); } } /* * ROOT state. Defaults are used, except for YA and WAW. */ { [yw] { // YA, WAW last = yytext(); return convert(last); } } /* * Arabic letters. These rules apply in all scanner states. Many are * handled by the identity transformation. */ "a"?"Aa" { last = "\u0101"; return convert(last); } "a"?"A" { // ALEF last = "\u0101"; return convert(last); } // SMALL LETTER A MACRON "Y" { // ALEF MAQSURAH last = "\u0101"; return convert(last); } // SMALL LETTER A MACRON "p" { // TAA MARBUTAH last = "t"; return convert(last); } "v" { // THAA last = "\u1e6f"; return convert(last); } // SMALL LETTER T WITH LINE BELOW "j" { // JEEM last = "\u01e7"; return convert(last); } // SMALL LETTER G HACEK "H" { // HAA last = "\u1e25"; return convert(last); } // SMALL LETTER H WITH DOT BELOW "x" { // KHAA last = "\u1e2b"; return convert(last); } // SMALL LETTER H WITH BREVE BELOW "*" { // THAL last = "\u1e0f"; return convert(last); } // SMALL LETTER D WITH LINE BELOW "$" { // SHEEN last = "\u0161"; return convert(last); } // SMALL LETER S HACEK "S" { // SAD last = "\u1e63"; return convert(last); } // SMALL LETTER S WITH DOT BELOW "D" { // DAD last = "\u1e0d"; return convert(last); } // SMALL LETTER D WITH DOT BELOW "T" { // TAH last = "\u1e6d"; return convert(last); } // SMALL LETTER T WITH DOT BELOW "Z" { // DHAH last = "\u1e93"; return convert(last); } // SMALL LETTER Z WITH DOT BELOW "E" { // AIN last = "\u02bf"; return convert(last); } // MODIFIER LETTER LEFT HALF RING "g" { // GHAIN last = "\u0121"; return convert(last); } // SMALL LETTER G DOT "_" { } { // but not ROOT "y" { // YA last = (postconsonantal) ? "\u012b" : "y"; return convert(last); } "y"/[Aw] { last = "y"; return convert("y"); } } {IDENTITY} { last = yytext(); return convert(last); } "N" { // DAMMATAN last = "un"; return convert(last); } "K" { // KASRATAN last = "in"; return convert(last); } "a"?"AF" { last = "an"; return convert(last); } "F" { // FATHATAN last = "an"; return convert(last); } [@o] { } "`" { // DAGGER ALEF last = "\u0101"; return convert(last); } // SMALL LETTER A MACRON "~" { // SHADDAH return convert(last); } "^" { uppercase = true; } " " { yybegin(YYINITIAL); article = false; return " "; } "-" { yybegin(YYINITIAL); return "-"; } \n { yybegin(YYINITIAL); article = false; return "\n"; } /* * YYINITIAL is used as word-initial state. The method convert() always * puts the scanner in NONINITIAL state. */ { "|" { // MADDAH ON ALEF last = "\u0101"; return convert(last); } // cf. ALA-LC rule 10 "{" { // HAMZAT WASL ON ALEF (see also the ARTICLE) last = "i"; return convert(last); } // cf. ALA-LC rule 9 ">""a"? { // HAMZA ON ALEF (+ FATHAH) last = "a"; return convert("a"); } ">u" { // HAMZA ON ALEF (+ DAMMAH) last = "u"; return convert("u"); } "<""i"? { // HAMZA ON ALEF (+ KASRAH) last = "i"; return convert("i"); } [A{]"a"?"l""-"? { // the ARTICLE if (! article) { last = "l"; article = true; yybegin(YYINITIAL); return "al-"; } else { last = "l"; return convert("\u0101l"); }} "^"?"Allah" { last = "h"; return convert("Allah"); } "Aal""~"?"aty" { last = "\u012b"; return convert("allat\u012b"); } "Aal""~"?"a*y" { last = "\u012b"; return convert("alla\u1e0f\u012b"); } "Ai" { last = "i"; return convert("i"); } "Ay" { last = "\u012b"; return convert(last); } "y"/{VOWEL}|"&" { last = "y"; return convert(last); } "u"?"w"/{NONVOCALIC} { last = "\u016b"; return convert(last); } } /* * Expressions that get matched only in NONINITIAL state. */ { "&u" { last = "u"; return convert("\u02beu"); } "&" { // HAMZAH ON WAW if (! last.equals("u")) { last = "\u02be"; return convert("u\u02be"); } else { last = "\u02be"; return convert(last); }} {HAMZA} { last = "\u02be"; return convert(last); } "|" { // MADDAH ON ALEF last = "\u0101"; return convert("\u02be\u0101"); } // cf. ALA-LC rule 10 "y"/{VOWEL} { if (postconsonantal) { last = "y"; return convert("iy"); } else { last = "y"; return convert(last); }} "u"?"w"/{NONVOCALIC} { last = (postconsonantal) ? "\u016b" : "w"; return convert(last); } } . { return convert(yytext()); }