From 76b849fbaa276566fa8838d745c0e5fbd2f138bc Mon Sep 17 00:00:00 2001 From: Ralitsa Dardjonova Date: Wed, 7 Nov 2018 16:01:18 +0200 Subject: First homework - highlighter for python (#17) * Initial commit * Fix some typos modified: README * Delete index.html --- homework/81350/py2html/README | 12 ++ homework/81350/py2html/Token.cpp | 39 +++++ homework/81350/py2html/Token.h | 52 +++++++ homework/81350/py2html/build_lexer.sh | 5 + homework/81350/py2html/program.py | 10 ++ homework/81350/py2html/py2html.cpp | 258 ++++++++++++++++++++++++++++++++++ 6 files changed, 376 insertions(+) create mode 100644 homework/81350/py2html/README create mode 100644 homework/81350/py2html/Token.cpp create mode 100644 homework/81350/py2html/Token.h create mode 100755 homework/81350/py2html/build_lexer.sh create mode 100644 homework/81350/py2html/program.py create mode 100644 homework/81350/py2html/py2html.cpp diff --git a/homework/81350/py2html/README b/homework/81350/py2html/README new file mode 100644 index 0000000..da727c2 --- /dev/null +++ b/homework/81350/py2html/README @@ -0,0 +1,12 @@ +To build the program run the bash script build_lexer.sh: +$ ./build_lexer.sh + +To run the highlighter on a given program: +$ ./py2html +When you run the highlighter, it will produce an html +file in the current directory named "index.html". + +There is a test program named program.py: +$ ./py2html program.py + + diff --git a/homework/81350/py2html/Token.cpp b/homework/81350/py2html/Token.cpp new file mode 100644 index 0000000..ea17db5 --- /dev/null +++ b/homework/81350/py2html/Token.cpp @@ -0,0 +1,39 @@ +#include "Token.h" +#include + +std::unordered_map keywords = { + {"False", TokenType::False}, + {"True", TokenType::True}, + {"None", TokenType::None}, + {"and", TokenType::And}, + {"as", TokenType::As}, + {"assert", TokenType::Assert}, + {"break", TokenType::Break}, + {"class", TokenType::Class}, + {"continue", TokenType::Continue}, + {"def", TokenType::Def}, + {"del", TokenType::Del}, + {"elif", TokenType::Elif}, + {"else", TokenType::Else}, + {"except", TokenType::Except}, + {"finally", TokenType::Finally}, + {"for", TokenType::For}, + {"from", TokenType::From}, + {"global", TokenType::Global}, + {"if", TokenType::If}, + {"import", TokenType::Import}, + {"in", TokenType::In}, + {"is", TokenType::Is}, + {"lambda", TokenType::Lambda}, + {"nonlocal", TokenType::Nonlocal}, + {"not", TokenType::Not}, + {"or", TokenType::Or}, + {"pass", TokenType::Pass}, + {"print", TokenType::Print}, + {"raise", TokenType::Raise}, + {"return", TokenType::Return}, + {"try", TokenType::Try}, + {"while", TokenType::While}, + {"with", TokenType::With}, + {"yield", TokenType::Yield} +}; diff --git a/homework/81350/py2html/Token.h b/homework/81350/py2html/Token.h new file mode 100644 index 0000000..97dda8d --- /dev/null +++ b/homework/81350/py2html/Token.h @@ -0,0 +1,52 @@ +#pragma once +#include +#include + +typedef std::string IPLString ; + + enum TokenType{ + False, + None, + True, + And, + As, + Assert, + Break, + Class, + Continue, + Def, + Del, + Elif, + Else, + Except, + Finally, + For, + From, + Global, + If, + Import, + In, + Is, + Lambda, + Nonlocal, + Not, + Or, + Pass, + Print, + Raise, + Return, + Try, + While, + With, + Yield + }; + +struct Token +{ + TokenType Type; + unsigned Line; + IPLString Lexeme; + double Number = 0.0; +}; + +extern std::unordered_map keywords; diff --git a/homework/81350/py2html/build_lexer.sh b/homework/81350/py2html/build_lexer.sh new file mode 100755 index 0000000..95492e0 --- /dev/null +++ b/homework/81350/py2html/build_lexer.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +g++ -Wall -O2 -std=c++11 -c py2html.cpp -o py2html.o +g++ -Wall -O2 -std=c++11 -c Token.cpp -o Token.o +g++ -o py2html py2html.o Token.o -s diff --git a/homework/81350/py2html/program.py b/homework/81350/py2html/program.py new file mode 100644 index 0000000..8343c02 --- /dev/null +++ b/homework/81350/py2html/program.py @@ -0,0 +1,10 @@ +num1 = 1.5 +num2 = 6.3 + +sum = float(num1) + float(num2) + +print('The sum of {0} and {1} is {2}'.format(num1, num2, sum)) + +table = {'Sjoerd': 4127, 'Jack': 4098, 'Dcab': 7678} +for name, phone in table.items(): + print(f'{name:10} ==> {phone:10d}') diff --git a/homework/81350/py2html/py2html.cpp b/homework/81350/py2html/py2html.cpp new file mode 100644 index 0000000..65d28da --- /dev/null +++ b/homework/81350/py2html/py2html.cpp @@ -0,0 +1,258 @@ +#include +#include +#include +#include +#include +#include +#include +#include "Token.h" + +std::string operatorChars = "+-*/%=<>&|^~"; +std::string parenthesisChars = "[]{}(),"; +std::set operators = { + "+", + "-", + "*", + "/", + "//", + "%", + "**", + ">", + "<", + ">=", + "<=", + "==", + "!=", + "&", + "|", + "~", + "^", + ">>", + "<<", + "=", + "+=", + "-=", + "*=", + "/=", + "%=", + "**=", + "//=", + "^=", + "&=", + "|=", + ">>=", + "<<=" +}; + +using namespace std; +FILE* in; +FILE* out; + +bool isNumber(char c){ + return c >= '0' && c <= '9'; +} + +bool notValidNumber(char c){ + return !(isNumber(c) || c == '.'); +} + +bool isQuote(char c){ + return c == '\'' || c == '"'; +} + +bool isLastQuote(char firstQuote, char previousChar, char currentChar){ + return firstQuote == currentChar && previousChar != '\\'; +} + +bool isOperator(char c){ + return operatorChars.find(c) != std::string::npos; +} + +bool isParenthesis(char c){ + return parenthesisChars.find(c) != std::string::npos; +} + +bool isValidIdentifierChar(char c){ + return !(isOperator(c) || isParenthesis(c) || isQuote(c) || c == '\n' || isblank(c) || c == ','); +} + +bool isValidOperator(std::string word){ + std::set::iterator iter; + iter = operators.find(word); + return iter != operators.end(); +} + +std::string readFormat(){ + std::string word = "{"; + char c; + + while((c = fgetc(in)) != EOF && c != '}'){ + word += c; + } + word += '}'; + return word; +} + +std::string readNumber(){ + fseek(in, -1, SEEK_CUR); + std::string word; + char c; + int dotCount = 0; + + while((c = fgetc(in)) != EOF && !notValidNumber(c)){ + //printf("%c", c); + if(notValidNumber(c)){ + return ""; + } else if(c == '.'){ + dotCount++; + if(dotCount >= 2){ + return ""; + } + } + word += c; + } + if(notValidNumber(c)){ + fseek(in, -1, SEEK_CUR); + } + return word; +} + +std::string readString(char firstQuote){ + std::string word = ""; + word += firstQuote; + char c; + char previousChar = ' '; + + while((c = fgetc(in)) != EOF && !isLastQuote(firstQuote, previousChar, c)){ + if( c == '{'){ + fprintf(out, "%s", word.c_str()); + word = readFormat(); + fprintf(out, "%s", word.c_str()); + word = ""; + } else { + word += c; + } + previousChar = c; + } + word += firstQuote; + fprintf(out, "%s", word.c_str()); + return word; +} + +std::string readOperator(){ + fseek(in, -1, SEEK_CUR); + std::string word; + char c; + while((c = fgetc(in)) != EOF && isOperator(c)){ + word += c; + } + if(!isOperator(c)){ + fseek(in, -1, SEEK_CUR); + } + return word; +} + +std::string readWord(){ + fseek(in, -1, SEEK_CUR); + std::string word; + char c; + while((c = fgetc(in)) != EOF && isValidIdentifierChar(c)){ + word += c; + } + + if(!isValidIdentifierChar(c)){ + fseek(in, -1, SEEK_CUR); + } + return word; +} + +void lexer(){ + char c; + bool validSyntaxis = 1; + std::string word; + std::unordered_map::const_iterator iter; + + while((c = fgetc(in)) != EOF){ + if(isQuote(c)){ + word = readString(c); + //fprintf(out, "%s", word.c_str()); + continue; + } + if(isNumber(c)){ + word = readNumber(); + fprintf(out, "%s", word.c_str()); + continue; + } + if(isOperator(c)){ + word = readOperator(); + if(isValidOperator(word)){ + validSyntaxis = 0; + } + fprintf(out, "%s", word.c_str()); + // trqbwa da se proweti dali e korektno + // t.e. da e w nqkyw set ili hash + continue; + } + if(isParenthesis(c)){ + fprintf(out, "%c", c); + continue; + } + if(isblank(c) || c == '\n'){ + fprintf(out, "%c", c); + continue; + } + + word = readWord(); + iter = keywords.find(word); + if(iter == keywords.end()){ + fprintf(out, "%s", word.c_str()); + } else { + fprintf(out, "%s", word.c_str()); + } + + } +} + +int main(int argc, const char* argv[]) +{ + ++argv, --argc; /* skip over program name */ + if ( argc > 0 ) + in = fopen( argv[0], "r" ); + else + in = stdin; + + out = fopen("index.html", "w"); + + fputs( + "" + "" + "" + " program.py" + " " + "" + "" + "
",
+        out);
+
+    lexer();
+    fputs("
", out); + fclose(in); + fclose(out); + return 0; +} -- cgit v1.3.1-23-gd82d