public Token Clonar () { Token cloneToken = new Token(); cloneToken.Lexema = this.Lexema; cloneToken.Simbolo = this.Simbolo; cloneToken.Linha = this.Linha; return cloneToken; }
/// <summary> /// inicializa o léxico /// </summary> /// <param name="dados"></param> /// public Lexico(string dados, ref List<Token> tokens) public Lexico(string dados) { this.caminho = dados; this.linha = 1; this.coluna = 0; //this.tokens = tokens; this.token = new Token(); this.arquivo = new Arquivo(); }
/// <summary> /// Método destinado a inserir um item na pilha de prioridade realizando a lógica da /// pós fixa /// </summary> /// <param name="item"></param> private void InserePilha(Token item) { if (pilhaPrioridade.Count == 0 || (item.Simbolo == Simbolo.Sabreparenteses)) pilhaPrioridade.Add(item); else { if(item.Simbolo == Simbolo.Sfechaparenteses) { //caso seja um fecha parenteses realiza o desempilhamento até encontrar um abre while (pilhaPrioridade.Last().Simbolo != Simbolo.Sabreparenteses) { //remove da pilha de prioridade e insere na lista PosFixa InsereLista(pilhaPrioridade.Last()); // pilhaPrioridade.RemoveAt(pilhaPrioridade.Count - 1); } //remove da pilha de prioridade o abre parenteses pilhaPrioridade.RemoveAt(pilhaPrioridade.Count - 1); } else { // verifica se a prioridade do item atual é MENOR que o ultimo item, entao insere na pilha. if (tabelaPrioridade[item.Simbolo] < tabelaPrioridade[pilhaPrioridade.Last().Simbolo]) pilhaPrioridade.Add(item); else { if (pilhaPrioridade.Last().Simbolo == Simbolo.Snao && item.Simbolo == Simbolo.Snao) pilhaPrioridade.Add(item); else { do { //remove da pilha de prioridade e insere na lista PosFixa InsereLista(pilhaPrioridade.Last()); // pilhaPrioridade.RemoveAt(pilhaPrioridade.Count - 1); if (pilhaPrioridade.Count == 0) break; //verifica se a prioridade do item atual é MAIOR ou IGUAL que o ultimo item, entao desimpilha } while (tabelaPrioridade[item.Simbolo] >= tabelaPrioridade[pilhaPrioridade.Last().Simbolo]); pilhaPrioridade.Add(item); } } } } }
//public Sintatico(string dados,GeradorCodigo gerador, ref List<Token> tokens) public Sintatico(string dados,GeradorCodigo gerador) { this.token = new Token(); //this.lexico = new Lexico(dados, ref tokens); this.lexico = new Lexico(dados); this.tabelaSimbolos = new TabelaSimbolo(); this.semantico = new Semantico(tabelaSimbolos); this.retornoFuncaoFlag = false; this.geradorCodigo = gerador; }
/// <summary> /// Método responsável por Analisar o tipo de cada membro da expressao e validar o tipo final da expressâo /// </summary> /// <param name="tabelaSimbolos"></param> /// <param name="tokenAtual"></param> /// <param name="simboloValido"></param> /// <param name="comando"></param> public void AnalisaExpressaoSemanticamente(GeradorCodigo gerador,Token tokenAtual,Simbolo simboloValido, String comando) { posFixa.DesimpilharPilhaPrioridade(); // remove os membros restantes da pilha, caso venha ter. // verifica se o tipo da expressao retornada é de fato igual ao tipo exigido if (AnalisaExpressaoPosFixa() != simboloValido) { if (simboloValido == Simbolo.Sbooleano) throw new ErroException(String.Format("Linha: {0}. Erro Semântico! {1} deve conter uma expressão booleana!", tokenAtual.Linha, comando), tokenAtual.Linha); else throw new ErroException(String.Format("Linha: {0}. Erro Semântico! {1} deve conter uma expressão inteira!", tokenAtual.Linha, comando), tokenAtual.Linha); } //gera código da expressao pos fixa GeraCodigoExpressao(gerador); // limpar lista da pos fixa posFixa.ResetarPosFixa(); }
/// <summary> /// método responsável por garantiar a gramática e semantica da chamada de procedimento /// </summary> /// <param name="tokenProcedimento"></param> private void AnalisaChamadaProcedimento(Token tokenProcedimento) { //verifica se não existe um procedimento declarado em todo o escopo ItemSimbolo procedimento = tabelaSimbolos.PesquisaItem(tokenProcedimento.Lexema); if ( procedimento == null) throw new ErroException(String.Format("Linha: {0}. Erro Semântico! Este procedimento \"{1}\" não está declarado!", tokenProcedimento.Linha, tokenProcedimento.Lexema), tokenProcedimento.Linha); if (procedimento.GetType() != typeof(ProcedimentoSimbolo)) throw new ErroException(String.Format("Linha: {0}. Erro Semântico! Uso da variável \"{1}\" de forma indevida!", tokenProcedimento.Linha, tokenProcedimento.Lexema), tokenProcedimento.Linha); // gerar codigo da chamada de procedimento geradorCodigo.GerarCodigo(Codigo.CALL, new string[] { ((ProcedimentoSimbolo)procedimento).Nivel.ToString() }); }
private void TrataDigito(ref List<Token> Tokens) { string num = caracter.ToString(); Token novo = new Token(); caracter = arquivo.LerCaracter(); while (caracter >= '0' && caracter <= '9') { num += caracter; caracter = arquivo.LerCaracter(); } novo.Lexema = num; //novo.Simbolo = "Snumero"; Tokens.Add(novo); }
private void TrataPontuacao(ref List<Token> Tokens) { string id = caracter.ToString(); Token novo = new Token(); novo.Lexema = id; if (id == ";") { //novo.Simbolo = "Sponto_virgula"; } else { if (id == ",") { //novo.Simbolo = "Svirgula"; } else { if (id == "(") { //novo.Simbolo = "Sabre_parenteses"; } else { if (id == ")") { //novo.Simbolo = "Sfecha_parenteses"; } else { //novo.Simbolo = "Sponto"; } } } } Tokens.Add(novo); caracter = arquivo.LerCaracter(); }
private void TrataOperadorRelacional(ref List<Token> Tokens) { string id = caracter.ToString(); Token novo = new Token(); caracter = arquivo.LerCaracter(); if (caracter == '=') { if(id == ">") { //novo.Simbolo = "Smaiorig"; } else { if(id == "<") { //novo.Simbolo = "Smenorig"; } else { //novo.Simbolo = "Sdif"; } } id += caracter; caracter = arquivo.LerCaracter(); } else { if (id == ">") { //novo.Simbolo = "Smaior"; } else { if (id == "<") { //novo.Simbolo = "Smenor"; } else { //novo.Simbolo = "Sig"; } } } novo.Lexema = id; Tokens.Add(novo); }
private void TrataOperadorAritmetico(ref List<Token> Tokens) { string id = caracter.ToString(); Token novo = new Token(); novo.Lexema = id; if (id == "+") { //novo.Simbolo = "Smais"; } else { if(id == "-") { //novo.Simbolo = "Smenos"; } else { //novo.Simbolo = "Smult"; } } Tokens.Add(novo); caracter = arquivo.LerCaracter(); }
/// <summary> /// método destinado a receber um token do léxico /// </summary> private void ObtemTokenLexico() { token = lexico.AnalisadorLexico(); }
/// <summary> /// metodo responsável por inserir um token ou na pilha de prioridade ou na lista da pós-fixa /// conforme a logica de geração da pós-fixa /// </summary> /// <param name="item"></param> public void InserePosFixa(Token item) { Token novoItem = item.Clonar(); // se for um identificador insere direto na lista if (novoItem.Simbolo == Simbolo.Sidentificador || novoItem.Simbolo == Simbolo.Snumero || novoItem.Simbolo == Simbolo.Sverdadeiro || novoItem.Simbolo == Simbolo.Sfalso) InsereLista(novoItem); else InserePilha(novoItem); }
//private void InserePilha(Token item) //{ // if (pilhaPrioridade.Count == 0 || (item.Simbolo == Simbolo.Sabreparenteses)) // pilhaPrioridade.Add(item); // else // { // if (item.Simbolo == Simbolo.Sfechaparenteses) // { //caso seja um fecha parenteses realiza o desempilhamento até encontrar um abre // while (pilhaPrioridade.Last().Simbolo != Simbolo.Sabreparenteses) // { // //remove da pilha de prioridade e insere na lista PosFixa // InsereLista(pilhaPrioridade.Last()); // // pilhaPrioridade.RemoveAt(pilhaPrioridade.Count - 1); // } // //remove da pilha de prioridade o abre parenteses // pilhaPrioridade.RemoveAt(pilhaPrioridade.Count - 1); // } // else // { // // verifica se a prioridade do item atual é MENOR que o ultimo item, entao insere na pilha. // if (tabelaPrioridade[item.Simbolo] < tabelaPrioridade[pilhaPrioridade.Last().Simbolo]) // pilhaPrioridade.Add(item); // else // { // do // { // //remove da pilha de prioridade e insere na lista PosFixa // InsereLista(pilhaPrioridade.Last()); // // pilhaPrioridade.RemoveAt(pilhaPrioridade.Count - 1); // if (pilhaPrioridade.Count == 0) // break; // //verifica se a prioridade do item atual é MAIOR ou IGUAL que o ultimo item, entao desimpilha // } while (tabelaPrioridade[item.Simbolo] >= tabelaPrioridade[pilhaPrioridade.Last().Simbolo]); // pilhaPrioridade.Add(item); // } // } // } //} /// <summary> /// método responsável por inserir na lista da formação da PosFixa /// </summary> /// <param name="item"></param> private void InsereLista(Token item) { listaPosFixa.Add(item); }
/// <summary> /// método que obtem os tokens a partir do arquivo /// </summary> /// <param name="tokens"></param> public Token AnalisadorLexico() { if (!arquivo.FimArquivo()) // || caracter != '\0' { /*Remove comentários, espaços, enter, carriage return e tabulação */ while ((caracter == '{' || caracter == ' ' || caracter == '\n' || caracter == '\r' || caracter == '\t') && !arquivo.FimArquivo()) { if (caracter == '{') { while (caracter != '}' && !arquivo.FimArquivo()) { if (caracter == '\n') { linha++; coluna = 0; } LerCaracter(); } LerCaracter(); } while ((caracter == ' ' || caracter == '\n' || caracter == '\r' || caracter == '\t') && !arquivo.FimArquivo()) { if (caracter == '\n') { linha++; coluna = 0; } LerCaracter(); } } if (caracter != '\0') { PegaToken(); Token teste = new Token(); teste.Lexema = token.Lexema; teste.Simbolo = token.Simbolo; //tokens.Add(teste); } else { token.Lexema = null; token.Simbolo = Simbolo.Ssemtoken; token.Linha = linha; } } else { token.Lexema = null; token.Simbolo = Simbolo.Ssemtoken; token.Linha = linha; } return token; }
/// <summary> /// método responsável por garantiar a gramática e semantica da atribuição /// </summary> /// <param name="tokenAnterior"></param> private void AnalisaAtribuicao(Token tokenAnterior) { ObtemTokenLexico(); AnalisaExpressao(); semantico.AnalisaExpressaoSemanticamente(geradorCodigo,token,tabelaSimbolos.PesquisaSimbolo(tokenAnterior.Lexema), "A atribuição"); if (retornoFuncaoFlag) // gera o códgo do returnf caso seja o retorno de função { //gerador de codigo, gera o comando returnf int qtdVariaveis = geradorCodigo.PilhaQtdVariaveisAlocadas.Pop(); //insere na pilha, pois pode ter outros retornos geradorCodigo.PilhaQtdVariaveisAlocadas.Push(qtdVariaveis); int baseFuncao = geradorCodigo.BaseVariavel - qtdVariaveis; geradorCodigo.GerarCodigo(Codigo.RETURNF, new string[] { baseFuncao.ToString(), qtdVariaveis.ToString() }); } else // senao gera um str geradorCodigo.GerarCodigo(Codigo.STR, new string[] {((VariavelSimbolo)tabelaSimbolos.PesquisaItem(tokenAnterior.Lexema)).Memoria.ToString() }); }
private void TrataIdentificadorPalavraReservada(ref List<Token> Tokens) { string id = caracter.ToString(); Token novo = new Token(); caracter = arquivo.LerCaracter(); while((caracter >= 'a' && caracter <= 'z') || (caracter >= '0' && caracter <= '9') || caracter == '_') { id += caracter; caracter = arquivo.LerCaracter(); } novo.Lexema = id; switch (id) { case "programa": //novo.Simbolo = "Sprograma"; break; case "se": //novo.Simbolo = "Sse"; break; case "entao": //novo.Simbolo = "Sentao"; break; case "senao": //novo.Simbolo = "Ssenao"; break; case "enquanto": //novo.Simbolo = "Senquanto"; break; case "faca": //novo.Simbolo = "Sfaca"; break; case "inicio": //novo.Simbolo = "Sinicio"; break; case "fim": //novo.Simbolo = "Sfim"; break; case "escreva": //novo.Simbolo = "Sescreva"; break; case "leia": //novo.Simbolo = "Sleia"; break; case "var": //novo.Simbolo = "Svar"; break; case "inteiro": //novo.Simbolo = "Sinteiro"; break; case "booleano": //novo.Simbolo = "Sbooleano"; break; //case "verdadeiro": // novo.Simbolo = "Sverdadeiro"; // break; //case "falso": // novo.Simbolo = "Sfalso"; // break; case "procedimento": //novo.Simbolo = "Sprocedimento"; break; case "funcao": //novo.Simbolo = "Sfuncao"; break; case "div": //novo.Simbolo = "Sdiv"; break; case "e": //novo.Simbolo = "Se"; break; case "ou": //novo.Simbolo = "Sou"; break; case "nao": //novo.Simbolo = "Snao"; break; default: //novo.Simbolo = "Sidentificador"; break; } Tokens.Add(novo); }
private void TrataAtribuicao(ref List<Token> Tokens) { string id = caracter.ToString(); Token novo = new Token(); caracter = arquivo.LerCaracter(); if(caracter == '=') { //novo.Simbolo = "Satribuicao"; novo.Lexema = id + caracter; caracter = arquivo.LerCaracter(); } else { //novo.Simbolo = "Sdoispontos"; novo.Lexema = id; } Tokens.Add(novo); }
/// <summary> /// método responsável por analisar a garantia da gramática e semantica do programa /// </summary> public void AnalisadorSintatico() { lexico.AbreArquivo(); //rotulo = 1 -- disable token = lexico.AnalisadorLexico(); if (token.Simbolo == Simbolo.Sprograma) { geradorCodigo.GerarCodigo(Codigo.START,new string[] { }); ObtemTokenLexico(); if (token.Simbolo == Simbolo.Sidentificador) { //insere tabela(token.lexema, nome do programa, "","") -- disable tabelaSimbolos.InserirTabela(new ProgramaSimbolo {Lexema = token.Lexema }); // insere na tabela de simbolos o programa semantico.PilhaRetornoFuncao.Push(token.Clonar()); ObtemTokenLexico(); if (token.Simbolo == Simbolo.Spontovirgula) { AnalisaBloco(); semantico.PilhaRetornoFuncao.Pop(); //gerador de codigo, gera o comando Dalloc int qtdVariaveis = geradorCodigo.PilhaQtdVariaveisAlocadas.Pop(); if (qtdVariaveis != 0) { //gera um dalloc geradorCodigo.BaseVariavel -= qtdVariaveis; // decrementa a base geradorCodigo.GerarCodigo(Codigo.DALLOC, new string[] { geradorCodigo.BaseVariavel.ToString(), qtdVariaveis.ToString() }); } if (token.Simbolo == Simbolo.Sponto) { geradorCodigo.GerarCodigo(Codigo.HLT, new string[] { }); // verifica se acabou arquivo ou é comentário ObtemTokenLexico(); if (token.Simbolo != Simbolo.Ssemtoken) { //erro token a mais throw new ErroException(String.Format("Linha: {0}. Erro Sintático! Código excedente encontrado!", token.Linha),token.Linha); } //gerador do arquivo } else { //erro falta ponto throw new ErroException(String.Format("Linha: {0}. Erro Sintático! \".\" esperado!", token.Linha), token.Linha); } } else { //erro falta ponto virgula throw new ErroException(String.Format("Linha: {0}. Erro Sintático! \";\" esperado!", token.Linha), token.Linha); } } else { //erro falta identificador throw new ErroException(String.Format("Linha: {0}. Erro Sintático! Nome do programa esperado!", token.Linha), token.Linha); } } else { //erro falta: sprograma throw new ErroException(String.Format("Linha: {0}. Erro Sintático! \"programa\" esperado!", token.Linha), token.Linha); } lexico.FechaArquivo(); }
/// <summary> /// método destinado a fazer a inserção na lista da pós fixa /// </summary> /// <param name="token"></param> public void InsereTokenPosFixa (Token token) { posFixa.InserePosFixa(token); }