Como construir um compilador utilizando ferramentas Java Aula 2 – BNF e Grafo Sintático Prof. Márcio Delamaro [email protected] Como construir um compilador utilizando ferramentas Java – p. 1/2 Linguagem Livre de Contexto Em geral, uma linguagem de programação pertence a uma classe de linguagens chamadas de linguagens livres de contexto. Como construir um compilador utilizando ferramentas Java – p. 2/2 Linguagem Livre de Contexto Em geral, uma linguagem de programação pertence a uma classe de linguagens chamadas de linguagens livres de contexto. Uma das maneiras de se definirem tais linguagens é por meio das gramáticas livres de contexto. Como construir um compilador utilizando ferramentas Java – p. 2/2 Gramática Livre de Contexto Uma gramática livre de contexto (GLC) é uma quádrupla hΩ, Σ, S, P i, onde Σ – é o alfabeto sobre o qual a linguagem é definida; Ω – é um conjunto não vazio de símbolos não terminais; P – é um conjunto de produções da forma A → α, onde A ∈ Ω e α ∈ (Σ ∪ Ω)∗ ; S – é o símbolo inicial da gramática, S ∈ Ω. Como construir um compilador utilizando ferramentas Java – p. 3/2 Exemplo G1 = h{S, A, B}, {a, b, c}, S, P i, onde P é: (1) S → AB (2) A → aAb (3) A → λ (4) B → cB (5) B → λ Como construir um compilador utilizando ferramentas Java – p. 4/2 Exemplo Iniciamos com S temos AB temos aAbB temos aaAbbB temos aabbB temos aabbcB temos aabbccB aplicamos (1) aplicamos (2) aplicamos (2) aplicamos (3) aplicamos (4) aplicamos (4) aplicamos (5) obtemos AB obtemos aAbB obtemos aaAbbB obtemos aabbB obtemos aabbcB obtemos aabbccB obtemos aabbcc Como construir um compilador utilizando ferramentas Java – p. 5/2 Exemplo Iniciamos com S temos AB temos aAbB temos aaAbbB temos aabbB temos aabbcB temos aabbccB ou aplicamos (1) aplicamos (2) aplicamos (2) aplicamos (3) aplicamos (4) aplicamos (4) aplicamos (5) obtemos AB obtemos aAbB obtemos aaAbbB obtemos aabbB obtemos aabbcB obtemos aabbccB obtemos aabbcc S ⇒ AB ⇒ aAbB ⇒ aaAbbB ⇒ aabbB ⇒ aabbcB ⇒ aabbccB ⇒ aabbcc Como construir um compilador utilizando ferramentas Java – p. 5/2 Forma de Backus-Naur (BNF) A Forma de Backus-Naur (BNF) é uma outra maneira de se definir linguagens livres de contexto. Ela é semelhante a uma gramática livre de contexto, mas permite que o lado direito das produções possua alguns operadores. seleção opcional repetição 0 ou mais vezes repetição 1 ou mais vezes Como construir um compilador utilizando ferramentas Java – p. 6/2 Seleção (α | β) – Um dos elementos entre parênteses (α ou β ) pode ser utilizado na aplicação da produção. Como construir um compilador utilizando ferramentas Java – p. 7/2 Seleção (α | β) – Um dos elementos entre parênteses (α ou β ) pode ser utilizado na aplicação da produção. S → a(b | c | d)e Como construir um compilador utilizando ferramentas Java – p. 7/2 Seleção (α | β) – Um dos elementos entre parênteses (α ou β ) pode ser utilizado na aplicação da produção. S → a(b | c | d)e S ⇒ abe S ⇒ ace S ⇒ ade Como construir um compilador utilizando ferramentas Java – p. 7/2 Seleção (α | β) – Um dos elementos entre parênteses (α ou β ) pode ser utilizado na aplicação da produção. S → a(b | c | d)e S ⇒ abe S ⇒ ace S ⇒ ade S → abe S → ace S → ade Como construir um compilador utilizando ferramentas Java – p. 7/2 Exemplo S → (c(aSa | bSb)c | λ) Como construir um compilador utilizando ferramentas Java – p. 8/2 Exemplo S → (c(aSa | bSb)c | λ) S → λ S → caSac S → cbSbc Como construir um compilador utilizando ferramentas Java – p. 8/2 Exemplo S → (c(aSa | bSb)c | λ) S → λ S → caSac S → cbSbc cacacbbcacac Como construir um compilador utilizando ferramentas Java – p. 8/2 Exemplo S → (c(aSa | bSb)c | λ) S → λ S → caSac S → cbSbc cacacbbcacac S ⇒ caSac ⇒ cacaSacac ⇒ cacacbSbcacac ⇒ cacacbbcacac Como construir um compilador utilizando ferramentas Java – p. 8/2 Opcional [α] – O que estiver entre os colchetes pode ser utilizado ou não na aplicação da produção. Como construir um compilador utilizando ferramentas Java – p. 9/2 Opcional [α] – O que estiver entre os colchetes pode ser utilizado ou não na aplicação da produção. S → a[bcd]e Como construir um compilador utilizando ferramentas Java – p. 9/2 Opcional [α] – O que estiver entre os colchetes pode ser utilizado ou não na aplicação da produção. S → a[bcd]e S ⇒ ae S ⇒ abcde Como construir um compilador utilizando ferramentas Java – p. 9/2 Exemplo S → a[(A | B)c]d A → a[a] B → [b] Como construir um compilador utilizando ferramentas Java – p. 10/2 Exemplo S → a[(A | B)c]d A → a[a] B → [b] S ⇒ ad S ⇒ aAcd ⇒ aacd S ⇒ aAcd ⇒ aaacd S ⇒ aBcd ⇒ abcd S ⇒ aBcd ⇒ acd Como construir um compilador utilizando ferramentas Java – p. 10/2 Exemplo S → a[(A | B)c]d A → a[a] B → [b] S → ad S → aAcd S → aBcd A → aa A → a B → b B → λ Como construir um compilador utilizando ferramentas Java – p. 11/2 Repetição 0 ou mais vezes (α)∗ – O que estiver entre parêntese pode ser usado um número qualquer de vezes na aplicação da produção e pode também não ser usado (repetido nenhuma vez). Como construir um compilador utilizando ferramentas Java – p. 12/2 Repetição 0 ou mais vezes (α)∗ – O que estiver entre parêntese pode ser usado um número qualquer de vezes na aplicação da produção e pode também não ser usado (repetido nenhuma vez). S → a(b)∗ c Como construir um compilador utilizando ferramentas Java – p. 12/2 Repetição 0 ou mais vezes (α)∗ – O que estiver entre parêntese pode ser usado um número qualquer de vezes na aplicação da produção e pode também não ser usado (repetido nenhuma vez). S → a(b)∗ c {ac, abc, abbc, abbbc, ...} Como construir um compilador utilizando ferramentas Java – p. 12/2 Repetição 0 ou mais vezes (α)∗ – O que estiver entre parêntese pode ser usado um número qualquer de vezes na aplicação da produção e pode também não ser usado (repetido nenhuma vez). S → a(b)∗ c {ac, abc, abbc, abbbc, ...} Como qualquer outra BNF, podemos encontrar uma S → aZc GLC correspondente, como, por exemplo: Z → bZ Z → λ Como construir um compilador utilizando ferramentas Java – p. 12/2 Exemplo S → a(b | c)∗ d Como construir um compilador utilizando ferramentas Java – p. 13/2 Exemplo S → a(b | c)∗ d Gera todas as cadeias que iniciam com a, terminam com d e têm entre estes o λ ou qualquer cadeia formada por b e c. Como construir um compilador utilizando ferramentas Java – p. 13/2 Exemplo S → a(b | c)∗ d Gera todas as cadeias que iniciam com a, terminam com d e têm entre estes o λ ou qualquer cadeia formada por b e c. {ad, abd, acd, abbd, abcd, acbd, accd, abbbd, ...} Como construir um compilador utilizando ferramentas Java – p. 13/2 Repetição 1 ou mais vezes (α)+ – O que estiver entre parêntese pode ser usado uma ou mais vezes na aplicação da produção. A produção α → β(γ)+ δ é equivalente a α → βγ(γ)∗ δ . Como construir um compilador utilizando ferramentas Java – p. 14/2 Repetição 1 ou mais vezes (α)+ – O que estiver entre parêntese pode ser usado uma ou mais vezes na aplicação da produção. A produção α → β(γ)+ δ é equivalente a α → βγ(γ)∗ δ . S → a(b)+ c Como construir um compilador utilizando ferramentas Java – p. 14/2 Repetição 1 ou mais vezes (α)+ – O que estiver entre parêntese pode ser usado uma ou mais vezes na aplicação da produção. A produção α → β(γ)+ δ é equivalente a α → βγ(γ)∗ δ . S → a(b)+ c {abc, abbc, abbbc, ...} Como construir um compilador utilizando ferramentas Java – p. 14/2 Repetição 1 ou mais vezes (α)+ – O que estiver entre parêntese pode ser usado uma ou mais vezes na aplicação da produção. A produção α → β(γ)+ δ é equivalente a α → βγ(γ)∗ δ . S → a(b)+ c {abc, abbc, abbbc, ...} Como qualquer outra BNF, podemos encontrar uma S → aZc GLC correspondente, como, por exemplo: Z → bZ Z → b Como construir um compilador utilizando ferramentas Java – p. 14/2 Exemplo S → a(b | c)+ d Como construir um compilador utilizando ferramentas Java – p. 15/2 Exemplo S → a(b | c)+ d Gera todas as cadeias que iniciam com a, terminam com d e têm entre estes qualquer cadeia formada por b e c. Como construir um compilador utilizando ferramentas Java – p. 15/2 Exemplo S → a(b | c)+ d Gera todas as cadeias que iniciam com a, terminam com d e têm entre estes qualquer cadeia formada por b e c. {abd, acd, abbd, abcd, acbd, accd, abbbd, ...} Como construir um compilador utilizando ferramentas Java – p. 15/2 Escrever na BNF hprogrami → {hstatlisti} hstatlisti → λ | hstatementihstatlisti hstatementi → hassignmenti | hconditionali | hloopi hconditionali → if hexprei {hstatlisti} else {hstatlisti} | if hexprei {hstatlisti} hassignmenti → ident = hexpri; hloopi → while hexpri {hstatlisti} hexpri → ident | numero | (hexpri) | hexpri hoperi hexpri hoperi → + | − | ∗ | / | < | > | <= | >= | == | ! = Como construir um compilador utilizando ferramentas Java – p. 16/2 Grafo sintático Outra maneira de representar uma linguagem, chamada de grafo sintático. Essa representação facilita a visualização do tipo de cadeias ou formas sentenciais que cada não-terminal pode gerar. A → abc A a b c Como construir um compilador utilizando ferramentas Java – p. 17/2 Grafo sintático Os nós correspondentes a símbolos não terminais são representados no diagrama por retângulos. Como construir um compilador utilizando ferramentas Java – p. 18/2 Grafo sintático Os nós correspondentes a símbolos não terminais são representados no diagrama por retângulos. A → aBc B → de Como construir um compilador utilizando ferramentas Java – p. 18/2 Grafo sintático Os nós correspondentes a símbolos não terminais são representados no diagrama por retângulos. A → aBc B → de A a B d e c B Como construir um compilador utilizando ferramentas Java – p. 18/2 Grafo sintático Se tivermos operadores de seleção na produção do não-terminal teremos caminhos alternativos no grafo. Como construir um compilador utilizando ferramentas Java – p. 19/2 Grafo sintático Se tivermos operadores de seleção na produção do não-terminal teremos caminhos alternativos no grafo. A → B(a | b | c)B B → (de | λ) Como construir um compilador utilizando ferramentas Java – p. 19/2 Grafo sintático Se tivermos operadores de seleção na produção do não-terminal teremos caminhos alternativos no grafo. A → B(a | b | c)B B → (de | λ) A B a B b c B d e Como construir um compilador utilizando ferramentas Java – p. 19/2 Grafo sintático Opcionais são uma seleção com o λ. Como construir um compilador utilizando ferramentas Java – p. 20/2 Grafo sintático Opcionais são uma seleção com o λ. A → B[abc]B B → (de | λ) Como construir um compilador utilizando ferramentas Java – p. 20/2 Grafo sintático Opcionais são uma seleção com o λ. A → B[abc]B B → (de | λ) A B a b c B B d e Como construir um compilador utilizando ferramentas Java – p. 20/2 Grafo sintático E os operadores de repetição podem ser representados por meio de laços no grafo. Como construir um compilador utilizando ferramentas Java – p. 21/2 Grafo sintático E os operadores de repetição podem ser representados por meio de laços no grafo. A → B(a | b | c)∗ B B → (de)+ Como construir um compilador utilizando ferramentas Java – p. 21/2 Grafo sintático E os operadores de repetição podem ser representados por meio de laços no grafo. A → B(a | b | c)∗ B B → (de)+ A B B a b c B d e Como construir um compilador utilizando ferramentas Java – p. 21/2 Escrever na forma de grafo sintático hprogrami → {hstatmenti∗ } hstatementi → hassignmenti | hconditionali | hloopi hconditionali → if hexprei {hstatmenti∗ } [else {hstatmenti∗ }] hassignmenti → ident = hexpri; hloopi → while hexpri {hstatmenti∗ } hexpri → ident | numero | (hexpri) | hexpri hoperi hexpri hoperi → + | − | ∗ | / | < | > | <= | >= | == | ! = Como construir um compilador utilizando ferramentas Java – p. 22/2