Newsgroup: it.comp.lang.visual-basic
Titolo: Routine per la sillabazione !

Cerco disperatamente routine ( in qualsiasi linguaggio ) per sillabazione italiana o inglese.
Possibilmente indirizzi internet sull' argomento.
Leonardo Di Pinto
prom...@mail5.clio.it
--
Automatic posted from [195.60.128.103]
via Mailgate Server - 
http://www.mailgate.org


Di seguito c'é una unit Delphi che fa quello che ti serve.
Non ricordo più se sia completamente bug-free, ma in ogni caso è un
buon punto di partenza
Ciao
unit Sillabaz;
interface
type TDatiSillabazione = record
  nDivisioni: integer;
  Divisioni: array[1..20] of integer; { posizioni prima delle quali si
deve dividere la parola }
end;
{ restituisce la parola spezzata da trattini }
function Sillaba( Parola: string ): string;
{ divide in sillabe una parola (strettamente) prima della posizione
specificata }
{ restituisce la prima parte della parola (compreso trattino) e la
seconda parte }
{ se non riesce a dividere la prima parte è vuota e la seconda
contiene tutta la parola }
procedure SillabaPrimaDi( Parola: string; Posizione: integer; var
PrimaParte, SecondaParte: string );
implementation
uses
  SysUtils;
const
  SepChar = '-';  { carattere separatore sillabe }
{///////////////////////////////////////////////////////////////// }
function GruppoConsInizioParola( pParola: string; Indice: integer ):
boolean;
{ ritorna true se a partire da indice c'è un gruppo di consonanti che
}
{ possono trovarsi a inizio parola }
type
  TConsInizio = array[1..31] of string;
const
  GruppiConsonantiInizio: TConsInizio = ( 'BL', 'BR', 'CH', 'CL',
'CR', 'DR',
          'FL' , 'FR', 'GH', 'GL', 'GN', 'GR', 'PL', 'PNE', 'PR',
'PSE', 'PSI',
          'PTE', 'PTI', 'PTO', 'SB', 'SC', 'SD', 'SF', 'SG', 'SM',
          'SP', 'SQ', 'ST', 'SV', 'TR' );
var
  k: integer;
  RetVal: boolean;
  Parola: string;
begin
  Parola := UpperCase( pParola );
  RetVal := false;
  if Length(Parola) > (Indice + 1) then
    for k := 1 to 28 do
      if Copy( Parola, Indice, Length(GruppiConsonantiInizio[k]) ) =
GruppiConsonantiInizio[k] then
        RetVal := true;
  GruppoConsInizioParola := RetVal;
end;
{////////////////////////////////////////////////////////////////// }
function Vocale( ch: char ): boolean;
{ ritorna true se la lettera è una vocale }
type
  TVocArr = array[1..16] of char;
const
  Vocali: TVocArr = ( 'A', 'E', 'I', 'O', 'U',
                    'a', 'e', 'i', 'o', 'u',
                    'à', 'è', 'é', 'ì', 'ò', 'ù' );
var
  k: integer;
  RetVal: boolean;
begin
  RetVal := false;
  for k := 1 to 16 do
    if ch = Vocali[k] then
      RetVal := true;
  Vocale := RetVal;
end;
{/////////////////////////////////////////////////////////////////// }
procedure DividiInSillabe( Parola: string; var DS: TDatiSillabazione
);
var
  ptNext: integer; { prossima lettera da processare }
  lParola, k: integer;
  ParOut: string;
  DaDividere: boolean;
begin
  DS.nDivisioni := 0;
  ParOut := '';
  ptNext := 1;
  lParola := Length(Parola);
  { verifica se la parola contiene delle cifre: se le contiene non
sillaba }
  for k := 1 to lParola do
    if (Parola[k] >= '0') and (Parola[k] <= '9') then
      ptNext := lParola + 10; { in questo modo non esegue il while
successivo }
  while ptNext <= lParola do
  begin
    { test su due doppie }
    if (ptNext > 1) and
       (Parola[ptNext + 1] = Parola[ptNext]) and
       (not Vocale(Parola[ptNext])) then
    begin
      DS.nDivisioni := DS.nDivisioni + 1;
      DS.Divisioni[DS.nDivisioni] := ptNext + 1;
      ParOut := ParOut + Parola[ptNext] + SepChar + Parola[ptNext +
1];
      ptNext := ptNext + 2;
      Continue;
    end;
    { test su consonante tra due vocali }
    if (ptNext > 1) and
       (lParola > ptNext) and
       (Vocale(Parola[ptNext - 1])) and
       (not Vocale(Parola[ptNext])) and
       (Vocale(Parola[ptNext + 1])) then
    begin
      DS.nDivisioni := DS.nDivisioni + 1;
      DS.Divisioni[DS.nDivisioni] := ptNext;
      ParOut := ParOut + SepChar + Parola[ptNext];
      ptNext := ptNext + 1;
      Continue;
    end;
    { test su 'S' seguita da consonanti }
    if (lParola > ptNext) and
       {(Vocale(Parola[ptNext - 1])) and}
       ( (Parola[ptNext] = 's') or (Parola[ptNext] = 'S') ) and
       (not Vocale(Parola[ptNext + 1])) then
    begin
      if ptNext > 1 then
      begin
        DS.nDivisioni := DS.nDivisioni + 1;
        DS.Divisioni[DS.nDivisioni] := ptNext;
        ParOut := ParOut + SepChar;{ + Parola[ptNext]; }
      {ptNext := ptNext + 1; }
      end;
      while (ptNext <= lParola) and (not Vocale(Parola[ptNext])) do
      begin
        ParOut := ParOut + Parola[ptNext];
        ptNext := ptNext + 1;
      end;
      Continue;
    end;
    { test su due consonanti consecutive }
    if (lParola > ptNext) and
       (not Vocale(Parola[ptNext])) and
       (not Vocale(Parola[ptNext + 1])) then
      if GruppoConsInizioParola( Parola, ptNext ) then
      begin
        if ptNext > 1 then
        begin
          { sono un gruppo che può stare a inizio parola, taglia prima
}
          DS.nDivisioni := DS.nDivisioni + 1;
          DS.Divisioni[DS.nDivisioni] := ptNext;
          ParOut := ParOut + SepChar + Parola[ptNext] + Parola[ptNext
+ 1];
          ptNext := ptNext + 2;
          Continue;
        end
      end
      else
      begin
        { si taglia tra le due consonanti }
        DS.nDivisioni := DS.nDivisioni + 1;
        DS.Divisioni[DS.nDivisioni] := ptNext + 1;
        ParOut := ParOut + Parola[ptNext] + SepChar + Parola[ptNext +
1];
        ptNext := ptNext + 2;
        Continue;
      end;
    ParOut := ParOut + Parola[ptNext];
    ptNext := ptNext + 1;
  end;
{  for k := ptNext to Length( Parola ) do }
{    ParOut := ParOut + Parola[k]; }
end;
{//////////////////////////////////////////////////////////// }
function Sillaba( Parola: string ): string;
{ restituisce la parola con trattini di divisione in sillabe }
var
  DS: TDatiSillabazione;
  k, j, prev: integer;  { prev: prima lettera da trasferire }
  ParOut: string;
begin
  DividiInSillabe( Parola, DS );
  ParOut := '';
  prev := 1;
  for k:= 1 to DS.nDivisioni do
  begin
    for j := prev to DS.Divisioni[k] - 1 do
      ParOut := ParOut + Parola[j];
    prev := DS.Divisioni[k];
    ParOut := ParOut + SepChar;
  end;
  for j := prev to Length(Parola) do
    ParOut := ParOut + Parola[j];
  Sillaba := ParOut;
end;
procedure SillabaPrimaDi( Parola: string; Posizione: integer; var
PrimaParte, SecondaParte: string );
var
  DS: TDatiSillabazione;
  k: integer;
  PosDiv: integer;  { posizione in cui dividere la parola }
begin
  DividiInSillabe( Parola, DS );
  if (DS.nDivisioni = 0) or (DS.Divisioni[1] > Posizione) then
  begin
    { parola non divisa o prima divisione troppo avanti }
    PrimaParte := '';
    SecondaParte := Parola;
  end
  else
  begin
    { ha diviso la parola }
    for k := DS.nDivisioni downto 1 do
      if DS.Divisioni[k] <= Posizione then
      begin
        PosDiv := DS.Divisioni[k];
        break;
      end;
    PrimaParte := '';
    SecondaParte := '';
    for k := 1 to PosDiv - 1 do
      PrimaParte := PrimaParte + Parola[k];
    PrimaParte := PrimaParte + SepChar;
    for k := PosDiv to Length(Parola) do
      SecondaParte := SecondaParte + Parola[k];
  end;
end;
end.
--------------------------------------------------------------------
Fulvio Senore
Eliminate "zz" dall'indirizzo e-mail per scrivermi (spammers...)
Remove "zz" from e-mail address to write me (spammers...)
--------------------------------------------------------------------

Possibilmente indirizzi internet sull' argomento.
Ho letto una risposta ed e' un filino complicata... anni fa su
Commodore Computer Club pubblicarono regolette molto piu' semplici, e
tuttavia perfette. Se ti andasse bene, potrei postarti un pezzo di
codice in C che faceva proprio questo, oppure i sorgenti completi del
mio programmino SiLLABA! (che avevo scritto anni fa per DOS in C).
Fammi sapere.
Paolo
P.S.
Per la sillabazione in inglese, una volta ho chiesto ad un insegnante
di madrelingua, e quello mi ha risposto che non ce ne sono, in
generale si va a senso (soprattutto con parole composte). Quindi direi
che ti conviene lasciar perdere la parte inglese... :)