Pregunta

Estoy programando en C ++ y no estoy seguro de cómo lograr lo siguiente:

Estoy copiando una secuencia de archivo de la memoria (porque me pidieron que, preferiría la lectura de la corriente), y a continuación, tratar de acceder a sus valores para almacenarlos en cadenas y int variables.

Esta es la creación de un intérprete. El código Voy a tratar de interpretar es (es decir):

10 PRINT A
20 GOTO 10

Esto es sólo un ejemplo de código rápido. Ahora los valores se almacenan en una estructura de "mapa" en un primer momento y se puede acceder más tarde, cuando todo va a ser "interpretado". Los valores a ser almacenados son:

int LNUM // número de línea

cmd cadena // comando (impresos y GOTO)

string exp // expresión (A y 10 en este caso, pero podría contener expresiones como (a * b) -c)

pregunta se da el siguiente código, cómo accedo a esos valores y almacenarlos en la memoria? También la cadena exp es de tamaño variable (puede ser sólo una variable o una expresión) así que no estoy seguro de cómo leer eso y almacenarlo en la cadena.

código:


#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <map>
#include <sstream>

using namespace std;

 #include "main.hh"


int main () 
{
    int lenght;
    char *buffer;

// get file directory
    string dir;
    cout << "Please drag and drop here the file to interpret: ";
    getline (cin,dir);
    cout << "Thank you.\n";
    cout << "Please wait while your file is being interpreted.\n \n";

// Open File
    ifstream p_prog;
    p_prog.open (dir.c_str());

// Get file size
    p_prog.seekg (0, ios::end);
    lenght = p_prog.tellg();
    p_prog.seekg(0, ios::beg);

// Create buffer and copy stream to it
    buffer = new char[lenght];
    p_prog.read (buffer,lenght);
    p_prog.close();

// Define map<int, char>
    map<int, string> program;
    map<int, string>::iterator iter;


/***** Read File *****/
    int lnum; // line number
    string cmd; // store command (goto, let, etc...)
    string exp; // to be subst with expr. type inst.

//  this is what I had in mind but not sure how to use it properly
//  std::stringstream buffer;
//  buffer >> lnum >> cmd >> exp;

    program [lnum] = cmd; // store values in map




// free memory from buffer, out of scope
    delete[] buffer;
    return 0;
}

Espero que esto está claro.

Gracias por su ayuda.

Valerio

¿Fue útil?

Solución

Puede utilizar un std::stringstream para tirar fichas, suponiendo que ya conoce el tipo.

Para un intérprete, lo recomiendo encarecidamente utilizar un analizador real en lugar de escribir el suyo propio. Xpressive biblioteca de Boost o antlr funciona bastante bien. Usted puede construir sus primitivas intérprete mediante acciones semánticas a medida que analizar la gramática o simplemente construir un AST.

Otra opción sería Flex & bisonte . Básicamente, estas son todas las herramientas para el análisis de gramáticas predefinidas. Usted puede construir su propia, pero prepararse para la frustración. Recursivamente equilibrio de paréntesis, o el orden de las operaciones de hacer cumplir (Dividir antes de multiplicar, por ejemplo) no es trivial.

La prima C ++ método de análisis sintáctico sigue:


#include <sstream>
#include <string>

// ... //

istringstream iss(buffer);
int a, b;
string c, d;

iss >> a;
iss >> b;
iss >> c;
iss >> d;

Otros consejos

La forma algo así como esto se puede hacer (sobre todo la parte expresión aritmética que aludía a) es:

  • Escribir un código que determina el lugar en un token termina y comienza. Por ejemplo 5 o + se llamaría un token. Es posible escanear el texto de estos, o separadores comunes, tales como espacios en blanco.
  • Escribir la gramática de la lengua que está el análisis. Por ejemplo, puede escribir:
    expression -> value
    expression -> expression + expression
    expression -> expression * expression
    expression -> function ( expression )
    expression -> ( expression )

A continuación, sobre la base de esta gramática que iba a escribir algo que analiza muestras de expresiones en los árboles.

Así que es posible tener un árbol que tiene este aspecto (perdón por el arte ASCII)

            +
          /   \
         5     *
              / \
             x   3

Cuando esto representa la expresión 5 + (x * 3). Al tener esto en una estructura de árbol que es muy fácil de evaluar las expresiones del código: puede descender de forma recursiva el árbol, la realización de las operaciones con los nodos secundarios como argumentos

.

Vea los siguientes artículos de la Wikipedia:

O consulte a su departamento de informática local. : -)

También existen herramientas que generarán estos analizadores para usted, basado en una gramática. Usted puede hacer una búsqueda de "generador de análisis".

No hacer la asignación dinámica de la memoria intermedia de utilizar un vector de forma explícita.
Esto hace que la gestión de la memoria implícita.

// Create buffer and copy stream to it   
std::vector<char>   buffer(lenght);
p_prog.read (&buffer[0],lenght);
p_prog.close();

En lo personal yo no uso explícitamente close () (a menos que quiera capturar una excepción). Sólo tiene que abrir un archivo en un ámbito que hará que el destructor para cerrar el archivo cuando se sale del ámbito.

Esto puede ser de ayuda:

http://oopweb.com/ CPP / Documentos / CPPHOWTO / Volumen / C ++ Programación-COMO-7.html

Especialmente sección 7.3.

Usted puede ser mejor simplemente << 'ing las líneas en lugar de la ruta y la búsqueda de CharBuffer.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top