contribución mini ejemplo de lenguaje interpretado

Iniciado por sapito169, 15 Noviembre 2018, 21:32 PM

0 Miembros y 1 Visitante están viendo este tema.

sapito169

hola para todos aquellos que se preguntan como crear su propio evaluador de expresiones del tipo 5*4 +3 -2 *(5) a qui les tengo un pequeño ejemplito en menos de 81 lineas y sin usar regex


Código (java) [Seleccionar]
package javaapplication17;

import java.util.HashMap;

public class Interpreter {

    private final HashMap<String, String> variables = new HashMap<>();

    public static void main(String[] args) {
         Interpreter interpreter = new Interpreter();
        //calculation
        for (String text : new String[]{
            "1",
            "12",
            "5^2",
            "12+13",
            "4+2-1",
            "(1)",
            "(4/2+1*2)",
            "(1+3)+(5+6-3+13)",
            "3*(4+2)",
            "3*4*(5+3)+16+2",
            "8*7+(4+3+6*(5+4))",}) {

            System.out.println("text= " + text + " " + interpreter.evalProgram(text));
        }
        //programing feature booleans
        System.out.println();
        System.out.println("booleans");
        System.out.println();
        for (String text : new String[]{
            "1<2",
            "2>3",
            "12>13",
            "12<14",
            "(5+1)<14",
            "14<(5+1)",
            "(1+2)-3<4*2",
            "true",
            "false",
            "false&true",
            "false&true",
            "false&true|true",
            "true&false|true",
            "1+2<3&4<2|false",
            "(1+2)*3-1<4|false&true|(3+1)<4"}) {
            Interpreter programEvaluetor = new Interpreter();
            final String evalBoolean = programEvaluetor.evalProgram(text);
            System.out.println(text + " = " + evalBoolean);
        }
        //simple scripts

        System.out.println();
        System.out.println("programs");
        System.out.println();
        for (String text : new String[]{
            "1",
            "3+2-1",
            "3+2-1\n1+2+1",
            "4*5\n5*3",
            "5*8\n4+2\n5+5+5",
            "a=3*4\na",
            "b=3*4\nb",
            "abc=3*4\nabc\ncde=2*5+1\ncde",
            "a=2\nb=3\nc=a+b\nc",
            "c=true\nc",}) {
            Interpreter programEvaluetor = new Interpreter();
            System.out.println("=======program================================");
            System.out.println(text);
            System.out.println("=======endprogram=============================");
            System.out.println("=======output program=========================");
            System.out.println(programEvaluetor.evalProgram(text));
            System.out.println("=======end output program=====================");
            System.out.println("");
            System.out.println("");
        }

        //conditionals programs
        System.out.println();
        System.out.println("conditionals programs");
        System.out.println();
        for (String text : new String[]{
            "1\nif(true){\n2\n}",
            "if(false){\n1\n}",
            "2\nif(true){\n1\n}",
            "2\nif(false){\n1\n}\n3",
            "1\nif(true){\n2\n}\n3",}) {
            Interpreter programEvaluetor = new Interpreter();
            System.out.println("=======program================================");
            System.out.println(text);
            System.out.println("=======endprogram=============================");
            System.out.println("=======output program=========================");
            System.out.println(programEvaluetor.evalProgram(text));
            System.out.println("=======end output program=====================");
            System.out.println("");
            System.out.println("");
        }
        //conditionals programs
    }

    private boolean evalCondition(String condition) {
        final String evalBoleanExpresion = evalBoleanExpresion(condition.substring(3, condition.length() - 2));
        return Boolean.parseBoolean(evalBoleanExpresion);
    }

    private String evalProgram(final String expresion) {
        String[] comands = expresion.split("\n");
        String result = "";
        boolean run = true;
        for (int i = 0; i < comands.length; i++) {
            String comand = comands[i];
            if (comand.startsWith("if")) {
                run = evalCondition(comand);
                continue;
            }

            if (comand.startsWith("}")) {
                run = true;
                continue;
            }

            if (run) {
                final String evalComand = evalComand(comand);
                if (!evalComand.isEmpty()) {
                    result += evalComand + "\n";
                }
            }

        }

        return result.isEmpty() ? "" : result.substring(0, result.length() - 1);
    }

    private String evalComand(String expresion) {
        String[] comandPart = expresion.split("=");
        String result = "";

        if (comandPart.length == 1) {
            String candidate = comandPart[0];
            if (candidate.equals("true") || candidate.equals("false")) {
                return eval(expresion);
            }
            if (candidate.chars().allMatch(Character::isLetter)) {
                return "" + variables.get(candidate);
            }
            return eval(expresion);
        }
        if (comandPart.length == 2) {
            variables.put(comandPart[0], (eval(comandPart[1])));

            return "";
        }

        return result;
    }

    private String eval(String inputString) {

        String buffer = "";
        int beginIndex = -1;

        for (int i = 0; i < inputString.length(); i++) {
            final char character = inputString.charAt(i);
            if (character == '(') {
                beginIndex = i;
                buffer = "";
                buffer += character;
            }
            if (!buffer.isEmpty()) {
                String charLetter = (character + "");
                buffer += charLetter.equals("(") || charLetter.equals(")") ? "" : charLetter;
            }
            if (character == ')') {

                buffer += character;
                inputString = inputString.substring(0, beginIndex) + evalParentesis(buffer) + inputString.substring(beginIndex + buffer.length());
                i = 0;
                buffer = "";

            }
        }

        return "" + evalExpresion(inputString);
    }

    private String evalParentesis(String coeficientString) {

        return evalExpresion(coeficientString.substring(1, coeficientString.length() - 1));
    }

    private String evalExpresion(String expresion) {
        String result = "";
        if (expresion.contains("<")
                || expresion.contains(">")
                || expresion.contains("&")
                || expresion.contains("|")
                || expresion.contains("true")
                || expresion.contains("false")) {
            result = evalBoleanExpresion(expresion);
        } else {
            result = evalAddExpresion(expresion) + "";
        }

        return result;
    }

    private int evalAddExpresion(String expresion) {
        char[] characters = expresion.toCharArray();
        String buffer = "";
        int result = 0;
        for (int i = 0; i < expresion.length(); i++) {
            char character = expresion.charAt(i);
            buffer += character;
            if (i == characters.length - 1
                    || characters[i + 1] == '+'
                    || characters[i + 1] == '-') {

                if (buffer.startsWith("-")) {
                    result -= evalSub(buffer.replace("-", ""));
                } else {
                    result += evalSub(buffer.replace("+", ""));
                }
                buffer = "";
            }

        }

        return result;
    }

    private int evalSub(final String expresion) {
        char[] characters = expresion.toCharArray();
        String buffer = "";
        int result = 1;
        for (int i = 0; i < expresion.length(); i++) {
            char character = expresion.charAt(i);
            buffer += character;
            if (i == characters.length - 1
                    || characters[i + 1] == '*'
                    || characters[i + 1] == '/') {

                if (buffer.startsWith("/")) {
                    result /= evalExpo(buffer.replace("/", ""));
                } else {
                    result *= evalExpo(buffer.replace("*", ""));
                }
                buffer = "";
            }

        }

        return result;
    }

    private int evalExpo(final String expresion) {
        char[] characters = expresion.toCharArray();
        String buffer = "";
        int result = 1;
        for (int i = expresion.length() - 1; i >= 0; i--) {
            char character = expresion.charAt(i);
            buffer = character + buffer;
            if (i == 0 || characters[i - 1] == '^') {
                result = (int) (Math.pow(Integer.parseInt(evalElement(buffer.replace("^", ""))), (result)));
                buffer = "";
            }

        }
        return result;
    }

    private String evalElement(String expresion) {

        if (expresion.chars().allMatch(Character::isLetter)) {
            return variables.get(expresion);
        } else {
            return expresion;
        }

    }

    private String evalBoleanExpresion(String expresion) {
        char[] characters = expresion.toCharArray();
        String buffer = "";
        boolean result = true;
        for (int i = 0; i < expresion.length(); i++) {
            char character = expresion.charAt(i);
            buffer += character;
            if (i == characters.length - 1
                    || characters[i + 1] == '&'
                    || characters[i + 1] == '|') {

                if (buffer.startsWith("&")) {
                    result &= Boolean.parseBoolean(evalBooleanElement(buffer.replace("&", "")));
                } else if (buffer.startsWith("|")) {
                    result |= Boolean.parseBoolean(evalBooleanElement(buffer.replace("|", "")));
                } else {
                    result = Boolean.parseBoolean(evalBooleanElement(buffer));
                }
                buffer = "";
            }

        }

        return result + "";
    }

    private String evalBooleanElement(final String expresion) {
        String result = "";
        if (expresion.contains("<") || expresion.contains(">")) {

            String[] split = expresion.split("<|>");
            String left = evalExpresion(split[0]);
            String right = evalExpresion(split[1]);

            if (expresion.contains("<")) {
                result = "" + (Integer.parseInt(left) < Integer.parseInt(right));

            }
            if (expresion.contains(">")) {
                result = "" + (Integer.parseInt(left) > Integer.parseInt(right));
            }
        } else {
            result = expresion;
        }

        return result;
    }
}




en un futuro agregare la funcionalidad de de agregar variables funciones bucles y condicionales para que se paresca a javascript   ::)

porfavor cuentenme lo que quieran del post preguntas traumas amensas o respuesta troll pero no me ignoren por que soy una perra de atención


diganme si lo han usado y en que

antopixel

Excelente la idea compañero, habia visto algo similar utilizando pilas para saber si una ecuacion estaba bien escrita o no, pero se ve igualmente muy limpio tu codigo. Espero nuevas versiones.

sapito169

#2
ahora estoy trabajando en el algebrea booleana para luego hacer condicionales
luego hare funciones y talves termine en bucles

bueno este desarrollo es incremental y tendre un tiempo de refactoring para mejorar el rendimiento la testeabilidad y facilidad de lectura

ya he escrito codigo mas complicado y con mas limpieza

***** que p**a he hecho con mi vida he puesta a la programación en un pedestal le dedique mucho de mi no se si esta bien o esta mal no se que mas sentir

la sarna con gusto no pica

estoy estudiando AI

quieren que les enseñe como se usa inteligencia artificial para hacer cosas aterradoras
saltar captchas, controlar los clasificadores de imagen ( que reconoscan mal el rostro ) una aplicacion con un solo botonazo y devuelva shell para los que tienen el dedo gordo como yo

hagan su pedido

rub'n

#3
Cita de: sapito169 en 16 Noviembre 2018, 17:46 PM
ahora estoy trabajando en el algebrea booleana para luego hacer condicionales
luego hare funciones y talves termine en bucles

bueno este desarrollo es incremental y tendre un tiempo de refactoring para mejorar el rendimiento la testeabilidad y facilidad de lectura

ya he escrito codigo mas complicado y con mas limpieza

***** que p**a he hecho con mi vida he puesta a la programación en un pedestal le dedique mucho de mi no se si esta bien o esta mal no se que mas sentir

la sarna con gusto no pica

estoy estudiando AI

quieren que les enseñe como se usa inteligencia artificial para hacer cosas aterradoras
saltar captchas, controlar los clasificadores de imagen ( que reconoscan mal el rostro ) una aplicacion con un solo botonazo y devuelva shell para los que tienen el dedo gordo como yo

hagan su pedido


Hola doc,

interesado harás un tutorial?

algo con open cv ?

google usa mucho de java tambien para backend front end, e igual manera, por ejemplo polymer donde va mas a estándar de web components doc, consiguiendo reemplazar si mal no recuerdo a google web toolkit un compilador de codigo java el codigo fuente .java a html,css,y js


ahora mismo estoy probando selenium web driver, con tesseract y opencv


rubn0x52.com KNOWLEDGE  SHOULD BE FREE!!!
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen

sapito169

recien estoy estudiando y mejorando mi habilidad en IA cuando tenga algo hare tutorial bueno y si les es importante usar opencv lo hare con eso

rub'n

Cita de: sapito169 en 16 Noviembre 2018, 18:45 PM
recien estoy estudiando y mejorando mi habilidad en IA cuando tenga algo hare tutorial bueno y si les es importante usar opencv lo hare con eso

yo apunto por opencv es bastante bueno y muy usado. no solamente con python jajaj  :xD


rubn0x52.com KNOWLEDGE  SHOULD BE FREE!!!
If you don't have time to read, you don't have the time (or the tools) to write, Simple as that. Stephen

sapito169

ya es demasiado difícil entrar a temas mas avanzados (que estoy interesado en desarrollador) con una sola clase seria demasiado grande difícil de atender y muy frágil así que cambio de estrategia

voy a crear una clase interpretador que transforme el código fuente en una lista de instruciones tipo ensamblador y realize una seria de normalizaciones y pequeñas limpieza para que no tengas que crear codigo fuente de manera perfecta a la primera ves y si no se puede informara la linea del error

luego tendre una clase para el preporcesamiento de los comandos (para las validaciones para que te diga si estas escribiendo estupidez que nunca funcionaran)   y post procesacion de los comandos(para las optimizaciones)

luego una clase maquina virtual para que se encarge de ejecutar los comandos