gokernel
(usa Linux Mint)
Enviado em 03/08/2015 - 19:15h
Olá !
Qual seria o motivo de querer tipo interpretada ?
Basicamente uma implementação de uma linguagem similar a C seria assim:
/*
**-------------------------------------------------------------------
**
** "Exemplo/esqueleto" de modelo de uma linguagem:
**
**-------------------------------------------------------------------
*/
static char *str;
static int token [1024];
static char prog [10000];
static int tok;
static int erro;
enum {
TOK_INT = 255,
TOK_IF,
TOK_FOR,
//------------
TOK_ID,
TOK_NUMBER,
TOK_STRING
};
int lex (void)
{
switch (*str) {
// ... aqui:
// 01: ler/incrementa str:
// 02: modifica token[]
// 03: retorna ( TOK_INT, TOK_IF, TOK_FOR, TOK_MUMERO, TOK_STRING ... )
//
// ou:
case 0: return 0;
default:
return *str++;
}
return 0;
}
int stmt (VM *a)
{
switch (tok) {
case '{'
tok = lex();
while (tok && tok != '}') stmt(a); // processa um BLOCO
tok = lex();
break;
case TOK_INT:
// processa int ... usando lex();
break;
case TOK_IF:
// processa if ... usando lex();
break;
case TOK_FOR:
// processa for ... usando lex();
break;
default:
expression (a);
}
return tok;
}
void expression (VM *a)
{
// aqui pode ser typo:
// 01: variavel
// 02: funcao
// 03: ou ERRO ;)
//
if (tok == TOK_ID) {
expr0(a);
// ....
}
tok = lex();
}
int Parse (VM *a, char *text)
{
str = text;
erro = 0;
while (stmt(a)) { } // SIM: um loop vazio para ser mais claro
return erro;
}
int main (int argc, char *argv[])
{
VM *fe;
// ABRE UM ARQUIVO E ARMAZENA EM ( prog ):
// ...
// CRIA/INICIA O FRONTEND:
// ...
if (!Parse(fe, prog)) {
// executa o "FRONTEND"
}
return 0;
}
Modelo de analisador de expressão baseado na dica do colega acima:
// +, - : soma
void expr0 (ASM *a) {
int op;
expr1(a);
while ((op=tok) == '+' || (op=tok) == '-') {
tok=lex();
expr1(a);
switch (op) {
case '+':
asm_add_eax_esp (a);
break;
case '-':
asm_sub_eax_esp (a);
break;
}
}
}
// *, / : multiplica
void expr1 (ASM *a) {
int op;
expr2(a);
while ((op=tok) == '*' || (op=tok) == '/') {
tok=lex();
expr2(a);
switch (op) {
case '*':
asm_imul_eax_esp(a);
break;
case '/':
break;
}
}
}
// (
void expr2 (ASM *a) {
if(tok=='('){
tok=lex();
expr0(a);
if(tok != ')'){
printf ("ERRO )\n");
erro_line (" ");
}
tok=lex();
}
else expr3(a); // atom:
}
// atom:
void expr3 (ASM *a) {
if(tok==TOK_ID){
VAR *v = csVarFind(token);
if (v) {
asm_pushl_var (a, &v->value);
tok=lex();
}
else erro_line("Expression var not found");
}
else if(tok==TOK_NUMBER){
asm_push_number (a, atoi(token));
tok=lex();
}
else erro_line("Expression");
}
Veja algo aqui:
http://www.t3x.org/subc/
T+.