2013-05-21 4 views
1

키보드 (표준 입력)에서 다음 텍스트를 읽어야합니다. P1은 사용자가 키보드에서이 형식으로 입력 만합니다.키보드에서 입력 읽기

#the total size of physical memory (units are B, KB, MB, GB) 
    512MB 2  #the following are memory allocations 
    { 
      abc = alloc(1KB); 
      { 
       y_ = alloc(128MB); 
       x1= alloc(128MB); 
       y_ = alloc(32MB); 
       for (i = 0; i < 256; i++) abc[i] =alloc(512kB); 
        x1 = alloc(32MB); x2 = alloc(32MB); x3 = alloc(32MB); 
       x1.next = x2, x2.next = x3, x3.next = x1; 
    } 
    abc = alloc(256MB); 
    } 

그래서 기본적으로 설명해 드리겠습니다. # 기호로 시작하는 줄은 주석으로 간주되어 무시됩니다. 처음 두 할당은 실제 메모리 크기와 세대 수입니다. 글로벌 브래킷이 열립니다. 과이 줄 이어 될 수는

ABC 개체 이름은
abc = alloc(1KB); 

라고 1킬로바이트는 할당 된 메모리의 크기이다. x1.next = x2, 여기 x1은 x2를 가리 킵니다.

for (i = 0; i < 256; i++) abc[i] =alloc(512kB); 

for 루프 os는이 형식으로 입력되며 동일한 회선 명령을 가질 수 있으며 for 루프를 중첩 할 수 있습니다.

다음과 같은 코드가 있습니다. 나는 그것에 대해 개선하고 싶다. 도와주세요.

그리고 내 코드는 다음과 같습니다

#include <iostream> 
#include <algorithm> 
#include <string> 
#include <iomanip> 
#include <limits> 
#include <stdio.h> 
#include <sstream> 



using namespace std; 
using std::stringstream; 

string pMem,sGen, comment,val,input,input_for,id_size,id,init_str1, init_str2, inc_str, id_dummy,s_out,sss, id_dummy1; 
int gen=0, pMem_int=0,i=0, gBrckt =0,cBrckt=0, oBrckt=0, id_size_int,v1,v2, for_oBrckt=0,for_cBrckt=0,y=0, y1=0, g=0; 
unsigned long pMem_ulong =0, id_size_ulong; 
char t[20], m[256], init1[10],init2[10],inc[10]; 
unsigned pos_start, pos,pos_strt=0,pos_end=0; 

string extract(string pMem_extract); 
unsigned long toByte(int pMem_int_func, string val); 
void commentIgnore(string& input); 
void func_insert(); 
void func_insert_for(); 
stringstream out; 
void commentIgnore_for(string& input_for); 

int main() 
{ 
    /* Reading the input main memory and num of generations */ 
    /* Ignoring comment line */ 
    cin >> pMem; 
    if(pMem == "#") { 
    cin.clear(); 
    pMem.clear(); 
    getline(cin,comment); 
    cin >> pMem; 
    } 
    if(pMem == "#") { 
    cin.clear(); 
    pMem.clear(); 
    getline(cin,comment); 
    cin >> pMem; 
    } 
    if(pMem == "#") { 
    cin.clear(); 
    pMem.clear(); 
    getline(cin,comment); 
    cin >> pMem; 
    } 
    /* Reading input generations */ 
    cin>> sGen; 
    if(sGen == "#") { 
    cin.clear(); 
    sGen.clear(); 
    getline(cin,comment); 
    cin >> sGen; 
    } 
    if(sGen == "#") { 
    cin.clear(); 
    sGen.clear(); 
    getline(cin,comment); 
    cin >> sGen; 
    } 
    if(sGen == "#") { 
    cin.clear(); 
    sGen.clear(); 
    getline(cin,comment); 
    cin >> sGen; 
    } 
    /* Convert sGen and physical memory to int and report error if not a number */ 
    gen = atoi(sGen.c_str()); 
    if(gen ==0) { 
    cerr << "Generation must be a number"<<endl; 
     exit(0); 
    } 
    pMem_int = atoi(pMem.c_str()); 
    // cout<< gen<<" "<<pMem_int<<endl; 

    /* Now that the number from pMem is removed, get its unit B,MB,KB */ 
    extract(pMem); /* returns val(string) */ 

    /* convert the given physical memory to Byte. input: pMem_int*/ 
    toByte(pMem_int, val); /* return(pMem_ulong)*/ 
    // move pMem_ulond to another location to keep address intact 
    /* read rest of the inputs */ 
    /* Ignore comment lines before the global bracket */ 
    cin >> input; 
    if(input == "#"){ 
    cin.clear(); 
    input.clear(); 
    getline(cin,comment); 
    cin >> input; 
    } 
    if(input == "#"){ 
    cin.clear(); 
    input.clear(); 
    getline(cin,comment); 
    cin >> input; 
    } 
    if(input == "#"){ 
    cin.clear(); 
    input.clear(); 
    getline(cin,comment); 
    cin >> input; 
    } 

    if(input.compare("{") ==0) 
    gBrckt=1; 

    else { 
    cerr<< "Syntax error\n"; 
    exit(0); 
    } 

    /* Clearing the input stream for next input */ 
    cin.ignore(numeric_limits<streamsize>::max(), '\n'); 
    cin.clear(); 
    input.clear(); 
    //cout<<"input: "<<input<<endl; 
    while(getline(cin,input)) { 

    if(input == "CTRL-D") 
     break; 

    commentIgnore(input); 
    //cout<<"inputloop: "<<input<<endl; 

    /* If input = '{' or '}'*/ 
    if(input.compare("{") ==0) 
     oBrckt = oBrckt + 1; 

    if (input.compare("}") ==0) 
     cBrckt = cBrckt + 1; 

    if (((input.find("alloc"))!= string::npos) && (input.find("alloc") < input.find("for"))) { 
     func_insert(); 
     //call the allocate function here with name: id, size: id_size_ulong 
    } 

    if ((input.find("for")) != string::npos) { 
     sscanf(input.c_str(), "for (%s = %d; %s < %d; %[^)])", init1, &v1, init2, &v2, inc); 
    init_str1 = init1, init_str2 = init2, inc_str = inc; 

    cout<<init1<<" ="<< v1<<" "<<init_str1<<" < " << v2<< " "<< inc_str<<endl; 
    cout << input <<endl; 

    if(init_str1 != init_str2) { 
     cerr << "Error!\n"; 
     exit(0); 
    } 

    if ((input.find("alloc"))!= string::npos) { 
     // unsigned pos = (input.find("alloc")); 

     if((input.find(";")) != string::npos) { 

     pos_start = (input.find(")")+1); 
     string alloc_substr = input.substr(pos_start); 
     cout<<"Substring alloc: "<< alloc_substr<<endl; 

     func_insert(); 
     //call the allocate function here with name: id, size: id_size_ulong 
     } 
     else { 
     cerr << "ERROR: SYNTAX\n"; 
     exit(0); 
     } 


    } 
    // cin.ignore(); 
    while(getline(cin,input_for)) { 
     commentIgnore_for(input_for); 

     if ((input_for.find("{") != string::npos)) { 
     pos = input_for.find("{"); 
     for_oBrckt = for_oBrckt+1; 
     string for_brckt = input_for.substr(pos,pos); 
     cout<< "Found: " << for_oBrckt<<endl; 
     } 


     if ((input_for.find("}") != string::npos)) { 
     pos = input_for.find("}"); 
     for_cBrckt = for_cBrckt+1; 
     string for_brckt = input_for.substr(pos,pos); 
     cout<< "Found: " << for_cBrckt<<endl; 
     } 

     if (((input_for.find("alloc"))!= string::npos) && (input_for.find("alloc") < input_for.find("for"))) { 
     func_insert_for(); 
     //call the allocate function here with name: id, size: id_size_ulong 
     } 




     if(for_oBrckt == for_cBrckt) 
     break; 


    } 
    cout<<"out of break"<<endl; 
    } 

     if (((input.find(".next"))!= string::npos) && (input.find(".next") < input.find("for"))) { 
     func_insert(); 
     //call the allocate function here with name: id, size: id_size_ulong 
    } 

     if(((cBrckt-oBrckt)) == gBrckt) 
     break; 
    } 

} 

/*---------------------- Function definitions --------------------------------*/ 
/* Function to extract the string part of physical memory */ 
string extract(string pMem_extract) { 
    i=0; 
    const char *p = pMem_extract.c_str(); 
    for(i=0; i<=(pMem_extract.length()); i++) { 
    if (*p=='0'|| *p=='1'|| *p=='2'|| *p=='3'|| *p =='4'|| *p=='5'|| *p=='6'|| *p=='7'|| *p=='8'|| *p=='9') 
     *p++; 
    else { 
     val = pMem_extract.substr(i); 
     return(val); 
    } 
    } 
} 

/* Convert the physical memory to bytes. return(pMem_ulong);*/ 
unsigned long toByte(int pMem_int_func, string val) 
{ 
    if (val == "KB") 
    pMem_ulong = (unsigned long) pMem_int_func * 1024; 
    else if (val == "B") 
    pMem_ulong = (unsigned long) pMem_int_func; 
    else if (val == "GB") 
    pMem_ulong = (unsigned long) pMem_int_func * 1073741824; 
    else if (val == "MB") 
    pMem_ulong = (unsigned long) pMem_int_func * 1048576; 
    else { 
    cerr<<"Missing the value in memory, B, KB, MB, GB\n"; 
    exit(0); 
    } 

    return(pMem_ulong); 
} 


/*Ignoring comment line*/ 
void commentIgnore(string& input) 
{ 
    unsigned found = input.find('#'); 

    if (found!=std::string::npos) 
    input= input.erase(found); 

    else 
    return; 
    return; 
} 


void func_insert() { 
sscanf(input.c_str(), "%s = alloc(%[^)]);", t, m); 
     id =t; 
     id_size =m; 
     cout<<"Tag: "<<id <<" Memory: "<<id_size<<endl; 
     extract(id_size); /* Separates B,MB,KB and GB of input, returns val*/ 
     id_size_int = atoi(id_size.c_str()); 
     /* Convert object size to B */ 
     toByte(id_size_int, val); /* return(pMem_ulong) */ 
     id_size_ulong = pMem_ulong; 

} 

void func_insert_for() { 
    sscanf(input_for.c_str(), "%s = alloc(%[^)]);", t, m); 
    id =t; 
    id_size =m; 
    if(!((id.find("[")) && (id.find("]")) != string::npos)) { 
    cout<<"Tag: "<<id <<" Memory: "<<id_size<<endl; 
    extract(id_size); /* Separates B,MB,KB and GB of input, returns val*/ 
    id_size_int = atoi(id_size.c_str()); 
    /* Convert object size to B */ 
    toByte(id_size_int, val); /* return(pMem_ulong) */ 
    id_size_ulong = pMem_ulong; 
    // allocate here 
    return; 
    } 
    else { 
    if(inc_str.find("++")) 
     y1 =1; 
    if(inc_str.find("=")) 
     { 
    sss = inc_str.substr(inc_str.find("+") +1); 
    y1 = atoi(sss.c_str()); 
    cout<<"y1:"<<y1<<endl; 

     } 
    pos_strt = id.find("["); 
    pos_end = id.find("]") -1; 
    cout<<"Positions start and ebd: " << pos_strt<<pos_end<<endl; 
    id_dummy = id.substr(0,pos_strt); 
    id = id_dummy; 
    cout<<"Tag: "<<id_dummy <<" Memory: "<<id_size<<endl; 
    extract(id_size); /* Separates B,MB,KB and GB of input, returns val*/ 
    id_size_int = atoi(id_size.c_str()); 
    /* Convert object size to B */ 
    toByte(id_size_int, val); /* return(pMem_ulong) */ 
    id_size_ulong = pMem_ulong; 
    //allocate here 
    cout<<"v1: " << v1 << " " << v2<<endl; 
    // g = 0; 
    for(y = v1; y < v2; y= y+y1) { 
     // allocate here 
    } 
    } 
    return; 
} 

void commentIgnore_for(string& input_for) 
{ 
    unsigned found = input_for.find('#'); 

    if (found!=std::string::npos) 
    input_for= input_for.erase(found); 

    else 
    return; 
    return; 
} 

은 또한 내가 그것을 공백 호환되도록 요구하고있다. 이것이 의미하는 바는 입력을 한 줄에 입력 할 수 있다는 것입니다. 한 줄에 두 개의 할당이 있습니다. 나는 신경 쓸 수 없었습니다. 도움이 필요해.

+1

[http://codereview.stackexchange.com/](http://codereview.stackexchange.com/) –

+0

@CaptainObvlious : 여기에 질문하는 데 문제가 있습니다. –

+0

공백으로 사용할 수 있도록해야합니다. 이것이 의미하는 바는 입력을 한 줄에 입력 할 수 있다는 것입니다. 한 줄에 두 개의 할당이 있습니다. 나는 내가 돌 보았다고 생각하지 않는다. 도움이 필요해. – Tuffy

답변

1

내 의견에는 적절한 토큰 화기 (단어와 같은 단어)와 함께 속하는 것을 이해하는 코드 조각 (예 : "(,), {,}")을 작성하는 것이 좋습니다. tokenizer는 다음과 같은 열거 형을 반환합니다.

enum Token { 
    Token_Unknown, // Error indiciation. 
    Token_LeftParen, 
    Token_RightParen, 
    Token_LeftBracket, 
    Token_RightBracket, 
    Token_Comma, 
    Token_Semicolon, 
    Token_Equal, 
    Token_Word,  // Sequence of alphanumerics 
}; 

일단 토큰이 있으면 토큰이 무엇인지 이해해야합니다. "mem", "alloc", "for"등과 같이 "알려진"토큰 (일명 "키워드") 테이블을 갖는 것이 이치에 맞을 수도 있습니다. 무언가가 키워드가 아닌 경우 변수와 같은 심볼의 이름입니다. 테이블에 저장하여 나중에 참조 할 수 있습니다.

어디서든 스택을 사용해야하므로 마쳤을 때 다시 돌아올 수 있습니다.

일반 구문 분석기를 작성하는 것은 그리 어려운 일이 아니며 대부분의 경우 현재 코드보다 훨씬 적은 코드로 끝납니다.

물론, 당신은 모두 제거 할 수있을 것입니다 : 입력으로 '#'가있는 경우

if(input == "#"){ 
    cin.clear(); 
    input.clear(); 
    getline(cin,comment); 
    cin >> input; 
    } 

그냥 파서 확인을하자, 그리고 줄의 끝으로 (완료를 건너 현재 토큰이있는 경우 현재 토큰,없는 경우 그냥 계속).

+0

시도해보십시오. 감사합니다 ... – Tuffy

+0

토큰 화기와 파서를 생성 할 수있는 자유롭게 사용할 수있는 도구가 있습니다. 모든 것을 직접 작성하는 대신 이러한 방법을 사용해야합니다. –

+0

그리고 주석의 시작을 본 후에 왜'clear()'입니까? 다음 라인 끝을 볼 때까지 그냥 건너 뜁니다. (이것은 토크 나이저의 규칙 일 수도 있고 입력 스트림에 필터링 streambuf를 삽입 할 수도 있습니다.) –

1

IIUC는 입력 하지 라인 배향 때문에 적용되지 않을 std::getline를 사용 의 일반적인 규정이다. 내 접근 방식은 다음과 같습니다.

  • 의견을 삭제하기 위해 필터링 streambuf를 삽입하십시오.

  • 어떤 종류의 정규 표현식 기반 렉서 (예 : flex) 을 사용하여 입력을 토큰으로 분리하십시오.

  • 문법을 정의하십시오. 문법을 구문 분석 할 코드를 생성하기 위해 까지이 코드를 사용하면 bison을 사용하지만 간단한 재귀 파서를 작성하는 것은 너무 어렵지 않습니다.

당신은 당신이 이 그것을 구문 분석 일단 당신이 정보로 무엇을해야하는지 말을하지 않습니다, 그래서 더 정확한 조언을 제공하기 어렵다.

+0

기본적으로 주어진 물리적 메모리를 할당하고 세대 수로 나눕니다. 내가 alloc을 가로 질러 왔을 때, 나는 alloc에 ​​의해 지정된 메모리로 객체를 할당한다. – Tuffy

+0

for 루프에서 재귀 적으로 할당합니다. 이것은 내가 작업하고있는 가비지 수집 알고리즘입니다. x1.net = x2는 x1을 x2로 만듭니다. 그것은 연결된 목록입니다. – Tuffy

+0

세대 별 알고리즘을 사용한 마크 및 스윕 – Tuffy

관련 문제