나는 확신 파일을 구문 분석하고 그냥 토큰, 어휘를 표시하는 어휘 분석기를 코딩하고 가치/문자 평가자/경우 (INT, 부동 또는 문자) 한 분석기의 작동에 대한 코드 그러나 나는 그것은 다음과 같은 방법으로 출력을 표시합니다 displaytoken 아래로 쓸 수 없습니다 : 문자
토큰 어휘 값/평가자/
NUMT 1234 값
를 내가 이 공동있다. 드 샘플 다음 lexical.cpp에 대한
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include "lexical.h"
int value ; // integer
float valuer ; // float
char ch ; // character
string lexeme ; // string
SYMBOL Token ; // token of symbols
string Literal ; // string literals
string reswords[15] ; // reserved words
using namespace std;
//constructor
Lexical::Lexical()
{
}
//destructor
Lexical::~Lexical()
{
}
void Lexical::GetNextToken()
{
// getting the lexeme *******************
// **************************************
value = 0 ;
valuer = 0.0 ;
int i = 1 ; // line tracker
while(!(fin.eof()))
{
lexeme[i] = ch ;
fin.get(ch);
}
if(fin.peek() == '\n')
{
i++ ; // increment the line !
}
if(!fin.eof())
{
ProcessToken() ;
}
else
{
fin.close() ;
Token = eofilet ; // set to end of file
}
}
//rules not implemented yet
void Lexical::displayToken()
{
cout << "Token" << " " << "Lexeme" << " " << " value/valuer/Literal " << endl ;
cout << Token << " " << lexeme << " " << value ;
}
//initialize reserved words
void Lexical::InitResWords()
{
reswords[begint].copy("BEGIN",5,0);
reswords[programt].copy("PROGRAM",7,0);
reswords[constt].copy("CONST",5,0);
reswords[vart].copy("VAR",3,0);
reswords[proceduret].copy("PROCEDURE",9,0);
reswords[ift].copy("IF",2,0);
reswords[whilet].copy("WHILE",5,0);
reswords[thent].copy("THEN",4,0);
reswords[elset].copy("ELSE",4,0);
reswords[realt].copy("REAL",4,0);
reswords[integert].copy("INTEGER",7,0);
reswords[booleant].copy("BOOLEAN",7,0);
reswords[chart].copy("CHAR",4,0);
reswords[arrayt].copy("ARRAY",5,0);
reswords[endt].copy("END",3,0);
}
void Lexical::ProcessToken()
{
lexeme.at(0) = ch ; // 1 character at a time
fin.get(ch) ;
if((lexeme.at(0) >= 'A' && lexeme.at(0) <= 'Z') || (lexeme.at(0) >= 'a' && lexeme.at(0) <= 'z')) // if alphabets
{
int counter = 0 ;
//match word token
if(!isdigit(lexeme.at(0)) && !isalpha(lexeme.at(0)) && lexeme.at(0) != '_')
{
//*********** Working with reserved words !!! **************************************************
int j = 0 ;
bool flag = false ;
while(j < endt)
{
if(lexeme.compare(reswords[j]) == 0)
{
Token = (SYMBOL)j;
displayToken();
flag = true ;
}
}
//**********************************************************************************************
// if not a token , then we are alrea
Token = idt ;// then an identifier token
displayToken();
return ;
}// if ends
lexeme.at(counter) = ch ;// keep proceeding
fin.get(ch) ;
}
else if (lexeme.at(0) >= '0' && lexeme.at(0) <= '9') // if numbers
{
NumToken() ;
}
else if (lexeme.at(0) == '\"') // for string literal
{
ProcessLiteralToken();
}
else if (lexeme.at(0) == '/') // entering comment section
{
if (ch == '/' || ch == '*')
{
// MatchComment();
if (ch == '/') // start of a comment maybe ?
{
//Line comment
while(ch != '\n')
fin.get(ch);
}
else if(ch == '*') // end of a comment ?
{
while(true)
{
fin.get(ch);
if (ch == '*')
{
char peek_value = fin.peek();
if (peek_value == '/')
{
fin.get(ch);
// fin.get(ch);
return;
}
else
continue;
}
} // while ends
}
else
{
cout << "ERROR !!!" ;
}
GetNextToken();
} // comment analyzer then moves to next token !
else
{
OpToken();
}
}
else if ((lexeme.at(0) == '<') || (lexeme.at(0) == '>') || (lexeme.at(0) == '='))
{
if (ch == '=')
{
lexeme.at(1) = ch;
Token = relop ;
fin.get(ch);
}
else
OpToken() ; // process the final token
}
else if ((lexeme.at(0)) == ':')
{
if (ch == '=')
{
lexeme.at(1) = ch;
Token = relop ;
fin.get(ch);
}
}
else
OpToken();
}
void Lexical::OpToken()
{
//Need to detect +, -, ||, *, /, &&, =,(), {}, comma, semicolon, period, quotation("), and []
if(lexeme.at(0) == '+' || lexeme.at(0) == '-' || lexeme.at(0) == 'OR')
{
Token = addop ;
return;
}
else if(lexeme.at(0) == '*' || lexeme.at(0) == '/' || lexeme.at(0) == 'DIV' || lexeme.at(0) == 'MOD' || lexeme.at(0) == 'AND')
{
Token = mulop ;
return;
}
else if(lexeme.at(0) == '<' || lexeme.at(0) == '>' || lexeme.at(0) == '=')
{
Token = relop ;
return;
}
else if(lexeme.at(0) == '(')
{
Token = lparen;
return;
}
else if(lexeme.at(0) == ')')
{
Token = rparen;
return;
}
else if(lexeme.at(0) == '{')
{
Token = clbrat;
return;
}
else if(lexeme.at(0) == '}')
{
Token = crbrat;
return;
}
else if(lexeme.at(0) == ',')
{
Token = comma;
return;
}
else if(lexeme.at(0) == ';')
{
Token = semicolon ;
return;
}
else if(lexeme.at(0) == '.')
{
Token = period ;
return;
}
else if(lexeme.at(0) == '~')
{
Token = tildat;
return;
}
else if(lexeme.at(0) == '[')
{
Token = lbrat;
return;
}
else if(lexeme.at(0) == ']')
{
Token = rbrat;
return;
}
else if(lexeme.at(0) == '#')
{
Token = nott ;
return;
}
else
{
Token = unknownt ;
cout << "Error !!" ;
exit(0);
}
}
void Lexical::NumToken()
{
int i = 0;
while (isdigit(ch))
{
//Update Lexeme and keep going
lexeme.at(i++) = ch;
fin.get(ch);
}
if (ch == '.') // checking for float
{
//if ch is a period, then we might be dealing with a float. We need to ensure that the next character is a digit
lexeme.at(i++) = ch;
fin.get(ch);
if (isdigit(ch))
{
//ch is a digit, so we are good to go.
while (isdigit(ch))
{
lexeme.at(i++) = ch;
fin.get(ch);
}
//If we are here, then we have a float and we have just encountered a new token
Token = numt;
valuer = atof(lexeme.c_str());
return;
}
//If we are here, then we have a period but no digit after it--an error
Token = unknownt ;
cout << "Error." << endl;
exit(0);
}
else {
//If we are here, then it means that the next char is not a period.... so we have a NUMT int token
Token = numt;
value = atoi(lexeme.c_str());
return;
}
}
void Lexical::ProcessLiteralToken()
{
int i = 0;
while (ch != '\"')
{
if (ch == '\n')
{
Token = unknownt ;
cout << "Error!" << endl ;
exit(0);
}
Literal.at(i++) = ch ; // advance !
fin.get(ch);
}
//Literal[i++] = ch;
Token = literalt;
fin.get(ch);
return;
}
내 lexical.h (헤더 파일)이 있습니다 파일 :
#ifndef _LEXICAL_H
#define _LEXICAL_H
#include <iostream>
#include <fstream>
using namespace std ;
// enumerated data type
enum SYMBOL
{
begint,programt, constt, vart, proceduret, ift, whilet, thent, elset, realt, integert, booleant, chart, arrayt, endt, divt, modt, andt, nott, ort, addop, mulop, assignop, lparen, rparen, comma, semicolon, period, numt, idt, literalt, unknownt, eofilet, relop, clbrat, crbrat, tildat, lbrat, rbrat ,colon
};
//extern int size = 15 ;
extern int value ; // integer
extern float valuer ; // float
extern char ch ; // character
extern string lexeme ; // string
extern SYMBOL Token ; // token of symbols
extern string Literal ; // string literals
extern string reswords[15] ; // string array
class Lexical {
public :
Lexical(); // constructor
~Lexical() ; // destructor
//GetNextToken function
void GetNextToken() ;
//displayToken function
void displayToken() ;
private :
//initialize reserved words
void InitResWords() ;
//ProcessToken
void ProcessToken() ;
// operator tokens
void OpToken() ;
//NumToken
void NumToken() ;
//Process string literals
void ProcessLiteralToken() ;
ifstream fin ; // file
} ;
#endif // !_lexical_H
코드는 사람이 어떤 기능을 위해, 그것을 통해 가고 싶은 경우에 제공합니다.
내 토큰을 올바르게 표시하는 방법을 알 수 없습니다. (displayToken) 어떤 사람이 함수를 도와 줄 수 있습니다. 따라서 모든 토큰에 대해 구문 분석하여 다음 형식으로 표시합니다. 토큰 ----- Lexeme ------- 값/가치/리터럴 numt ----- 1234 ------ 값
그냥 디스플레이 토큰 기능을 기록하고 싶습니다. 어휘, 토큰 및 각 토큰을 처리 한 후 값/값 또는 리터럴인지 여부를 어떻게 표시 할 것입니까?
이 내 드라이버 파일
#include "lexical.h"
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
cout << "creating the constructor" << endl << endl ;
Lexical myLex ;
ifstream fin;
fin.open("test.txt") ;
while (Token != eofilet)
{
myLex.GetNextToken();
myLex.displayToken();
}
cout << endl << "success" << endl ;
fin.close();
//system("pause");
return 0;
}
어떤 문제가 있습니까? 너 뭐 해봤 니? –
디버깅을 시도 했습니까? – neagoegab
원하는 출력을 얻기 위해 내 디스플레이 토큰 기능을 보낼 위치를 파악할 수 없습니다! @sftrabbit – thestralFeather7