Re[3]: Lisp без скобок
От: frogkiller Россия  
Дата: 11.12.06 16:02
Оценка: 1 (1) :)
Вот, может, кому пригодится. Форматирует кусок кода на lisp для используемой там css.

// SchemeColorer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <string>

bool isSpace(char ch) {    return ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t'; }
bool isDelimeter(char ch) { return ch == '(' || ch == ')' || isSpace(ch); }

const char *findmatched(const char *str, const char *fin)
{
    const char *tmp = str;
    for (int cnt = 1; tmp != fin && cnt > 0; ++tmp)
    {
        if (*tmp == '(') { ++cnt; }
        if (*tmp == ')') { --cnt; }
    }
    return tmp;
}

const char *findword(const char *str, const char *fin)
{
    for (const char *tmp = str; tmp != fin; ++tmp) if (isDelimeter(*tmp)) return tmp;
    return fin;
}

const char *skipspace(const char *str, const char *fin)
{
    for (const char *tmp = str; tmp != fin; ++tmp) if (!isSpace(*tmp)) return tmp;
    return fin;
}

std::string process_body(const char *str, const char *fin)
{
    if (str == fin)    return "";
    if (*str == '(')
    {
        const char *tmp = findmatched(str + 1, fin);
        std::string tmpres = std::string("<span class=\"paren\">(") + process_body(str + 1, tmp - 1) + std::string(")</span>");
        return tmpres + process_body(tmp, fin);
    }
    std::string res = "";
    const char *tmp1 = skipspace(str, fin);
    if (tmp1 != str) { res += std::string(str, tmp1); }
    const char *tmp2 = findword(tmp1, fin);
    if (tmp2 != tmp1)
    {
        res += std::string("<span class=\"scheme-documentation\">") + std::string(tmp1, tmp2) + std::string("</span>");
    }
    const char *tmp3 = skipspace(tmp2, fin);
    if (tmp3 != tmp2) { res += std::string(tmp2, tmp3); }
    return res + process_body(tmp3, fin);
}

std::string process(const char *str, const char *fin)
{
    return std::string("<pre class=\"scheme\">") + process_body(str, fin) + std::string("</pre>");
}

long getFileSize(FILE *f)
{
    long cur = ftell(f); fseek(f,0,SEEK_END);
    long len = ftell(f); fseek(f,cur,SEEK_SET);
    return len;
}

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc < 3)
    {
        std::cout << "usage: schemecolorer in.sch out.txt";
    }

    FILE *g_in = fopen(argv[1], "rb");
    if (!g_in)
    {
        std::cout << "cannot open source file " << argv[1] << std::endl;
        return -1;
    }

    FILE *g_out = fopen(argv[2], "wb");
    if (!g_out)
    {
        fclose(g_in);
        std::cout << "cannot open destination file " << argv[2] << std::endl;
        return -2;
    }

    long len = getFileSize(g_in);

    char *buffer = new char[len + 1];
    fread(buffer, sizeof(char), len , g_in);
    buffer[len] = '\0';

    std::string result = process(buffer, buffer + len).c_str();
    fwrite(result.c_str(), sizeof(char), result.length(), g_out); fflush(g_out);

    delete [] buffer;
    fclose(g_in); fclose(g_out);

    return 0;
}
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Курица — это инструмент, с помощью которого одно яйцо производит другие.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.