给出这样的输入(USER DEFINED FORMAT):
type dog<
int years
char[] name
>
如何生成2个或更多这样的不同文件:
file1.c
------------
struct dog{
int years
char name
}
file2.cpp
-------------
class dog{
int years
string name
%get and set methods
}
像flex和bison这样的解析器生成器是最好的方法吗?或者有更好的方法吗?
答案 0 :(得分:0)
这一切都取决于您的语言的互补性和您想要的转变。
选项1:手工制作的临时处理
如果您的转换很简单,并且主要将源语言中的某些令牌转换为目标语言(例如,将“type”转换为“struct”,将“&lt;&gt;”转换为“{}”),您可以想到一只手使用字符串操作进行解析,或使用regexes进行std::regex
。
但这还不够:你必须在源代码中识别语句,以生成半列分隔的c和c ++语句。此外,您必须将[]
与正确的元素相关联。此外,要生成正确的getter / setter,您的代码必须了解语句内容。
所以是的,在这里你需要一个词法分析器和一个解析器。
选项2:手工制作的解析器
对于“简单”语言,您可以轻松制作a recursive descent parser。 “简单”是什么意思?它意味着可以用LL(1)语法描述的语言。如果现在没有在编译器理论中输入太多,那么或多或少的语言中前面的一个标记唯一地确定了你拥有的语法结构。
请注意,您在Bjarne Stroustrup的“ C ++编程语言”中设计了一个非常简单的计算器示例。
选项3:使用编译器生成器
虽然词法扫描器和递归下降解析器相对容易编码,但它仍然以某种方式重新发明轮子。对于不符合LL(1)的语言,除了使用编译器生成器之外别无选择。
Flex / bison是一个非常合理且受到广泛支持的选择。但您必须熟悉其逻辑,语法文件和代码模板。这不是你可以在几个小时内掌握的东西。
如果您必须专业地支持自定义语言,那么投资确实值得。如果这是一个小项目,学习曲线可能会对你不利。
选项4:轻量级提升替代
另一种更轻松的方法可能是使用boost spirit,它基于c ++而且更容易学习:你直接用C ++表达语法规则。还有太多主要组件:词法扫描程序为Lex,解析程序为Qi。
适用于中小型解析器(如数据定义语言),但如果您使用完整语言,则可以some serious limitations。顺便说一下,据我所知,它仅限于LL(k)语法。