Saltar para o conteúdo

Algoritmo Earley: diferenças entre revisões

Origem: Wikipédia, a enciclopédia livre.
Conteúdo apagado Conteúdo adicionado
Justin000 (discussão | contribs)
m
 
(Há 14 revisões intermédias de 14 utilizadores que não estão a ser apresentadas)
Linha 1: Linha 1:
{{sem-fontes|data=junho de 2009}}
{{mais-fontes|data=junho de 2009}}
{{contextualizar|data=outubro de 2023}}
{{contexto}}
{{wikificar|data=junho de 2009}}


O algorítimo de análise gramatical '''Earley''' é um tipo de programa que subdivide uma entrada (input) para que um outro possa atuar sobre ela mais comumente usado em [[linguística computacional]], nomeado após seu inventor, [[Jay Earley]]. O algorítmo faz uso de [[programação dinâmica]].
O algoritmo de análise gramatical '''Earley''' é um tipo de programa que subdivide uma entrada (input) para que um outro possa atuar sobre ela mais comumente usado em [[linguística computacional]], nomeado após seu inventor, [[Jay Earley]]. O algoritmo faz uso de [[programação dinâmica]].<Ref>J. Aycock and R.N. Horspool. [http://www.cs.uvic.ca/~nigelh/Publications/PracticalEarleyParsing.pdf Practical Earley Parsing]. ''The Computer Journal'', '''45''':6:620-630, 2002.</ref>


Os analisadores gramaticais Earley são interessantes porque podem analisar todas as [[Linguagem livre de contexto|linguagens livre de contexto]]. O algorítmo Earley tem tempo de execução [[Big O notation|O]](n<sup>3</sup>) (onde ''n'' é o comprimento da cadeia de caracteres analisada), no caso geral, tempo quadrático ([[Big O notation|O]](n<sup>2</sup>)) para gramáticas não ambígua, e tempo linear para quase toda as gramáticas LR(k)<sup>?</sup>. Seu desempenho é relativamente bom quando as regras são escritas de forma recursivamente.
Os analisadores gramaticais Earley são interessantes porque podem analisar todas as [[Linguagem livre de contexto|linguagens livre de contexto]]. O algoritmo Earley tem tempo de execução [[Big O notation|O]](n³) (onde ''n'' é o comprimento da cadeia de caracteres analisada), no caso geral, tempo quadrático ([[Big O notation|O]](n²)) para gramáticas não ambígua, e tempo linear para quase toda as gramáticas LR(k)<sup>?</sup>. Seu desempenho é relativamente bom quando as regras são escritas de forma recursiva.


== Exemplos ==
== Exemplos ==


Considerar a seguinte gramática simples para expressões aritiméticas:
*Considerar a seguinte gramática simples para expressões aritméticas:


P → S # the start rule
P → S # the start rule
Linha 18: Linha 17:
T → number
T → number


Com as entradas:
*Com as entradas:


2 + 3 * 4
2 + 3 * 4


Esta é a seqüência do estado conjuntos:
*Esta é a seqüência do estado conjuntos:


(state no.) Production (Origin) # Comment
(state no.) Production (Origin) # Comment
---------------------------------
---------------------------------
== S(0): • 2 + 3 * 4 ==
== S(0): • 2 + 3 * 4 ==
(1) P → • S (0) # start rule
(1) P → • S (0) # start rule
(2) S → • S + M (0) # predict from (1)
(2) S → • S + M (0) # predict from (1)
Linha 33: Linha 32:
(5) M → • T (0) # predict from (3)
(5) M → • T (0) # predict from (3)
(6) T → • number (0) # predict from (5)
(6) T → • number (0) # predict from (5)

== S(1): 2 • + 3 * 4 ==
== S(1): 2 • + 3 * 4 ==
(1) T → number • (0) # scan from S(0)(6)
(1) T → number • (0) # scan from S(0)(6)
(2) M → T • (0) # complete from S(0)(5)
(2) M → T • (0) # complete from S(0)(5)
Linha 41: Linha 40:
(5) S → S • + M (0) # complete from S(0)(2)
(5) S → S • + M (0) # complete from S(0)(2)
(6) P → S • (0) # complete from S(0)(1)
(6) P → S • (0) # complete from S(0)(1)

== S(2): 2 + • 3 * 4 ==
== S(2): 2 + • 3 * 4 ==
(1) S → S + • M (0) # scan from S(1)(5)
(1) S → S + • M (0) # scan from S(1)(5)
(2) M → • M * T (2) # predict from (1)
(2) M → • M * T (2) # predict from (1)
(3) M → • T (2) # predict from (1)
(3) M → • T (2) # predict from (1)
(4) T → • number (2) # predict from (3)
(4) T → • number (2) # predict from (3)

== S(3): 2 + 3 • * 4 ==
== S(3): 2 + 3 • * 4 ==
(1) T → number • (2) # scan from S(2)(4)
(1) T → number • (2) # scan from S(2)(4)
(2) M → T • (2) # complete from S(2)(3)
(2) M → T • (2) # complete from S(2)(3)
Linha 55: Linha 54:
(5) S → S • + M (0) # complete from S(0)(2)
(5) S → S • + M (0) # complete from S(0)(2)
(6) P → S • (0) # complete from S(0)(1)
(6) P → S • (0) # complete from S(0)(1)

== S(4): 2 + 3 * • 4 ==
== S(4): 2 + 3 * • 4 ==
(1) M → M * • T (2) # scan from S(3)(3)
(1) M → M * • T (2) # scan from S(3)(3)
(2) T → • number (4) # predict from (1)
(2) T → • number (4) # predict from (1)

== S(5): 2 + 3 * 4 • ==
== S(5): 2 + 3 * 4 • ==
(1) T → number • (4) # scan from S(4)(2)
(1) T → number • (4) # scan from S(4)(2)
(2) M → M * T • (2) # complete from S(4)(1)
(2) M → M * T • (2) # complete from S(4)(1)
Linha 67: Linha 66:
(5) S → S • + M (0) # complete from S(0)(2)
(5) S → S • + M (0) # complete from S(0)(2)
(6) P → S • (0) # complete from S(0)(1)
(6) P → S • (0) # complete from S(0)(1)

O estado (P → S •, 0) representa um parse concluído. Este estado também aparece em S (3) e S (1), que são frases completas.
*O estado (P → S •, 0) representa um parse concluído. Este estado também aparece em S (3) e S (1), que são frases completas.



Etapa 1: construção de D0: primeiro conjunto de produções
Etapa 1: construção de D0: primeiro conjunto de produções
produções que partem de S (1)
* produções que partem de S (1)
produções que podem ser aplicadas (2)
* produções que podem ser aplicadas (2)
em sucessivas derivações mais à esquerda (a partir de S)
* em sucessivas derivações mais à esquerda (a partir de S)

D0 = ∅
para toda S → α ∈ P (1)
D0 = ∅
para toda S → α ∈ P (1)
faça D0 = D0 ∪ { S → •α/0 }
faça D0 = D0 ∪ { S → •α/0 }
repita para toda A → •Bβ/0 ∈ D0 (2)
repita para toda A → •Bβ/0 ∈ D0 (2)
faça para toda B → φ ∈ P
faça para toda B → φ ∈ P
faça D0 = D0 ∪ { B → •φ/0 }
faça D0 = D0 ∪ { B → •φ/0 }
até que o cardinal de D0 não aumente
até que o cardinal de D0 não aumente


Etapa 2: construção dos demais conjuntos de produção
Etapa 2: construção dos demais conjuntos de produção
n = w conjuntos de produção a partir de D0
* n = w conjuntos de produção a partir de D0
ao gerar ar, constrói Dr: produções que podem gerar ar+1
* ao gerar ar, constrói Dr: produções que podem gerar ar+1

para r variando de 1 até n (1)
para r variando de 1 até n (1)
faça Dr = ∅;
para toda A → α•arβ/s ∈ Dr-1 (2)
faça Dr = ∅;
para toda A → α•arβ/s ∈ Dr-1 (2)
faça Dr = Dr ∪ { A → αar•β/s };
faça Dr = Dr ∪ { A → αar•β/s };
repita
repita
para toda A → α•Bβ/s ∈ Dr (3)
para toda A → α•Bβ/s ∈ Dr (3)
faça para toda B → φ ∈ P
faça para toda B → φ ∈ P
faça Dr = Dr ∪ { B → •φ/r }
faça Dr = Dr ∪ { B → •φ/r }
para toda A → α•/s de Dr (4)
para toda A → α•/s de Dr (4)
faça para toda B → β•Aφ/k ∈ Ds
faça para toda B → β•Aφ/k ∈ Ds
faça Dr = Dr ∪ { B → βA•φ/k }
faça Dr = Dr ∪ { B → βA•φ/k }
atéque o cardinal de Dr não aumente
atéque o cardinal de Dr não aumente



(1) cada ciclo gera um conjunto de produções Dr
# cada ciclo gera um conjunto de produções Dr
(2) gera o símbolo ar
# gera o símbolo ar
(3) produções que podem derivar o próximo símbolo
# produções que podem derivar o próximo símbolo
(4) uma subpalavra de w foi reduzida à variável A
# uma subpalavra de w foi reduzida à variável A
inclui em Dr todas as produções de Ds que referenciaram •A;
* inclui em Dr todas as produções de Ds que referenciaram •A;


Etapa 3: condição de aceitação da entrada.
Etapa 3: condição de aceitação da entrada.
uma produção da forma S → α•/0 pertence a Dn
* uma produção da forma S → α•/0 pertence a Dn
w foi aceita
* w foi aceita
S → α•/0 é uma produção que
* S → α•/0 é uma produção que
parte do símbolo inicial S
* parte do símbolo inicial S
foi incluída em D0 ("/0")
* foi incluída em D0 ("/0")
todo o lado direito da produção foi analisado com sucesso
* todo o lado direito da produção foi analisado com sucesso
("•" está no final de α)
* ("•" está no final de α)


Otimização do Algoritmo de Early
ciclos repita-até
podem ser restritos exclusivamente às produções recentemente
incluídas em Dr ou em D0 ainda não-analisadas.


[[Categoria:Algoritmos]]


* Otimização do Algoritmo de Early
[[bg:Алгоритъм на Ерли]]
* ciclos repita-até
[[de:Earley-Algorithmus]]
* podem ser restritos exclusivamente às produções recentemente incluídas em Dr ou em D0 ainda não-analisadas.
[[en:Earley parser]]

[[es:Algoritmo de Earley]]
{{Referências}}
[[fr:Analyse Earley]]

[[ja:アーリー法]]
[[Categoria:Algoritmos]]
[[pl:Algorytm Earleya]]
[[Categoria:Programação dinâmica]]
[[sr:Erlijev analizator]]
[[uk:Алгоритм Ерлі]]

Edição atual tal como às 21h01min de 22 de outubro de 2023

O algoritmo de análise gramatical Earley é um tipo de programa que subdivide uma entrada (input) para que um outro possa atuar sobre ela mais comumente usado em linguística computacional, nomeado após seu inventor, Jay Earley. O algoritmo faz uso de programação dinâmica.[1]

Os analisadores gramaticais Earley são interessantes porque podem analisar todas as linguagens livre de contexto. O algoritmo Earley tem tempo de execução O(n³) (onde n é o comprimento da cadeia de caracteres analisada), no caso geral, tempo quadrático (O(n²)) para gramáticas não ambígua, e tempo linear para quase toda as gramáticas LR(k)?. Seu desempenho é relativamente bom quando as regras são escritas de forma recursiva.

  • Considerar a seguinte gramática simples para expressões aritméticas:
 P → S      # the start rule
 S → S + M
    | M
 M → M * T
    | T
 T → number
  • Com as entradas:
 2 + 3 * 4
  • Esta é a seqüência do estado conjuntos:
 (state no.) Production          (Origin) # Comment
 ---------------------------------

S(0): • 2 + 3 * 4

[editar | editar código-fonte]
 (1)  P → • S         (0)    # start rule
 (2)  S → • S + M     (0)    # predict from (1)
 (3)  S → • M         (0)    # predict from (1)
 (4)  M → • M * T     (0)    # predict from (3)
 (5)  M → • T         (0)    # predict from (3)
 (6)  T → • number    (0)    # predict from (5)

S(1): 2 • + 3 * 4

[editar | editar código-fonte]
 (1)  T → number •    (0)    # scan from S(0)(6)
 (2)  M → T •         (0)    # complete from S(0)(5)
 (3)  M → M • * T     (0)    # complete from S(0)(4)
 (4)  S → M •         (0)    # complete from S(0)(3)
 (5)  S → S • + M     (0)    # complete from S(0)(2)
 (6)  P → S •         (0)    # complete from S(0)(1)

S(2): 2 + • 3 * 4

[editar | editar código-fonte]
 (1)  S → S + • M     (0)    # scan from S(1)(5)
 (2)  M → • M * T     (2)    # predict from (1)
 (3)  M → • T         (2)    # predict from (1)
 (4)  T → • number    (2)    # predict from (3)

S(3): 2 + 3 • * 4

[editar | editar código-fonte]
 (1)  T → number •    (2)    # scan from S(2)(4)
 (2)  M → T •         (2)    # complete from S(2)(3)
 (3)  M → M • * T     (2)    # complete from S(2)(2)
 (4)  S → S + M •     (0)    # complete from S(2)(1)
 (5)  S → S • + M     (0)    # complete from S(0)(2)
 (6)  P → S •         (0)    # complete from S(0)(1)

S(4): 2 + 3 * • 4

[editar | editar código-fonte]
 (1)  M → M * • T     (2)    # scan from S(3)(3)
 (2)  T → • number    (4)    # predict from (1)

S(5): 2 + 3 * 4 •

[editar | editar código-fonte]
 (1)  T → number •    (4)    # scan from S(4)(2)
 (2)  M → M * T •     (2)    # complete from S(4)(1)
 (3)  M → M • * T     (2)    # complete from S(2)(2)
 (4)  S → S + M •     (0)    # complete from S(2)(1)
 (5)  S → S • + M     (0)    # complete from S(0)(2)
 (6)  P → S •         (0)    # complete from S(0)(1)
  • O estado (P → S •, 0) representa um parse concluído. Este estado também aparece em S (3) e S (1), que são frases completas.

Etapa 1: construção de D0: primeiro conjunto de produções

  • produções que partem de S (1)
  • produções que podem ser aplicadas (2)
  • em sucessivas derivações mais à esquerda (a partir de S)
 D0 = ∅
 para toda S → α ∈ P (1)
 faça D0 = D0 ∪ { S → •α/0 }
 repita para toda A → •Bβ/0 ∈ D0 (2)
 faça para toda B → φ ∈ P
 faça D0 = D0 ∪ { B → •φ/0 }
 até que o cardinal de D0 não aumente

Etapa 2: construção dos demais conjuntos de produção

  • n = w conjuntos de produção a partir de D0
  • ao gerar ar, constrói Dr: produções que podem gerar ar+1
 para r variando de 1 até n (1)
 faça Dr = ∅;
 para toda A → α•arβ/s ∈ Dr-1 (2)
 faça Dr = Dr ∪ { A → αar•β/s };
 repita
 para toda A → α•Bβ/s ∈ Dr (3)
 faça para toda B → φ ∈ P
 faça Dr = Dr ∪ { B → •φ/r }
 para toda A → α•/s de Dr (4)
 faça para toda B → β•Aφ/k ∈ Ds
 faça Dr = Dr ∪ { B → βA•φ/k }
 atéque o cardinal de Dr não aumente


  1. cada ciclo gera um conjunto de produções Dr
  2. gera o símbolo ar
  3. produções que podem derivar o próximo símbolo
  4. uma subpalavra de w foi reduzida à variável A
  • inclui em Dr todas as produções de Ds que referenciaram •A;

Etapa 3: condição de aceitação da entrada.

  • uma produção da forma S → α•/0 pertence a Dn
  • w foi aceita
  • S → α•/0 é uma produção que
  • parte do símbolo inicial S
  • foi incluída em D0 ("/0")
  • todo o lado direito da produção foi analisado com sucesso
  • ("•" está no final de α)


  • Otimização do Algoritmo de Early
  • ciclos repita-até
  • podem ser restritos exclusivamente às produções recentemente incluídas em Dr ou em D0 ainda não-analisadas.

Referências

  1. J. Aycock and R.N. Horspool. Practical Earley Parsing. The Computer Journal, 45:6:620-630, 2002.