首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >ANTLR -保持块不变

ANTLR -保持块不变
EN

Stack Overflow用户
提问于 2013-01-29 13:16:51
回答 1查看 120关注 0票数 2

我是一个使用ANTLR的初学者,我需要修改一个现有的和复杂的语法。

我想要创建一个规则来保留一个块,而不需要与其他规则进行解析。为了更清楚地说明,我需要在解释的代码中插入用c++编写的代码。

编辑11/02/2013

经过多次测试,这里是我的语法,我的测试,我的结果,以及结果和想要的:

语法

代码语言:javascript
运行
复制
cppLiteral
    : cppBegin cppInnerTerm cppEnd
    ;
cppBegin
    :  '//$CPP_IN$'
    ;
cppEnd
    : '//$CPP_OUT$'
    ;
cppInnerTerm
    : ( ~('//$CPP_OUT$') )*
    ;

测试

代码语言:javascript
运行
复制
//$CPP_IN$
txt1 txt2
//$CPP_OUT$

结果

代码语言:javascript
运行
复制
cppLiteral ->
cppBegin = '//$CPP_IN$'
cppInnerTerm = 'txt1' 'txt2'
cppEnd = '//$CPP_OUT$'

预期结果

代码语言:javascript
运行
复制
cppLiteral ->
cppBegin = '//$CPP_IN$'
cppInnerTerm = 'txt1 txt2'
cppEnd = '//$CPP_OUT$'

(对不起,我不能贴出AST的照片,因为我没有10个名誉)

三个令牌"cppBegin“、"cppInnerTerm”和"cppEnd“可以放在一个令牌中,如下所示:

代码语言:javascript
运行
复制
cppLiteral
    : '//$CPP_IN$'( ~('//$CPP_OUT$') )*'//$CPP_OUT$'
    ;

为了取得这样的结果:

代码语言:javascript
运行
复制
cppLiteral = '//$CPP_IN$\n txt1 txt2\n //$CPP_OUT$'
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-12 04:14:41

我想要创建一个规则来保留一个块,而不需要与其他规则进行解析。

像多行注释一样解析它,例如/* foobar */。下面是一个使用您问题中指定的关键字的小示例。

请注意,大部分工作都是用lexer规则(以大写字母开头的规则)完成的。当您想要处理文本块时,特别是如果您想避免使用其他规则(在本例中),您可能会考虑的是lexer规则,而不是解析器规则。

CppBlock.g

代码语言:javascript
运行
复制
grammar CppBlock;

document: CPP_LITERAL* EOF;


fragment CPP_IN:'//$CPP_IN$';
fragment CPP_OUT:'//$CPP_OUT$';
 
CPP_LITERAL:  CPP_IN .* CPP_OUT
            {
                String t = getText(); 
                t = t.substring(10, t.length() - 11); //10 = length of CPP_IN, 11 = length of CPP_OUT
                setText(t);
            }
            ;
WS: (' '|'\t'|'\f'|'\r'|'\n')+ {skip();};

下面是一个简单的测试用例:

输入

代码语言:javascript
运行
复制
//$CPP_IN$
static const int x = 0; //magic number
int *y; //$CPP_IN$ <-- junk comment
static void foo(); //forward decl...
//$CPP_OUT$

//$CPP_IN$
//Here is another block of CPP code...
const char* msg = ":D";
//The end.
//$CPP_OUT$

输出令牌

代码语言:javascript
运行
复制
[CPP_LITERAL : 
static const int x = 0; //magic number
int *y; //$CPP_IN$ <-- junk comment
static void foo(); //forward decl...
]
[CPP_LITERAL : 
//Here is another block of CPP code...
const char* msg = ":D";
//The end.
] 

规则CPP_LITERAL在输入的开头和结尾保留换行符(在//$CPP_IN$之后和//$CPP_OUT$之前)。如果你不想要这些,只需更新动作,把它们去掉。否则,我认为这个语法能满足你的要求。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14583843

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档