-1

我正在创建一个 CLI,但无法解析这样的代码:

io.print("Hello World!");

我将如何在不滥用 if 语句逐个字符解析代码的情况下解析这样的内容?

我希望控制台在窗口上打印这个:

Hello World!
4

2 回答 2

2

从技术上讲,这可以解决您的问题,如下所述:

std::map< std::string, std::function<void()> > program_map;

void define_programs() {
  program_map[ "io.print("Hello World!");\n" ] = []{
    std::cout << "Hello World!\n";
  };
  program_map[ "io.print("Goodbye World!");\n" ] = []{
    std::cout << "Goodbye World!\n";
  };
};

int main() {
  // load parser:
  define_programs();
  // read program from user:
  std::string s;
  std::cin >> s;
  // compile and execute:
  if (program_map.find( s ) != program_map.end()) {
    (*program_map.find( s ))();
  } else {
    std::cout << "ERROR: unknown program.\n";
  }
}

但它可能无法解决您想要解决的问题。

通常,解析 C 或 C++ 类语言需要大量工作。您可以通过制作更易于解析的语言来使您的工作更轻松(类似 LISP 的语法非常容易解析)。

如果您确实想解析类似 C/C++ 的语言,我建议您学习语法和词法分析器。有完整的本科课程以为比 C/C++ 更简单的语言编写编译器结束——尤其是 C++ 是一种很难解析的语言,通常你不希望完全遵循它的约定。

为您的语法设计语法和编写词法分析器(或教授预先编写的词法分析器)应该齐头并进。

当我设计玩具语言时,我通常让它们像 LISP,因为像 LISP 的语言真的很容易使用。所以你有一个命令初始化器(,一个命令,一个参数列表(可能是 futher ('d),当你到达匹配的).

所以相当于你的代码是:

(io print "Hello World")

现在我有了io命令(对象实例将是各种“命令”)和方法 print(它从插槽 2 读取),以及所述方法“Hello World”的参数。结果,如果我感觉功能正常,那将是一个打印的程序Hello World——如果不是,它会作为副作用执行此操作并返回错误代码或不返回任何内容。

然后我会围绕它编写一个环境来定义一些命令(包括“make object”),可能是某种引用语法(所以我可以定义 lambdas)等等。我最终会得到一种设计不佳的语言, 次优的, 小部分 common lisp 的受限实现, 这是传统的。

只有在我可以做类似上述的事情之后,我才会考虑为像 C/C++ 这样更难解析的语言编写一个解析器。即便如此,我还是先将上面的玩具语言重写为一些词法分析/解析框架,然后在同一个框架中编写我的 C/C++ 类语言。

于 2013-04-26T19:41:57.783 回答
0

这就是你在 C++ 中编写 HelloWorld 的方式:

#include <iostream>

int main() {
  std::cout << "Hello World!";
  return 0;
}

该字符串将在编译时进行解析,因此无需担心打印效率低下。

如果我误解了你的问题(我只知道 CLI 代表命令行界面),而你真的想解析 C++ 源代码。我建议您阅读有关 yacc 之类的工具的教程,并从开源 C 语法开始。

这是一个很好的 yacc 教程: http ://www.ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html

这是语法的一个很好的起点:http: //www.computing.surrey.ac.uk/research/dsrg/fog/CxxGrammar.y

于 2013-04-26T18:30:03.803 回答