ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

03-编译小Parser

2021-04-19 23:32:18  阅读:216  来源: 互联网

标签:03 visitor Parser MyTestLVisitor 编译 antlr4 new include delete


可以使用很多工具编译之,因为我们的运行时库是VS构建的,为了不出问题也为了操作简单,仍旧使用VS建立项目。

建立工程

创建一个TestL的Cpp空项目,并将Cpp文件复制到工程文件中去。注意只要cpp和h文件就可以,其他的辅助文件不需要。然后将所有的文件添加到工程中。

新建一个main.cpp文件,写一个做简单的helloworld程序,如下:

#include <iostream>

int main(int argc, char** argv) {
	std::cout << "Hello World" << std::endl;
	return 0;
}

配置项目,把运行时库添加进来。如下:
includelib目录lib文件
然后编译测试一下。正常情况下会出现大量C4251警告,但这是Antlr运行时的问题,忽略就好了。如果没有报错,说明配置正确,可以进行下一步的工作了。

Visitor模式与Listener模式

这两种模式有本质的区别,但其实都能完成工作,个人喜欢visitor模式。具体请参看官方文档。

TestLVisitor类是接口类,TestLBaseVisitor是其默认实现,但我们往往需要修改一些默认实现,所以这里新建一个MyTestLVisitor类,继承自TestLBaseVisitor类,并重新实现接口方法。

visitDoc没必要重新实现,visitItem重新实现,我们希望当解析出一个item的时候输出到屏幕上。

在MyTestLVisitor.h中,代码如下:

#pragma once

#include "antlr4-runtime.h"
#include "TestLBaseVisitor.h"
#include <iostream>

class MyTestLVisitor :
    public TestLBaseVisitor
{
    virtual antlrcpp::Any visitItem(TestLParser::ItemContext* ctx) override {
        std::cout << "Name:" << ctx->STRING()->getText()
            << "Age:" << ctx->NUM().at(0)->getText()
            << "Height" << ctx->NUM().at(1)->getText()
            << std::endl;
        return defaultResult();
    }
};


ctx,就是识别出来的那个结构,这里是item。每一个item只包含一个STRING数据,所以STRING()方法返回一个对象,如果是多个,则返回一个vector。

解析过程

在main.cpp里面修改代码如下:

#include "antlr4-runtime.h"
#include "TestLLexer.h"
#include "TestLParser.h"
#include "MyTestLVisitor.h"

int main(int argc, char** argv) {
	// 建立一个字符流,可以从input,可以从文件。
	antlr4::ANTLRFileStream* file = new antlr4::ANTLRFileStream();
	file->loadFromFile("test.txt");
	// 词法分析,生成token流
	TestLLexer* lexer = new TestLLexer(file);
	antlr4::CommonTokenStream* tokenstream = new antlr4::CommonTokenStream(lexer);
	// 语法分析,并使用visitor处理ast。
	TestLParser* parser = new TestLParser(tokenstream);
	MyTestLVisitor* visitor = new MyTestLVisitor();
	visitor->visit(parser->doc());
	// 释放内存
	delete visitor;
	delete parser;
	delete tokenstream;
	delete lexer;
	delete file;
	return 0;
}

编译。生成一个TestL.exe,把antlr4-runtime.dll复制过来(或者设置调试环境也行,随便了),在同目录下建立一个test.txt文件(源码中写死了),并在其中写入以下内容:

Name{小强}Age{11}Height{23}
Name{小强}Age{11}Height{23}

注意txt文件的编码格式如果是ANSI,直接运行,如果是UTF8,需要用chcp 65001切换代码页,不然是乱码。得到如下结果:

结果
可以看到,我们自定义的visitor成功的解析了文本数据,并执行了我们自定义的动作。

小结

本文和前面一篇,就是使用antlr进行结构化文本数据处理的简单完整的流程,当然有很多地方并没有覆盖到,比如复杂规则的定义(岛语言,左递归等),比如解析过程中的错误处理等等。有时间再写那些东西吧,比较蛋疼。

标签:03,visitor,Parser,MyTestLVisitor,编译,antlr4,new,include,delete
来源: https://blog.csdn.net/xuanjueheshang/article/details/115875307

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有