
/*
 * Modified by Vasantha Saparamadu <vsaparam@ocs.mq.edu.au>
 * 08 January 1996
 */

%{
#define VERSION "2.1"

#define BOOLEAN char
#define UNSIGNED_BYTE unsigned char
#define SIGNED_BYTE signed char
#define TRUE 1
#define FALSE 0
#define DEBUG_PROMPT "\n%DEBUG:" 
#define HASH_TABLE_SIZE 251
#define MAX_COMMAND_NAME_LENGTH 32

#define ANUSVARA 2
#define VISARGA 3
#define VOW_A 4
#define VOW_AA 5
#define VOW_AAA 6
#define VOW_AAAA 7
#define VOW_I 8
#define VOW_II 9
#define VOW_U 10
#define VOW_UU 11
#define VOW_R 12
#define VOW_RR 13
#define VOW_L 14
#define VOW_LL 15
#define CANDRA_E 16
#define VOW_E 17
#define VOW_EE 18
#define VOW_AI 19
#define CANDRA_O 20
#define VOW_O 21
#define VOW_OO 22
#define VOW_AU 23
#define CON_K 30
#define CON_KH 31
#define CON_G 32
#define CON_GH 33
#define CON_NG 34
#define CON_C 35
#define CON_CH 36
#define CON_J 37
#define CON_JH 38
#define CON_NY 39
#define CON_TT 40
#define CON_TTH 41
#define CON_DD 42
#define CON_DDH 43
#define CON_NN 44
#define CON_T 45
#define CON_TH 46
#define CON_D 47
#define CON_DH 48
#define CON_N 49
#define CON_NNN 50
#define CON_P 51
#define CON_PH 52
#define CON_B 53
#define CON_BH 54
#define CON_M 55
#define CON_Y 56
#define CON_R 57
#define CON_RR 58
#define CON_L 59
#define CON_LL 60
#define CON_V 61
#define CON_SH 62
#define CON_SS 63
#define CON_S 64
#define CON_H 65
#define NUKTA 66
#define AVAGRAHA 67
#define VIRAMA 68
#define OM 69
#define UDATTA 70
#define ANUDATTA 71
#define GRAVE 72
#define ACUTE 73
#define LENGTH_MARK 74
#define AI_LENGTH_MARK 75
#define CON_Q 76
#define CON_KKH 77
#define CON_GHH 78
#define CON_Z 79
#define CON_DDDH 80
#define CON_RH 81
#define CON_F 82
#define CON_YY 83
#define VBAR 84
#define VBARVBAR 85
#define CON_NAS_G 86
#define CON_NAS_C 87
#define CON_NAS_DD 88
#define CON_NAS_D 89
#define CON_NAS_B 90
#define CON_NAS_J 91
#define CON_KS 92
#define CON_LLL 93
#define CANDRABINDU 94
#define BANDI 95

#define HINDI 1
#define SANSKRIT 2
#define BENGALI 3
#define GURMUKHI 4
#define ORIYA 5
#define TAMIL 6
#define TELUGU 7
#define KANNADA 8
#define SINHALESE 9
#define SINHALA 9
#define GUJARATI 10
#define MALAYALAM 11
#define TIBETAN 12


typedef struct{
char name[MAX_COMMAND_NAME_LENGTH];
UNSIGNED_BYTE ID;
} command_type;
command_type cur_command;

unsigned char *token,string[33] = "",buffer[1024];
int current_buffer_position = 0;
int current_line=1;

BOOLEAN debug = FALSE;
int i=0;

typedef struct hash_list*hash_list_pointer;
struct hash_list{
command_type command;
hash_list_pointer link;};
hash_list_pointer hash_table[HASH_TABLE_SIZE];

int current_language = 0, current_input_mode = 1;
BOOLEAN already_read = FALSE, r_con_a = FALSE, sh_hyphens_activated = FALSE;


void hash_insert(command_type);
unsigned int hash(char*);
int look_in_hash(char[]);
void put_indic(int);
void put_other(unsigned char);
void release_buffer(void);
void sh_cons_vow(int, int, int);
void sh_ra_cons_a(int);
void sh_lig_vow(int, int, int, int);
void sh_ra_lig_a(int, int);

%}

%s SEVENBIT
%s LATEX
%s SAMANALA

SHVOWEL		("\x01\x09"[\x04-\x17])
SHCONSONANT	("\x01\x09"[\x1E-\x41\x52\x56-\x5B])
SHLIGATURE	("\x01\x09\x25\x01\x09\x27"|"\x01\x09\x1E\x01\x09\x3D"|"\x01\x09\x1E\x01\x09\x3F"|"\x01\x09\x31\x01\x09\x30"|"\x01\x09\x31\x01\x09\x2E"|"\x01\x09\x31\x01\x09\x2F"|"\x01\x09\x2D\x01\x09\x2E"|"\x01\x09\x2F\x01\x09\x3D")
SMNLIGATURE	("\x01\x09\x5F\x01\x09\x25\x01\x09\x27"|"\x01\x09\x5F\x01\x09\x1E\x01\x09\x3D"|"\x01\x09\x5F\x01\x09\x1E\x01\x09\x3F"|"\x01\x09\x5F\x01\x09\x31\x01\x09\x30"|"\x01\x09\x5F\x01\x09\x31\x01\x09\x2E"|"\x01\x09\x5F\x01\x09\x31\x01\x09\x2F"|"\x01\x09\x5F\x01\x09\x2D\x01\x09\x2E"|"\x01\x09\x5F\x01\x09\x2F\x01\x09\x3D")
SHRA		("\x01\x09\x39")
SHYA		("\x01\x09\x38")
SHBANDI		("\x01\x09\x5F")

%%

^"#ALIAS"[ \t]+[^ \t\n]{1,32}[ \t]+[^ \t\n]{1,32}	{ 
								token = (unsigned char*) strtok(yytext," \t"); /* #def */
								token = (unsigned char*) strtok(NULL," \t"); /* first argument */
								if ((cur_command.ID = look_in_hash(token)) != -1) {
									token = (unsigned char*) strtok(NULL," \t"); /* second argument */
									strcpy(cur_command.name,token);
									hash_insert(cur_command);
									}
								}

"#"[A-Z\x80-\xff]{1,32}		{ for (i=1;i<yyleng;i++) string[i-1] = yytext[i]; string[yyleng-1] = 0x00;
									i = look_in_hash(string);
									switch (i) {
										case -1: printf("#"); yyless(1); if (debug==TRUE) { 
												printf("%s couldn't find %s in the hash table, putting it back",
												DEBUG_PROMPT,string); } break;
										case 1: printf("#"); yyless(1); if (debug==TRUE) { 
												printf("%s not the right syntax for #alias, putting it back",
												DEBUG_PROMPT,string); } break;
										case 10: if (debug==TRUE) { printf("%s Starting UNICODE mode",
												DEBUG_PROMPT,string); } break;
										case 11: if (debug==TRUE) { printf("%s Starting 7 BIT mode",
												DEBUG_PROMPT,string); } 
												current_input_mode = SEVENBIT;
												break;
										case 12: if (debug==TRUE) { printf("%s Starting CSX mode",
												DEBUG_PROMPT,string); } break;
										case 13: if (debug==TRUE) { printf("%s Starting LaTeX mode",
												DEBUG_PROMPT,string); } 
												current_input_mode = LATEX;
												break;
										case 14: if (debug==TRUE) { printf("%s Starting samanala mode",
												DEBUG_PROMPT,string); } 
												current_input_mode = SAMANALA;
												break;
										case 20: if (debug==TRUE) { printf("%s Starting NIL mode",
												DEBUG_PROMPT,string); } 
												current_language = 0; BEGIN 0; release_buffer();
												break;
										case 21: if (debug==TRUE) { printf("%s Starting HINDI mode",
												DEBUG_PROMPT,string); } 
												current_language = HINDI; 
												BEGIN current_input_mode;
												break;
										case 22: if (debug==TRUE) { printf("%s Starting SANSKRIT mode",
												DEBUG_PROMPT,string); } 
												current_language = SANSKRIT; 
												BEGIN current_input_mode;
												break;
										case 23: if (debug==TRUE) { printf("%s Starting BENGALI mode",
												DEBUG_PROMPT,string); } 
												current_language = BENGALI; 
												BEGIN current_input_mode;
												break;
										case 24: if (debug==TRUE) { printf("%s Starting GURMUKHI mode",
												DEBUG_PROMPT,string); } 
												current_language = GURMUKHI; 
												BEGIN current_input_mode;
												break;
										case 25: if (debug==TRUE) { printf("%s Starting GUJARATI mode",
												DEBUG_PROMPT,string); } 
												current_language = GUJARATI; 
												BEGIN current_input_mode;
												break;
										case 26: if (debug==TRUE) { printf("%s Starting TAMIL mode",
												DEBUG_PROMPT,string); } 
												current_language = TAMIL; 
												BEGIN current_input_mode;
												break;
										case 27: if (debug==TRUE) { printf("%s Starting TELUGU mode",
												DEBUG_PROMPT,string); } 
												current_language = TELUGU; 
												BEGIN current_input_mode;
												break;
										case 28: if (debug==TRUE) { printf("%s Starting KANNADA mode",
												DEBUG_PROMPT,string); } 
												current_language = KANNADA; 
												BEGIN current_input_mode;
												break;
										case 29: if (debug==TRUE) { printf("%s Starting MALAYALAM mode",
												DEBUG_PROMPT,string); } 
												current_language = MALAYALAM; 
												BEGIN current_input_mode;
												break;
										case 30: if (debug==TRUE) { printf("%s Starting ORIYA mode",
												DEBUG_PROMPT,string); } 
												current_language = ORIYA; 
												BEGIN current_input_mode;
												break;
										case 31: if (debug==TRUE) { printf("%s Starting SINHALESE mode",
												DEBUG_PROMPT,string); } 
												current_language = SINHALESE; 
												BEGIN current_input_mode;
												break;
										default: break;
										}
									}
										
([ ])|("\\"[A-Za-z]+)		{ if (already_read == FALSE)  { yyless(0); release_buffer(); already_read = TRUE; }
									else { ECHO; already_read = FALSE; }}

[\n]				{ if (already_read == FALSE)  { yyless(0); release_buffer(); already_read = TRUE; }
									else { ECHO; already_read = FALSE; current_line++; }}

<SEVENBIT>("."m)|M			{ put_indic(ANUSVARA); }

<SEVENBIT>("."h)|H			{ put_indic(VISARGA); }
									
<SEVENBIT>a					{ put_indic(VOW_A); }

<SEVENBIT>aa|A				{ put_indic(VOW_AA); }

<SEVENBIT>\"a|"."A			{ put_indic(VOW_AAA); }

<SEVENBIT>\"aa|\"A|"."AA		{ put_indic(VOW_AAAA); }

<SEVENBIT>i					{ put_indic(VOW_I); }

<SEVENBIT>ii|I				{ put_indic(VOW_II); }

<SEVENBIT>u					{ put_indic(VOW_U); }

<SEVENBIT>uu|U				{ put_indic(VOW_UU); }

<SEVENBIT>"."r				{ put_indic(VOW_R); }

<SEVENBIT>"."R				{ put_indic(VOW_RR); }

<SEVENBIT>"."l				{ put_indic(VOW_L); }

<SEVENBIT>"."L				{ put_indic(VOW_LL); }

<SEVENBIT>\"e				{ put_indic(CANDRA_E); }

<SEVENBIT>"^e"				{ put_indic(VOW_E); }

<SEVENBIT>e					{ put_indic(VOW_EE); }

<SEVENBIT>ai|E				{ put_indic(VOW_AI); }

<SEVENBIT>\"o				{ put_indic(CANDRA_O); }

<SEVENBIT>"^o"				{ put_indic(VOW_O); }

<SEVENBIT>o					{ put_indic(VOW_OO); }

<SEVENBIT>au|O				{ put_indic(VOW_AU); }

<SEVENBIT>k					{ put_indic(CON_K); }

<SEVENBIT>kh|K				{ put_indic(CON_KH); }

<SEVENBIT>g					{ put_indic(CON_G); }

<SEVENBIT>gh|G				{ put_indic(CON_GH); }

<SEVENBIT>\"n				{ put_indic(CON_NG); }

<SEVENBIT>c					{ put_indic(CON_C); }

<SEVENBIT>ch|C				{ put_indic(CON_CH); }

<SEVENBIT>j					{ put_indic(CON_J); }

<SEVENBIT>jh|J				{ put_indic(CON_JH); }

<SEVENBIT>~n				{ put_indic(CON_NY); }

<SEVENBIT>"."t				{ put_indic(CON_TT); }

<SEVENBIT>"."th|"."T		{ put_indic(CON_TTH); }

<SEVENBIT>"."d				{ put_indic(CON_DD); }

<SEVENBIT>"."dh|"."D		{ put_indic(CON_DDH); }

<SEVENBIT>"."n				{ put_indic(CON_NN); }

<SEVENBIT>t					{ put_indic(CON_T); }

<SEVENBIT>th|T				{ put_indic(CON_TH); }

<SEVENBIT>d					{ put_indic(CON_D); }

<SEVENBIT>dh|D				{ put_indic(CON_DH); }

<SEVENBIT>n					{ put_indic(CON_N); }

<SEVENBIT>\"n				{ put_indic(CON_NNN); }

<SEVENBIT>p					{ put_indic(CON_P); }

<SEVENBIT>ph|P				{ put_indic(CON_PH); }

<SEVENBIT>b					{ put_indic(CON_B); }

<SEVENBIT>bh|B				{ put_indic(CON_BH); }

<SEVENBIT>m					{ put_indic(CON_M); }

<SEVENBIT>y					{ put_indic(CON_Y); }

<SEVENBIT>r					{ put_indic(CON_R); }

<SEVENBIT>\"r				{ put_indic(CON_RR); }

<SEVENBIT>l					{ put_indic(CON_L); }

<SEVENBIT>L					{ put_indic(CON_LL); }

<SEVENBIT>\"l				{ put_indic(CON_LLL); }

<SEVENBIT>v					{ put_indic(CON_V); }

<SEVENBIT>\"s				{ put_indic(CON_SH); }

<SEVENBIT>"."s				{ put_indic(CON_SS); }

<SEVENBIT>s					{ put_indic(CON_S); }

<SEVENBIT>h					{ put_indic(CON_H); }

<SEVENBIT>"."a				{ put_indic(AVAGRAHA); }

<SEVENBIT>&					{ put_indic(VIRAMA); }

<SEVENBIT>"."o				{ put_indic(OM); }

<SEVENBIT>q					{ put_indic(CON_Q); }

<SEVENBIT>"."kh|"."K		{ put_indic(CON_KKH); }

<SEVENBIT>"."g				{ put_indic(CON_GHH); }

<SEVENBIT>R					{ put_indic(CON_DDDH); }

<SEVENBIT>Rh				{ put_indic(CON_RH); }

<SEVENBIT>f					{ put_indic(CON_F); }

<SEVENBIT>\"y				{ put_indic(CON_YY); }

<SEVENBIT>"|"					{ put_indic(VBAR); }

<SEVENBIT>"||"				{ put_indic(VBARVBAR); }

<SEVENBIT>Ng				{ put_indic(CON_NAS_G); }

<SEVENBIT>Nc				{ put_indic(CON_NAS_C); }

<SEVENBIT>N"."d				{ put_indic(CON_NAS_DD); }

<SEVENBIT>Nd				{ put_indic(CON_NAS_D); }

<SEVENBIT>Nb				{ put_indic(CON_NAS_B); }

<SEVENBIT>Nj				{ put_indic(CON_NAS_J); }

<SEVENBIT>x					{ put_indic(CON_KS); }

<SEVENBIT>.					{ put_other(yytext[0]); }

<SAMANALA>NG			{ put_indic(ANUSVARA); }

<SAMANALA>H			{ put_indic(VISARGA); }
									
<SAMANALA>a					{ put_indic(VOW_A); }

<SAMANALA>a~				{ put_indic(VOW_AA); }

<SAMANALA>a"^"			{ put_indic(VOW_AAA); }

<SAMANALA>a"^"~		{ put_indic(VOW_AAAA); }

<SAMANALA>i					{ put_indic(VOW_I); }

<SAMANALA>i~				{ put_indic(VOW_II); }

<SAMANALA>u					{ put_indic(VOW_U); }

<SAMANALA>u~				{ put_indic(VOW_UU); }

<SAMANALA>RU				{ put_indic(VOW_R); }

<SAMANALA>RU~				{ put_indic(VOW_RR); }

<SAMANALA>"."l				{ put_indic(VOW_L); }

<SAMANALA>"."L				{ put_indic(VOW_LL); }

<SAMANALA>\"e				{ put_indic(CANDRA_E); }

<SAMANALA>e				{ put_indic(VOW_E); }

<SAMANALA>e~					{ put_indic(VOW_EE); }

<SAMANALA>ai				{ put_indic(VOW_AI); }

<SAMANALA>\"o				{ put_indic(CANDRA_O); }

<SAMANALA>o				{ put_indic(VOW_O); }

<SAMANALA>o~					{ put_indic(VOW_OO); }

<SAMANALA>au				{ put_indic(VOW_AU); }

<SAMANALA>k					{ put_indic(CON_K); }

<SAMANALA>K				{ put_indic(CON_KH); }

<SAMANALA>g					{ put_indic(CON_G); }

<SAMANALA>G				{ put_indic(CON_GH); }

<SAMANALA>\"NG			{ put_indic(CON_NG); put_indic(VOW_A); }

<SAMANALA>ch					{ put_indic(CON_C); }

<SAMANALA>CH				{ put_indic(CON_CH); }

<SAMANALA>j					{ put_indic(CON_J); }

<SAMANALA>J				{ put_indic(CON_JH); }

<SAMANALA>kn				{ put_indic(CON_NY); }

<SAMANALA>t				{ put_indic(CON_TT); }

<SAMANALA>T		{ put_indic(CON_TTH); }

<SAMANALA>d				{ put_indic(CON_DD); }

<SAMANALA>D		{ put_indic(CON_DDH); }

<SAMANALA>N				{ put_indic(CON_NN); }

<SAMANALA>th					{ put_indic(CON_T); }

<SAMANALA>TH				{ put_indic(CON_TH); }

<SAMANALA>dh					{ put_indic(CON_D); }

<SAMANALA>DH				{ put_indic(CON_DH); }

<SAMANALA>n					{ put_indic(CON_N); }

<SAMANALA>p					{ put_indic(CON_P); }

<SAMANALA>P				{ put_indic(CON_PH); }

<SAMANALA>b					{ put_indic(CON_B); }

<SAMANALA>B				{ put_indic(CON_BH); }

<SAMANALA>m					{ put_indic(CON_M); }

<SAMANALA>y					{ put_indic(CON_Y); }

<SAMANALA>r					{ put_indic(CON_R); }

<SAMANALA>l					{ put_indic(CON_L); }

<SAMANALA>L					{ put_indic(CON_LL); }

<SAMANALA>\"l				{ put_indic(CON_LLL); }

<SAMANALA>v|w					{ put_indic(CON_V); }

<SAMANALA>sh				{ put_indic(CON_SH); }

<SAMANALA>SH				{ put_indic(CON_SS); }

<SAMANALA>s					{ put_indic(CON_S); }

<SAMANALA>h					{ put_indic(CON_H); }

<SAMANALA>"."a				{ put_indic(AVAGRAHA); }

<SAMANALA>&					{ put_indic(VIRAMA); }

<SAMANALA>"."o				{ put_indic(OM); }

<SAMANALA>q					{ put_indic(CON_Q); }

<SAMANALA>"."kh|"."K		{ put_indic(CON_KKH); }

<SAMANALA>"."g				{ put_indic(CON_GHH); }

<SAMANALA>R					{ put_indic(CON_DDDH); }

<SAMANALA>Rh				{ put_indic(CON_RH); }

<SAMANALA>f					{ put_indic(CON_F); }

<SAMANALA>\"y				{ put_indic(CON_YY); }

<SAMANALA>"|"					{ put_indic(VBAR); }

<SAMANALA>"||"				{ put_indic(VBARVBAR); }

<SAMANALA>\"ng				{ put_indic(CON_NAS_G); }

<SAMANALA>Nc				{ put_indic(CON_NAS_C); }

<SAMANALA>\"nd				{ put_indic(CON_NAS_DD); }

<SAMANALA>\"ndh				{ put_indic(CON_NAS_D); }

<SAMANALA>\"mb				{ put_indic(CON_NAS_B); }

<SAMANALA>Nj				{ put_indic(CON_NAS_J); }

<SAMANALA>gn				{ put_indic(BANDI);
					  put_indic(CON_J);
					  put_indic(CON_NY); }

<SAMANALA>\"n_dh			{ put_indic(BANDI);
					  put_indic(CON_N);
					  put_indic(CON_D); }


<SAMANALA>x					{ put_indic(CON_KS); }

<SAMANALA>_					{ put_other('{'); put_other('}'); }

<SAMANALA>\"					{ put_indic(BANDI); }

<SAMANALA>.					{ put_other(yytext[0]); }

<LATEX>"\\d{m}"|"\\d{M}"	{ put_indic(ANUSVARA); }

<LATEX>"\\d{h}"|"\\d{H}"	{ put_indic(VISARGA); }
									
<LATEX>a|A					{ put_indic(VOW_A); }

<LATEX>"\\={a}"|"\\={A}"	{ put_indic(VOW_AA); }

<LATEX>"\\\"{a}"|"\\\"{A}"	{ put_indic(VOW_AAA); }

<LATEX>"\\diatop[\\=|\\\" a]"|"\\diatop[\\=|\\\"a]"|"\\diatop[\\=|\\\" A]"|"\\diatop[\\=|\\\"A]"		{ put_indic(VOW_AAAA); }

<LATEX>i|I					{ put_indic(VOW_I); }

<LATEX>"\\={\\i}"|"\\={i}"|"\\={I}"		{ put_indic(VOW_II); }

<LATEX>u|U					{ put_indic(VOW_U); }

<LATEX>"\\={u}"|"\\={U}"	{ put_indic(VOW_UU); }

<LATEX>"\\d{r}"|"\\d{R}"	{ put_indic(VOW_R); }

<LATEX>"\\diatop[\\=|\\d r]"|"\\diatop[\\=|\\d R]"	{ put_indic(VOW_RR); }

<LATEX>"\\d{l}"|"\\d{L}"	{ put_indic(VOW_L); }

<LATEX>"\\diatop[\\=|\\d l]"|"\\diatop[\\=|\\d L]"	{ put_indic(VOW_LL); }

<LATEX>"\\u{e}"|"\\u{E}"	{ put_indic(CANDRA_E); }

<LATEX>"\\v{e}"|"\\v{E}"	{ put_indic(VOW_E); }

 /* <LATEX>e|E 					{ put_indic(VOW_EE); } original version */
 /* Begin DW input coding for Somadasa; DW 15/7/94 */

<LATEX>"\\={e}"|"\\={E}" 			{ put_indic(VOW_EE); }

<LATEX>e|E     					{ put_indic(VOW_E); }

 /* End DW input coding */

<LATEX>ai|AI|Ai 			{ put_indic(VOW_AI); }

<LATEX>"\\u{o}"|"\\u{O}"	{ put_indic(CANDRA_O); }

<LATEX>"\\v{o}"|"\\v{O}"	{ put_indic(VOW_O); }

 /* <LATEX>o|O					{ put_indic(VOW_OO); } original version */
 /* Begin DW input coding for Somadasa; DW 15/7/94 */

<LATEX>"\\={o}"|"\\={O}" 			{ put_indic(VOW_OO); }

<LATEX>o|O     					{ put_indic(VOW_O); }

 /* End DW input coding */

<LATEX>au|AU|Au				{ put_indic(VOW_AU); }

<LATEX>k|K					{ put_indic(CON_K); }

<LATEX>kh|KH|Kh				{ put_indic(CON_KH); }

<LATEX>g|G					{ put_indic(CON_G); }

<LATEX>gh|GH|Gh				{ put_indic(CON_GH); }

<LATEX>"\\.{n}"|"\\.{N}"	{ put_indic(CON_NG); }

<LATEX>c|C					{ put_indic(CON_C); }

<LATEX>ch|CH|Ch				{ put_indic(CON_CH); }

<LATEX>j|J					{ put_indic(CON_J); }

<LATEX>jh|JH|Jh				{ put_indic(CON_JH); }

<LATEX>"\\~{n}"|"\\~{N}"	{ put_indic(CON_NY); }

<LATEX>"\\d{t}"|"\\d{T}"	{ put_indic(CON_TT); }

<LATEX>"\\d{t}h"|"\\d{T}H"|"\\d{T}h"	{ put_indic(CON_TTH); }

<LATEX>"\\d{d}"|"\\d{D}"				{ put_indic(CON_DD); }

<LATEX>"\\d{d}h"|"\\d{D}H"|"\\d{D}h"	{ put_indic(CON_DDH); }

<LATEX>"\\d{n}"|"\\d{N}"				{ put_indic(CON_NN); }

<LATEX>t|T					{ put_indic(CON_T); }

<LATEX>th|TH|Th				{ put_indic(CON_TH); }

<LATEX>d|D					{ put_indic(CON_D); }

<LATEX>dh|DH|Dh				{ put_indic(CON_DH); }

<LATEX>n|N					{ put_indic(CON_N); }

<LATEX>"\\\"{n}"|"\\\"{N}"	{ put_indic(CON_NNN); }

<LATEX>p|P					{ put_indic(CON_P); }

<LATEX>ph|PH|Ph				{ put_indic(CON_PH); }

<LATEX>b|B					{ put_indic(CON_B); }

<LATEX>bh|BH|Bh				{ put_indic(CON_BH); }

<LATEX>m|M					{ put_indic(CON_M); }

<LATEX>y|Y					{ put_indic(CON_Y); }

<LATEX>r|R					{ put_indic(CON_R); }

<LATEX>"\\\"{r}"|"\\\"{R}"	{ put_indic(CON_RR); }

<LATEX>l|L					{ put_indic(CON_L); }

<LATEX>"\\b{l}"|"\\b{L}"	{ put_indic(CON_LL); }

<LATEX>"\\\"{l}"|"\\\"{L}"	{ put_indic(CON_LLL); }

<LATEX>v|V					{ put_indic(CON_V); }

<LATEX>"\\'{s}"|"\\'{S}"	{ put_indic(CON_SH); }

<LATEX>"\\d{s}"|"\\d{S}"	{ put_indic(CON_SS); }

<LATEX>s|S					{ put_indic(CON_S); }

<LATEX>h|H					{ put_indic(CON_H); }

<LATEX>"\\d{a}"|"\\d{A}"	{ put_indic(AVAGRAHA); }

<LATEX>&					{ put_indic(VIRAMA); }

<LATEX>"o\\d{m}"|"O\\d{M}"|"O\\d{m}"	{ put_indic(OM); }

<LATEX>q|Q					{ put_indic(CON_Q); }

<LATEX>"\\b{k}h"|"\\b{K}H"|"\\b{K}h"|"\\underlin{kh}"|"\\underlin{KH}"|"\\underlin{Kh}"	{ put_indic(CON_KKH); }

<LATEX>"\\b{g}"|"\\b{G}"	{ put_indic(CON_GHH); }

<LATEX>"\\b{r}"|"\\b{R}"	{ put_indic(CON_DDDH); }

<LATEX>"\\b{r}h"|"\\b{R}H"|"\\b{R}h"	{ put_indic(CON_RH); }

<LATEX>f|F					{ put_indic(CON_F); }

<LATEX>"\\\"{y}"|"\\\"{Y}"	{ put_indic(CON_YY); }

<LATEX>"|"					{ put_indic(VBAR); }

<LATEX>"||"					{ put_indic(VBARVBAR); }

<LATEX>"\\u{n}g"|"\\u{N}G"|"\\u{N}g"	{ put_indic(CON_NAS_G); }

<LATEX>"\\u{n}c"|"\\u{N}C"|"\\u{N}c"	{ put_indic(CON_NAS_C); }

<LATEX>"\\u{n}\\d{d}"|"\\u{N}\\d{D}"|"\\u{N}\\d{d}"	{ put_indic(CON_NAS_DD); }

<LATEX>"\\u{n}d"|"\\u{N}D"|"\\u{N}d"	{ put_indic(CON_NAS_D); }

<LATEX>"\\u{m}b"|"\\u{M}B"|"\\u{M}b"	{ put_indic(CON_NAS_B); }

<LATEX>"\\u{n}j"|"\\u{N}J"|"\\u{N}j"	{ put_indic(CON_NAS_J); }

<LATEX>x|X					{ put_indic(CON_KS); }

<LATEX>.					{ put_other(yytext[0]); }

"\x01\xff".					{ printf("%c",yytext[2]); }

"\x01\x09\x02"						{ sh_cons_vow(ANUSVARA,0,0); }

"\x01\x09\x03"						{ sh_cons_vow(VISARGA,0,0); }

{SHLIGATURE}(({SHRA}{SHYA})|({SHYA}{SHRA})){SHVOWEL}			{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],CON_R+CON_Y,yytext[14]); else REJECT; }

{SHLIGATURE}(({SHRA}{SHYA})|({SHYA}{SHRA}))			{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],CON_R+CON_Y,0); else REJECT; }

{SHLIGATURE}{SHRA}{SHVOWEL}			{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],CON_R,yytext[11]); else REJECT; }

{SHLIGATURE}{SHRA}					{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],CON_R,0); else REJECT; }

{SHLIGATURE}{SHYA}{SHVOWEL}			{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],CON_Y,yytext[11]); else REJECT; }

{SHLIGATURE}{SHYA}					{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],CON_Y,0); else REJECT; }

{SHLIGATURE}{SHVOWEL}				{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],0,yytext[8]); else REJECT; }

{SHLIGATURE}						{ if(current_input_mode!=SAMANALA) sh_lig_vow(yytext[2],yytext[5],0,0); else REJECT; }

{SMNLIGATURE}(({SHRA}{SHYA})|({SHYA}{SHRA})){SHVOWEL}			{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],CON_R+CON_Y,yytext[17]); else REJECT; }

{SMNLIGATURE}(({SHRA}{SHYA})|({SHYA}{SHRA}))			{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],CON_R+CON_Y,0); else REJECT; }

{SMNLIGATURE}{SHRA}{SHVOWEL}			{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],CON_R,yytext[14]); else REJECT; }

{SMNLIGATURE}{SHRA}					{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],CON_R,0); else REJECT; }

{SMNLIGATURE}{SHYA}{SHVOWEL}			{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],CON_Y,yytext[14]); else REJECT; }

{SMNLIGATURE}{SHYA}					{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],CON_Y,0); else REJECT; }

{SMNLIGATURE}{SHVOWEL}				{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],0,yytext[11]); else REJECT; }

{SMNLIGATURE}						{ if(current_input_mode==SAMANALA) sh_lig_vow(yytext[5],yytext[8],0,0); else REJECT; }

{SHCONSONANT}(({SHRA}{SHYA})|({SHYA}{SHRA})){SHVOWEL}		{ sh_cons_vow(yytext[2],CON_R+CON_Y,yytext[11]); }

{SHCONSONANT}(({SHRA}{SHYA})|({SHYA}{SHRA}))				{ sh_cons_vow(yytext[2],CON_R+CON_Y,0); }

{SHCONSONANT}{SHRA}{SHVOWEL}		{ sh_cons_vow(yytext[2],CON_R,yytext[8]); }

{SHCONSONANT}{SHRA}					{ sh_cons_vow(yytext[2],CON_R,0); }

{SHCONSONANT}{SHYA}{SHVOWEL}		{ sh_cons_vow(yytext[2],CON_Y,yytext[8]); }

{SHCONSONANT}{SHYA}					{ sh_cons_vow(yytext[2],CON_Y,0); }

{SHRA}{SHLIGATURE}"\x01\x09\x04"	{ if(current_input_mode!=SAMANALA) sh_ra_lig_a(yytext[5],yytext[8]); else REJECT; }

{SHRA}{SHCONSONANT}"\x01\x09\x04"	{ if(current_input_mode!=SAMANALA) sh_ra_cons_a(yytext[5]); else REJECT; }

{SHBANDI}{SHRA}{SMNLIGATURE}"\x01\x09\x04"	{ if(current_input_mode==SAMANALA) sh_ra_lig_a(yytext[11],yytext[14]); else REJECT; }

{SHBANDI}{SHRA}{SHCONSONANT}"\x01\x09\x04"	{ if(current_input_mode==SAMANALA) sh_ra_cons_a(yytext[8]); else REJECT; }

{SHCONSONANT}{SHVOWEL}				{ sh_cons_vow(yytext[2], 0,yytext[5]); }

{SHCONSONANT}						{ sh_cons_vow(yytext[2], 0,0); }

{SHVOWEL}							{ sh_cons_vow(0, 0,yytext[2]); }

"\x01\x09".							{ fprintf(stderr,"line %d: Unrecognized Sinhala character\n",current_line); }

%%

void sh_place_normal_vowel(char *s, int extension, int vow)
{
	char r[32],y[32];
	
	switch (extension) {
		case 0x00: r[0] = 0x00; y[0] = 0x00; break;
		case CON_R:	strcpy(r,"r"); y[0] = 0x00; break;
		case CON_Y:	r[0] = 0x00; strcpy(y,"a\\SHb\\char205"); break;
		case CON_R + CON_Y: strcpy(r,"r"); strcpy(y,"a\\SHb\\char205"); break;
		default: break; }

	switch (vow) {
		case 0:	printf("%s%s%s",s,r,y); break;
		case VOW_A: printf("%s%sa%s",s,y,r); break;
		case VOW_AA: printf("%s%sa%s\\char0",s,y,r); break;
		case VOW_AAA: if ((!strcmp(s,"\\char29")) && (extension == 0x00)) printf("\\char29u"); else
						printf("%s%sa%s\\char8",s,y,r); break;
		case VOW_AAAA: if ((!strcmp(s,"\\char29")) && (extension == 0x00)) printf("\\char29uu"); else
						printf("%s%sa%s\\char9",s,y,r); break;
		case VOW_I: printf("%s%si%s",s,y,r); break;
		case VOW_II: printf("%s%sii%s",s,y,r); break;
		case VOW_U: if ((extension == 0x00) || (extension == CON_Y)) 
			{	if ((!strcmp(s,"\\char29")) && (extension == 0x00)) printf("\\char29a\\char8"); else
				printf("%s%su",s,y); }
			else if ((extension == CON_R) || (extension == CON_R+CON_Y)) printf("%s%sa\\char1",s,y); break;
		case VOW_UU: if ((extension == 0x00) || (extension == CON_Y)) 
			{	if ((!strcmp(s,"\\char29")) && (extension == 0x00)) printf("\\char29a\\char9"); else
				printf("%s%suu",s,y); }
			else if ((extension == CON_R) || (extension == CON_R+CON_Y)) printf("%s%sa\\char2",s,y); break;
		case VOW_R: printf("%s%sa%s\\char1",s,y,r); break;
		case VOW_RR: printf("%s%sa%s\\char2",s,y,r); break;
		case VOW_L: printf("%s%sa%s\\char3",s,y,r); break;
		case VOW_LL: printf("%s%sa%s\\char4",s,y,r); break;
		case CANDRA_E: break;
		case VOW_E: printf("\\char5%s%sa%s",s,y,r); break;
		case VOW_EE: printf("\\char5%s%s%s",s,y,r); break;
		case VOW_AI: printf("\\char6%s%sa%s",s,y,r); break;
		case CANDRA_O: break;
		case VOW_O: printf("\\char5%s%sa%s\\char0",s,y,r); break;
		case VOW_OO: printf("\\char5%s%sa%s\\char7",s,y,r); break;
		case VOW_AU: printf("\\char5%s%sa%s\\char3",s,y,r); break;
		default: break;
		}
}

void sh_place_da_like_vowel(char *s, int extension, int vow)
{
	char r[32],y[32];
	
	switch (extension) {
		case 0x00:	r[0] = 0x00; y[0] = 0x00; break;
		case CON_R: strcpy(r,"r"); y[0] = 0x00; break;
		case CON_Y: r[0] = 0x00; strcpy(y,"a\\SHb\\char'205"); break;
		case CON_R + CON_Y:	strcpy(r,"r"); strcpy(y,"a\\SHb\\char'205"); break;
		default: break; }

	switch (vow) {
		case 0:	switch(extension) {
			case CON_R: printf("%sr",s); break;
			case CON_Y: printf("%sa\\char205",s); break;
			case CON_R+CON_Y: printf("%sar\\char205",s); break;
			default: printf("%s",s); break; } break;
		case VOW_A: switch(extension) {
			case CON_R: printf("%sar",s); break;
			case CON_Y: printf("%sy",s); break;
			case CON_R+CON_Y: printf("%sar\\char200",s); break;
			default: printf("%sa",s); break; } break;
		case VOW_AA: switch(extension) {
			case CON_R: printf("%sar\\char0",s); break;
			case CON_Y: printf("%sy\\char0",s); break;
			case CON_R+CON_Y: printf("%sar\\char200\\char0",s); break;
			default: printf("%saa",s); break; } break;
		case VOW_AAA: switch(extension) {
			case CON_R: printf("%sar\\char8",s); break;
			case CON_Y: printf("%sy\\char8",s); break;
			case CON_R+CON_Y: printf("%sar\\char200\\char8",s); break;
			default: printf("%saaa",s); break; } break;
		case VOW_AAAA: switch(extension) {
			case CON_R: printf("%sar\\char9",s); break;
			case CON_Y: printf("%sy\\char9",s); break;
			case CON_R+CON_Y: printf("%sar\\char200\\char9",s); break;
			default: printf("%saaaa",s); break; } break;
		case VOW_I: switch(extension) {
			case CON_R: printf("%sir",s); break;
			case CON_Y: printf("%sa\\char205i",s); break;
			case CON_R+CON_Y: printf("%sar\\char205i",s); break;
			default: printf("%si",s); break; } break;
		case VOW_II: switch(extension) {
			case CON_R: printf("%siir",s); break;
			case CON_Y: printf("%sa\\char205ii",s); break;
			case CON_R+CON_Y: printf("%sar\\char205ii",s); break;
			default: printf("%sii",s); break; } break;
		case VOW_U: switch(extension) {
			case CON_R: printf("%srr",s); break;
			case CON_Y: printf("%sa\\char205u",s); break;
			case CON_R+CON_Y: printf("%sar\\char205u",s); break;
			default: printf("%su",s); break; } break;
		case VOW_UU: switch(extension) {
			case CON_R: printf("%srrr",s); break;
			case CON_Y: printf("%sa\\char205uu",s); break;
			case CON_R+CON_Y: printf("%sar\\char205uu",s); break;
			default: printf("%suu",s); break; } break;
		case VOW_R: switch(extension) {
			case CON_R: printf("%s\\char29a\\char1",s); break;
			case CON_Y: printf("%sy\\char1",s); break;
			case CON_R+CON_Y: printf("%s\\char29\\char16\\char1",s); break;
			default: printf("%srr",s); break; } break;
		case VOW_RR: switch(extension) {
			case CON_R: printf("%s\\char29a\\char2",s); break;
			case CON_Y: printf("%sy\\char2",s); break;
			case CON_R+CON_Y: printf("%s\\char29\\char16\\char2",s); break;
			default: printf("%srrr",s); break; } break;
		case VOW_L: switch(extension) {
			case CON_R: printf("%sar\\char3",s); break;
			case CON_Y: printf("%sy\\char3",s); break;
			case CON_R+CON_Y: printf("%sar\\char205a\\char3",s); break;
			default: printf("%sa\\char3",s); break; } break;
		case VOW_LL: switch(extension) {
			case CON_R: printf("%sar\\char4",s); break;
			case CON_Y: printf("%sy\\char4",s); break;
			case CON_R+CON_Y: printf("%sar\\char205a\\char4",s); break;
			default: printf("%sa\\char4",s); break; } break;
		case CANDRA_E: break;
		case VOW_E: switch(extension) {
			case CON_R: printf("\\char5%sar",s); break;
			case CON_Y: printf("\\char5%sy",s); break;
			case CON_R+CON_Y: printf("\\char5%sar\\char205a",s); break;
			default: printf("\\char5%sa",s); break; } break;
		case VOW_EE: switch(extension) {
			case CON_R: printf("\\char5%sr",s); break;
			case CON_Y: printf("\\char5%sa\\char205",s); break;
			case CON_R+CON_Y: printf("\\char5%sar\\char205",s); break;
			default: printf("\\char5%s",s); break; } break;
		case VOW_AI: switch(extension) {
			case CON_R: printf("\\char6%sar",s); break;
			case CON_Y: printf("\\char6%sy",s); break;
			case CON_R+CON_Y: printf("\\char6%sar\\char205a",s); break;
			default: printf("\\char6%sa",s); break; } break;
		case CANDRA_O: break;
		case VOW_O: switch(extension) {
			case CON_R: printf("\\char5%sar\\char0",s); break;
			case CON_Y: printf("\\char5%sy\\char0",s); break;
			case CON_R+CON_Y: printf("\\char5%sar\\char205a\\char0",s); break;
			default: printf("\\char5%saa",s); break; } break;
		case VOW_OO: switch(extension) {
			case CON_R: printf("\\char5%sar\\char7",s); break;
			case CON_Y: printf("\\char5%sy\\char7",s); break;
			case CON_R+CON_Y: printf("\\char5%sar\\char205a\\char7",s); break;
			default: printf("\\char5%so",s); break; } break;
		case VOW_AU: switch(extension) {
			case CON_R: printf("\\char5%sar\\char3",s); break;
			case CON_Y: printf("\\char5%sy\\char3",s); break;
			case CON_R+CON_Y: printf("\\char5%sar\\char205a\\char3",s); break;
			default: printf("\\char5%sa\\char3",s); break; } break;
		default: break;}
}

void sh_cons_vow(int con, int extension, int vow)
{
	printf("{");
	if (con == 0) {
		switch (vow) {
			case VOW_A:		printf("\\SHa\\char16"); break;
			case VOW_AA:	printf("\\SHa\\char16\\char0"); break;
			case VOW_AAA:	printf("\\SHa\\char16\\char8"); break;
			case VOW_AAAA:	printf("\\SHa\\char16\\char9"); break;
			case VOW_I:		printf("\\SHa\\char17"); break;
			case VOW_II:	printf("\\SHa\\char18"); break;
			case VOW_U:		printf("\\SHa\\char19"); break;
			case VOW_UU:	printf("\\SHa\\char19\\char3"); break;
			case VOW_R:		printf("\\SHa\\char20\\char1"); break;
			case VOW_RR:	printf("\\SHa\\char20\\char2"); break;
			case VOW_L:		printf("\\SHa\\char21"); break;
			case VOW_LL:	printf("\\SHa\\char21\\char3"); break;
			case CANDRA_E:	break;
			case VOW_E:		printf("\\SHa\\char22"); break;
			case VOW_EE:	printf("\\SHa\\char23"); break;
			case VOW_AI:	printf("\\SHa\\char5\\char22"); break;
			case CANDRA_O:	break;
			case VOW_O:		printf("\\SHa\\char24"); break;
			case VOW_OO:	printf("\\SHa\\char25"); break;
			case VOW_AU:	printf("\\SHa\\char24\\char3"); break;
			default: break;
			}}
	else if (con == ANUSVARA) printf("\\SHa\\char11");
	else if (con == VISARGA) printf("\\SHa\\char10");
	else {
		if ((con >= 30) && (con <= 55) && (con != 39) && (con != 47)) printf("\\SHa");
		else printf("\\SHb");
		if (sh_hyphens_activated == TRUE) printf("\\-"); else sh_hyphens_activated = TRUE;
		if (r_con_a == TRUE) printf("{}r");
		switch(con) {
			case CON_K: 	sh_place_normal_vowel("\\char77",extension,vow); break;
			case CON_KH: 	sh_place_normal_vowel("\\char85",extension,vow); break;
			case CON_G: 	sh_place_normal_vowel("\\char66",extension,vow); break;
			case CON_GH: 	sh_place_normal_vowel("\\char101",extension,vow); break;
			case CON_NG: 	sh_place_normal_vowel("\\char109",extension,vow); break;
			case CON_C: 	sh_place_normal_vowel("\\char117",extension,vow); break;
			case CON_CH: 	sh_place_normal_vowel("\\char125",extension,vow); break;
			case CON_J: 	sh_place_normal_vowel("\\char133",extension,vow); break;
			case CON_JH: 	sh_place_normal_vowel("\\char141",extension,vow); break;
			case CON_NY: 	if(current_input_mode == SAMANALA)
					{
						sh_place_normal_vowel("\\char139",extension,vow); break;
					}
					else
					{
						sh_place_da_like_vowel("\\char139",extension,vow); break;
					}
			case CON_TT: 	sh_place_normal_vowel("\\char149",extension,vow); break;
			case CON_TTH: 	sh_place_normal_vowel("\\char157",extension,vow); break;
			case CON_DD: 	sh_place_normal_vowel("\\char165",extension,vow); break;
			case CON_DDH: 	sh_place_normal_vowel("\\char173",extension,vow); break;
			case CON_NN: 	sh_place_normal_vowel("\\char181",extension,vow); break;
			case CON_T: 	sh_place_normal_vowel("\\char189",extension,vow); break;
			case CON_TH: 	sh_place_normal_vowel("\\char197",extension,vow); break;
			case CON_D: 	if(current_input_mode == SAMANALA)
					{
						sh_place_normal_vowel("\\char163",extension,vow); break;
					}
					else
					{
						sh_place_da_like_vowel("\\char163",extension,vow); break;
					}
			case CON_DH: 	sh_place_normal_vowel("\\char205",extension,vow); break;
			case CON_N: 	sh_place_normal_vowel("\\char213",extension,vow); break;
			case CON_NNN: 	break;
			case CON_P: 	sh_place_normal_vowel("\\char221",extension,vow); break;
			case CON_PH: 	sh_place_normal_vowel("\\char229",extension,vow); break;
			case CON_B: 	sh_place_normal_vowel("\\char237",extension,vow); break;
			case CON_BH: 	sh_place_normal_vowel("\\char245",extension,vow); break;
			case CON_M: 	sh_place_normal_vowel("\\char253",extension,vow); break;
			case CON_Y: 	sh_place_normal_vowel("\\char21",extension,vow); break;
			case CON_R: 	sh_place_normal_vowel("\\char29",extension,vow); break;
			case CON_RR: 	break;
			case CON_L: 	sh_place_normal_vowel("\\char37",extension,vow); break;
			case CON_LL: 	sh_place_normal_vowel("\\char85",extension,vow); break;
			case CON_V: 	sh_place_normal_vowel("\\char14",extension,vow); break;
			case CON_SH: 	sh_place_normal_vowel("\\char53",extension,vow); break;
			case CON_SS: 	sh_place_normal_vowel("\\char61",extension,vow); break;
			case CON_S: 	sh_place_normal_vowel("\\char69",extension,vow); break;
			case CON_H: 	sh_place_normal_vowel("\\char77",extension,vow); break;
			case CON_F: 	sh_place_normal_vowel("\\char213",extension,vow); break;
			case CON_NAS_G: 	sh_place_normal_vowel("\\char93",extension,vow); break;
			case CON_NAS_C: 	sh_place_normal_vowel("\\char101",extension,vow); break;
			case CON_NAS_DD: 	sh_place_normal_vowel("\\char109",extension,vow); break;
			case CON_NAS_D: 	if(current_input_mode == SAMANALA)
						{
							sh_place_normal_vowel("\\char187",extension,vow); break;
						}
						else
						{
					 		sh_place_da_like_vowel("\\char187",extension,vow); break;
						}
			case CON_NAS_B: 	sh_place_normal_vowel("\\char117",extension,vow); break;
			case CON_NAS_J: 	sh_place_normal_vowel("\\char125",extension,vow); break;
			case CON_KS: 		break;
			case CON_LLL: 		break;
			default: break;
			}
		}
	printf("}");
}

void sh_ra_cons_a(int con)
{
	r_con_a = TRUE; sh_cons_vow(con, 0, 0); r_con_a = FALSE; 
}

void sh_lig_vow(int cona, int conb, int extension, int vow)
{
	if ((cona == CON_D) && (conb == CON_V)) printf("{\\SHb");
	else printf("{\\SHc");
	if (sh_hyphens_activated == TRUE) printf("\\-"); else sh_hyphens_activated = TRUE;
	if (r_con_a == TRUE) printf("{}r");
	switch(cona) {
		case CON_K: switch(conb) {
			case CON_V: sh_place_normal_vowel("\\char15",extension,vow); break;
			case CON_SS: sh_place_normal_vowel("\\char61",extension,vow); break;
			default: break; } break;
		case CON_N: switch(conb) {
			case CON_DH: sh_place_normal_vowel("\\char69",extension,vow); break;
			case CON_TH: sh_place_normal_vowel("\\char77",extension,vow); break;
			case CON_D: 	if(current_input_mode == SAMANALA)
					{
						sh_place_normal_vowel("\\char91",extension,vow); break;
					}
					else
					{
						sh_place_da_like_vowel("\\char91",extension,vow); break;
					}
			default: break; } break;
		case CON_J: switch(conb) {
			case CON_NY: 	if(current_input_mode == SAMANALA)
					{
						sh_place_normal_vowel("\\char27",extension,vow); break;
					}
					else
					{
						sh_place_da_like_vowel("\\char27",extension,vow); break;
					}
			default: break; } break;
		case CON_T: switch(conb) {
			case CON_TH: sh_place_normal_vowel("\\char109",extension,vow); break;
			default: break; } break;
		case CON_D: switch(conb) {
			case CON_V: sh_place_normal_vowel("\\char101",extension,vow); break;
			default: break; } break;
		default: break; }
		printf("}");
}

void sh_ra_lig_a(int cona, int conb)
{
	r_con_a = TRUE; sh_lig_vow(cona, conb, 0, 0); r_con_a = FALSE; 
}

void put_indic(int code)
{
unsigned char s[4];

s[0] = 0x01;
s[1] = current_language;
s[2] = code;
s[3] = 0x00;

if (strlen(buffer) > 1000) release_buffer();
strcat(buffer,s);
/* printf("Buffer is: '%s' of length %d\n",buffer,strlen(buffer)); */
}

void put_other(unsigned char xx)
{
unsigned char s[4];

s[0] = 0x01;
s[1] = 0xff;
s[2] = xx;
s[3] = 0x00;

if (strlen(buffer) > 1000) release_buffer();
strcat(buffer,s);
/* printf("Buffer is: '%s' of length %d\n",buffer,strlen(buffer)); */
}

void release_buffer(void)
{
	if ((strlen(buffer) > 0) && (strlen(buffer) < 1024)) 
		{ for (i=strlen(buffer)-1;i>=0;i--) { unput(buffer[i]); /* printf(": char %d=%d:",i,buffer[i]); */ }} 
	buffer[0] = 0x00; /* printf("step-1"); */
	sh_hyphens_activated = FALSE;
}

unsigned int hash(char *key)
{
long int number= 0L;
int k= 0;

for(k= 0;(key[k]!=0)&&(k<32);k++) number+= abs((int)key[k]);
k= ((unsigned int)(number % HASH_TABLE_SIZE));
return k;
}

void hash_insert(command_type command)
{
unsigned int hash_value= hash(command.name);
BOOLEAN already_there= FALSE;
hash_list_pointer ptr,trail= NULL,lead= hash_table[hash_value];

for(;lead;trail= lead,lead= lead->link){
	if(!strcmp(lead->command.name,command.name))
	already_there= TRUE;
	}
if(already_there==FALSE){
	ptr= (hash_list_pointer)malloc(sizeof(struct hash_list));
	if(!(ptr)){printf("\nERROR: no more memory for hashing!!...\n");
	exit(0);
	}
ptr->command= command;
ptr->link= NULL;
if(trail) trail->link= ptr;
	else hash_table[hash_value]= ptr;
if(debug==TRUE) printf("%s Just placed %s in hash_table[%d]...", DEBUG_PROMPT,command.name,hash_value);}
}

int look_in_hash(char name_[MAX_COMMAND_NAME_LENGTH])
{
unsigned int hash_value= hash(name_);
hash_list_pointer trail= NULL,lead= hash_table[hash_value];
BOOLEAN found= FALSE;

for(;((lead)&&(found==FALSE));trail= lead,lead= lead->link){
	if(!strcmp(lead->command.name,name_)) {
		found= TRUE;
		if(debug==TRUE)printf("%s Just found command %s in the hash table, it has ID %d", DEBUG_PROMPT,lead->command.name,lead->command.ID);
		return lead->command.ID;
		}
	}
if(found==FALSE) {
	if(debug==TRUE)printf("%s Couldn't find command %s in the hash table, putting it back into the stream", DEBUG_PROMPT,name_);
	return-1;
	}
}

void initialize_hash_table(void)
{
	command_type command;
	
	strcpy(command.name,"ALIAS"); command.ID = 1; hash_insert(command);

	strcpy(command.name,"UNICODE"); command.ID = 10; hash_insert(command);
	strcpy(command.name,"SEVENBIT"); command.ID = 11; hash_insert(command);
	strcpy(command.name,"CSX"); command.ID = 12; hash_insert(command);
	strcpy(command.name,"LATEX"); command.ID = 13; hash_insert(command);
	strcpy(command.name,"SAMANALA"); command.ID = 14; hash_insert(command);

	strcpy(command.name,"NIL"); command.ID = 20; hash_insert(command);
	strcpy(command.name,"HINDI"); command.ID = 21; hash_insert(command);
	strcpy(command.name,"SANSKRIT"); command.ID = 22; hash_insert(command);
	strcpy(command.name,"BENGALI"); command.ID = 23; hash_insert(command);
	strcpy(command.name,"GURMUKHI"); command.ID = 24; hash_insert(command);
	strcpy(command.name,"GUJARATI"); command.ID = 25; hash_insert(command);
	strcpy(command.name,"TAMIL"); command.ID = 26; hash_insert(command);
	strcpy(command.name,"TELUGU"); command.ID = 27; hash_insert(command);
	strcpy(command.name,"KANNADA"); command.ID = 28; hash_insert(command);
	strcpy(command.name,"MALAYALAM"); command.ID = 29; hash_insert(command);
	strcpy(command.name,"ORIYA"); command.ID = 30; hash_insert(command);
	strcpy(command.name,"SINHALESE"); command.ID = 31; hash_insert(command);
	strcpy(command.name,"SINHALA"); command.ID = 31; hash_insert(command);
	strcpy(command.name,"TIBETAN"); command.ID = 32; hash_insert(command);
}	

main(int argc, char *argv[])
{
	if( (argc==2) && (strcmp(argv[1],"-v")==0) )
	{
		fprintf(stderr, "indica version %s\n",VERSION);
		exit(0);
	}
	initialize_hash_table(); buffer[0] = 0x00;
	yylex();
	return 0;
}

yywrap()
{
	return 1;
}
