Created
June 6, 2015 00:57
-
-
Save haskellcamargo/896b82a4f30e5aef239c to your computer and use it in GitHub Desktop.
Expressions analyzer - AdvPL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "protheus.ch" | |
/** | |
* Gramatica formal da analise de expressoes, dentro do parser, levando em conta | |
* a geracao de tokens. | |
* @author Marcelo Camargo | |
* @since 17/04/2015 | |
* | |
* expr := string | number | array | nil | codeblock | date | object | |
* string := <? T_STRING ?> | |
* number := <? T_NUMBER ?> | |
* array := expr | <? NT_EMPTY_ARRAY ?> | |
* nil := <? T_NIL ?> | |
* codeblock := <? T_CODEBLOCK ?> | |
* date := <? T_DATE ?> | |
* object := { property } | |
* property := <? T_PROPERTY ?> | |
* logic = <? T_TRUE ?> | <? T_FALSE ?> | |
*/ | |
#xtranslate BREAKLINE => CHR( 13 ) + CHR( 10 ) | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} VarDump | |
Analisa recursivamente uma expressao, em sua equivalencia a var_dump (PHP), | |
dir (Python), console.log (Javascript) ou obj.inspect (Ruby). Monta uma arvore | |
visual com definicoes de escopo e informacoes precisas sobre a expressao | |
recebida. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param xVar - Expressao a ser analisada. | |
@return | |
/*/ | |
//------------------------------------------------------------------------------ | |
Function VarDump( xVar ) | |
Scope := 0 // Scope initial value | |
ConOut( ParseExpr( xVar ) ) | |
Return | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseExpr | |
Analisa uma expressao usando um micro top-down recursive descent parser, | |
utilizando informacoes sobre o tipo como tokens. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param xVar - Expressao a ser analisada. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseExpr( xVar ) | |
Local cType := ValType( xVar ) | |
Do Case | |
Case cType == "C" // String | |
Return ParseString( xVar ) | |
Case cType == "N" // Number | |
Return ParseNumber( xVar ) | |
Case cType == "A" // Array | |
Return ParseArray( xVar ) | |
Case cType == "U" // Nil | |
Return ParseNil() | |
Case cType == "B" // Codeblock | |
Return ParseBlock( xVar ) | |
Case cType == "D" // Date | |
Return ParseDate( xVar ) | |
Case cType == "O" // Object | |
Return ParseObject( xVar ) | |
Case cType == "L" // Logic | |
Return ParseBool( xVar ) | |
Otherwise | |
Return ParseUnknown( xVar ) | |
EndCase | |
Return | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseString | |
Analisa uma string e retorna seu tamanho e conteudo interno corretamente | |
formatados. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param cData - String a ser analisada. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseString( cData ) | |
Return "string<" + AllTrim( Str( Len( cData ) ) ) + ">('" + cData + "')" ; | |
+ BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseNumber | |
Analisa uma numero e retorna seu conteudo visualmente formatado. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param nData - Numero (inteiro ou real) a ser analisado. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseNumber( nData ) | |
Return "number(" + AllTrim( Str( nData ) ) + ")" + BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseBool | |
Analisa um valor logico e retorna seu conteudo visualmente formatado, | |
neste caso, seu source. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param lData - Vaor logico a ser analisado. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseBool( lData ) | |
Return "logic(" + IIf( lData, "True", "False" ) + ")" + BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseUnknown | |
Analisa um valor com tipo desconhecido e retorna este de forma formatada, | |
quando possivel. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param xData - Valor desconhecido (talvez novos tipos) a serem analisados. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseUnknown( xData ) | |
Return "unknown(" + ValType( xData ) + ")" + BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseNil | |
Simbolo nao-terminal que representa um terminal literal nulo. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseNil() | |
Return "NIL" + BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseArray | |
Analisa recursivamente um array e seus sub-elementos, seguindo a gramatica | |
definida no começo do arquivo e montando um template com os dados analisados, | |
seguindo uma ordem logica de escopo. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param aData - Array a ser analisado. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseArray( aData ) | |
Local nI | |
Local cTemplate := "" | |
// Array e um nao terminal que pode conter itens em seu escopo. | |
Scope++ | |
cTemplate += "array<" + AllTrim( Str( Len( aData ) ) ) + ">(" | |
If Len( aData ) > 0 // Vamos quebrar linha apenas quando o array tiver itens. | |
cTemplate += BREAKLINE | |
EndIf | |
// Percorrendo todos os elementos do array, vamos, recursivamente, analisar | |
// os valores contidos em cada um deles, ate alcancarmos algum simbolo | |
// literal. | |
For nI := 1 To Len( aData ) | |
cTemplate += Replicate( " ", Scope * 2 ) + "[" + Alltrim( Str( nI ) ) ; | |
+ "] => " + ParseExpr( aData[ nI ] ) | |
Next nI | |
// Retornamos ao nosso escopo anterior caso tenhamos itens no array, por | |
// questoes esteticas de formatacao. | |
cTemplate += IIf( Len( aData ) > 0, Replicate( " ", ( Scope * 2 ) - 2 ), ; | |
"" ) + ")" + BREAKLINE | |
Scope-- | |
Return cTemplate | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseBlock | |
Analisa um bloco e retorna seu conteudo visualmente formatado, neste caso, | |
seu source. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param bData - Bloco a ser analisado. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseBlock( bData ) | |
Return "block(" + GetCBSource( bData ) + ")" + BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseDate | |
Analisa uma data e retorna seu conteudo visualmente formatado. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param dData - Data a ser analisada. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseDate( dData ) | |
Return "date(" + DtoC( dData) + ")" + BREAKLINE | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseObject | |
Aplica reflexao e, dentro de um objeto, busca por suas propriedades e exibe | |
seus pares de chave e valor de forma formatada. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param oData - Objeto a ser analisado. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseObject( oData ) | |
Local cTemplate := "" | |
// Array contendo os dados do objeto. | |
Local aChildren := ClassDataArr( oData ) | |
// Objeto e um nao terminal que pode conter itens em seu escopo. | |
Scope++ | |
cTemplate += "object<" + GetClassName( oData ) + "> {" + BREAKLINE | |
cTemplate += ParseProperty( aChildren ) | |
cTemplate += Replicate( " ", ( Scope * 2 ) - 2 ) + "}" + BREAKLINE | |
Scope-- | |
Return cTemplate | |
//------------------------------------------------------------------------------ | |
/*{Protheus.doc} ParseProperty | |
Analise de propriedades de objetos. | |
@author Marcelo Camargo | |
@since 17/04/2015 | |
@param aProp - Array reflectivo de propriedades a serem analisadas. | |
@return string | |
/*/ | |
//------------------------------------------------------------------------------ | |
Static Function ParseProperty( aProp ) | |
Local nI | |
Local cTemplate := "" | |
// Cada propriedade corresponde a um elemento. | |
// [ nI ][ 1 ] => Chave | |
// [ nI ][ 2 ] => Valor | |
// [ nI ][ 3 ] => Campo com valor number(0) | |
For nI := 1 To Len( aProp ) | |
cTemplate += Replicate( " ", Scope * 2 ) + "Property<" + aProp[ nI ][ 1 ] + ; | |
">: " + ParseExpr( aProp[ nI ][ 2 ] ) | |
Next nI | |
Return cTemplate |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment