Tuesday, 20 September 2016

程序员修炼之道读书笔记 24 code generator 实现



Exercises 13.
Write a code generator that takes the input file in
Figure 3.4, and generates output in two languages of
your choice. Try to make it easy to add new languages

下面是C++ 实现,只对例题中给出的例子有效,很多代码时hard code,如果要更generic 实现,可以修改实现。 由此可以如果是使用Python 或perl 脚本实现会容易的多,C++,C需要考虑过多的细节,不太适合文本操作,过于复杂。

-bash-4.2$ cat codeGenerator.cpp
// This cpp file is used to generate source code for C and Pascal automatically
#include<iostream>
#include<string>
#include<string.h>
#include <fstream>
using namespace std;

string getElementN(string &str, int n) {
  //assert(n >= 0 && n <=4);
  string strWords[5];
  int counter = 0;

  for(short i=0;i<str.length();i++){
      if(str[i] == ' '){
          counter++;
          i++;
      }
      if (str[i] != ' ')
        strWords[counter] += str[i];
  }

  return strWords[n];
}

void CGenerator() {
  string line;
  ifstream fin ("msg.def");
  ofstream fout ("msg.c");
  if (fin.is_open() && fout.is_open())
  {
    string structName;
    string charArray;
    while ( getline (fin,line) )
    {
      switch ((char)line[0]) {
        case 'M':
          fout << "typedef struct {" << '\n';
          structName = line.substr(2);
          break;
        case 'F':
          charArray = getElementN(line, 2);
          if (charArray.substr(0,3) == "char")
            fout << "  char " << getElementN(line, 1) << charArray.substr(4) << ";" << '\n';
          else
            fout << "  " << getElementN(line, 2) << " " << getElementN(line, 1) << ";"  << '\n';
          break;
        case 'E':
          fout << "} " << structName << ";" <<  '\n';
          break;
        default:
           cerr << "Unsupported type! " << endl;
           break;
      }
    }
    fin.close();
    fout.close();
  }
  else cout << "Unable to open file";
}
void PascalGCenerator() {}
int main(void) {
  CGenerator();
  //PascalGenerator(); //Similarly, you can implement PascalGeneator
  return 0;
}

Input file:
-bash-4.2$ cat msg.def
M AddProduct
F id  int
F name  char[30]
F order_code int
E

Generated file:
-bash-4.2$ cat msg.c
typedef struct {
  int id;
  char[30] name;
  int order_code;
} AddProduct;

No comments:

Post a Comment