Created
November 30, 2016 19:51
-
-
Save antvconst/b69068938a80c327aeab190b8ccbd2a4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <vector> | |
#include <iostream> | |
#include <fstream> | |
using namespace std; | |
struct str_pair { // упорядоченная пары строк | |
string u, v; | |
}; | |
void shift_numeration(vector<string>& v, int k) { // функция, сдвигающая адресацию переходов в v на k позиций | |
for (int i = 0; i < v.size(); ++i) { | |
string s = v.at(i); | |
if ((s.at(0) == '>') || (s.at(0) == '&')) | |
v.at(i) = s.at(0) + to_string(stoi(s.substr(1)) + k); | |
} | |
} | |
string remove_parentheses(string s) { // функция, удаляющая из строки окаймляющие скобки | |
if ((s.at(0) == '(') && (s.at(s.length()-1) == ')')) { | |
return s.substr(1, s.length()-2); | |
} | |
else | |
return s; | |
} | |
int last_top_level(string s, char op) { // функция, возвращающая позицию последнего вхождения op в s вне скобок | |
int pos = -1; | |
int braces_open = 0; | |
for (int i = 0; i < s.length(); ++i) { | |
char c = s.at(i); | |
if (c == '(') | |
braces_open++; | |
else if (c == ')') | |
braces_open--; | |
else if ((c == op) && (braces_open == 0)) | |
pos = i; | |
} | |
return pos; | |
} | |
str_pair unfold(string s, char op) { // функция, разделяющая выражение s по последнему применению оператора op | |
int pos = last_top_level(s, op); | |
return str_pair { | |
s.substr(0, pos), | |
s.substr(pos+1) | |
}; | |
} | |
vector<string> parse(string s) { // главная функция обработки строки | |
str_pair p; | |
vector<string> v; | |
if (last_top_level(s, ';') != -1) { | |
p = unfold(s, ';'); | |
vector<string> l = parse(remove_parentheses(p.u)); | |
vector<string> r = parse(remove_parentheses(p.v)); | |
v.push_back(">" + to_string(l.size() + 3)); // переход на второй операнд | |
shift_numeration(l, 1); // сдвигаем адресацию первого операнда | |
v.insert(v.end(), l.begin(), l.end()); // вставляем его | |
shift_numeration(r, l.size()+2); // сдвигаем адресацию второго операнда | |
v.push_back("&" + to_string(l.size() + r.size() + 3)); // переход через второй операнд после обработки первого | |
v.insert(v.end(), r.begin(), r.end()); // вставляем второй операнд | |
// Остальные операторы обрабатываются аналогично | |
} | |
else if (last_top_level(s, ',') != -1) { | |
p = unfold(s, ','); | |
vector<string> l = parse(remove_parentheses(p.u)); | |
vector<string> r = parse(remove_parentheses(p.v)); | |
v.insert(v.end(), l.begin(), l.end()); | |
shift_numeration(r, l.size()); | |
v.insert(v.end(), r.begin(), r.end()); | |
} | |
else if (last_top_level(s, '#') != -1) { | |
p = unfold(s, '#'); | |
vector<string> l = parse(remove_parentheses(p.u)); | |
vector<string> r = parse(remove_parentheses(p.v)); | |
v.insert(v.end(), l.begin(), l.end()); | |
v.push_back(">" + to_string(l.size() + r.size() + 3)); | |
shift_numeration(r, l.size()+2); | |
v.insert(v.end(), r.begin(), r.end()); | |
v.push_back("&" + to_string(1)); | |
} | |
else if (last_top_level(s, '+') != -1) { | |
p = unfold(s, '+'); | |
vector<string> l = parse(remove_parentheses(p.u)); | |
v.insert(v.end(), l.begin(), l.end()); | |
v.push_back(">" + to_string(l.size() + 3)); | |
v.push_back("&" + to_string(1)); | |
} | |
else if (last_top_level(s, '*') != -1) { | |
p = unfold(s, '*'); | |
vector<string> l = parse(remove_parentheses(p.u)); | |
v.push_back(">" + to_string(l.size() + 3)); | |
shift_numeration(l, 1); | |
v.insert(v.end(), l.begin(), l.end()); | |
v.push_back("&" + to_string(1)); | |
} | |
else { | |
v.push_back(s); | |
} | |
return v; | |
} | |
vector<string> process_rule(string s) { // функция, обрабатывающая одно правило | |
vector<string> t; | |
str_pair p = unfold(s, ':'); | |
t.push_back("BEG<" + p.u + ">"); | |
vector<string> l = parse(p.v); | |
shift_numeration(l, 1); | |
t.insert(t.end(), l.begin(), l.end()); | |
t.push_back("END<" + p.u + ">"); | |
return t; | |
} | |
int main() { | |
ifstream file; | |
file.open("gram.txt", std::ifstream::in); | |
string s; | |
int shift = 0; | |
while (getline(file, s)) { | |
vector<string> t = process_rule(s); | |
shift_numeration(t, shift); | |
for (int i = 0; i < t.size(); ++i) { | |
cout << i+shift+1 << ": " << t.at(i) << endl; | |
} | |
shift += t.size(); | |
cout << endl; | |
cout << endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment