rendered paste body<?php
require_once 'config.php';
class Lexico
{
var $_array_token = array();
var $_nlinhas=1;
function analisar( $file)
{
(file_exists($file )?true:die("File does not exist!\n"));
$_fp = fopen($file ,"rb");
flock( $_fp,LOCK_SH);
while(!feof( $_fp))
{
$_char = fgetc ($_fp);
if($_char === "=" ) {
if($_char = fgetc ($_fp) === "=") {
$this->_array_token[] = TOKEN_IGUALDADE . "==" . "__" . $this ->_nlinhas;
}
else {
fseek ($_fp,ftell($_fp ) - 1);
$this->_array_token [] = TOKEN_ATRIBUICAO . "=" . "__" . $this->_nlinhas;
}
}
else if($_char === "-") {
$this->_array_token[] = TOKEN_SINAL_MENOS . "-" . "__" . $this->_nlinhas;
}
else if( $_char === "/") {
$this ->_array_token[] = TOKEN_DIVISAO . "/" . "__" . $this-> _nlinhas;
}
else if($_char === "+" ) {
$this->_array_token[] = TOKEN_SINAL_MAIS . "+" . "__" . $this->_nlinhas;
}
else if( $_char === "*") {
$this ->_array_token[] = TOKEN_MULTIPLICACAO . "*" . "__" . $this-> _nlinhas;
}
else if($_char === "^") {
$this->_array_token [] = TOKEN_POW . "^" . "__" . $this->_nlinhas;
}
else if( $_char === "(") {
$this ->_array_token[] = TOKEN_ABRE_PARENTESES . "(" . "__" . $this ->_nlinhas;
}
else if($_char === ")") {
$this-> _array_token[] = TOKEN_FECHA_PARENTESES . ")" . "__" . $this->_nlinhas ;
}
else if($_char === "{" ) {
$this->_array_token[] = TOKEN_ABRE_CHAVE . "{" . "__" . $this->_nlinhas;
}
else if( $_char === "}") {
$this ->_array_token[] = TOKEN_FECHA_CHAVE . "}" . "__" . $this-> _nlinhas;
}
else if($_char === ">") {
if($_char = fgetc ($_fp) === "=") {
$this->_array_token[] = TOKEN_MAIOR_IGUAL . ">=" . "__" . $this ->_nlinhas;
}
else
{
$this ->_array_token[] = TOKEN_MAIOR . ">" . "__" . $this ->_nlinhas;
fseek($_fp ,ftell($_fp) - 1);
}
}
else if($_char === "<" ) {
if($_char = fgetc( $_fp) === "=") {
$this ->_array_token[] = TOKEN_MENOR_IGUAL . "<=" . "__" . $this ->_nlinhas;
}
else
{
fseek( $_fp,ftell($_fp ) -1);
$this->_array_token [] = TOKEN_MENOR . "<" . "__" . $this->_nlinhas ;
}
}
else if($_char === '"')
{
$_string = "\"";
while(( $_prox = fgetc($_fp)) != '"'){
if($_prox === "\n" ){
$_nlinhas++;
}
$_string .= $_prox;
}
$this-> _array_token[] = TOKEN_STRING . $_string . "\"" . "__" . $this->_nlinhas;
$_string .= '';
}
else if(preg_match( "/\d/",$_char))
{
$_numero = $_char;
while(preg_match ("/\d/",$_char = fgetc ($_fp)))
{
$_numero .= $_char;
}
if( ($_char === "." ) AND (preg_match("/\d/",$_char = fgetc($_fp))))
{
$_numero .= ".";
fseek($_fp,ftell( $_fp) -1);
while(preg_match ("/\d/",$_char = fgetc ($_fp)))
{
$_numero .= $_char;
}
}
$this-> _array_token[] = TOKEN_NUMERO . $_numero . "__" . $this->_nlinhas ;
$_numero .= '';
fseek($_fp,ftell ($_fp) -1);
}
else if( $_char === "!") {
if($_char = fgetc($_fp) === "=" )
{
$this->_array_token[] = TOKEN_DIFERENTE . "!=" . "__" . $this->_nlinhas;
}
else
{
fseek($_fp,ftell ($_fp) -1);
}
}
else if( $_char === "#"){
$_comentario_linha = "#";
while(($_char = fgetc($_fp)) !== "\n")
{
$_comentario_linha .= $_char;
}
$this->_nlinhas++;
//$this->_array_token[] = TOKEN_COMENTARIO_LINHA . $_comentario_linha;
$_comentario_linha = '';
}
else if( $_char === "\$"){
if(($_char = fgetc($_fp)) === "/" ) {
$_cc = "\$/";
$_signal = true;
while($_signal === true)
{
$_char = fgetc($_fp);
$_cc .= $_char;
if(($_char === "\n")){
$_nlinhas++;
}
if(( $_char === "/"))
{
$_char = fgetc($_fp);
if(( $_char === "\$"))
{
//print $_char;
//$this->_array_token[] = TOKEN_COMENTARIO_LONGO . $_cc . "\$";
$_cc = '';
$_signal = false;
}
else
{
fseek($_fp,ftell( $_fp) -1);
}
}
}
}
}
else if(preg_match("/[a-z]/", $_char)) {
$_variavel = $_char ;
while(preg_match("/[a-z]/", $_char = fgetc($_fp)) )
{
$_variavel .= $_char;
}
$this->_array_token[] = TOKEN_ID . $_variavel . "__" . $this->_nlinhas;
$_variavel = '';
fseek($_fp ,ftell($_fp) -1 );
}
else if(preg_match("/[A-Z]/", $_char)) {
$_word = $_char ;
$_set = false;
while(preg_match("/[A-Z]/", $_char=fgetc($_fp)))
{
$_word .= $_char;
$_set = false;
if(strcmp( $_word,"INT") == 0 ) {
$this->_array_token[] = TOKEN_DECLARACAO_INT . "INT" . "__" . $this->_nlinhas;
$_word = '';
$_set = true;
break;
}
else if(strcmp($_word ,"CARACTERE") == 0 ) {
$this->_array_token[] = TOKEN_DECLARACAO_CARACTERE . "CARACTERE" . "__" . $this->_nlinhas;
$_word = '';
$_set = true;
break;
}
else if(strcmp( $_word,"TRUE") == 0 ) {
$this->_array_token[] = TOKEN_DECLARACAO_TRUE . "TRUE" . "__" . $this->_nlinhas;
$_word = '';
$_set = true ;
break;
}
else if(strcmp($_word, "FALSE") == 0 ) {
$this ->_array_token[] = TOKEN_DECLARACAO_FALSE . "FALSE" . "__" . $this ->_nlinhas;
$_word = '' ;
$_set = true;
break;
}
else if(strcmp($_word, "PRINCIPAL") == 0) {
$this ->_array_token[] = TOKEN_DECLARACAO_PRINCIPAL . "PRINCIPAL" . "__" . $this ->_nlinhas;
$_word = '' ;
$_set = true;
break;
}
else if(strcmp($_word, "BOOL") == 0) {
$this ->_array_token[] = TOKEN_DECLARACAO_BOOL . "BOOL" . "__" . $this ->_nlinhas;
$_word = '' ;
$_set = true;
break;
}
else if(strcmp($_word, "STRING") == 0) {
$this ->_array_token[] = TOKEN_DECLARACAO_STRING . "STRING" . "__" . $this ->_nlinhas;
$_word = '' ;
$_set = true;
break;
}
else if(strcmp($_word, "FUNCAO") == 0) {
$this->_array_token[] = TOKEN_DECLARACAO_FUNCAO . "FUNCAO" . "__" . $this ->_nlinhas;
$_word = '';
$_set = true ;
break;
}
else if(strcmp($_word ,"REAL") == 0) {
$this->_array_token[] = TOKEN_DECLARACAO_REAL . "REAL" . "__" . $this ->_nlinhas;
$_word = '';
$_set = true ;
break;
}
else if(strcmp($_word ,"IF") == 0) {
$this->_array_token[] = TOKEN_DECLARACAO_IF . "IF" . "__" . $this ->_nlinhas;
$_word = '';
$_set = true ;
break;
}
else if(strcmp($_word ,"ELSE") == 0) {
$this->_array_token[] = TOKEN_DECLARACAO_ELSE . "ELSE" . "__" . $this ->_nlinhas;
$_word = '';
$_set = true ;
break;
}
else if(strcmp($_word ,"WHILE") == 0) {
$this->_array_token[] = TOKEN_DECLARACAO_WHILE . "WHILE" . "__" . $this ->_nlinhas;
$_word = '';
$_set = true ;
break;
}
else if(strcmp($_word, "RETURN") == 0) {
$this->_array_token[] = TOKEN_DECLARACAO_RETURN . "RETURN" . "__" . $this ->_nlinhas;
$_word = '';
$_set = true ;
break;
}
}
if($_set === false ) {
printf("Palavra \"%s\" desconhecida\n", $_word);
fseek($_fp ,ftell($_fp)-1 );
}
}
else if($_char === ",") {
$this->_array_token[] = TOKEN_VIRGULA . "," . "__" . $this->_nlinhas;
}
else if( $_char === "'") {
$_caractere = "'";
if( ($_char = fgetc($_fp)) !== "'") {
$_caractere .= $_char;
$_caractere .= "'";
if( ($_char = fgetc($_fp)) === "'" ) {
$this->_array_token[] = TOKEN_CARACTERE . $_caractere . "__" . $this->_nlinhas;
$_caractere = "";
}
else {
break;
}
}
}
else if($_char === ";") {
$this->_array_token[] = TOKEN_FIM_INSTRUCAO . ";" . "__" . $this->_nlinhas;
}
else if($_char === "\n") {
$this ->_nlinhas++;
}
else if($_char === "_" OR $_char === "?" ) {
printf("Caractere '%s' desconhecido\n", $_char);
}
}
}
function toTable()
{
require_once 'Table.php';
$_table = new Console_Table ();
$_table->setHeaders(array( "Tipo de Token","Valor do Token", "Linha do Token"));
while(list(,$_value) = each ($this->_array_token))
{
$_string_table = explode("__" ,$_value);
$_table-> addRow(array($_string_table[0 ],$_string_table[1],$_string_table [2]));
}
print $_table-> getTable();
}
function getArrayToken()
{
return $this->_array_token;
}
function splitToken()
{
while(list(,$v) = each ($this->_array_token))
{
$cracker = explode("__", $v);
$this->_array_split [] = array($cracker[0],$cracker [1],$cracker[2 ]);
}
}
function debug($debug = null)
{
(!is_null($debug )?var_dump($this->_array_split ):exit);
}
function inicio(){
$this-> palavra = $this->_array_split[ 0];
}
function proximo(){
$this ->palavra = next($this ->_array_split);
}
function start()
{
$this->inicio();
$this ->codigo();
return;
}
function codigo()
{
$this->funcao();
$this-> principal();
return;
}
function principal()
{
if( $this->palavra[1] === "PRINCIPAL") {
$this->proximo ();
$this->bloco();
return;
}
else {
print "\n\n Erro: a funcao PRINCIPAL deve estar definida!\n\n";
exit;
}
}
function bloco ()
{
if($this->palavra[ 1] === "{") {
$this ->proximo();
$this->declaracoes ();
$this->instrucao();
$this->retorno();
if($this ->palavra[1] === "}") {
$this->proximo ();
return;
}
else {
print "\n\n Erro: TOKEN \"}\" esperado na linha: ". $this->palavra[2]. "!\n\n";
exit;
}
}
else {
print "\n\n Erro: TOKEN \"{\" esperado para fechar o bloco!\n\n" ;
exit;
}
}
function declaracoes()
{
if( $this->palavra[1] === "CARACTERE" OR $this->palavra [1] === "STRING" OR $this ->palavra[1] === "REAL" OR $this->palavra[ 1] === "INT" OR $this ->palavra[1] === "BOOL" ) {
$this->declaracao();
var_dump($this->palavra [1]);
$this-> declaracoes();
return;
}
else {
return;
}
}
function declaracao ()
{
$this->tipo();
if( $this->palavra[0] === "TOKEN_ID") {
$this->proximo ();
if($this->palavra[1 ] === ";") {
$this-> proximo();
return;
}
else {
print "\n\n Erro: ; esperado na linha: " .$this->palavra[ 2]."!\n\n";
exit;
}
}
else {
print "\n\n Erro: Identificador esperado na linha: ".$this->palavra [2]."!\n\n";
exit;
}
}
function funcao()
{
if($this-> palavra[1] === "FUNCAO") {
$this->proximo();
$this ->tipo();
if($this->palavra [0] === "TOKEN_ID") {
$this->proximo();
if($this ->palavra[1] === "(") {
$this->proximo ();
$this->parametros();
if( $this->palavra[1] === ")") {
$this->proximo ();
$this->bloco();
$this->funcao();
return;
}
else {
print "\n\n Erro: TOKEN \")\" esperado na linha: ".$this-> palavra[2]." ou apos!\n\n";
exit;
}
}
else {
print "\n\n Erro: TOKEN \"(\" esperado na linha: " .$this->palavra[2 ]." ou apos!\n\n";
exit;
}
}
else {
print "\n\n Erro: Identificador esperado na linha: " .$this->palavra[ 2]."!\n\n";
exit;
}
}
else {
return;
}
}
function parametros()
{
$this-> parametro();
$this->mparametros ();
return;
}
function parametro()
{
$this-> tipo();
if($this->palavra [0] === "TOKEN_ID") {
$this ->proximo();
return;
}
else {
print "\n\n Erro: Identificador esperado na linha: " .$this->palavra[ 2]."!\n\n";
exit;
}
}
function mparametros ()
{
if($this->palavra[ 1] === ",") {
$this-> proximo();
$this->parametro ();
$this->mparametros();
return;
}
else {
return;
}
}
function cparametros()
{
$this ->operando();
$this->mcparametros ();
return;
}
function mcparametros()
{
if($this ->palavra[1] === ",") {
$this->proximo ();
$this->operando();
$this->mcparametros();
return;
}
else {
return;
}
}
function instrucao()
{
if($this->palavra [1] === "WHILE") {
$this ->proximo();
if($this-> palavra[1] === "(" ) {
$this->proximo();
$this->comparacao();
if($this-> palavra[1] === ")" ) {
$this->proximo();
$this->bloco();
$this-> instrucao();
return;
}
else {
print "\n\n Erro: TOKEN \")\" esperado na linha: " .$this->palavra[ 2]." ou apos!\n\n";
exit;
}
}
else {
print "\n\n Erro: TOKEN \"(\" esperado na linha: ".$this->palavra [2]." ou apos!\n\n";
exit;
}
}
else if($this->palavra[ 1] === "IF") {
$this-> proximo();
if($this->palavra [1] === "(") {
$this->proximo();
$this-> comparacao();
if($this->palavra [1] === ")") {
$this->proximo();
$this-> bloco();
$this->evidencia ();
$this->instrucao();
return;
}
else {
print "\n\n Erro: TOKEN \")\" esperado na linha: ".$this ->palavra[2]. " ou apos!\n\n";
exit;
}
}
else {
print "\n\n Erro: TOKEN \"(\" esperado na linha: " .$this->palavra[ 2]." ou apos!\n\n";
exit;
}
}
else if( $this->palavra[0] === "TOKEN_ID") {
$this->proximo ();
$this->fatora();
return;
}
else {
return;
}
}
function fatora()
{
if($this-> palavra[1] === "=") {
$this->proximo();
$this ->expr();
if($this->palavra [1] === ";") {
$this->proximo();
$this-> instrucao();
return;
}
else {
print "\n\n Erro: TOKEN \";\" esperado na linha: " .$this->palavra[ 2]."!\n\n";
exit;
}
}
else if($this ->palavra[1] === "(") {
$this->proximo ();
$this->cparametros();
if( $this->palavra[1] === ")") {
$this->proximo ();
if($this->palavra[1 ] === ";") {
$this-> proximo();
return;
}
else {
print "\n\n Erro: TOKEN \";\" esperado na linha: " .$this->palavra[ 2]."!\n\n";
exit;
}
}
else {
print "\n\n Erro: TOKEN \")\" esperado na linha: ".$this-> palavra[2]." ou apos!\n\n";
exit;
}
}
else {
print "\n\n Erro: Instrucao invalida na linha: ". $this->palavra[2]. " ou apos!\n\n";
exit;
}
}
function evidencia()
{
if( $this->palavra[1] === "ELSE") {
$this->proximo ();
$this->bloco();
return;
}
else {
return;
}
}
function retorno()
{
if($this-> palavra[1] === "RETURN") {
$this->proximo();
if($this ->palavra[1] === "(") {
$this->proximo ();
$this->operando();
if( $this->palavra[1] === ")") {
$this->proximo ();
if($this->palavra[1 ] === ";") {
$this ->proximo();
return;
}
else {
print "\n\n Erro: TOKEN \";\" esperado na linha: " .$this->palavra[ 2]."!\n\n";
exit;
}
}
else {
print "\n\n Erro: TOKEN \")\" esperado na linha: ".$this-> palavra[2]." ou apos!\n\n" ;
exit;
}
}
else {
print "\n\n Erro: TOKEN \"(\" esperado na linha: " .$this->palavra[2 ]." ou apos!\n\n";
exit;
}
}
else {
return;
}
}
function comparacao()
{
if($this->palavra [1] === "TRUE") {
$this ->proximo();
return;
}
else if($this ->palavra[1] === "FALSE" ) {
$this->proximo();
return;
}
else {
$this->operando();
$this->comparador();
$this-> operando();
return;
}
}
function expr()
{
$this->md();
$this ->nexpr();
return;
}
function nexpr()
{
if( $this->palavra[1 ] === "+") {
$this-> proximo();
$this->md();
$this->nexpr();
return;
}
else if( $this->palavra[1] === "-") {
$this->proximo ();
$this->md();
$this->nexpr();
return;
}
else {
return;
}
}
function md()
{
$this->pot ();
$this->nmd();
return;
}
function nmd()
{
if($this->palavra[ 1] === "*") {
$this ->proximo();
$this->pot ();
$this->nmd();
return;
}
else if($this->palavra[1 ] === "/") {
$this-> proximo();
$this->pot ();
$this->nmd();
return;
}
else {
return;
}
}
function pot()
{
$this-> operando();
$this->npot ();
return;
}
function npot()
{
if($this-> palavra[1] === "^") {
$this->proximo();
$this ->operando();
$this->npot ();
return;
}
else {
return;
}
}
function operando()
{
if( $this->palavra[0] === "TOKEN_ID") {
$this->proximo ();
return;
}
else {
$this->tconstante();
}
}
function tconstante(){
if($this ->palavra[0] === "TOKEN_NUMERO" ){
$this->proximo();
return;
}
else if($this->palavra[ 0] === "TOKEN_CARACTERE"){
$this->proximo();
return;
}
else if($this ->palavra[0] === "TOKEN_STRING"){
$this->proximo ();
return;
}
else if($this->palavra[ 0] === "TOKEN_DECLARACAO_TRUE"){
$this->proximo();
return;
}
else if($this ->palavra[0] === "TOKEN_DECLARACAO_FALSE"){
$this->proximo ();
return;
}
else{
print "\n\n Erro: Padrao de constante inexistente na linha:". $this->palavra[2 ]." ou apos!\n\n";
exit;
}
}
function tipo (){
if($this->palavra[ 1] === "INT"){
$this ->proximo();
return;
}
else if($this ->palavra[1] === "CARACTERE" ){
$this->proximo();
return;
}
else if($this->palavra[ 1] === "REAL"){
$this ->proximo();
return;
}
else if($this ->palavra[1] === "STRING" ){
$this->proximo();
return;
}
else if($this->palavra[ 1] === "BOOL"){
$this ->proximo();
return;
}
else{
print "\n\n Erro: Tipo inexistente na linha:".$this->palavra [2]." ou apos!\n\n";
exit;
}
}
function comparador(){
if($this-> palavra[1] === "=="){
$this->proximo();
return;
}
else if( $this->palavra[1 ] === "!="){
$this-> proximo();
return;
}
else if($this-> palavra[1] === "<"){
$this->proximo();
return;
}
else if( $this->palavra[1 ] === ">"){
$this-> proximo();
return;
}
else if($this-> palavra[1] === ">="){
$this->proximo();
return;
}
else if( $this->palavra[1 ] === "<="){
$this-> proximo();
return;
}
else{
print "\n\n Erro: TOKEN de comparacao inadequado na linha:" .$this->palavra[ 2]." ou apos!\n\n";
exit;
}
}
}
$l = new Lexico();
$l->analisar("foo.txt" );
//$l->toTable();
// nao chamar a toTable antes do start() - o array sofre limpeza na memoria
$l ->splitToken();
//$l->debug("on");
$l ->start();
echo "\n\nErros de sintaxe nao foram detectados!\n\n" ;
?>