diff --git a/homework/62374/java2html/CommonTypes.h b/homework/62374/java2html/CommonTypes.h new file mode 100644 index 00000000..d85a10bc --- /dev/null +++ b/homework/62374/java2html/CommonTypes.h @@ -0,0 +1,41 @@ +#pragma once +#include +#include +#include +#include +#include +#include + +template +using IPLVector = std::vector; +using IPLString = std::string; + +template +using IPLPair = std::pair; + +template +using IPLStack = std::stack; + +template +using IPLUnorderedMap = std::unordered_map; + +template +using IPLSharedPtr = std::shared_ptr; + +template +inline IPLSharedPtr IPLMakeSharePtr(Args&&... args) { + return std::make_shared(args...); +}; + +template< typename T> +using IPLEnableShared = std::enable_shared_from_this; + +struct IPLError +{ + unsigned Row; + unsigned Column; + IPLString File; + IPLString What; +}; + +#define NOT_IMPLEMENTED assert(0 && "not-implemented") diff --git a/homework/62374/java2html/Lexer.h b/homework/62374/java2html/Lexer.h new file mode 100644 index 00000000..d5149f97 --- /dev/null +++ b/homework/62374/java2html/Lexer.h @@ -0,0 +1,154 @@ +#pragma once + +#include "CommonTypes.h" + +enum class TokenType +{ + // Single-character tokens. + LeftParen, + RightParen, + LeftBrace, + RightBrace, + Comma, + Dot, + Minus, + Plus, + Semicolon, + Star, + Division, + Modulo, + BitwiseNot, + BitwiseAnd, + BitwiseXor, + BitwiseOr, + QuestionMark, + Colon, + LeftSquareBracket, + RightSquareBracket, + + // One or two character tokens + Bang, + BangEqual, + Equal, + EqualEqual, + StrictEqual, + StrictNotEqual, + Greater, + GreaterEqual, + Less, + LessEqual, + MinusMinus, + PlusPlus, + LeftShift, + RightShift, + LogicalAnd, + LogicalOr, + StarEqual, + DivideEqual, + ModuloEqual, + PlusEqual, + MinusEqual, + LeftShiftEqual, + RightShiftEqual, + BitwiseAndEqual, + BitwiseXorEqual, + BitwiseOrEqual, + Backslash, + + Identifier, + String, + Number, + + // Keywords. ECMAScript 2015 + Abstract, + Package, + Synchronize, + Boolean, + Private, + Double, + Implements, + Protected, + Byte, + Public, + Throws, + Transient, + Int, + Short, + Char, + Final, + Interface, + Static, + Long, + Float, + Break, + Case, + Catch, + Class, + Const, + Continue, + Debugger, + Default, + Delete, + Do, + Else, + Export, + Extends, + Finally, + For, + Function, + If, + Import, + In, + Instanceof, + New, + Return, + Super, + Switch, + This, + Throw, + Try, + Typeof, + Var, + Let, + Void, + While, + With, + Yield, + Null, + Undefined, + True, + False, + + Whitespace, + Tab, + NewLine, + Comment, + + Eof, + Invalid +}; + +struct Token +{ + TokenType Type; + unsigned Line; + unsigned Column; + IPLString Lexeme; + double Number; +}; + +struct LexerResult +{ + bool IsSuccessful; + IPLError Error; + IPLVector tokens; +}; + +struct LexerSettings +{ + bool CreateWhitespaceTokens; + bool CreateCommentTokens; +}; + +LexerResult Tokenize(const char* code, const LexerSettings& settings); +LexerResult Tokenize(const char* code); \ No newline at end of file diff --git a/homework/62374/java2html/Main.java b/homework/62374/java2html/Main.java new file mode 100644 index 00000000..f7b4fb89 --- /dev/null +++ b/homework/62374/java2html/Main.java @@ -0,0 +1,11 @@ +public class Main { + + public static void main(String[] args) { + // This is a comment; + + int a = 5; + + System.out.println("Hello World"); + } + +} diff --git a/homework/62374/java2html/java2html.cpp b/homework/62374/java2html/java2html.cpp new file mode 100644 index 00000000..f294c5cd --- /dev/null +++ b/homework/62374/java2html/java2html.cpp @@ -0,0 +1,681 @@ +#include +#include +#include "Lexer.h" +#include +#include + +namespace +{ +inline bool IsUpperCase(char c) +{ + return c >= 'A' && c <= 'Z'; +} + +inline bool IsLowerCase(char c) +{ + return c >= 'a' && c <= 'z'; +} + +inline bool IsDigit(char c) +{ + return c >= '0' && c <= '9'; +} + +inline bool IsValidIdentifierStartingChar(char c) +{ + return IsUpperCase(c) || IsLowerCase(c) || c == '_'; +} + +inline bool IsValidIdentifierChar(char c) +{ + return IsValidIdentifierStartingChar(c) || IsDigit(c); +} + +inline bool IsStringBound(char c) +{ + return c == '"'; +} + +inline bool IsNewLine(char c) +{ + return c == '\n'; +} + +inline bool IsEnd(char c) +{ + return c == '\0'; +} +} + +struct Keyword +{ + TokenType Type; + IPLString Content; +}; + +using Identifier = Keyword; + +enum class State : unsigned char +{ + Success, + Fail, + Error +}; + +#define RETURN_SUCCESS(ret) m_GenerationState = State::Success; return ret; +#define RETURN_FAIL(ret) m_GenerationState = State::Fail; return ret; +#define RETURN_ERROR(ret) m_GenerationState = State::Error; return ret; + +class Tokenizer +{ +public: + Tokenizer(const char* code, const LexerSettings& settings); + LexerResult Tokenize(); + +private: + Token NextToken(); + + inline Token ProduceSkipToken(); + inline Token ProduceToken(TokenType type); + inline Token ProduceCommentToken(TokenType type, const IPLString& comment); + inline Token ProduceSingleCharacterToken(TokenType type, const IPLString& operatorLexeme); + inline Token ProduceStringToken(TokenType type, const IPLString& str); + inline Token ProduceIdentifierToken(TokenType type, const IPLString& identifier); + inline Token ProduceKeywordToken(TokenType type, const IPLString& keyword); + inline Token ProduceToken(TokenType type, const IPLString& lexeme, double number); + inline Token ProduceErrorToken(); + inline Token ProduceInvalidToken(); + + bool FilterToken(TokenType type); + + IPLString ParseComment(); + double ParseNumber(); + IPLString ParseString(); + Keyword ParseKeyword(); + Identifier ParseIdentifier(); + + inline bool IsStateSuccess() const; + inline bool IsStateError() const; + + void SetError(const IPLString& what); + + bool Match(const char c); + + inline void NextSymbol(); + inline void PreviousSymbol(); + inline void NextLine(); + + unsigned m_Line; + unsigned m_Column; + unsigned m_Current; + unsigned m_LastTokenPozition; + const char* m_Code; + + IPLError m_Error; + State m_GenerationState; + + LexerSettings m_Settings; + + IPLUnorderedMap m_KeyWordsTable; +}; + +LexerResult Tokenize(const char* code, const LexerSettings& settings) +{ + Tokenizer tokenizer(code, settings); + return tokenizer.Tokenize(); +} + +LexerResult Tokenize(const char * code) +{ + return Tokenize(code, { false, false }); +} + +Tokenizer::Tokenizer(const char* code, const LexerSettings& settings) + : m_Line(0) + , m_Column(0) + , m_Current(0) + , m_LastTokenPozition(0) + , m_Code(code) + , m_Error() + , m_GenerationState(State::Success) + , m_Settings(settings) +{ + //TODO + m_KeyWordsTable["abstract"] = TokenType::Abstract; + m_KeyWordsTable["continue"] = TokenType::Continue; + m_KeyWordsTable["for"] = TokenType::For; + m_KeyWordsTable["new"] = TokenType::New; + m_KeyWordsTable["switch"] = TokenType::Switch; + m_KeyWordsTable["default"] = TokenType::Default; + m_KeyWordsTable["package"] = TokenType::Package; + m_KeyWordsTable["synchronized"] = TokenType::Synchronize; + m_KeyWordsTable["boolean"] = TokenType::Boolean; + m_KeyWordsTable["do"] = TokenType::Do; + m_KeyWordsTable["if"] = TokenType::If; + m_KeyWordsTable["private"] = TokenType::Private; + m_KeyWordsTable["this"] = TokenType::This; + m_KeyWordsTable["break"] = TokenType::Break; + m_KeyWordsTable["double"] = TokenType::Double; + m_KeyWordsTable["implements"] = TokenType::Implements; + m_KeyWordsTable["protected"] = TokenType::Protected; + m_KeyWordsTable["throw"] = TokenType::Throw; + m_KeyWordsTable["byte"] = TokenType::Byte; + m_KeyWordsTable["else"] = TokenType::Else; + m_KeyWordsTable["import"] = TokenType::Import; + m_KeyWordsTable["public"] = TokenType::Public; + m_KeyWordsTable["throws"] = TokenType::Throws; + m_KeyWordsTable["case"] = TokenType::Case; + m_KeyWordsTable["instanceof"] = TokenType::Instanceof; + m_KeyWordsTable["return"] = TokenType::Return; + m_KeyWordsTable["transient"] = TokenType::Transient; + m_KeyWordsTable["catch"] = TokenType::Catch; + m_KeyWordsTable["extends"] = TokenType::Extends; + m_KeyWordsTable["int"] = TokenType::Int; + m_KeyWordsTable["short"] = TokenType::Short; + m_KeyWordsTable["try"] = TokenType::Try; + m_KeyWordsTable["char"] = TokenType::Char; + m_KeyWordsTable["final"] = TokenType::Final; + m_KeyWordsTable["interface"] = TokenType::Interface; + m_KeyWordsTable["static"] = TokenType::Static; + m_KeyWordsTable["void"] = TokenType::Void; + m_KeyWordsTable["class"] = TokenType::Class; + m_KeyWordsTable["finally"] = TokenType::Finally; + m_KeyWordsTable["long"] = TokenType::Long; + m_KeyWordsTable["float"] = TokenType::Float; + m_KeyWordsTable["super"] = TokenType::Super; + m_KeyWordsTable["while"] = TokenType::While; + +} + +LexerResult Tokenizer::Tokenize() +{ + LexerResult result{ true, IPLError(), IPLVector() }; + Token token; + do + { + token = NextToken(); + + if (m_GenerationState == State::Error ) + { + result.IsSuccessful = false; + result.Error = IPLError(m_Error); + return result; + } + if (FilterToken(token.Type)) + { + result.tokens.emplace_back(token); + } + } while (token.Type != TokenType::Eof && token.Type != TokenType::Invalid); + + return result; +} + +Token Tokenizer::NextToken() +{ + if (IsEnd(m_Code[m_Current])) + { + return ProduceToken(TokenType::Eof); + } + + const auto& comment = ParseComment(); + if (IsStateError()) + { + return ProduceErrorToken(); + } + if (IsStateSuccess()) + { + return ProduceCommentToken(TokenType::Comment, comment); + } + + // Single Char + switch (m_Code[m_Current]) + { + case '(': NextSymbol(); return ProduceToken(TokenType::LeftParen); + case ')': NextSymbol(); return ProduceToken(TokenType::RightParen); + case '{': NextSymbol(); return ProduceToken(TokenType::LeftBrace); + case '}': NextSymbol(); return ProduceToken(TokenType::RightBrace); + case ',': NextSymbol(); return ProduceToken(TokenType::Comma); + case '.': NextSymbol(); return ProduceToken(TokenType::Dot); + case '-': NextSymbol(); return Match('-') ? ProduceToken(TokenType::MinusMinus) : ProduceToken(TokenType::Minus); + case '+': NextSymbol(); return Match('+') ? ProduceToken(TokenType::PlusPlus) : ProduceToken(TokenType::Plus); + case ';': NextSymbol(); return ProduceToken(TokenType::Semicolon); + case '*': NextSymbol(); return ProduceToken(TokenType::Star); + case '/': NextSymbol(); return ProduceToken(TokenType::Division); + case '%': NextSymbol(); return ProduceToken(TokenType::Modulo); + case '~': NextSymbol(); return ProduceToken(TokenType::BitwiseNot); + case '=': NextSymbol(); return Match('=') ? Match('=') ? ProduceToken(TokenType::StrictEqual) : ProduceToken(TokenType::EqualEqual) : ProduceToken(TokenType::Equal); + case '!': NextSymbol(); return Match('=') ? Match('=') ? ProduceToken(TokenType::StrictNotEqual) : ProduceToken(TokenType::BangEqual) : ProduceToken(TokenType::Bang); + case '>': NextSymbol(); return Match('=') ? ProduceToken(TokenType::GreaterEqual) : Match('>') ? ProduceToken(TokenType::RightShift) : ProduceToken(TokenType::Greater); + case '<': NextSymbol(); return Match('=') ? ProduceToken(TokenType::LessEqual) : Match('<') ? ProduceToken(TokenType::LeftShift) : ProduceToken(TokenType::Less); + case '&': NextSymbol(); return Match('&') ? ProduceToken(TokenType::LogicalAnd) : ProduceToken(TokenType::BitwiseAnd); + case '^': NextSymbol(); return ProduceToken(TokenType::BitwiseXor); + case '|': NextSymbol(); return Match('|') ? ProduceToken(TokenType::LogicalOr) : ProduceToken(TokenType::BitwiseOr); + case '?': NextSymbol(); return ProduceToken(TokenType::QuestionMark); + case ':': NextSymbol(); return ProduceToken(TokenType::Colon); + case '[': NextSymbol(); return ProduceToken(TokenType::LeftSquareBracket); + case ']': NextSymbol(); return ProduceToken(TokenType::RightSquareBracket); + case '\\': NextSymbol(); return ProduceToken(TokenType::Backslash); + case '\n': NextLine(); return ProduceToken(TokenType::NewLine); + case ' ': NextSymbol(); return ProduceToken(TokenType::Whitespace); + case '\t': NextSymbol(); return ProduceToken(TokenType::Tab); + default: + break; + } + + const auto& number = ParseNumber(); + if (IsStateSuccess()) + { + return ProduceToken(TokenType::Number, "", number); + } + + const auto& string = ParseString(); + if (IsStateSuccess()) + { + return ProduceStringToken(TokenType::String, string); + } + else if (IsStateError()) + { + return ProduceErrorToken(); + } + + const auto& keyword = ParseKeyword(); + if (IsStateSuccess()) + { + return ProduceKeywordToken(keyword.Type, keyword.Content); + } + + const auto& identifier = ParseIdentifier(); + if (IsStateSuccess()) + { + return ProduceIdentifierToken(identifier.Type, identifier.Content); + } + + return ProduceInvalidToken(); +} + +bool Tokenizer::FilterToken(TokenType type) +{ + if (type == TokenType::Comment) + { + return m_Settings.CreateCommentTokens; + } + else if (type == TokenType::Whitespace || + type == TokenType::Tab || + type == TokenType::NewLine) + { + return m_Settings.CreateWhitespaceTokens; + } + return true; +} + +bool Tokenizer::Match(const char c) +{ + if (c == m_Code[m_Current]) + { + NextSymbol(); + return true; + } + return false; +} + +inline void Tokenizer::NextSymbol() +{ + ++m_Current; + ++m_Column; +} + +inline void Tokenizer::PreviousSymbol() +{ + --m_Current; + --m_Column; +} + +inline void Tokenizer::NextLine() +{ + ++m_Current; + ++m_Line; + m_LastTokenPozition = m_Column = 0; +} + +inline Token Tokenizer::ProduceIdentifierToken(TokenType type, const IPLString& identifier) { + auto token = Token { type, m_Line, m_LastTokenPozition, "

" + identifier + "

", 0.0}; + + m_LastTokenPozition = m_Column; + + return token; +} + +inline Token Tokenizer::ProduceKeywordToken(TokenType type, const IPLString& keyword) { + auto token = Token { type, m_Line, m_LastTokenPozition, "

" + keyword + "

", 0.0}; + + m_LastTokenPozition = m_Column; + + return token; +} + +inline Token Tokenizer::ProduceStringToken(TokenType type, const IPLString& str) { + auto token = Token { type, m_Line, m_LastTokenPozition, "

" + str + "

", 0.0}; + + m_LastTokenPozition = m_Column; + + return token; +} + +inline Token Tokenizer::ProduceCommentToken(TokenType type, const IPLString& comment) { + auto token = Token { type, m_Line, m_LastTokenPozition, "

" + comment + "

", 0.0}; + + m_LastTokenPozition = m_Column; + + return token; +} + +inline Token Tokenizer::ProduceToken(TokenType type, const IPLString& lexeme, double number = 0.0) +{ + auto token = Token{ type, m_Line, m_LastTokenPozition, lexeme, number }; + m_LastTokenPozition = m_Column; + return token; +} + +inline Token Tokenizer::ProduceSkipToken() +{ + return ProduceToken(TokenType::Invalid, ""); +} + +inline Token Tokenizer::ProduceSingleCharacterToken(TokenType type, const IPLString& operatorLexeme) { + auto token = Token { type, m_Line, m_LastTokenPozition, "

" + operatorLexeme + "

", 0.0}; + + m_LastTokenPozition = m_Column; + + return token; +} + +inline Token Tokenizer::ProduceToken(TokenType type) +{ + switch (type) + { + case TokenType::RightSquareBracket: + return ProduceSingleCharacterToken(type, "]"); + case TokenType::LeftSquareBracket: + return ProduceSingleCharacterToken(type, "["); + case TokenType::Colon: + return ProduceSingleCharacterToken(type, ":"); + case TokenType::QuestionMark: + return ProduceSingleCharacterToken(type, "?"); + case TokenType::BitwiseXor: + return ProduceSingleCharacterToken(type, "^"); + case TokenType::LogicalOr: + return ProduceSingleCharacterToken(type, "||"); + case TokenType::BitwiseOr: + return ProduceSingleCharacterToken(type, "|"); + case TokenType::LogicalAnd: + return ProduceSingleCharacterToken(type, "&&"); + case TokenType::BitwiseAnd: + return ProduceSingleCharacterToken(type, "&"); + case TokenType::LessEqual: + return ProduceSingleCharacterToken(type, "<="); + case TokenType::LeftShift: + return ProduceSingleCharacterToken(type, "<<"); + case TokenType::Less: + return ProduceSingleCharacterToken(type, "<"); + case TokenType::GreaterEqual: + return ProduceSingleCharacterToken(type, ">="); + case TokenType::RightShift: + return ProduceSingleCharacterToken(type, ">>"); + case TokenType::Greater: + return ProduceSingleCharacterToken(type, ">"); + case TokenType::StrictNotEqual: + return ProduceSingleCharacterToken(type, "!=="); + case TokenType::BangEqual: + return ProduceSingleCharacterToken(type, "!="); + case TokenType::Bang: + return ProduceSingleCharacterToken(type, "!"); + case TokenType::StrictEqual: + return ProduceSingleCharacterToken(type, "==="); + case TokenType::EqualEqual: + return ProduceSingleCharacterToken(type, "=="); + case TokenType::Equal: + return ProduceSingleCharacterToken(type, "="); + case TokenType::BitwiseNot: + return ProduceSingleCharacterToken(type, "~"); + case TokenType::Modulo: + return ProduceSingleCharacterToken(type, "%"); + case TokenType::Division: + return ProduceSingleCharacterToken(type, "/"); + case TokenType::LeftParen: + return ProduceSingleCharacterToken(type, "("); + case TokenType::RightParen: + return ProduceSingleCharacterToken(type, ")"); + case TokenType::LeftBrace: + return ProduceSingleCharacterToken(type, "{"); + case TokenType::RightBrace: + return ProduceSingleCharacterToken(type, "}"); + case TokenType::Comma: + return ProduceSingleCharacterToken(type, ","); + case TokenType::Dot: + return ProduceSingleCharacterToken(type, "."); + case TokenType::Minus: + return ProduceSingleCharacterToken(type, "-"); + case TokenType::MinusMinus: + return ProduceSingleCharacterToken(type, "--"); + case TokenType::Plus: + return ProduceSingleCharacterToken(type, "+"); + case TokenType::PlusPlus: + return ProduceSingleCharacterToken(type, "++"); + case TokenType::Semicolon: + return ProduceSingleCharacterToken(type, ";"); + case TokenType::Star: + return ProduceSingleCharacterToken(type, "*"); + case TokenType::Backslash: + return ProduceSingleCharacterToken(type, "\\"); + case TokenType::NewLine: + return ProduceToken(TokenType::NewLine, "

"); + case TokenType::Whitespace: + return ProduceToken(TokenType::Whitespace, " "); + case TokenType::Tab: + return ProduceToken(TokenType::Tab, "    "); + default: // EoF Invalid + break; + } + return ProduceToken(type, ""); +} + +inline Token Tokenizer::ProduceErrorToken() +{ + return ProduceToken(TokenType::Invalid, ""); +} + +inline Token Tokenizer::ProduceInvalidToken() +{ + SetError("Invalid or unexpected token"); + RETURN_ERROR(ProduceToken(TokenType::Invalid, "")); +} + +IPLString Tokenizer::ParseComment() +{ + auto start = m_Current; + + if (!Match('/')) + { + RETURN_FAIL(IPLString()); + } + + if (Match('/')) + { + while (!IsEnd(m_Code[m_Current]) && !IsNewLine(m_Code[m_Current])) + { + NextSymbol(); + } + RETURN_SUCCESS(IPLString(m_Code + start, m_Code + m_Current)) + } + else if (!Match('*')) + { + PreviousSymbol(); + RETURN_FAIL(IPLString()); + } + + while (!IsEnd(m_Code[m_Current])) + { + if (Match('*') && Match('/')) + { + RETURN_SUCCESS(IPLString(m_Code + start, m_Code + m_Current)); + } + NextSymbol(); + } + + SetError("unterminated comment"); + RETURN_ERROR(IPLString()); +} + +double Tokenizer::ParseNumber() +{ + if (!IsDigit(m_Code[m_Current])) + { + RETURN_FAIL(0.0); + } + + size_t parsedBytes = 0; + double number = std::stod(m_Code + m_Current, &parsedBytes); + m_Current += static_cast(parsedBytes); + m_Column += static_cast(parsedBytes); + + RETURN_SUCCESS(number); +} + +IPLString Tokenizer::ParseString() +{ + if (!IsStringBound(m_Code[m_Current])) + { + RETURN_FAIL(IPLString()); + } + + char bound = m_Code[m_Current]; + auto start = m_Current; + + // skip first " or ' + NextSymbol(); + while (m_Code[m_Current] != bound && !IsEnd(m_Code[m_Current]) && !IsNewLine(m_Code[m_Current])) + { + NextSymbol(); + } + + if (IsEnd(m_Code[m_Current]) || IsNewLine(m_Code[m_Current])) + { + SetError("\"\" string literal contains an unescaped line break"); + RETURN_ERROR(IPLString()); + } + + // skip second " or ' + NextSymbol(); + + RETURN_SUCCESS(IPLString(m_Code + start, m_Code + m_Current)); +} + +Keyword Tokenizer::ParseKeyword() +{ + if (!IsLowerCase(m_Code[m_Current])) + { + RETURN_FAIL(Keyword()); + } + + auto start = m_Current; + + NextSymbol(); + while (IsLowerCase(m_Code[m_Current])) + { + NextSymbol(); + } + + auto key = IPLString(m_Code + start, m_Code + m_Current); + auto keyword = m_KeyWordsTable.find(key); + + if (keyword == m_KeyWordsTable.end()) + { + // It's not a keyword so we must revert current counter + m_Column -= m_Current - start; + m_Current = start; + + RETURN_FAIL(Keyword()); + } + + RETURN_SUCCESS((Keyword{ keyword->second, keyword->first })); +} + +Identifier Tokenizer::ParseIdentifier() +{ + if (!IsValidIdentifierStartingChar(m_Code[m_Current])) + { + RETURN_FAIL(Identifier()); + } + + auto start = m_Current; + + NextSymbol(); + while (IsValidIdentifierChar(m_Code[m_Current])) + { + NextSymbol(); + } + + RETURN_SUCCESS((Identifier{ TokenType::Identifier, IPLString(m_Code + start, m_Code + m_Current) })); +} + +inline bool Tokenizer::IsStateSuccess() const +{ + return m_GenerationState == State::Success; +} + +inline bool Tokenizer::IsStateError() const +{ + return m_GenerationState == State::Error; +} + +void Tokenizer::SetError(const IPLString& what) +{ + m_Error = IPLError{ m_Line, m_Column, "", "Syntax error: " + what }; +} + +int main(int argc, char* argv[]) +{ + if (argc == 0) { + return 1; + } + + char* inputFilePath = argv[1]; + + LexerSettings* settings = new LexerSettings(); + settings->CreateCommentTokens = true; + settings->CreateWhitespaceTokens = true; + + std::ifstream in(inputFilePath); + std::string contents((std::istreambuf_iterator(in)), + std::istreambuf_iterator()); + + const char* code = contents.c_str(); + + Tokenizer* tokenizer = new Tokenizer(code, *settings); + + LexerResult result = tokenizer->Tokenize(); + + std::string output = ""; + + for (int i = 0; i < result.tokens.size(); i++) { + Token token = result.tokens[i]; + + if (token.Type == TokenType::Number) { + output.append(std::to_string(token.Number)); + + continue; + } + + output.append(token.Lexeme); + } + + output += ""; + + std::ofstream MyFile("output.html"); + + MyFile << output; + + MyFile.close(); + + return 0; +} diff --git a/homework/62374/java2html/java2html.exe b/homework/62374/java2html/java2html.exe new file mode 100644 index 00000000..ee09f325 Binary files /dev/null and b/homework/62374/java2html/java2html.exe differ diff --git a/homework/62374/java2html/output.html b/homework/62374/java2html/output.html new file mode 100644 index 00000000..7955e7be --- /dev/null +++ b/homework/62374/java2html/output.html @@ -0,0 +1,34 @@ + +

public

  +

class

  +

Main

  +

{





   +

public

  +

static

  +

void

  +

main

+

(

+

String

+

[

+

]

  +

args

+

)

  +

{



     +

// This is a comment;





     +

int

  +

a

  +

=

 5.000000 +

;





     +

System

+

.

+

out

+

.

+

println

+

(

+

"Hello World"

+

)

+

;



   +

}





+

}



+ + \ No newline at end of file